tabby-agentdeck 0.2.1 → 0.3.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","mappings":"AAAA;AACA;AACA,4JAA4J,MAAM,8BAA8B,aAAa;AAC7M;AACA;AACA;AACA,iLAAiL,MAAM,8BAA8B,aAAa;AAClO;AACA;AACA,CAAC;AACD,O;;;;;;;;;;;;;;;;;;ACVA;AAC0G;AACjB;AACzF,8BAA8B,mFAA2B,CAAC,4FAAqC;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,OAAO,kFAAkF,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,MAAM,KAAK,UAAU,WAAW,UAAU,WAAW,WAAW,UAAU,WAAW,WAAW,KAAK,KAAK,YAAY,MAAM,KAAK,YAAY,MAAM,KAAK,YAAY,MAAM,KAAK,YAAY,MAAM,KAAK,UAAU,UAAU,WAAW,UAAU,WAAW,KAAK,KAAK,UAAU,KAAK,KAAK,UAAU,WAAW,WAAW,WAAW,WAAW,UAAU,WAAW,WAAW,WAAW,UAAU,KAAK,KAAK,WAAW,KAAK,KAAK,WAAW,UAAU,WAAW,WAAW,KAAK,KAAK,WAAW,KAAK,OAAO,UAAU,UAAU,UAAU,WAAW,KAAK,MAAM,WAAW,MAAM,KAAK,WAAW,MAAM,MAAM,UAAU,UAAU,UAAU,WAAW,KAAK,KAAK,WAAW,MAAM,KAAK,WAAW,MAAM,KAAK,WAAW,WAAW,WAAW,WAAW,WAAW,KAAK,KAAK,UAAU,WAAW,WAAW,WAAW,KAAK,KAAK,UAAU,KAAK,KAAK,WAAW,WAAW,KAAK,KAAK,WAAW,MAAM,MAAM,WAAW,UAAU,WAAW,UAAU,WAAW,WAAW,WAAW,UAAU,WAAW,MAAM,MAAM,WAAW,MAAM,MAAM,UAAU,OAAO,MAAM,WAAW,MAAM,MAAM,UAAU,OAAO,MAAM,UAAU,WAAW,WAAW,MAAM,MAAM,UAAU,UAAU,MAAM,MAAM,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,MAAM,MAAM,UAAU,WAAW,UAAU,UAAU,WAAW,WAAW,WAAW,MAAM,MAAM,UAAU,WAAW,WAAW,MAAM,MAAM,WAAW,WAAW,MAAM,MAAM,UAAU,WAAW,UAAU,UAAU,UAAU,WAAW,MAAM,MAAM,UAAU,WAAW,WAAW,WAAW,WAAW,MAAM,MAAM,WAAW,MAAM,MAAM,UAAU,WAAW,WAAW,UAAU,MAAM,MAAM,UAAU,UAAU,UAAU,WAAW,WAAW,WAAW,UAAU,WAAW,UAAU,MAAM,MAAM,WAAW,MAAM,MAAM,UAAU,WAAW,UAAU,UAAU,UAAU,UAAU,WAAW,UAAU,WAAW,WAAW,UAAU,UAAU,UAAU,WAAW,MAAM,MAAM,WAAW,WAAW,MAAM,MAAM,UAAU,UAAU,UAAU,WAAW,MAAM,MAAM,UAAU,WAAW,WAAW,WAAW,WAAW,WAAW,UAAU,UAAU,MAAM,MAAM,WAAW,UAAU,MAAM,MAAM,UAAU,UAAU,UAAU,UAAU,OAAO,MAAM,UAAU,UAAU,WAAW,UAAU,WAAW,WAAW,WAAW,WAAW,UAAU,WAAW,MAAM,MAAM,WAAW,WAAW,WAAW,UAAU,MAAM,MAAM,WAAW,UAAU,OAAO,MAAM,UAAU,UAAU,UAAU,WAAW,OAAO,MAAM,UAAU,UAAU,WAAW,WAAW,WAAW,WAAW,OAAO,MAAM,UAAU,UAAU,UAAU,WAAW,WAAW,WAAW,WAAW,WAAW,UAAU,WAAW,WAAW,MAAM,MAAM,UAAU,UAAU,WAAW,WAAW,MAAM,MAAM,WAAW,WAAW,MAAM,MAAM,YAAY,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,QAAQ,MAAM,UAAU,MAAM,MAAM,WAAW,OAAO,MAAM,WAAW,MAAM,MAAM,UAAU,WAAW,WAAW,WAAW,uZ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ACA,qBAAqB;AACrB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,iBAAiB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,sFAAsF,qBAAqB;AAC3G;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,iDAAiD,qBAAqB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,sDAAsD,qBAAqB;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;;;;;ACpFa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,cAAc;AACrE;AACA;AACA;AACA;AACA,E;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACdA,MAA+F;AAC/F,MAAqF;AACrF,MAA4F;AAC5F,MAA+G;AAC/G,MAAwG;AACxG,MAAwG;AACxG,MAA6I;AAC7I;AACA;;AAEA;;AAEA,4BAA4B,qGAAmB;AAC/C,wBAAwB,kHAAa;;AAErC,uBAAuB,uGAAa;AACpC;AACA,iBAAiB,+FAAM;AACvB,6BAA6B,sGAAkB;;AAE/C,aAAa,0GAAG,CAAC,6HAAO;;;;AAIuF;AAC/G,OAAO,iEAAe,6HAAO,IAAI,6HAAO,UAAU,6HAAO,mBAAmB,EAAC;;;;;;;;;;;AC1BhE;;AAEb;AACA;AACA;AACA,kBAAkB,wBAAwB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,iBAAiB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,4BAA4B;AAChD;AACA;AACA;AACA;AACA;AACA,qBAAqB,6BAA6B;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;;;;;ACnFa;;AAEb;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kC;;;;;;;;;;ACjCa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oC;;;;;;;;;;ACTa;;AAEb;AACA;AACA,cAAc,KAAwC,GAAG,sBAAiB,GAAG,CAAI;AACjF;AACA;AACA;AACA;AACA,gD;;;;;;;;;;ACTa;;AAEb;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA,iFAAiF;AACjF;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,yDAAyD;AACzD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,wB;;;;;;;;;;AC5Da;;AAEb;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,mC;;;;;;;;;;;;;;ACJA,0CAA0C;AACnC,MAAM,aAAa,GAAoC;IAC1D,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;IACtD,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;IACvD,IAAI,EAAK,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;IACrD,KAAK,EAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;IACrD,IAAI,EAAK,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;CACxD;;;;;;;;;;;;;;;ACQM,SAAS,aAAa,CAAK,IAA0B,EAAE,OAAyB;IACnF,MAAM,MAAM,GAAG,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrE,IAAI,OAAO,GAAG,KAAK;IACnB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE;QACjC,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,OAAO,GAAG,IAAI;YACd,MAAK;SACR;KACJ;IACD,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE;QAC5B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE;KACvC;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE;QAC/B,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;YAC5B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE;SAC9B;KACJ;IACD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE;AAC1C,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3CuB;AACA;AACI;AAE5B;;;;;;;;;;;GAWG;AAEH,4CAA4C;AAC5C,MAAM,IAAI,GAAG,kBAAkB;AAE/B;;;;;;;GAOG;AACH,MAAM,IAAI,GAAsC;IAC5C,UAAU;IACV,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,iBAAiB,EAAE;IACtD,WAAW;IACX,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,iBAAiB,EAAE;IAClD,SAAS;IACT,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE;CAC1C;AAEM,SAAS,kBAAkB;IAC9B,OAAO,sCAAS,CAAC,uCAAU,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC;AAC9D,CAAC;AAED,wDAAwD;AACjD,SAAS,gBAAgB;IAC5B,OAAO,sCAAS,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,sBAAsB,CAAC;AACtE,CAAC;AAED,6DAA6D;AACtD,SAAS,cAAc;IAC1B,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,0CAAa,CAAC,gBAAgB,EAAE,CAAC;AAC5E,CAAC;AAED,SAAS,YAAY;IACjB,IAAI;QACA,MAAM,GAAG,GAAG,4CAAe,CAAC,kBAAkB,EAAE,EAAE,MAAM,CAAC;QACzD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;KAC3C;IAAC,MAAM;QACJ,wCAAwC;QACxC,OAAO,EAAE;KACZ;AACL,CAAC;AAED,oCAAoC;AACpC,SAAS,WAAW,CAAE,OAAY;IAC9B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;SACzC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,aAAD,CAAC,cAAD,CAAC,GAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACI,SAAS,QAAQ,CAAE,QAAa;;IACnC,MAAM,KAAK,GAAG,cAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,mCAAI,EAAE;IACnC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QAClB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;QACnE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,aAAD,CAAC,cAAD,CAAC,GAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC,CAAC;AACN,CAAC;AAED;;;GAGG;AACI,SAAS,UAAU,CAAE,QAAa,EAAE,MAAc;;IACrD,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,CAAC,EAAE;IACpC,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,CAAC,UAAI,CAAC,KAAK,mCAAI,EAAE,CAAC,EAAE;IACtC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE;QAClB,MAAM,OAAO,GAAG,wDAAwD,MAAM,KAAK,CAAC,CAAC,IAAI,EAAE;QAC3F,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG;YAClB,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACnC,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE;SACtE;KACJ;IACD,OAAO,IAAI;AACf,CAAC;AAED,oDAAoD;AAC7C,SAAS,UAAU,CAAE,QAAa;IACrC,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,CAAC,EAAE;IACpC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;QACb,OAAO,IAAI;KACd;IACD,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE;IAC9B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE;QAClB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI;SAC7B;aAAM;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;SAC7B;KACJ;IACD,OAAO,IAAI;AACf,CAAC;AAEM,SAAS,cAAc;IAC1B,OAAO,QAAQ,CAAC,YAAY,EAAE,CAAC;AACnC,CAAC;AAED,cAAc;AACP,SAAS,YAAY;IACxB,MAAM,MAAM,GAAG,gBAAgB,EAAE;IACjC,IAAI,CAAC,0CAAa,CAAC,MAAM,CAAC,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC;KAC/C;IACD,aAAa,CAAC,UAAU,CAAC,YAAY,EAAE,EAAE,MAAM,CAAC,CAAC;AACrD,CAAC;AAED,YAAY;AACL,SAAS,cAAc;IAC1B,aAAa,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,aAAa,CAAE,QAAa;IACjC,MAAM,IAAI,GAAG,kBAAkB,EAAE;IACjC,yCAAY,CAAC,yCAAY,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACrD,kCAAkC;IAClC,IAAI,0CAAa,CAAC,IAAI,CAAC,EAAE;QACrB,4CAAe,CAAC,IAAI,EAAE,IAAI,GAAG,mBAAmB,CAAC;KACpD;IACD,6CAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC;AAC5E,CAAC;;;;;;;;;;;;;;;;;;AC5I0C;AAE3C;;;GAGG;AACI,MAAM,eAAe,GAAG;IAC3B;;;OAGG;IACH,WAAW,EAAE,OAAO;IACpB;;;;OAIG;IACH,YAAY,EAAE,CAAC;IACf,4CAA4C;IAC5C,aAAa,EAAE,GAAG;CACrB;AAED,cAAc;AACP,MAAM,uBAAwB,SAAQ,sDAAc;IAA3D;;QACI,aAAQ,GAAG;YACP,SAAS,EAAE;gBACP,0BAA0B;gBAC1B,OAAO,EAAE,IAAI;gBACb,uBAAuB;gBACvB,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,CAAC;gBACV;;;;mBAIG;gBACH,UAAU,EAAE,GAAG;gBACf,UAAU,EAAE,GAAG;gBACf,0DAA0D;gBAC1D,GAAG,eAAe;gBAClB;;;;;;;mBAOG;gBACH,UAAU,EAAE,KAAK;gBACjB;;;;;;;;mBAQG;gBACH,aAAa,EAAE,IAAI;gBACnB;;;;;mBAKG;gBACH,mBAAmB,EAAE,KAAK;gBAC1B,8CAA8C;gBAC9C,WAAW,EAAE,IAAI;gBACjB,0BAA0B;gBAC1B,UAAU,EAAE,IAAI;gBAChB,qBAAqB;gBACrB,WAAW,EAAE,IAAI;gBACjB;;;;;;;mBAOG;gBACH,uBAAuB,EAAE,IAAI;gBAC7B,wDAAwD;gBACxD,gDAAgD;gBAChD;;;;mBAIG;gBACH,YAAY,EAAE,IAAI;gBAClB;;;;;;;;;mBASG;gBACH,UAAU,EAAE,IAAI;gBAChB;;;;;;mBAMG;gBACH,mBAAmB,EAAE,IAAI;gBACzB;;;;;;;;;;mBAUG;gBACH,aAAa,EAAE,OAAO;gBACtB;;;;;mBAKG;gBACH,eAAe,EAAE,IAAI;gBACrB,+CAA+C;gBAC/C,gBAAgB,EAAE,GAAG;gBAErB;;;;;;;;;;;;mBAYG;gBACH,eAAe,EAAE,EAAE;gBACnB,mDAAmD;gBACnD,cAAc,EAAE,EAAE;gBAClB;;;;;;;;mBAQG;gBACH,wBAAwB,EAAE,IAAI;gBAC9B,oEAAoE;gBACpE,uDAAuD;gBACvD,kEAAkE;gBAClE,+DAA+D;gBAC/D,8CAA8C;gBAE9C;;;;;;;;mBAQG;gBACH;;;;;;;;;;;;;;;mBAeG;gBACH;;;;;;;;;;;;;;;;;;;;mBAoBG;gBACH;;;;;;;;;;;;mBAYG;gBACH,gBAAgB,EAAE,KAAK;gBACvB;;;;;;;;;mBASG;gBACH,WAAW,EAAE,IAAI;gBACjB,yCAAyC;gBACzC,oBAAoB,EAAE,KAAK;gBAC3B;;;;mBAIG;gBACH,mBAAmB,EAAE,CAAC;gBACtB;;;mBAGG;gBACH,mBAAmB,EAAE,CAAC;gBACtB;;;;mBAIG;gBACH,UAAU,EAAE,KAAK;gBACjB;;;mBAGG;gBACH,mBAAmB,EAAE,IAAI;gBAEzB;;;;;;mBAMG;gBACH,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,mDAAmD;gBACnD,qBAAqB;gBACrB,cAAc,EAAE,EAAE;gBAClB,kBAAkB,EAAE,gBAAgB;gBACpC;;;;mBAIG;gBACH,eAAe,EAAE,CAAC,SAAS,EAAE,kBAAkB,EAAE,QAAQ,CAAC;gBAC1D;;;mBAGG;gBACH,cAAc,EAAE;oBACZ,IAAI,EAAE,gBAAgB;oBACtB,SAAS,EAAE,WAAW;oBACtB,WAAW,EAAE,GAAG;iBACnB;gBACD,oDAAoD;gBACpD,kBAAkB,EAAE,KAAK;aAC5B;YACD,OAAO,EAAE;gBACL,kBAAkB,EAAE,EAAE;gBACtB;;;mBAGG;gBACH,mBAAmB,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC;gBAClD;;;mBAGG;gBACH,iBAAiB,EAAE,CAAC,QAAQ,CAAC;aAChC;SACJ;IACL,CAAC;CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/SiD;AAC0E;AACvE;AAC7B;AACA;AACI;AACwB;AACgB;AACnB;AACT;AACU;AACyC;AAE3F,MAAM,UAAU,GAAG,mBAAmB;AACtC,MAAM,UAAU,GAAG,kBAAkB;AACrC,mEAAmE;AACnE,MAAM,aAAa,GAAG,YAAY;AAElC,sDAAsD;AACtD,MAAM,UAAU,GAAG,GAAG;AACtB,MAAM,UAAU,GAAG,GAAG;AACtB,uDAAuD;AACvD,MAAM,aAAa,GAAG,GAAG;AACzB,MAAM,aAAa,GAAG,EAAE;AAExB,uDAAuD;AACvD,MAAM,oBAAoB,GAAG,EAAE;AAC/B;;;;;;GAMG;AACH,MAAM,eAAe,GAAG,EAAE;AAC1B,mDAAmD;AACnD,MAAM,cAAc,GAAG,IAAI;AAC3B,uDAAuD;AACvD,MAAM,gBAAgB,GAAG,EAAE;AAE3B;;;;GAIG;AACH,MAAM,sBAAsB,GAAG,GAAG;AAClC,kDAAkD;AAClD,MAAM,aAAa,GAAG,IAAI;AAC1B,wDAAwD;AACxD;;;GAGG;AACH,MAAM,wBAAwB,GAAG,GAAG;AACpC;;;GAGG;AACH,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC;AACvD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,oBAAoB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC;AAC7C,kDAAkD;AAClD,MAAM,eAAe,GAAG,IAAI;AAC5B,mCAAmC;AACnC,MAAM,kBAAkB,GAAG,GAAG;AAC9B,MAAM,mBAAmB,GAAG,EAAE;AAC9B,MAAM,SAAS,GAAG,sCAAS,CAAC,uCAAU,EAAE,EAAE,qBAAqB,CAAC;AAChE;;;;;GAKG;AACH,MAAM,SAAS,GAAG,sCAAS,CAAC,uCAAU,EAAE,EAAE,uBAAuB,CAAC;AAQlE,IAAI,eAAqD;AAEzD;;;;;;GAMG;AACH,SAAS,YAAY;;IACjB,IAAI,eAAe,KAAK,SAAS,EAAE;QAC/B,OAAO,eAAe;KACzB;IACD,6EAA6E;IAC7E,wDAAwD;IACxD,0DAA0D;IAC1D,IAAI;QACA,eAAe,GAAG,+BAAO,CAAC,0BAAU,CAAC,0CAAE,SAAS,mCAAI,IAAI;KAC3D;IAAC,MAAM;QACJ,eAAe,GAAG,IAAI;KACzB;IACD,IAAI,CAAC,eAAe,EAAE;QAClB,IAAI;YACA,MAAM,GAAG,GAAG,MAAC,MAAc,CAAC,OAAO,mCAAK,UAAkB,CAAC,OAAO;YAClE,eAAe,GAAG,eAAG,aAAH,GAAG,uBAAH,GAAG,CAAG,UAAU,CAAC,0CAAE,SAAS,mCAAI,IAAI;SACzD;QAAC,MAAM;YACJ,eAAe,GAAG,IAAI;SACzB;KACJ;IACD,OAAO,eAAe;AAC1B,CAAC;AAED,SAAS,QAAQ,CAAE,KAAc;IAC7B,MAAM,CAAC,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;IACpE,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS,CAAE,KAAa,EAAE,GAAW;IAC1C,MAAM,CAAC,GAAG,wCAAwC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACrE,IAAI,CAAC,CAAC,EAAE;QACJ,OAAO,KAAK;KACf;IACD,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,GAAG,IAAI,GAAG,EAAE;QACZ,OAAO,GAAG;KACb;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;IACvE,OAAO,GAAG,GAAG,KAAK;AACtB,CAAC;AAED;;;;;;;;;;GAUG;AAEI,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IA8CzB,YACY,GAAe,EACf,MAAqB,EACrB,MAAyB,EACzB,OAAuB,EACvB,QAAyB,EACzB,UAA6B,EAC7B,IAAY;QANZ,QAAG,GAAH,GAAG,CAAY;QACf,WAAM,GAAN,MAAM,CAAe;QACrB,WAAM,GAAN,MAAM,CAAmB;QACzB,YAAO,GAAP,OAAO,CAAgB;QACvB,aAAQ,GAAR,QAAQ,CAAiB;QACzB,eAAU,GAAV,UAAU,CAAmB;QAC7B,SAAI,GAAJ,IAAI,CAAQ;QApDhB,YAAO,GAAuB,IAAI;QAClC,WAAM,GAAuB,IAAI;QACjC,aAAQ,GAAuB,IAAI;QACnC,WAAM,GAAuB,IAAI;QACjC,aAAQ,GAA0B,IAAI;QACtC,YAAO,GAA4B,IAAI;QACvC,iBAAY,GAAG,KAAK;QAC5B,wCAAwC;QAChC,gBAAW,GAAQ,IAAI;QAC/B,2CAA2C;QACnC,cAAS,GAAG,CAAC,CAAC;QACd,iBAAY,GAAG,CAAC,CAAC;QACzB,gDAAgD;QACxC,aAAQ,GAAoB,IAAI;QACxC,sCAAsC;QAC9B,SAAI,GAA0B,IAAI;QAClC,gBAAW,GAAG,KAAK;QAC3B,sCAAsC;QAC9B,YAAO,GAAG,IAAI,OAAO,EAAoB;QACzC,iBAAY,GAAG,IAAI,OAAO,EAAoB;QACtD,sCAAsC;QAC9B,sBAAiB,GAAG,IAAI,OAAO,EAAyB;QAChE,uBAAuB;QACf,oBAAe,GAAG,IAAI,OAAO,EAA4B;QACjE,4CAA4C;QACpC,cAAS,GAAG,IAAI,OAAO,EAA0E;QACzG,6BAA6B;QACrB,iBAAY,GAAG,IAAI,OAAO,EAA4B;QAC9D,qCAAqC;QAC7B,oBAAe,GAAG,IAAI,OAAO,EAA4B;QACjE,sEAAsE;QAC9D,YAAO,GAAa,EAAE;QAC9B,yBAAyB;QACjB,iBAAY,GAAG,IAAI,GAAG,EAAU;QACxC,qCAAqC;QAC7B,gBAAW,GAAG,CAAC;QACvB,2CAA2C;QACnC,uBAAkB,GAAG,CAAC;QAC9B,yDAAyD;QACjD,kBAAa,GAAG,CAAC;QACzB,uDAAuD;QAC/C,gBAAW,GAAG,CAAC;QACvB,6DAA6D;QACrD,oBAAe,GAAG,CAAC;IAUvB,CAAC;IAEL,IAAI;QACA,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE;;YAC7D,gDAAgD;YAChD,6CAA6C;YAC7C,IAAI;gBACA,IAAI,CAAC,KAAK,EAAE;aACf;YAAC,OAAO,CAAM,EAAE;gBACb,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,gBAAgB,OAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,mCAAI,CAAC,EAAE,CAAC;gBACvE,MAAM,CAAC;aACV;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;OAGG;IACK,QAAQ,CAAE,GAAW,EAAE,IAAY;QACvC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAC5B,OAAM;SACT;QACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC;IACpD,CAAC;IAED,sDAAsD;IAC9C,IAAI,CAAE,IAAY;QACtB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QACvB,IAAI;YACA,8CAAiB,CAAC,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;SAC5C;QAAC,MAAM;YACJ,4BAA4B;SAC/B;IACL,CAAC;IAEO,KAAK;QACT,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC;QACjD,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAC;QACrD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAChB,OAAO,CAAC,IAAI,CAAC,4CAA4C,CAAC;YAC1D,OAAM;SACT;QAED,IAAI;YACA,6CAAgB,CAAC,SAAS,EAAE,EAAE,CAAC;SAClC;QAAC,MAAM;YACJ,qBAAqB;SACxB;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,qBAAqB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAEjF,IAAI,CAAC,YAAY,EAAE;QACnB,IAAI,CAAC,YAAY,EAAE;QACnB,IAAI,CAAC,YAAY,EAAE;QACnB,IAAI,CAAC,2BAA2B,EAAE;QAClC,IAAI,CAAC,iBAAiB,EAAE;QACxB,IAAI,CAAC,mBAAmB,EAAE;QAC1B,IAAI,CAAC,aAAa,EAAE;QACpB,IAAI,CAAC,eAAe,EAAE;QACtB,IAAI,CAAC,eAAe,EAAE;QAEtB,qDAAqD;QACrD,8CAA8C;QAC9C,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACpC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE;YAC/B,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,eAAe,CAAC;QACzD,CAAC,EAAE,IAAI,CAAC;QAER,qBAAqB;QACrB,mDAAmD;QACnD,iCAAiC;QACjC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,EAAE;YACjC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;gBAC7B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;aACrB;YACD,IAAI,CAAC,cAAc,EAAE;QACzB,CAAC,CAAC;QACF,sDAAsD;QACtD,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,GAAG,EAAE;YACrC,IAAI,CAAC,cAAc,EAAE;YACrB,IAAI,CAAC,aAAa,EAAE;QACxB,CAAC,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE;YAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAClB,iEAAiE;YACjE,IAAI,CAAC,aAAa,EAAE;YACpB,IAAI,CAAC,cAAc,EAAE;QACzB,CAAC,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QAE1D,iCAAiC;QACjC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;YAC7B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;SACrB;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE;YAChC,IAAI,CAAC,YAAY,EAAE;YACnB,IAAI,CAAC,YAAY,EAAE;YACnB,IAAI,CAAC,QAAQ,EAAE;YACf,IAAI,CAAC,cAAc,EAAE;QACzB,CAAC,CAAC;QAEF,2DAA2D;QAC3D,gDAAgD;QAChD,4BAA4B;QAC5B,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,eAAe,CAAC;QAEvD,uBAAuB;QACvB,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACzD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;QACpC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAExD,0DAA0D;QAC1D,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;YACpC,IAAI,MAAM,KAAK,kBAAkB,EAAE;gBAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO;gBAC1E,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;aACrB;YACD,IAAI,MAAM,KAAK,mBAAmB,EAAE;gBAChC,IAAI,CAAC,WAAW,EAAE;aACrB;YACD,IAAI,MAAM,KAAK,iBAAiB,EAAE;gBAC9B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;aACzB;YACD,IAAI,MAAM,KAAK,kBAAkB,EAAE;gBAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;aACrB;QACL,CAAC,CAAC;QAEF,mCAAmC;QACnC,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC;QAEpC,IAAI,CAAC,QAAQ,EAAE;QACf,IAAI,CAAC,MAAM,EAAE;QACb,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,oBAAoB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,YAAY,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAG/H;QAAC,MAAc,CAAC,WAAW,GAAG;YAC3B,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC/B,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE;YAC3B,MAAM,EAAE,CAAC,QAA0B,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAC/D,OAAO,EAAE,IAAI,CAAC,OAAO;SACxB;IACL,CAAC;IAED,8BAA8B;IAE9B;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAE,QAA0B,KAAK;QACnC,MAAM,OAAO,GAAG,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS;YACpD,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;YACtB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;QACnB,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,iBAAiB,KAAK,SAAS,OAAO,CAAC,MAAM,EAAE,CAAC;QAErF,uCAAuC;QACvC,IAAI,CAAC,QAAQ,EAAE;QAEf,4DAA4D;QAC5D,qBAAqB,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE;YACnD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE;gBACvB,MAAM,MAAM,GAAG,GAAU;gBACzB,MAAM,KAAK,GAAuB,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU;oBACrE,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE;oBACrB,CAAC,CAAC,CAAC,GAAG,CAAC;gBACX,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;oBACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;iBACxB;aACJ;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACK,UAAU,CAAE,IAAsB;;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;QACvC,MAAM,OAAO,GAAG,IAAW;QAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ;QACjC,MAAM,KAAK,GAAG,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK;QAC7B,oDAAoD;QACpD,4BAA4B;QAC5B,MAAM,IAAI,GAAG,WAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,0CAAE,aAAa;QAC1C,IAAI,CAAC,KAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,WAAW,KAAI,CAAC,KAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,YAAY,GAAE;YAC3C,OAAM;SACT;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QACpC,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,qDAAW,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QAC5E,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,aAAa;YAC9C,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YACtE,CAAC,CAAC,SAAS,EAAE,CAAC;QAElB,qCAAqC;QACrC,IAAI;YACA,oBAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,QAAQ,0CAAE,GAAG,kDAAI;SAC9B;QAAC,MAAM;YACJ,4BAA4B;SAC/B;QACD,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC;QAEhC,mCAAmC;QACnC,IAAI,MAAM,EAAE;YACR,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC;SACpC;QAED,gDAAgD;QAChD,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,EAAE;YACzB,IAAI;gBACA,WAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,qDAAI;aACnB;YAAC,MAAM;gBACJ,gBAAgB;aACnB;SACJ;QACD,IAAI;YACA,WAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,sDAAG,CAAC,EAAE,CAAC,WAAK,CAAC,IAAI,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;SAC7C;QAAC,MAAM,GAAG;QAEX,sDAAsD;QACtD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;QAEzB,oDAAoD;QACpD,qCAAqC;QACrC,IAAI,GAAG,CAAC,mBAAmB,KAAK,KAAK,EAAE;YACnC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,sBAAsB,CAAC;SACrE;QAED,6CAA6C;QAC7C,+BAA+B;QAC/B,UAAU,CAAC,GAAG,EAAE;YACZ,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACnC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,qDAAW,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;YACjE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;QAC7H,CAAC,EAAE,aAAa,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACK,aAAa,CAAE,IAAsB;;QACzC,MAAM,OAAO,GAAG,IAAW;QAC3B,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,UAAU,IAAI,CAAC,cAAO,CAAC,OAAO,0CAAE,IAAI,GAAE;YACnE,OAAM;SACT;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,2BAA2B,CAAC;QACjE,IAAI;YACA,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC;SAC5B;QAAC,MAAM;YACJ,YAAY;SACf;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACK,cAAc,CAAE,IAAsB,EAAE,IAA2C;;QACvF,MAAM,KAAK,GAAG,MAAC,IAAY,CAAC,QAAQ,0CAAE,KAAK;QAC3C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE;YAC7C,OAAO,KAAK;SACf;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK;QACxB,iDAAiD;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;QAC3C,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,EAAE;YAC3C,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE;gBAC1C,IAAI,GAAG,CAAC;gBACR,MAAK;aACR;SACJ;QACD,IAAI,IAAI,GAAG,CAAC,EAAE;YACV,OAAO,KAAK;SACf;QACD,uCAAuC;QACvC,IAAI,KAAK,GAAG,IAAI;QAChB,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACvD,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE;gBAC1C,KAAK,GAAG,CAAC;aACZ;SACJ;QACD,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,yBAAyB,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACpF,IAAI;YACA,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC;SACpC;QAAC,MAAM;YACJ,OAAO,KAAK;SACf;QACD,OAAO,IAAI;IACf,CAAC;IAED,oCAAoC;IAEpC;;;;;OAKG;IACK,mBAAmB,CAAE,IAAsB;QAC/C,0DAA0D;QAC1D,sDAAsD;QACtD,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE;YAChC,OAAM;SACT;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC;QAC7C,IAAI,IAAI,EAAE;YACN,YAAY,CAAC,IAAI,CAAC;SACrB;QACD,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,EAAE;YAC7C,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC;YACnC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAC1B,CAAC,EAAE,wBAAwB,CAAC,CAAC;IACjC,CAAC;IAED,kDAAkD;IAC1C,sBAAsB;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;QACvC,OAAO,GAAG,CAAC,WAAW,KAAK,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,gBAAgB;IAC9D,CAAC;IAED,uCAAuC;IAC/B,WAAW,CAAE,IAAsB;;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE;YACP,OAAM;SACT;QACD,MAAM,OAAO,GAAG,qDAAW,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;QAElD,6BAA6B;QAC7B,oDAAoD;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;QACxC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;QAC1C,wDAAwD;QACxD,kDAAkD;QAClD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,EAAC,CAAC,CAAC,CAAC,aAAO,CAAC,MAAM,mCAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvF,MAAM,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;QAC1F,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACpE,IAAI,OAAO,EAAE;YACT,IAAI,OAAO,CAAC,MAAM,EAAE;gBAChB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,MAAM,EAAE,CAAC;aAC7C;iBAAM,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,EAAE;gBACxB,6CAA6C;gBAC7C,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;aACxC;SACJ;QAED,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YACjB,OAAM;SACT;QACD,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE;YACvB,OAAM;SACT;QACD,oDAAoD;QACpD,mDAAmD;QACnD,kCAAkC;QAClC,IAAI,MAAM,GAAG,CAAC,SAAG,CAAC,mBAAmB,mCAAI,CAAC,CAAC,EAAE;YACzC,OAAM;SACT;QAED,MAAM,OAAO,GAAG,IAAW;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QACtB,MAAM,IAAI,GAAG,UAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAI,CAAC;QAC7C,MAAM,KAAK,GAAG,UAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAI,CAAC;QACjD,MAAM,GAAG,GAAG,SAAG,CAAC,mBAAmB,mCAAI,CAAC;QACxC,MAAM,QAAQ,GAAG,SAAG,CAAC,oBAAoB,mCAAI,IAAI;QAEjD,yCAAyC;QACzC,8CAA8C;QAC9C,IAAI,GAAG,GAAG,IAAI,GAAG,QAAQ,EAAE;YACvB,OAAM;SACT;QACD,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,IAAI,GAAG,EAAE;YACzB,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAC3B,6BAA6B,KAAK,IAAI,GAAG,gBAAgB;kBACvD,+BAA+B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACnE,OAAM;SACT;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,uBAAuB,IAAI,CAAC,IAAI,EAAE;cACjE,SAAS,aAAO,CAAC,IAAI,0CAAE,OAAO,IAAI,aAAO,CAAC,IAAI,0CAAE,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5F,4CAA4C;QAC5C,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACjE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC;QAChC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,wBAAwB,KAAK,GAAG,CAAC,EAAE,CAAC;QAEzE,mDAAmD;QACnD,wDAAwD;QACxD,8DAA8D;QAC9D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ;QACjC,+CAA+C;QAC/C,oDAAoD;QACpD,oDAAoD;QACpD,MAAM,KAAK,GAAG,cAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,0CAAE,IAAI;QACnC,MAAM,KAAK,GAAG,cAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,0CAAE,IAAI;QACnC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,cAAO,CAAC,IAAI,0CAAE,OAAO,MAAK,KAAK,IAAI,cAAO,CAAC,IAAI,0CAAE,IAAI,MAAK,KAAK,CAAC,EAAE;YAChF,IAAI;gBACA,oBAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,QAAQ,0CAAE,GAAG,kDAAI;aAC9B;YAAC,MAAM;gBACJ,yBAAyB;aAC5B;YACD,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC;YAChC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;SAC5B;QACD,uCAAuC;QACvC,oDAAoD;QACpD,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC;QAC/B,IAAI,GAAG,CAAC,mBAAmB,KAAK,KAAK,EAAE;YACnC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,sBAAsB,CAAC;SACrE;QACD,+CAA+C;QAC/C,UAAU,CAAC,GAAG,EAAE;YACZ,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACnC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,qDAAW,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;YACjE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;QAC3H,CAAC,EAAE,aAAa,CAAC;IACrB,CAAC;IAED,oCAAoC;IAC5B,YAAY;QAChB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE;YACjD,OAAM;SACT;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS;QAC9B,IAAI,CAAC,GAAG,EAAE;YACN,OAAM;SACT;QACD,MAAM,MAAM,GAAG,GAAU;QACzB,MAAM,KAAK,GAAuB,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU;YACrE,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE;YACrB,CAAC,CAAC,CAAC,GAAG,CAAC;QACX,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACtB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;SACzB;IACL,CAAC;IAED,mDAAmD;IAC3C,UAAU,CAAE,IAAsB;;QACtC,MAAM,OAAO,GAAG,IAAW;QAC3B,MAAM,KAAK,GAAG,aAAO,CAAC,QAAQ,0CAAE,KAAK;QACrC,MAAM,GAAG,GAAG,WAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,MAAM,0CAAE,MAAM;QACjC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,UAAU,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE;YAChE,OAAO,IAAI;SACd;QACD,qDAAqD;QACrD,MAAM,IAAI,GAAG,WAAK,CAAC,OAAO,0CAAE,aAAa;QACzC,IAAI,CAAC,KAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,WAAW,GAAE;YACpB,OAAO,IAAI;SACd;QACD,MAAM,KAAK,GAAiB,EAAE;QAC9B,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1D,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,UAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,iBAAiB,CAAC,KAAK,CAAC,mCAAI,EAAE;gBAC1C,OAAO,EAAE,CAAC,CAAC,KAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,SAAS;aAC7B,CAAC;SACL;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE;IACtC,CAAC;IAED;;;;;;OAMG;IACK,QAAQ,CAAE,IAAsB,EAAE,GAAW;;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE;YACP,OAAM;SACT;QACD,MAAM,OAAO,GAAG,IAAW;QAC3B,MAAM,KAAK,GAAG,aAAO,CAAC,QAAQ,0CAAE,KAAK;QACrC,MAAM,IAAI,GAAG,WAAW,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,GAAG,EAAE;cACnD,SAAS,IAAI,CAAC,IAAI,SAAS,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,SAAS,aAAO,CAAC,IAAI,0CAAE,OAAO,IAAI,aAAO,CAAC,IAAI,0CAAE,IAAI,EAAE;cAC5F,UAAU,IAAI,CAAC,SAAS,CAAC,UAAI,CAAC,KAAK,mCAAI,EAAE,CAAC,QAAQ;QACxD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK;aAClB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;aACnE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;aAChB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACrG,IAAI;YACA,8CAAiB,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC/D;QAAC,MAAM;YACJ,2BAA2B;SAC9B;IACL,CAAC;IAED,8BAA8B;IAE9B;;;;;;OAMG;IACK,QAAQ,CAAE,IAAsB;;QACpC,MAAM,OAAO,GAAG,IAAW;QAE3B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YACzB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAEtB,0CAA0C;YAC1C,IAAI,OAAO,CAAC,YAAY,EAAE;gBACtB,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,KAAa,EAAE,EAAE;oBAC7C,mDAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC;gBAChF,CAAC,CAAC;aACL;YACD,IAAI,OAAO,CAAC,KAAK,EAAE;gBACf,mDAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC;aACvF;YACD,2BAA2B;YAC3B,IAAI,OAAO,CAAC,SAAS,EAAE;gBACnB,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,IAAsB,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;aACtF;SACJ;QAED,4CAA4C;QAC5C,qDAAqD;QACrD,MAAM,KAAK,GAAuB,OAAO,OAAO,CAAC,UAAU,KAAK,UAAU;YACtE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE;YACtB,CAAC,CAAC,CAAC,IAAI,CAAC;QACZ,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,mBAAmB,KAAK,CAAC,MAAM,EAAE,CAAC;QACvE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACtB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC;SAC7B;QAED,yDAAyD;QACzD,kDAAkD;QAClD,4CAA4C;QAC5C,2DAA2D;QAC3D,sDAAsD;QACtD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YACf,MAAM,KAAK,GAAG,CAAC,UAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC;YACvD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC;YACrC,IAAI,KAAK,IAAI,mBAAmB,EAAE;gBAC9B,UAAU,CAAC,GAAG,EAAE;oBACZ,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;wBAC9B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;qBACtB;gBACL,CAAC,EAAE,kBAAkB,CAAC;aACzB;SACJ;IACL,CAAC;IAEO,SAAS,CAAE,IAAsB,EAAE,IAAsB;;QAC7D,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YAC7B,OAAM;SACT;QACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,cAAc,MAAC,IAAY,CAAC,WAAW,0CAAE,IAAI,EAAE,CAAC;QACrF,MAAM,OAAO,GAAG,IAAW;QAC3B,MAAM,IAAI,GAAG,CAAC,OAAY,EAAE,EAAE;;YAC1B,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;gBAC9B,OAAM;aACT;YACD,2DAA2D;YAC3D,yEAAyE;YACzE,uDAAuD;YACvD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,eAAe;kBAC9C,UAAU,mBAAO,CAAC,QAAQ,0CAAE,KAAK,0CAAE,IAAI,IAAI,mBAAO,CAAC,QAAQ,0CAAE,KAAK,0CAAE,IAAI,EAAE;kBAC1E,aAAa,aAAO,CAAC,IAAI,0CAAE,OAAO,IAAI,aAAO,CAAC,IAAI,0CAAE,IAAI,EAAE,CAAC;YACjE,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAY,EAAE,EAAE;gBACvC,oDAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC;gBAClF,oDAAoD;gBACpD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC;YAClC,CAAC,CAAC;QACN,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACrB,IAAI,OAAO,CAAC,eAAe,EAAE;YACzB,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,OAAY,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACrE;QAED,2CAA2C;QAC3C,wEAAwE;QACxE,mDAAmD;QACnD,wEAAwE;QACxE,IAAI,OAAO,CAAC,cAAc,EAAE;YACxB,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,EAAE;gBAClC,IAAI,CAAC,aAAa,EAAE;gBACpB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC;YACjC,CAAC,CAAC;SACL;QACD,8DAA8D;QAC9D,kDAAkD;QAClD,wCAAwC;QACxC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC;IACjC,CAAC;IAED;;;;;;;;OAQG;IACK,kBAAkB,CAAE,IAAsB;QAC9C,MAAM,OAAO,GAAG,IAAW;QAC3B,KAAK,MAAM,KAAK,IAAI,oBAAoB,EAAE;YACtC,UAAU,CAAC,GAAG,EAAE;;gBACZ,MAAM,CAAC,GAAG,aAAO,CAAC,QAAQ,0CAAE,KAAK;gBACjC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO;gBAC/B,IAAI,CAAC,QAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,KAAI,OAAO,OAAO,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,EAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,IAAI,IAAG,CAAC,CAAC,EAAE;oBAC1E,OAAM;iBACT;gBACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI;gBACzB,IAAI,KAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,MAAK,CAAC,CAAC,IAAI,IAAI,KAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,MAAK,CAAC,CAAC,IAAI,EAAE;oBACnD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,kBAAkB,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,IAAI,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,EAAE;0BAC9E,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,MAAM,KAAK,KAAK,CAAC;iBACjD;gBACD,IAAI;oBACA,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;oBAC9B,OAAO,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;iBACnD;gBAAC,MAAM;oBACJ,YAAY;iBACf;YACL,CAAC,EAAE,KAAK,CAAC;SACZ;IACL,CAAC;IAED,gCAAgC;IAChC,EAAE;IACF,yEAAyE;IACzE,oEAAoE;IACpE,0EAA0E;IAC1E,iDAAiD;IACjD,kDAAkD;IAClD,uDAAuD;IAEvD;;;;;;;;;;;;;;;;;OAiBG;IACK,iBAAiB;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO;QACzC,IAAI,CAAC,OAAO,EAAE;YACV,OAAM;SACT;QACD,IAAI,OAAO,GAAG,KAAK;QAEnB,+DAA+D;QAC/D,8DAA8D;QAC9D,0DAA0D;QAC1D,iEAAiE;QACjE,KAAK,MAAM,MAAM,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,CAAC,EAAE;YAC5E,IAAI,MAAM,IAAI,OAAO,EAAE;gBACnB,OAAO,OAAO,CAAC,MAAM,CAAC;gBACtB,OAAO,GAAG,IAAI;aACjB;SACJ;QAED,yDAAyD;QACzD,KAAK,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,EAAE;YAC3C,MAAM,IAAI,GAAa,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;YACpE,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;gBACzB,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC;gBAC9C,OAAO,GAAG,IAAI;aACjB;SACJ;QAED,IAAI,OAAO,EAAE;YACT,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;SACrB;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,kBAAkB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG;cACjF,mBAAmB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,GAAG;cAChE,UAAU,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;IACrG,CAAC;IAED;;;;;;;;;;;OAWG;IACK,aAAa;QACjB,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,KAAoB,EAAE,EAAE;YAC1D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,EAAE;gBACzC,OAAM;aACT;YACD,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE;gBACnE,OAAM;aACT;YACD,qDAAqD;YACrD,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE;gBAClE,OAAM;aACT;YACD,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;gBACjC,OAAM;aACT;YACD,KAAK,CAAC,cAAc,EAAE;YACtB,KAAK,CAAC,eAAe,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC7D,CAAC,EAAE,IAAI,CAAC;IACZ,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACK,eAAe;QACnB,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,KAAoB,EAAE,EAAE;YAC1D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,YAAY,EAAE;gBAC3C,OAAM;aACT;YACD,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE;gBAClE,OAAM,CAAC,gBAAgB;aAC1B;YACD,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE;gBACjF,OAAM;aACT;YACD,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO,KAAK,GAAG,EAAE;gBAC5C,OAAM,CAAC,kBAAkB;aAC5B;YACD,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;gBACjC,OAAM;aACT;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE;YAC/B,IAAI,CAAC,IAAI,EAAE;gBACP,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,gCAAgC,CAAC;gBACtE,OAAM;aACT;YACD,sDAAsD;YACtD,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YACtC,0DAA0D;YAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS;YAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,sBAAsB,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7F,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE;gBACf,OAAM;aACT;YACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;QACnC,CAAC,EAAE,IAAI,CAAC;IACZ,CAAC;IAED;;;;;;;;OAQG;IACK,cAAc,CAAE,IAAS;;QAC7B,MAAM,KAAK,GAAG,UAAI,CAAC,QAAQ,0CAAE,KAAK;QAClC,MAAM,GAAG,GAAG,WAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,MAAM,0CAAE,MAAM;QACjC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,UAAU,EAAE;YAC3C,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,mCAAmC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,UAAU,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACrI,OAAO,EAAE;SACZ;QACD,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAU,EAAY,EAAE;;YAChD,MAAM,KAAK,GAAa,EAAE;YAC1B,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;gBAC1C,KAAK,CAAC,IAAI,CAAC,eAAG,CAAC,OAAO,CAAC,CAAC,CAAC,0CAAE,iBAAiB,CAAC,IAAI,CAAC,mCAAI,EAAE,CAAC;aAC5D;YACD,OAAO,KAAK;QAChB,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,SAAG,CAAC,OAAO,mCAAI,CAAC,CAAC;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,GAAG,gBAAgB,EAAE,MAAM,CAAC;QAC1D,MAAM,QAAQ,GAAG,sDAAa,CAAC,UAAU,CAAC;QAC1C,IAAI,QAAQ,EAAE;YACV,OAAO,QAAQ;SAClB;QACD,2CAA2C;QAC3C,MAAM,QAAQ,GAAG,sDAAa,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,QAAQ,EAAE;YACX,iCAAiC;YACjC,uDAAuD;YACvD,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;iBAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;iBACxC,IAAI,CAAC,KAAK,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,2BAA2B,GAAG,CAAC,KAAK,YAAY,GAAG,CAAC,OAAO,SAAS,KAAK,CAAC,IAAI,SAAS,IAAI,EAAE,CAAC;SACtI;QACD,OAAO,QAAQ;IACnB,CAAC;IAED,2DAA2D;IACnD,YAAY,CAAE,MAA0B;;QAC5C,MAAM,EAAE,GAAG,MAA4B;QACvC,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,CAAC,OAAO,KAAK,UAAU,EAAE;YACzC,OAAO,KAAK;SACf;QACD,kDAAkD;QAClD,IAAI,SAAE,CAAC,SAAS,0CAAE,QAAQ,CAAC,uBAAuB,CAAC,KAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YACzE,OAAO,KAAK;SACf;QACD,OAAO,EAAE,CAAC,iBAAiB,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC;IAC7E,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACK,OAAO,CAAE,MAAc;QAC3B,kEAAkE;QAClE,6CAA6C;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QACtB,IAAI,GAAG,GAAG,IAAI,CAAC,WAAW,GAAG,eAAe,EAAE;YAC1C,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,uBAAuB,GAAG,GAAG,IAAI,CAAC,WAAW,OAAO,MAAM,GAAG,CAAC;YACnG,OAAM;SACT;QACD,IAAI,CAAC,WAAW,GAAG,GAAG;QAEtB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE;QAC/B,IAAI,CAAC,IAAI,EAAE;YACP,OAAM;SACT;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,EAAE;QAC9C,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,wBAAwB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,mBAAmB,cAAc,SAAS,cAAc,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;QACzK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,mBAAmB;eAC5C,SAAS;eACT,OAAO,IAAI,CAAC,SAAS,KAAK,UAAU,EAAE;YACzC,0CAA0C;YAC1C,uDAAuD;YACvD,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;YACjC,OAAM;SACT;QACD,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,UAAU,EAAE;YAClC,OAAM;SACT;QACD,+CAA+C;QAC/C,kDAAkD;QAClD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc;QAClD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QACrB,4CAA4C;QAC5C,iFAAiF;QACjF,6CAA6C;QAC7C,2DAA2D;QAC3D,oCAAoC;QACpC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,WAAW,MAAM,GAAG,CAAC;QAC1D,IAAI,MAAM,KAAK,QAAQ,EAAE;YACrB,uEAAuE;YACvE,KAAK,IAAI,CAAC,KAAK,EAAE;YACjB,OAAM;SACT;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;QAC5B,UAAU,CAAC,GAAG,EAAE;YACZ,IAAI,IAAI,CAAC,aAAa,IAAI,SAAS,EAAE;gBACjC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,iCAAiC,CAAC;gBACvE,OAAM;aACT;YACD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC;YACvD,KAAK,IAAI,CAAC,KAAK,EAAE;QACrB,CAAC,EAAE,oBAAoB,CAAC;IAC5B,CAAC;IAED;;;;;;;;;;OAUG;IACK,KAAK,CAAC,iBAAiB,CAAE,IAAS;QACtC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;QAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa;QAC5D,MAAM,IAAI,GAAG,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO;YACnC,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ;gBACxB,CAAC,CAAC,UAAU;QACpB,MAAM,GAAG,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;QAC1C,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,oBAAoB,GAAG,SAAS,IAAI,GAAG;cACtE,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;IACvB,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,cAAc,CAAE,IAAS;;QACnC,IAAI;YACA,MAAM,KAAK,GAAU,YAAM,iBAAI,CAAC,OAAO,0CAAE,iBAAiB,kDAAI,oCAAI,EAAE;YACpE,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,eAAC,UAAG,OAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,mCAAI,EAAE,IAAI,OAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,IAAI,mCAAI,EAAE,EAAE,IAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;YAC5F,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;gBACzB,OAAO,OAAO;aACjB;YACD,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;gBAC1B,OAAO,QAAQ;aAClB;SACJ;QAAC,MAAM;YACJ,sCAAsC;SACzC;QACD,MAAM,KAAK,GAAG,GAAG,UAAI,CAAC,KAAK,mCAAI,EAAE,IAAI,UAAI,CAAC,WAAW,mCAAI,EAAE,EAAE,CAAC,WAAW,EAAE;QAC3E,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;YACzB,OAAO,OAAO;SACjB;QACD,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;YAC1B,OAAO,QAAQ;SAClB;QACD,OAAO,SAAS;IACpB,CAAC;IAED;;;;;;OAMG;IACK,cAAc,CAAE,IAAS;QAC7B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,kBAAkB,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,UAAU,EAAE;YAC1E,OAAM;SACT;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QACtC,IAAI,CAAC,kBAAkB,GAAG,IAAI;QAC9B,IAAI,CAAC,SAAS,GAAG,CAAC,IAAS,EAAE,GAAG,IAAW,EAAE,EAAE;YAC3C,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE;gBACnC,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;gBAC3D,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,kBAAkB,IAAI,CAAC,MAAM,GAAG;sBAC/D,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;aAC7E;YACD,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC;QAC9B,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACK,UAAU,CAAE,IAAS;QACzB,MAAM,OAAO,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO;QAC7B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,cAAc,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU,EAAE;YAC3E,OAAM;SACT;QACD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;QACxC,OAAO,CAAC,cAAc,GAAG,IAAI;QAC7B,OAAO,CAAC,KAAK,GAAG,CAAC,IAAS,EAAE,GAAG,IAAW,EAAE,EAAE;YAC1C,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE;gBACnC,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;gBAC3D,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,cAAc,IAAI,CAAC,MAAM,GAAG;sBAC3D,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;aAC7E;YACD,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC;QAC9B,CAAC;IACL,CAAC;IAED,0CAA0C;IAClC,QAAQ;;QACZ,OAAO,CAAC,UAAI,KAAK,EAAE,CAAC,KAAK,mCAAI,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACtE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IAC9D,CAAC;IAED,gCAAgC;IACxB,qBAAqB;QACzB,MAAM,EAAE,GAAG,YAAY,EAAE;QACzB,IAAI,CAAC,EAAE,EAAE;YACL,wDAAwD;YACxD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,wBAAwB,CAAC;YAC9D,OAAO,KAAK;SACf;QACD,IAAI;YACA,MAAM,QAAQ,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE;YAC1C,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,EAAE;YAC1B,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,uBAAuB,QAAQ,YAAY,IAAI,CAAC,MAAM,EAAE,CAAC;YAC9F,OAAO,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;SACxC;QAAC,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,2BAA2B,GAAG,EAAE,CAAC;YACtE,OAAO,KAAK;SACf;IACL,CAAC;IAED,0CAA0C;IAClC,WAAW;;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,SAAgB;QACxC,IAAI,CAAC,MAAM,EAAE;YACT,OAAO,IAAI;SACd;QACD,OAAO,OAAO,MAAM,CAAC,aAAa,KAAK,UAAU;YAC7C,CAAC,CAAC,CAAC,YAAM,CAAC,aAAa,EAAE,mCAAI,MAAM,CAAC;YACpC,CAAC,CAAC,MAAM;IAChB,CAAC;IAED;;;;;OAKG;IACK,mBAAmB;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO;QACzC,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,EAAE;YAC1D,OAAM;SACT;QACD,MAAM,IAAI,GAAa,OAAO,CAAC,mBAAmB,CAAC;QACnD,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE;YAC9B,OAAM;SACT;QACD,OAAO,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,aAAa,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;IACtB,CAAC;IAED,4BAA4B;IAE5B;;;;;;;;;;;;;OAaG;IACK,eAAe;QACnB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,eAAe,EAAE;YAC9C,OAAM;SACT;QACD,kDAAkD;QAClD,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,KAAK,KAAK,EAAE;YAC/E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,GAAG,KAAK;YAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;SACrB;QAED,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE;YACxC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE;gBAC7C,OAAM;aACT;YACD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE;YAC7B,6DAA6D;YAC7D,+DAA+D;YAC/D,uDAAuD;YACvD,wEAAwE;YACxE,wCAAwC;YACxC,EAAE,CAAC,cAAc,EAAE;YACnB,EAAE,CAAC,eAAe,EAAE;QACxB,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAErB,4DAA4D;QAC5D,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE;YAC1C,IAAI,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE;gBACzB,EAAE,CAAC,cAAc,EAAE;gBACnB,EAAE,CAAC,eAAe,EAAE;aACvB;QACL,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAErB,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE;YACtC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE;gBAC7C,OAAM;aACT;YACD,EAAE,CAAC,cAAc,EAAE;YACnB,EAAE,CAAC,eAAe,EAAE;YAEpB,sCAAsC;YACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;YACtB,IAAI,GAAG,GAAG,IAAI,CAAC,kBAAkB,GAAG,GAAG,EAAE;gBACrC,OAAM;aACT;YACD,IAAI,CAAC,kBAAkB,GAAG,GAAG;YAE7B,MAAM,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,WAAW;YACnC,KAAK,IAAI,CAAC,gBAAgB,CAAC,EAAE,EAAE,IAAI,CAAC;QACxC,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,sCAAsC;IAC9B,cAAc,CAAE,EAAc;QAClC,MAAM,MAAM,GAAG,EAAE,CAAC,MAA4B;QAC9C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU,EAAE;YACjD,OAAO,KAAK;SACf;QACD,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,UAAU,EAAE,CAAC;IACjF,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAE,EAAc,EAAE,MAAc;;QAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE;QAC/B,IAAI,CAAC,IAAI,EAAE;YACP,OAAM;SACT;QAED,MAAM,MAAM,GAAG,UAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,gBAAgB,mCAAI,GAAG;QAClE,IAAI,MAAM,IAAI,MAAM,EAAE;YAClB,IAAI,OAAO,IAAI,CAAC,gBAAgB,KAAK,UAAU,IAAI,IAAI,CAAC,QAAQ,EAAE;gBAC9D,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,EAAE,EAAE,CAAC;aACpE;YACD,OAAM;SACT;QAED,MAAM,SAAS,GAAG,OAAO,WAAI,CAAC,QAAQ,0CAAE,YAAY,MAAK,UAAU;YAC/D,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE;YAC9B,CAAC,CAAC,EAAE;QACR,IAAI,SAAS,EAAE;YACX,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE;YAC7B,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;SACjC;aAAM;YACH,kDAAkD;YAClD,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;SAC7B;IACL,CAAC;IAED;;;;OAIG;IACK,WAAW;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE;QAC/B,IAAI,CAAC,IAAI,EAAE;YACP,OAAM;SACT;QACD,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,UAAU,EAAE;YACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SACvB;IACL,CAAC;IAED,6BAA6B;IAE7B,IAAY,OAAO;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO;IAC9C,CAAC;IAEO,YAAY;QAChB,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC;QACxD,IAAI,IAAI,CAAC,OAAO,EAAE;YACd,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM;SAC1D;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE;YAC9B,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ;gBACtD,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,CAAC,EAAE;gBAC/D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC;aACzC;YACD,mCAAmC;YACnC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;YACnB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;YACtB,IAAI,CAAC,QAAQ,GAAG,IAAI;YACpB,IAAI,CAAC,aAAa,EAAE;SACvB;QACD,IAAI,CAAC,kBAAkB,EAAE;IAC7B,CAAC;IAED;;;;;;;OAOG;IACK,kBAAkB;QACtB,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe;QACrC,MAAM,KAAK,GAAG,GAAS,EAAE;YACrB,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC;YAC7C,KAAK,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,CAAC,EAAE;gBAChF,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;aAC/B;QACL,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,wBAAwB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACxF,KAAK,EAAE;YACP,OAAM;SACT;QACD,qBAAqB,CAAC,GAAG,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;gBAC/B,KAAK,EAAE;gBACP,OAAM;aACT;YACD,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE;YAC7C,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE;gBAC/B,OAAM;aACT;YACD,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YACjE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YAC/D,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;YACnE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;YACrE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC;QAC9C,CAAC,CAAC;IACN,CAAC;IAED;;;;;;;;;;OAUG;IACK,YAAY;;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;QACvC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC;QAC7C,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC;QAE5C,wDAAwD;QACxD,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe;QACrC,IAAI,OAAO,IAAI,GAAG,EAAE;YAChB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC;SAC7C;aAAM;YACH,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,eAAe,EAAE,oBAAoB,OAAO,GAAG,GAAG,GAAG,CAAC;SAChF;QAED,0BAA0B;QAC1B,MAAM,MAAM,GAAG,UAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,0CAAE,WAAW;QACtD,IAAI,CAAC,OAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,UAAU,GAAE;YACrB,OAAM;SACT;QACD,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC;QAClD,gDAAgD;QAChD,MAAM,QAAQ,GAAG,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU;QACtF,IAAI,IAAI,KAAK,MAAM,CAAC,UAAU,IAAI,QAAQ,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE;YAClF,kDAAkD;YAClD,OAAM;SACT;QACD,MAAM,CAAC,UAAU,GAAG,IAAI;QACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,GAAG,QAAQ;QAChD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;IACtB,CAAC;IAED,gDAAgD;IAChD,IAAY,QAAQ;QAChB,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW;QACjD,OAAO,kDAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;IACtC,CAAC;IAED;;;;;OAKG;IACK,aAAa,CAAE,MAAc,EAAE,MAAc,EAAE,IAAY;QAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;QACvC,IAAI,wDAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;YACjC,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG;YACxC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,IAAI,GAAG,EAAE,UAAU,CAAC;YAC9D,IAAI,IAAI,GAAG,GAAG,CAAC,YAAY,IAAI,CAAC;YAChC,IAAI,CAAC,IAAI,EAAE;gBACP,gDAAgD;gBAChD,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;gBACrD,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;gBACtC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;gBAC5C,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC;gBACnC,IAAI,GAAG,MAAM,GAAG,KAAK;aACxB;YACD,+CAA+C;YAC/C,oCAAoC;YACpC,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU;YAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,UAAU,EAAE,OAAO,CAAC;YACtD,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,UAAU;YACtF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;SAC7D;QACD,sDAAsD;QACtD,mCAAmC;QACnC,MAAM,IAAI,GAAG,GAAG,CAAC,aAAa,IAAI,GAAG;QACrC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,UAAU,EAAE,aAAa,CAAC,CAAC;IAC9F,CAAC;IAED,sDAAsD;IAC9C,QAAQ;;QACZ,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YACjC,IAAI,CAAC,QAAQ,CAAC,uBAAuB,EAAE,4BAA4B,IAAI,CAAC,OAAO,aAAa,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9G,OAAM;SACT;QACD,qCAAqC;QACrC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACd,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAC;SACxD;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACd,IAAI,CAAC,QAAQ,CAAC,sBAAsB,EAAE,8BAA8B,CAAC;YACrE,OAAM;SACT;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW;QACxC,4CAA4C;QAC5C,2CAA2C;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY;QACrE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE;YACpB,OAAM;SACT;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ;QAC1B,MAAM,UAAU,GAAG,wDAAgB,CAAC,IAAI,CAAC;QACzC,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACvF,kDAAkD;QAClD,IAAI,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM;QAEjD,yBAAyB;QACzB,EAAE;QACF,8CAA8C;QAC9C,2DAA2D;QAC3D,0DAA0D;QAC1D,yDAAyD;QACzD,mDAAmD;QACnD,qDAAqD;QACrD,gEAAgE;QAChE,4CAA4C;QAC5C,mDAAmD;QACnD,+BAA+B;QAC/B,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAC3B,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAEzB,wDAAwD;QACxD,oCAAoC;QACpC,IAAI,KAAK,KAAK,IAAI,CAAC,SAAS,IAAI,MAAM,KAAK,IAAI,CAAC,YAAY,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,EAAE;YACpF,OAAM;SACT;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS;QAChC,IAAI,CAAC,SAAS,GAAG,KAAK;QACtB,IAAI,CAAC,YAAY,GAAG,MAAM;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI;QAEpB,mDAAmD;QAEnD,iDAAiD;QACjD,qEAAqE;QACrE,gCAAgC;QAChC,IAAI,IAAI,CAAC,OAAO,EAAE;YACd,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;YAC5B,CAAC,CAAC,QAAQ,GAAG,UAAU;YACvB,CAAC,CAAC,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;YACxC,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;YACxC,CAAC,CAAC,GAAG,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;YACxC,CAAC,CAAC,MAAM,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;YACxC,CAAC,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM;YAC7C,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI;YAC9C,KAAK,MAAM,CAAC,IAAI,8CAAU,EAAE;gBACxB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;aAC5D;SACJ;QAED,eAAe;QACf,EAAE;QACF,2DAA2D;QAC3D,gEAAgE;QAChE,6DAA6D;QAC7D,iCAAiC;QACjC,6DAA6D;QAC7D,6BAA6B;QAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK;QAC3B,IAAI,UAAU,EAAE;YACZ,CAAC,CAAC,IAAI,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI;YAC9B,CAAC,CAAC,KAAK,GAAG,KAAK,GAAG,IAAI;YACtB,CAAC,CAAC,QAAQ,GAAG,KAAK,GAAG,IAAI;YACzB,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC;YAC1B,CAAC,CAAC,SAAS,GAAG,GAAG;YACjB,CAAC,CAAC,YAAY,GAAG,GAAG;YACpB,8CAA8C;YAC9C,CAAC,CAAC,UAAU,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG;YACpD,CAAC,CAAC,WAAW,GAAG,GAAG;SACtB;aAAM;YACH,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC;YACxB,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC;YACzB,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC;YAC7B,CAAC,CAAC,UAAU,GAAG,GAAG;YAClB,CAAC,CAAC,WAAW,GAAG,GAAG;YACnB,CAAC,CAAC,SAAS,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG;YAClD,CAAC,CAAC,YAAY,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG;YACxD,mEAAmE;YACnE,yDAAyD;YACzD,iDAAiD;YACjD,kCAAkC;YAClC,sEAAsE;YACtE,yEAAyE;YACzE,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,GAAG,KAAK,EAAE,WAAW,CAAC;SACxE;QAED,UAAI,CAAC,IAAI,0CAAE,UAAU,EAAE;QACvB,IAAI,CAAC,kBAAkB,EAAE;QACzB,4DAA4D;QAC5D,EAAE;QACF,gEAAgE;QAChE,4EAA4E;QAC5E,sCAAsC;QACtC,gDAAgD;QAChD,iFAAiF;QACjF,wDAAwD;QACxD,4DAA4D;QAC5D,0CAA0C;QAC1C,4EAA4E;QAC5E,iCAAiC;QACjC,qDAAqD;QACrD,IAAI,CAAC,aAAa,EAAE;QACpB,wCAAwC;QACxC,2DAA2D;QAC3D,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,kBAAkB,IAAI,UAAU,MAAM,IAAI,MAAM,EAAE;cACjF,WAAW,MAAM,UAAU,KAAK,UAAU,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;IAC9E,CAAC;IAED;;;;;;;;;;;;;OAaG;IACK,aAAa;QACjB,IAAI,IAAI,CAAC,WAAW,EAAE;YAClB,OAAM;SACT;QACD,IAAI,CAAC,WAAW,GAAG,IAAI;QACvB,gDAAgD;QAChD,qBAAqB,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE;YACnD,IAAI,CAAC,WAAW,GAAG,KAAK;YACxB,IAAI,CAAC,cAAc,EAAE;QACzB,CAAC,CAAC,CAAC;QACH,uDAAuD;QACvD,gCAAgC;QAChC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,GAAG,CAAC;IAChD,CAAC;IAEO,cAAc;;QAClB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;YAC7B,MAAM,MAAM,GAAG,GAAU;YACzB,MAAM,KAAK,GAAuB,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU;gBACrE,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE;gBACrB,CAAC,CAAC,CAAC,GAAG,CAAC;YACX,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;gBACtB,MAAM,QAAQ,GAAI,IAAY,CAAC,QAAQ;gBACvC,MAAM,QAAQ,GAAG,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,QAAQ;gBACnC,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,CAAC,GAAG,KAAK,UAAU,EAAE;oBACjD,SAAQ;iBACX;gBACD,gDAAgD;gBAChD,kCAAkC;gBAClC,MAAM,IAAI,GAAG,oBAAQ,CAAC,KAAK,0CAAE,OAAO,0CAAE,aAAa;gBACnD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;oBAClD,SAAQ;iBACX;gBACD,IAAI;oBACA,QAAQ,CAAC,GAAG,EAAE;iBACjB;gBAAC,MAAM;oBACJ,wCAAwC;iBAC3C;gBACD,sDAAsD;gBACtD,0DAA0D;gBAC1D,0CAA0C;aAC7C;SACJ;IACL,CAAC;IAED;;;;;;;;;;OAUG;IACK,WAAW,CAAE,IAAsB,EAAE,QAAa;;QACtD,MAAM,IAAI,GAAG,cAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,0CAAE,IAAI;QAClC,MAAM,IAAI,GAAG,cAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,0CAAE,IAAI;QAClC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE;YAChB,OAAM;SACT;QACD,MAAM,OAAO,GAAG,IAAW;QAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO;QAC/B,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,UAAU,EAAE;YACnE,OAAM;SACT;QACD,mDAAmD;QACnD,2DAA2D;QAC3D,uDAAuD;QACvD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI;QACzB,IAAI,KAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,MAAK,IAAI,IAAI,KAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,MAAK,IAAI,EAAE;YAC/C,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,eAAe,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,IAAI,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,EAAE;kBAC3E,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC;SAC/B;QACD,IAAI;YACA,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC;YAC1B,OAAO,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE;SACzC;QAAC,MAAM;YACJ,gCAAgC;YAChC,OAAM;SACT;QAED,uBAAuB;QACvB,EAAE;QACF,sDAAsD;QACtD,gFAAgF;QAChF,6DAA6D;QAC7D,mDAAmD;QACnD,0DAA0D;QAC1D,uDAAuD;QACvD,EAAE;QACF,kDAAkD;QAClD,oDAAoD;QACpD,IAAI,KAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,MAAK,IAAI,IAAI,KAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,MAAK,IAAI,EAAE;YAC/C,KAAK,MAAM,KAAK,IAAI,mBAAmB,EAAE;gBACrC,UAAU,CAAC,GAAG,EAAE;;oBACZ,MAAM,GAAG,GAAG,aAAO,CAAC,QAAQ,0CAAE,KAAK;oBACnC,iDAAiD;oBACjD,IAAI,CAAC,cAAO,CAAC,OAAO,0CAAE,IAAI,KAAI,IAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,MAAK,IAAI,IAAI,IAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,MAAK,IAAI,EAAE;wBACpE,OAAM;qBACT;oBACD,IAAI;wBACA,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC;qBACrC;oBAAC,MAAM;wBACJ,UAAU;qBACb;gBACL,CAAC,EAAE,KAAK,CAAC;aACZ;SACJ;IACL,CAAC;IAED;;;;;;;;;;;OAWG;IACK,cAAc,CAAE,IAAsB;;QAC1C,MAAM,OAAO,GAAG,IAAW;QAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO;QAC/B,MAAM,IAAI,GAAG,mBAAO,CAAC,QAAQ,0CAAE,KAAK,0CAAE,IAAI;QAC1C,MAAM,IAAI,GAAG,mBAAO,CAAC,QAAQ,0CAAE,KAAK,0CAAE,IAAI;QAC1C,IAAI,CAAC,QAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,KAAI,OAAO,OAAO,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE;YACtF,OAAM;SACT;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,iBAAiB,IAAI,IAAI,IAAI,EAAE,CAAC;QACrE,IAAI;YACA,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC;YAC9B,OAAO,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE;YAC1C,UAAU,CAAC,GAAG,EAAE;;gBACZ,IAAI,CAAC,cAAO,CAAC,OAAO,0CAAE,IAAI,GAAE;oBACxB,OAAM;iBACT;gBACD,mDAAmD;gBACnD,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC;YAC5C,CAAC,EAAE,EAAE,CAAC;SACT;QAAC,MAAM;YACJ,YAAY;SACf;IACL,CAAC;IAED,2DAA2D;IAC3D,EAAE;IACF,mEAAmE;IACnE,kDAAkD;IAClD,qDAAqD;IACrD,mDAAmD;IACnD,8DAA8D;IAE9D,iCAAiC;IAEzB,YAAY;QAChB,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;QACxC,EAAE,CAAC,EAAE,GAAG,UAAU;QAClB,EAAE,CAAC,SAAS,GAAG;YACX,uBAAuB;YACvB,iDAAiD;YACjD,uCAAuC;YACvC,QAAQ;YACR,6BAA6B;YAC7B,uBAAuB;YACvB,4DAA4D;YAC5D,6DAA6D;YAC7D,6CAA6C;YAC7C,8CAA8C;YAC9C,2EAA2E;YAC3E,QAAQ;SACX,CAAC,IAAI,CAAC,IAAI,CAAC;QAEZ,4DAA4D;QAC5D,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,EAAE;QACjB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC;QAE1C,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACvD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC,UAAU,EAAE,EAAC,CAAC,CAAC;QACnD,CAAC,CAAC;QACF,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YAC1D,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC;QACF,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YAC5D,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QAC5C,CAAC,CAAC;QAEF,6BAA6B;QAC7B,+DAA+D;QAC/D,IAAI,CAAC,IAAI,GAAG,IAAI,kDAAc,CAAC;YAC3B,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ;YAC5B,OAAO,EAAE,IAAI,CAAC,EAAE;gBACZ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI;YAClD,CAAC;YACD,OAAO,EAAE,IAAI,CAAC,EAAE;gBACZ,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;gBACvC,IAAI,CAAC,wDAAgB,CAAC,IAAI,CAAC,EAAE;oBACzB,OAAO,GAAG,CAAC,aAAa,IAAI,CAAC;iBAChC;gBACD,wCAAwC;gBACxC,8CAA8C;gBAC9C,OAAO,wDAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,YAAY,GAAG,CAAC;oBAC3D,CAAC,CAAC,IAAI,CAAC,YAAY;oBACnB,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,CAAC;YACjC,CAAC;YACD,OAAO,EAAE,EAAE,CAAC,EAAE;gBACV,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;gBACvC,IAAI,wDAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;oBACjC,GAAG,CAAC,YAAY,GAAG,EAAE;iBACxB;qBAAM;oBACH,GAAG,CAAC,aAAa,GAAG,EAAE;iBACzB;YACL,CAAC;YACD,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACrD,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE;SAClC,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;IACvB,CAAC;IAED,kDAAkD;IAC1C,KAAK,CAAC,UAAU;;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO;QACjD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;QAClD,MAAM,OAAO,GAAG,cAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,mCAAI,QAAQ,CAAC,CAAC,CAAC;QAClE,IAAI,OAAO,EAAE;YACT,MAAM,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,OAAO,CAAC;SACpD;IACL,CAAC;IAEO,YAAY;QAChB,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,gEAAoB,EAAE,CAAC;IAC1D,CAAC;IAED;;;;;;;;;;;;OAYG;IACK,cAAc;QAClB,IAAI,IAAI,CAAC,YAAY,EAAE;YACnB,OAAM;SACT;QACD,IAAI,CAAC,YAAY,GAAG,IAAI;QACxB,MAAM,GAAG,GAAG,GAAG,EAAE;YACb,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;gBACpB,OAAM;aACT;YACD,IAAI,CAAC,YAAY,GAAG,KAAK;YACzB,IAAI,IAAI,CAAC,WAAW,EAAE;gBAClB,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;gBAC9B,IAAI,CAAC,WAAW,GAAG,IAAI;aAC1B;YACD,IAAI,CAAC,MAAM,EAAE;YACb,IAAI,CAAC,QAAQ,EAAE;QACnB,CAAC;QACD,qBAAqB,CAAC,GAAG,CAAC;QAC1B,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC;IAC1C,CAAC;IAED;;;;;;;OAOG;IACK,2BAA2B;;QAC/B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,uBAAuB,EAAE;YACtD,OAAM;SACT;QACD,IAAI;YACA,MAAM,GAAG,GAAG,MAAC,MAAc,CAAC,OAAO,mCAAK,UAAkB,CAAC,OAAO;YAClE,MAAM,GAAG,GAAG,eAAG,aAAH,GAAG,uBAAH,GAAG,CAAG,kBAAkB,CAAC,0CAAE,gBAAgB,kDAAI;YAC3D,eAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,WAAW,0CAAE,uBAAuB,mDAAG,KAAK,CAAC;SACrD;QAAC,MAAM;YACJ,2CAA2C;SAC9C;IACL,CAAC;IAEO,IAAI;QACR,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACf,OAAM;SACT;QACD,IAAI,KAAK,GAAG,KAAK;QACjB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,IAAI,IAAI;QACjE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;YAC7B,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE;gBACtC,KAAK,GAAG,IAAI;aACf;SACJ;QACD,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE;YAClD,IAAI,CAAC,MAAM,EAAE;SAChB;IACL,CAAC;IAEO,MAAM;QACV,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,EAAE;YAC/C,OAAM;SACT;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC;QAC5D,OAAO,CAAC,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QAEzC,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,EAAE;QAC1B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;YACpB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;SAC/C;IACL,CAAC;IAEO,SAAS,CAAE,GAAqB;QACpC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;QAC/B,MAAM,KAAK,GAAG,+CAAa,CAAC,EAAE,CAAC,MAAM,CAAC;QACtC,MAAM,MAAM,GAAG,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,SAAS;QAEzC,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;QACzC,GAAG,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ;QACnD,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC;QAEhD,sCAAsC;QACtC,MAAM,QAAQ,GAAG,yDAAgB,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QACrE,sBAAsB;QACtB,8CAA8C;QAC9C,6DAA6D;QAC7D,yCAAyC;QACzC,8BAA8B;QAC9B,uCAAuC;QACvC,MAAM,KAAK,GAAG,QAAQ,IAAI,SAAS;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW;YACnD,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC;YAC3C,CAAC,CAAC,EAAE;QAER,GAAG,CAAC,SAAS,GAAG;YACZ,4BAA4B;YAC5B,uBAAuB;YACvB,gCAAgC;YAChC,uDAAuD;YACvD,eAAe;YACf,+DAA+D;YAC/D,yBAAyB;YACzB,oCAAoC;YACpC,sCAAsC;YACtC,UAAU;YACV,QAAQ;YACR,wDAAwD;SAC3D,CAAC,IAAI,CAAC,IAAI,CAAC;QAEZ,qDAAqD;QACrD,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,WAAW,GAAG,KAAK;QAClD,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC;QAC9C,gDAAgD;QAChD,yBAAyB;QACzB,OAAO,CAAC,WAAW,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG;QACrC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QAC5C,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,WAAW,GAAG,OAAO;QACtD,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC;QAC5C,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC,KAAK;QAClD,IAAI,EAAE,CAAC,MAAM,EAAE;YACX,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;SAChC;QAED,GAAG,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE;YAC/B,IAAK,EAAE,CAAC,MAAsB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;gBACjD,OAAM;aACT;YACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAChD,CAAC,CAAC;QACF,GAAG,CAAC,gBAAgB,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE;YAClC,EAAE,CAAC,cAAc,EAAE;YACnB,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC;QACjC,CAAC,CAAC;QACF,GAAG,CAAC,gBAAgB,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE;YACrC,EAAE,CAAC,cAAc,EAAE;YACnB,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,GAAG,CAAC;QAChC,CAAC,CAAC;QACF,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE;YAC1D,EAAE,CAAC,eAAe,EAAE;YACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,EAAC,CAAC,CAAC;QAC9D,CAAC,CAAC;QACF,OAAO,GAAG;IACd,CAAC;IAED,2BAA2B;IACnB,cAAc,CAAE,GAAgB,EAAE,GAAqB;QAC3D,IAAI,CAAC,OAAO,GAAG,GAAG;QAClB,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,WAAW,CAAgB;QAC5D,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;QAC7C,KAAK,CAAC,SAAS,GAAG,gBAAgB;QAClC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK;QACxC,KAAK,CAAC,WAAW,GAAG,OAAO;QAC3B,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;QACzB,KAAK,CAAC,KAAK,EAAE;QACb,KAAK,CAAC,MAAM,EAAE;QAEd,MAAM,MAAM,GAAG,CAAC,MAAe,EAAE,EAAE;YAC/B,IAAI,IAAI,CAAC,OAAO,KAAK,GAAG,EAAE;gBACtB,OAAM;aACT;YACD,IAAI,CAAC,OAAO,GAAG,IAAI;YACnB,IAAI,MAAM,EAAE;gBACR,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;aAChD;YACD,IAAI,CAAC,MAAM,EAAE;QACjB,CAAC;QACD,8BAA8B;QAC9B,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE;YACnC,EAAE,CAAC,eAAe,EAAE;YACpB,IAAI,EAAE,CAAC,GAAG,KAAK,OAAO,EAAE;gBACpB,MAAM,CAAC,IAAI,CAAC;aACf;YACD,IAAI,EAAE,CAAC,GAAG,KAAK,QAAQ,EAAE;gBACrB,MAAM,CAAC,KAAK,CAAC;aAChB;QACL,CAAC,CAAC;QACF,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtD,CAAC;IAED,sBAAsB;IACd,cAAc,CAAE,EAAc,EAAE,GAAqB;QACzD,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC;QAC9C,IAAI,GAAG,EAAE;YACL,GAAG,CAAC,MAAM,EAAE;SACf;QACD,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,SAAS;QAE1B,MAAM,QAAQ,GAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC;QAC9E,MAAM,KAAK,GAAgC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YACxD,MAAM,KAAK,GAAG,+CAAa,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,GAAG,+CAAa,CAAC,CAAC,CAAC,CAAC,KAAK;YAClE,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,KAAK,EAAE,MAAM,CAAyB;QAClD,CAAC,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACtD,iDAAiD;QACjD,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE;gBACxB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC;gBACvB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;YACzB,CAAC,CAAC,CAAC;QAEH,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,EAAE;YACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;YAC1C,IAAI,CAAC,SAAS,GAAG,cAAc;YAC/B,IAAI,CAAC,WAAW,GAAG,KAAK;YACxB,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;gBAChC,MAAM,EAAE;gBACR,IAAI,CAAC,MAAM,EAAE;YACjB,CAAC,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;SACzB;QAED,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,GAAG,IAAI;QACnC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,IAAI;QAExF,MAAM,KAAK,GAAG,CAAC,CAAa,EAAE,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAc,CAAC,EAAE;gBAClC,IAAI,CAAC,MAAM,EAAE;gBACb,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,KAAK,CAAC;aACnD;QACL,CAAC;QACD,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IAEO,aAAa,CAAE,EAAU;QAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,GAAG,EAAE,EAAE;YACR,OAAO,CAAC,GAAG,GAAG;SACjB;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,EAAE,EAAE;YACR,OAAO,CAAC,GAAG,GAAG;SACjB;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG;IACtD,CAAC;CACJ;AA7/DY,gBAAgB;IAD5B,yDAAU,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;qCAgDd,kDAAU;QACP,qDAAa;QACb,8DAAiB;QAChB,sDAAc;QACb,uDAAe;QACb,yDAAiB;QACvB,iDAAM;GArDf,gBAAgB,CA6/D5B;AA7/D4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpKa;AAC8B;AACiB;AACrC;AACM;AAE1D;;;;;;GAMG;AAEI,IAAM,kBAAkB,GAAxB,MAAM,kBAAmB,SAAQ,6DAAiB;IACrD,YACY,MAAyB,EACzB,MAAqB,EACrB,GAAe;QAEvB,KAAK,EAAE;QAJC,WAAM,GAAN,MAAM,CAAmB;QACzB,WAAM,GAAN,MAAM,CAAe;QACrB,QAAG,GAAH,GAAG,CAAY;IAG3B,CAAC;IAED;;;;;;;OAOG;IACK,MAAM,CAAE,GAAkC;;QAC9C,OAAO,UAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,mCAAI,GAAG;IAC5C,CAAC;IAED,MAAM,CAAE,GAAkC;QACtC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE;QAC5B,IAAI,GAAG,CAAC,OAAO,EAAE;YACb,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC;SACzC;QACD,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;YACrE,IAAI,OAAO,EAAE;gBACT,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC;aACrC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED,MAAM,CAAE,GAAkC;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QAC7B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;QACjB,2DAAkB,CAAC,GAAG,CAAC;QACvB,mCAAmC;QACnC,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC/C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;SAC3B;IACL,CAAC;IAEO,eAAe,CAAE,GAAkC,EAAE,OAAoB;QAC7E,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;YAC9D,qDAAW,CACP,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAChB,GAAG,EACH,IAAI,EACJ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CACzC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AAtDY,kBAAkB;IAD9B,yDAAU,EAAE;qCAGW,8DAAiB;QACjB,qDAAa;QAChB,kDAAU;GAJlB,kBAAkB,CAsD9B;AAtD8B;;;;;;;;;;;;;;;;;;ACV/B,2EAA2E;AAC3E,MAAM,MAAM,GAAG,oEAAoE;AAEnF,gDAAgD;AAChD,MAAM,UAAU,GAAG;IACf,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,WAAW;IACX,0BAA0B;CAC7B;AAED;;;;;GAKG;AACH,MAAM,OAAO,GAAG;IACZ,mBAAmB;IACnB,uCAAuC;IACvC,4BAA4B;CAC/B;AAED,MAAM,KAAK,GAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC;AAE3E,sCAAsC;AACtC,MAAM,KAAK,GAAG,IAAI,OAAO,EAAkB;AAE3C;;;;;;;;GAQG;AACI,SAAS,WAAW,CACvB,MAAyB,EACzB,IAAsB,EACtB,KAAa,EACb,IAAY,EACZ,UAAmB;;IAEnB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;IACtB,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;IAEvB,MAAM,GAAG,GAAG,CAAC,WAAK,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAI,EAAE,CAAC,GAAG,IAAI;IAC3C,IAAI,OAAO,GAAG,KAAK;IACnB,IAAI,CAAyB;IAC7B,yCAAyC;IACzC,IAAI,QAAQ,GAAG,CAAC;IAChB,MAAM,CAAC,SAAS,GAAG,CAAC;IACpB,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE;QACpC,QAAQ,GAAG,MAAM,CAAC,SAAS;QAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAgB;QAC1C,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;YACnB,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;YACtB,OAAO,GAAG,IAAI;SACjB;KACJ;IACD,kCAAkC;IAClC,qDAAqD;IACrD,4CAA4C;IAC5C,kCAAkC;IAClC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC;IACjE,IAAI,OAAO,IAAI,CAAC,UAAU,EAAE;QACxB,OAAM;KACT;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE;QACtC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;QAC/B,OAAM;KACT;IAED,uCAAuC;IACvC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE;QACnF,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QACrB,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;QAC/B,OAAM;KACT;IAED,oDAAoD;IACpD,0DAA0D;IAC1D,2DAA2D;IAC3D,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QACzB,OAAM;KACT;IACD,+CAA+C;IAC/C,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;AACnC,CAAC;AAEM,SAAS,kBAAkB,CAAE,KAAa;IAC7C,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;AACvB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,QAAQ,GAAG,0BAA0B;AAE3C;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;AAEzD,SAAS,gBAAgB,CAAE,KAAa;IAC3C,OAAO,KAAK,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC;AACjD,CAAC;AAEM,SAAS,UAAU,CACtB,MAAyB,EACzB,IAAsB,EACtB,KAAa,EACb,UAAmB;IAEnB,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9B,IAAI,CAAC,EAAE;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAgB;QAC1C,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;YACnB,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE;YACxB,OAAM;SACT;KACJ;IACD,yCAAyC;IACzC,IAAI,UAAU,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QAC7D,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;KAClC;AACL,CAAC;;;;;;;;;;;;;;;;;;AC5ID;;;;;;GAMG;AAII,MAAM,UAAU,GAAe,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC;AAEjE,SAAS,UAAU,CAAE,CAAM;IAC9B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,mCAAmC;AAC5B,SAAS,gBAAgB,CAAE,IAAc;IAC5C,OAAO,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO;AAC9C,CAAC;AAqBD,iCAAiC;AACjC,MAAM,cAAc,GAAG,CAAC;AACxB,sCAAsC;AACtC,MAAM,UAAU,GAAG,IAAI;AAEhB,MAAM,cAAc;IAYvB,YAAqB,IAAc;QAAd,SAAI,GAAJ,IAAI,CAAU;QAX3B,WAAM,GAAuB,IAAI;QACjC,YAAO,GAAuB,IAAI;QAClC,YAAO,GAAuB,IAAI;QAClC,UAAK,GAAG,IAAI,GAAG,EAAyB;QAExC,aAAQ,GAAG,KAAK;QAChB,aAAQ,GAAG,KAAK;QAChB,cAAS,GAAG,KAAK;QACjB,aAAQ,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;QACzB,cAAS,GAAoB,IAAI;IAEF,CAAC;IAExC,2BAA2B;IAC3B,OAAO;QACH,IAAI,CAAC,mBAAmB,EAAE;QAC1B,IAAI,CAAC,eAAe,EAAE;IAC1B,CAAC;IAED,qCAAqC;IACrC,UAAU;QACN,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACd,OAAM;SACT;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;QAChC,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,sBAAsB,GAAG,IAAI;IACzD,CAAC;IAED,qCAAqC;IAE7B,mBAAmB;QACvB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;QAC5C,MAAM,CAAC,SAAS,GAAG,WAAW;QAC9B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM;QACpB,IAAI,CAAC,UAAU,EAAE;QAEjB,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,EAAgB,EAAE,EAAE;YACxD,SAAS;YACT,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;gBACjB,OAAM;aACT;YACD,EAAE,CAAC,cAAc,EAAE;YACnB,EAAE,CAAC,eAAe,EAAE;YACpB,IAAI,CAAC,QAAQ,GAAG,IAAI;YACpB,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC,SAAS,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC;QAC9C,CAAC,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,EAAgB,EAAE,EAAE;YACxD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;gBAChB,OAAM;aACT;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE;YACvD,gCAAgC;YAChC,IAAI,IAAY;YAChB,IAAI,IAAI,KAAK,OAAO,EAAE;gBAClB,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,OAAO;aACjC;iBAAM,IAAI,IAAI,KAAK,MAAM,EAAE;gBACxB,IAAI,GAAG,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI;aAChC;iBAAM,IAAI,IAAI,KAAK,QAAQ,EAAE;gBAC1B,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,OAAO;aAClC;iBAAM;gBACH,IAAI,GAAG,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG;aAC/B;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;QACxB,CAAC,CAAC;QAEF,MAAM,GAAG,GAAG,CAAC,EAAgB,EAAE,EAAE;YAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;gBAChB,OAAM;aACT;YACD,IAAI,CAAC,QAAQ,GAAG,KAAK;YACrB,IAAI;gBACA,MAAM,CAAC,qBAAqB,CAAC,EAAE,CAAC,SAAS,CAAC;aAC7C;YAAC,MAAM;gBACJ,6BAA6B;aAChC;YACD,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC;YAC7C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;QACtB,CAAC;QACD,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,GAAG,CAAC;QACzC,MAAM,CAAC,gBAAgB,CAAC,eAAe,EAAE,GAAG,CAAC;IACjD,CAAC;IAED,uCAAuC;IAE/B,eAAe;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,UAAU,CAAuB;QAC9E,IAAI,CAAC,IAAI,EAAE;YACP,OAAM;SACT;QAED,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,EAAgB,EAAE,EAAE;YACtD,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;gBACjB,OAAM;aACT;YACD,6BAA6B;YAC7B,IAAK,EAAE,CAAC,MAAsB,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE;gBACrD,OAAM;aACT;YACD,IAAI,CAAC,SAAS,GAAG,IAAI;YACrB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE;YAChD,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,SAAS,CAAC;QACxC,CAAC,CAAC;QAEF,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,EAAgB,EAAE,EAAE;YACtD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;gBACjB,OAAM;aACT;YACD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;gBAChB,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACvC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACvC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,cAAc,EAAE;oBACrC,OAAM;iBACT;gBACD,2BAA2B;gBAC3B,IAAI,CAAC,QAAQ,GAAG,IAAI;gBACpB,IAAI,CAAC,WAAW,EAAE;aACrB;YACD,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC;QAC5C,CAAC,CAAC;QAEF,MAAM,GAAG,GAAG,CAAC,EAAgB,EAAE,EAAE;YAC7B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;gBACjB,OAAM;aACT;YACD,IAAI,CAAC,SAAS,GAAG,KAAK;YACtB,IAAI;gBACA,IAAI,CAAC,qBAAqB,CAAC,EAAE,CAAC,SAAS,CAAC;aAC3C;YAAC,MAAM;gBACJ,KAAK;aACR;YACD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;gBAChB,OAAM;aACT;YACD,IAAI,CAAC,QAAQ,GAAG,KAAK;YACrB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS;YAC3B,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE;gBACtC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;gBACpB,IAAI,CAAC,UAAU,EAAE;gBACjB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;aACrB;QACL,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,GAAG,CAAC;QACvC,IAAI,CAAC,gBAAgB,CAAC,eAAe,EAAE,GAAG,CAAC;IAC/C,CAAC;IAED,+BAA+B;IAEvB,WAAW;QACf,IAAI,IAAI,CAAC,OAAO,EAAE;YACd,OAAM;SACT;QACD,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;QAC7C,OAAO,CAAC,SAAS,GAAG,iBAAiB;QAErC,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;QAC7C,OAAO,CAAC,SAAS,GAAG,iBAAiB;QACrC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC;QAE5B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE;YAC3B,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;YAC1C,IAAI,CAAC,SAAS,GAAG,4BAA4B,GAAG,IAAI;YACpD,IAAI,CAAC,SAAS,GAAG,oCAAoC;YACrD,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC;SAC7B;QAED,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,OAAO;QACtB,IAAI,CAAC,OAAO,GAAG,OAAO;QACtB,IAAI,CAAC,aAAa,EAAE;IACxB,CAAC;IAED,iEAAiE;IACzD,aAAa;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE;QACvD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;QACrC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;QACrC,MAAM,KAAK,GAAG,EAAE;QAChB,MAAM,KAAK,GAAuC;YAC9C,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;YAC7B,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,EAAE,EAAE,CAAC;YAC/B,GAAG,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC;YAC3B,MAAM,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;SACpC;QACD,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE;YAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YACjC,IAAI,CAAC,IAAI,EAAE;gBACP,SAAQ;aACX;YACD,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI;YAC1B,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI;SAC5B;IACL,CAAC;IAED,qCAAqC;IAC7B,WAAW,CAAE,CAAS,EAAE,CAAS;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,IAAI,KAAK,IAAI,CAAC,SAAS,EAAE;YACzB,IAAI,CAAC,SAAS,GAAG,IAAI;YACrB,KAAK,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE;gBAChC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAK,IAAI,CAAC;aAC9C;SACJ;QACD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACK,OAAO,CAAE,CAAS,EAAE,CAAS;QACjC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE;YACnC,MAAM,CAAC,GAAG,IAAI,CAAC,qBAAqB,EAAE;YACtC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE;gBAC5D,OAAO,IAAI;aACd;SACJ;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE;QACvD,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK;QACvC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM;QACvC,IAAI,EAAE,GAAG,UAAU,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;YAC7C,OAAO,MAAM;SAChB;QACD,IAAI,EAAE,GAAG,CAAC,GAAG,UAAU,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;YACzD,OAAO,OAAO;SACjB;QACD,IAAI,EAAE,GAAG,UAAU,EAAE;YACjB,OAAO,KAAK;SACf;QACD,IAAI,EAAE,GAAG,CAAC,GAAG,UAAU,EAAE;YACrB,OAAO,QAAQ;SAClB;QACD,OAAO,IAAI;IACf,CAAC;IAED,+CAA+C;IACvC,WAAW,CAAE,IAAqB;QACtC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACf,OAAM;SACT;QACD,IAAI,CAAC,IAAI,EAAE;YACP,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM;YACnC,OAAM;SACT;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE;QACvD,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC;QACzC,oDAAoD;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QACvC,MAAM,IAAI,GAAG,UAAU;YACnB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC;YAC3D,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAEhE,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;QAC5B,CAAC,CAAC,OAAO,GAAG,OAAO;QACnB,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI;QAClE,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI;QAClE,CAAC,CAAC,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI;QACjD,CAAC,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI;IACvD,CAAC;IAEO,WAAW;;QACf,UAAI,CAAC,OAAO,0CAAE,MAAM,EAAE;QACtB,IAAI,CAAC,OAAO,GAAG,IAAI;QACnB,IAAI,CAAC,OAAO,GAAG,IAAI;QACnB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;QAClB,IAAI,CAAC,SAAS,GAAG,IAAI;IACzB,CAAC;CACJ;;;;;;;;;;;;;;;;;;;;;;;;;ACjUyC;AACoB;AAE9D;;;;;;;GAOG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,sDAAc;IACvD,KAAK,CAAC,OAAO;QACT,OAAO;YACH;gBACI,EAAE,EAAE,kBAAkB;gBACtB,IAAI,EAAE,yBAAyB;aAClC;YACD;gBACI,EAAE,EAAE,mBAAmB;gBACvB,IAAI,EAAE,mDAAmD;aAC5D;YACD;gBACI,EAAE,EAAE,iBAAiB;gBACrB,IAAI,EAAE,4CAA4C;aACrD;YACD;gBACI,EAAE,EAAE,kBAAkB;gBACtB,IAAI,EAAE,iCAAiC;aAC1C;SACJ;IACL,CAAC;CACJ;AArBY,uBAAuB;IADnC,yDAAU,EAAE;GACA,uBAAuB,CAqBnC;AArBmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACZM;AAC+C;AACjE;AACE;AACF;AACI;AACwB;AAE4C;AAC1D;AAEtC,MAAM,SAAS,GAAG,sCAAS,CAAC,uCAAU,EAAE,EAAE,qBAAqB,CAAC;AAkBhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IA2B1B,YACY,GAAe,EACf,MAAqB,EACrB,MAAyB,EACzB,QAAyB;QAHzB,QAAG,GAAH,GAAG,CAAY;QACf,WAAM,GAAN,MAAM,CAAe;QACrB,WAAM,GAAN,MAAM,CAAmB;QACzB,aAAQ,GAAR,QAAQ,CAAiB;QA9B7B,SAAI,GAAG,sCAAS,CACpB,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,sCAAS,CAAC,uCAAU,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EACvE,iBAAiB,CACpB;QACO,QAAG,GAAG,sCAAS,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC;QAC5C,yBAAyB;QACjB,aAAQ,GAAG,sCAAS,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;QACvC,WAAM,GAAsB,IAAI;QAChC,eAAU,GAAG,IAAI,GAAG,EAA4B;QACxD,qCAAqC;QAC7B,eAAU,GAAG,IAAI,GAAG,EAA4B;QACxD,oDAAoD;QAC5C,YAAO,GAAG,IAAI,GAAG,EAAkB;QACnC,UAAK,GAAQ,IAAI;QACzB,0CAA0C;QAClC,cAAS,GAAG,CAAC;QACrB;;;WAGG;QACK,YAAO,GAAG,IAAI,GAAG,EAA8B;QAC/C,kBAAa,GAAG,KAAK;QACrB,cAAS,GAAG,CAAC;QACrB,6CAA6C;QACrC,gBAAW,GAAG,IAAI,GAAG,EAAkB;IAO3C,CAAC;IAEL;;;;;;OAMG;IACK,KAAK,CAAC,eAAe;;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;QACvC,IAAI,GAAG,CAAC,mBAAmB,IAAI,CAAC,4DAAc,EAAE,EAAE;YAC9C,OAAM;SACT;QACD,IAAI;YACA,IAAI,4DAAc,EAAE,EAAE;gBAClB,OAAM;aACT;SACJ;QAAC,MAAM;YACJ,yCAAyC;YACzC,OAAM;SACT;QAED,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;YACzC,kEAAkE;YAClE,kDAAkD;YAClD,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,uCAAuC;YAChD,MAAM,EAAE;gBACJ,yDAAyD;gBACzD,6DAA6D;gBAC7D,EAAE;gBACF,UAAU,gEAAkB,EAAE,EAAE;gBAChC,8DAA8D;aACjE,CAAC,IAAI,CAAC,IAAI,CAAC;YACZ,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC;YACpC,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,CAAC;SACd,CAAC;QAEF,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,EAAE;YAClB,IAAI;gBACA,0DAAY,EAAE;gBACd,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;oBACpB,GAAG,CAAC,aAAa,GAAG,IAAI;iBAC3B;gBACD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;aACrB;YAAC,OAAO,CAAM,EAAE;gBACb,MAAM,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;oBAC/B,IAAI,EAAE,OAAO;oBACb,OAAO,EAAE,4BAA4B;oBACrC,MAAM,EAAE,GAAG,OAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,mCAAI,CAAC,EAAE;oBAC5B,OAAO,EAAE,CAAC,IAAI,CAAC;iBAClB,CAAC;aACL;YACD,OAAM;SACT;QACD,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,EAAE;YAClB,GAAG,CAAC,mBAAmB,GAAG,IAAI;YAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;SACrB;IACL,CAAC;IAED,IAAI;QACA,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE;YAC3B,iDAAiD;YACjD,gDAAgD;YAChD,6BAA6B;YAC7B,UAAU,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC,eAAe,EAAE,EAAC,CAAC,EAAE,IAAI,CAAC;YAEvD,oCAAoC;YACpC,uCAAuC;YACvC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa,EAAE;gBAC5C,OAAM;aACT;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;YAC3B,IAAI,CAAC,MAAM,EAAE;YACb,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC;YAChD,KAAK,IAAI,CAAC,WAAW,EAAE;QAC3B,CAAC,CAAC;QACF,+DAA+D;QAC/D,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE;YAC/B,UAAU,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC,WAAW,EAAE,EAAC,CAAC,EAAE,IAAI,CAAC;QACvD,CAAC,CAAC;QACF,qCAAqC;QACrC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE;YAChC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;YACxB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;YACpC,IAAI,GAAG,EAAE;gBACL,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC;gBAC3B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC;aAC9B;QACL,CAAC,CAAC;IACN,CAAC;IAED,kEAAkE;IAC1D,IAAI,CAAE,IAAY;QACtB,IAAI;YACA,8CAAiB,CAAC,SAAS,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,IAAI,IAAI,CAAC;SACxE;QAAC,MAAM;YACJ,UAAU;SACb;IACL,CAAC;IAEO,OAAO,CAAE,GAAqB;QAClC,MAAM,MAAM,GAAG,GAAU;QACzB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACxF,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,WAAW;;QACrB,IAAI,IAAI,CAAC,aAAa,EAAE;YACpB,OAAM;SACT;QACD,IAAI,CAAC,aAAa,GAAG,IAAI;QACzB,IAAI;YACA,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;gBACnC,MAAM,OAAO,GAAG,IAAW;gBAC3B,MAAM,KAAK,GAAU,OAAO,OAAO,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC7F,MAAM,IAAI,GAAa,EAAE;gBACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;oBACtB,MAAM,GAAG,GAAG,UAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,0CAAE,GAAG;oBAC9B,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,UAAU,EAAE;wBAC1C,SAAQ;qBACX;oBACD,IAAI;wBACA,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE;wBAC9B,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE;4BAClC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;yBACjB;qBACJ;oBAAC,MAAM;wBACJ,cAAc;qBACjB;iBACJ;gBACD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;gBACnC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;oBAC5C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC;oBAC5B,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;iBAC1E;aACJ;SACJ;gBAAS;YACN,IAAI,CAAC,aAAa,GAAG,KAAK;SAC7B;IACL,CAAC;IAED,UAAU;IACV,IAAI,QAAQ,KAAc,OAAO,IAAI,CAAC,GAAG,EAAC,CAAC;IAC3C,wCAAwC;IACxC,IAAI,SAAS;;QACT,MAAM,IAAI,GAAG,UAAI,CAAC,MAAM,0CAAE,OAAO,EAAE;QACnC,OAAO,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;;;;;;OAUG;IACK,MAAM;QACV,MAAM,MAAM,GAAG,6CAAgB,CAAC,MAAM,CAAC,EAAE;YACrC,IAAI,GAAG,GAAG,EAAE;YACZ,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC;YAC1B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;gBACtB,GAAG,IAAI,KAAK;gBACZ,sCAAsC;gBACtC,IAAI,EAAU;gBACd,OAAO,CAAC,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;oBAClC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;oBAC7B,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;oBACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;iBACpB;YACL,CAAC,CAAC;YACF,oBAAoB;YACpB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACxC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAoC,CAAC,CAAC;QAClE,CAAC,CAAC;QACF,IAAI,QAAQ,GAAG,KAAK;QACpB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACpB,IAAI,CAAC,QAAQ,EAAE;gBACX,2CAA2C;gBAC3C,QAAQ,GAAG,IAAI;gBACf,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,CAAC;gBAC7B,OAAM;aACT;YACD,IAAI,CAAC,MAAM,GAAG,IAAI;YAClB,yCAAyC;YACzC,sDAAsD;YACtD,IAAI;gBACA,0CAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC/B;YAAC,MAAM;gBACJ,cAAc;aACjB;QACL,CAAC,CAAC;QACF,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;YACxB,IAAI,CAAC,MAAM,GAAG,MAAM;YACpB,IAAI;gBACA,yCAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;gBAC5C,6CAAgB,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;aAClE;YAAC,MAAM;gBACJ,2BAA2B;aAC9B;QACL,CAAC,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,EAAE,WAAW,CAAC;IAC3E,CAAC;IAED,yBAAyB;IACjB,MAAM,CAAE,IAAY;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE;QACxB,IAAI,CAAC,IAAI,EAAE;YACP,OAAM;SACT;QACD,IAAI;YACA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SAC/B;QAAC,MAAM;YACJ,0BAA0B;SAC7B;IACL,CAAC;IAEO,IAAI;QACR,4CAA4C;QAC5C,IAAI,EAAE,IAAI,CAAC,SAAS,GAAG,CAAC,KAAK,CAAC,EAAE;YAC5B,KAAK,IAAI,CAAC,WAAW,EAAE;SAC1B;QACD,IAAI,KAAe;QACnB,IAAI;YACA,KAAK,GAAG,2CAAc,CAAC,IAAI,CAAC,GAAG,CAAC;SACnC;QAAC,MAAM;YACJ,OAAM,CAAC,2BAA2B;SACrC;QACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;gBACzB,SAAQ;aACX;YACD,MAAM,IAAI,GAAG,sCAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC;YACtC,IAAI,IAAgB;YACpB,IAAI;gBACA,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,4CAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;aACnD;YAAC,MAAM;gBACJ,SAAQ,CAAC,2BAA2B;aACvC;YAED,sDAAsD;YACtD,uDAAuD;YACvD,2DAA2D;YAC3D,IAAI,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;gBAClE,IAAI;oBACA,0CAAa,CAAC,IAAI,CAAC;iBACtB;gBAAC,MAAM;oBACJ,oCAAoC;iBACvC;gBACD,SAAQ;aACX;YAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;SACnB;IACL,CAAC;IAED;;;;;;;;;OASG;IACK,KAAK,CAAE,IAAgB;;QAC3B,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAC1B,OAAM;SACT;QACD,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM;QAC/B,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;QACtE,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE;YACzB,OAAM;SACT;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC,EAAE,EAAE;YAC9C,OAAM;SACT;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC;QACtD,IAAI,CAAC,GAAG,EAAE;YACN,wDAAwD;YACxD,mDAAmD;YACnD,6DAA6D;YAC7D,8CAA8C;YAC9C,qDAAqD;YACrD,IAAI,CAAC,WAAI,CAAC,IAAI,0CAAE,MAAM,GAAE;gBACpB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC;aAC5C;YACD,OAAM;SACT;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC;QAEzC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QACvC,IAAI,SAAS,EAAE;YACX,wDAAwD;YACxD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,MAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;SACzE;aAAM;YACH,iCAAiC;YACjC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC;SACnC;QAED,+BAA+B;QAC/B,8CAA8C;QAC9C,uDAAuD;QACvD,uDAAuD;QACvD,yDAAyD;IAC7D,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACK,UAAU,CAAE,SAAiB,EAAE,IAAe;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;QAC5C,MAAM,KAAK,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;QAEnE,MAAM,IAAI,GAAG,oDAAa,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC;QAC9C,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE;YACjC,IAAI,IAAI,CAAC,GAAG,KAAK,KAAK,EAAE;gBACpB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;aAC7D;YACD,OAAO,IAAI,CAAC,GAAG;SAClB;QACD,IAAI,KAAK,EAAE;YACP,OAAO,KAAK;SACf;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE;YAC1B,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;iBACpC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;iBAChE,IAAI,CAAC,GAAG,CAAC;YACd,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,4BAA4B,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,KAAK,EAAE,CAAC;YAC5F,OAAO,IAAI;SACd;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS;QACjC,IAAI,CAAC,MAAM,EAAE;YACT,OAAO,IAAI;SACd;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;QACzC,IAAI,KAAK,IAAI,KAAK,KAAK,SAAS,EAAE;YAC9B,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,wCAAwC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC;YACrF,OAAO,IAAI;SACd;QACD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC;QACtC,OAAO,MAAM;IACjB,CAAC;IAED,mDAAmD;IAC3C,IAAI,CAAE,SAAiB,EAAE,GAAqB,EAAE,GAAW;QAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;QAC1C,IAAI,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE;YACtC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC;SACpC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;QAC9C,IAAI,OAAO,IAAI,OAAO,KAAK,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE;YAC1E,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC;SAClC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC;QACnC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC;QACnC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,YAAY,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,GAAG,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;cAC3E,CAAC,SAAS,IAAI,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,oBAAoB,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACrG,CAAC;IAED,wCAAwC;IAChC,OAAO,CAAE,SAAiB,EAAE,GAAW;QAC3C,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE;YACzC,OAAM;SACT;QACD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,YAAY,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;IACzD,CAAC;CACJ;AA3aY,iBAAiB;IAD7B,yDAAU,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;qCA6Bd,kDAAU;QACP,qDAAa;QACb,8DAAiB;QACf,uDAAe;GA/B5B,iBAAiB,CA2a7B;AA3a6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9DY;AACY;AAE/C,MAAM,eAAe,GAAG,gBAAgB;AAE/C;;;;;;GAMG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAChC,YACY,GAAe,EACf,MAAqB;QADrB,QAAG,GAAH,GAAG,CAAY;QACf,WAAM,GAAN,MAAM,CAAe;IAC7B,CAAC;IAEL,IAAI;QACA,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IACzD,CAAC;IAEO,aAAa;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;QACvC,oDAAoD;QACpD,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE;YACzC,OAAM;SACT;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE;QACjD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC;QAEpE,MAAM,OAAO,GAAG;YACZ,EAAE,EAAE,eAAe;YACnB,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,GAAG,CAAC,eAAe,IAAI,YAAY;YACzC,OAAO,EAAE;gBACL,OAAO,EAAE,GAAG,CAAC,kBAAkB,IAAI,gBAAgB;gBACnD,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;gBACtC,GAAG,EAAE,GAAG,CAAC,cAAc;gBACvB,GAAG,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE;gBACtC,+DAA+D;gBAC/D,2DAA2D;gBAC3D,gEAAgE;aACnE;SACJ;QAED,IAAI,QAAQ,EAAE;YACV,yCAAyC;YACzC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE;gBACnB,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO;gBAClC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;aACrB;iBAAM;gBACH,IAAI,KAAK,GAAG,KAAK;gBACjB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE;oBACvB,QAAQ,CAAC,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG;oBAC1C,KAAK,GAAG,IAAI;iBACf;gBACD,wDAAwD;gBACxD,+BAA+B;gBAC/B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;oBAC9D,QAAQ,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;oBACjD,KAAK,GAAG,IAAI;iBACf;gBACD,yCAAyC;gBACzC,QAAQ,CAAC,OAAO,CAAC,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE;gBACjD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;oBACtD,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE;wBACvC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;wBAC3B,KAAK,GAAG,IAAI;qBACf;iBACJ;gBACD,IAAI,KAAK,EAAE;oBACP,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;iBACrB;aACJ;SACJ;aAAM;YACH,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ;YACrC,oBAAoB;YACpB,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE;gBACzB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,GAAG,eAAe;gBACpD,GAAG,CAAC,kBAAkB,GAAG,IAAI;aAChC;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;SACrB;IACL,CAAC;CACJ;AA3EY,uBAAuB;IADnC,yDAAU,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;qCAGd,kDAAU;QACP,qDAAa;GAHxB,uBAAuB,CA2EnC;AA3EmC;;;;;;;;;;;;;;;;ACbpC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,wDAAwD;AACxD,MAAM,cAAc,GAAG,aAAa;AACpC;;;GAGG;AACH,MAAM,SAAS,GAAG,sCAAsC;AACxD,4CAA4C;AAC5C,MAAM,aAAa,GAAG,mCAAmC;AACzD,oCAAoC;AACpC,MAAM,cAAc,GAAG,CAAC;AACxB,uBAAuB;AAChB,MAAM,aAAa,GAAG,EAAE;AAE/B,qCAAqC;AACrC,SAAS,QAAQ,CAAE,IAAY;IAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE;AACtF,CAAC;AAEM,SAAS,aAAa,CAAE,KAAe;IAC1C,wCAAwC;IACxC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QACxC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC5B,SAAQ;SACX;QACD,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACtB,OAAO,EAAE,EAAC,sCAAsC;SACnD;QACD,IAAI,GAAG,CAAC;QACR,MAAK;KACR;IACD,IAAI,IAAI,GAAG,CAAC,EAAE;QACV,OAAO,EAAE;KACZ;IACD,MAAM,KAAK,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACjE,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAC1C,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;YAC9B,MAAK,CAAC,iCAAiC;SAC1C;QACD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,IAAI,EAAE;YACN,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;SACnB;KACJ;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE;IACxD,IAAI,IAAI,CAAC,MAAM,GAAG,cAAc,EAAE;QAC9B,OAAO,EAAE,EAAC,iCAAiC;KAC9C;IACD,OAAO,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI;AAC9F,CAAC;;;;;;;;;;;;;;;AC3ED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAcH;;;;GAIG;AACH,MAAM,OAAO,GAAG,aAAa;AAC7B,yDAAyD;AACzD,MAAM,OAAO,GAAG,gBAAgB;AAChC,wCAAwC;AACxC,MAAM,gBAAgB,GAAG,eAAe;AACxC,sCAAsC;AACtC,MAAM,SAAS,GAAG,sCAAsC;AACxD,aAAa;AACb,MAAM,YAAY,GAAG,OAAO;AAErB,SAAS,WAAW,CAAE,KAAmB,EAAE,IAAY;IAC1D,MAAM,OAAO,GAAa,EAAE;IAC5B,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;QAC9B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;KACxC;IAED,MAAM,KAAK,GAAa,EAAE;IAC1B,MAAM,KAAK,GAAa,EAAE;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1C,IAAI,CAAC,IAAI,EAAE;YACP,SAAQ;SACX;QAED,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACpB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACb,+CAA+C;YAC/C,6CAA6C;YAC7C,EAAE;YACF,qDAAqD;YACrD,+CAA+C;YAC/C,4DAA4D;YAC5D,2BAA2B;YAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE;gBACtB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,MAAM,YAAY,IAAI,EAAE,CAAC;aAC/D;YACD,SAAQ;SACX;QAED,wBAAwB;QACxB,uDAAuD;QACvD,qDAAqD;QACrD,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACxD,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;SAClE;QAED,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC7C,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;SAChB;KACJ;IAED,+CAA+C;IAC/C,EAAE;IACF,oDAAoD;IACpD,qDAAqD;IACrD,8DAA8D;IAC9D,mDAAmD;IACnD,EAAE;IACF,yDAAyD;IACzD,iDAAiD;IACjD,qCAAqC;IACrC,yDAAyD;IACzD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC;IACtF,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE;QACvB,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QAE3C,mDAAmD;QACnD,EAAE;QACF,mDAAmD;QACnD,qDAAqD;QACrD,4DAA4D;QAC5D,gDAAgD;QAChD,IAAI,MAAM,GAAG,GAAG,GAAG,CAAC,EAAE;YAClB,OAAO,CAAC,IAAI,CAAC,oBAAoB,GAAG,IAAI,MAAM,UAAU,CAAC;SAC5D;aAAM;YACH,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM;YAC9D,mDAAmD;YACnD,iDAAiD;YACjD,IAAI,MAAM,GAAG,CAAC,EAAE;gBACZ,OAAO,CAAC,IAAI,CAAC,YAAY,MAAM,SAAS,CAAC;aAC5C;SACJ;KACJ;IACD,wBAAwB;IACxB,EAAE;IACF,+DAA+D;IAC/D,2DAA2D;IAC3D,uDAAuD;IACvD,yDAAyD;IACzD,oDAAoD;IACpD,EAAE;IACF,2DAA2D;IAC3D,kDAAkD;IAClD,kDAAkD;IAClD,uCAAuC;IACvC,IAAI,KAAK,CAAC,MAAM,IAAI,SAAS,CAAC,MAAM,EAAE;QAClC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACpC,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;QAChD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;QAC/C,IAAI,WAAW,IAAI,CAAC,SAAS,EAAE;YAC3B,OAAO,CAAC,IAAI,CAAC,sBAAsB,IAAI,WAAW,IAAI,GAAG,CAAC,GAAG,CAAC;SACjE;KACJ;IAED,+BAA+B;IAC/B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;QAClB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QAC9E,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE;YACf,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;SACxD;KACJ;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,OAAO,EAAE;AAClD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpKwC;AACkB;AAEjB;AACkD;AAE5F,MAAM,WAAW,GAA2B;IACxC,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,KAAK;IACZ,GAAG,EAAE,IAAI;IACT,MAAM,EAAE,KAAK;CAChB;AAED;;;;;;;;;;GAUG;AAwHI,IAAM,6BAA6B,GAAnC,MAAM,6BAA6B;IAQtC,YACW,MAAqB,EACpB,QAAyB;QAD1B,WAAM,GAAN,MAAM,CAAe;QACpB,aAAQ,GAAR,QAAQ,CAAiB;QATrC,2DAA2D;QAC3D,mBAAc,GAAG,4DAAc,EAAE;QACjC,4CAA4C;QAC5C,YAAO,GAAG,KAAK;QACf,+CAA+C;QAC/C,cAAS,GAAG,EAAE;QAMV,IAAI,CAAC,YAAY,EAAE;IACvB,CAAC;IAEO,YAAY;;QAChB,IAAI;YACA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,cAAc,IAAI,4DAAc,EAAE;SACzD;QAAC,OAAO,CAAM,EAAE;YACb,IAAI,CAAC,OAAO,GAAG,KAAK;YACpB,IAAI,CAAC,SAAS,GAAG,eAAe,OAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,mCAAI,CAAC,EAAE;SACpD;IACL,CAAC;IAED;;;;;OAKG;IACH,WAAW;;QACP,IAAI,CAAC,SAAS,GAAG,EAAE;QACnB,IAAI;YACA,IAAI,IAAI,CAAC,OAAO,EAAE;gBACd,4DAAc,EAAE;aACnB;iBAAM;gBACH,0DAAY,EAAE;gBACd,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa,EAAE;oBAC5C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa,GAAG,IAAI;oBAChD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;iBACrB;aACJ;SACJ;QAAC,OAAO,CAAM,EAAE;YACb,IAAI,CAAC,SAAS,GAAG,GAAG,OAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,mCAAI,CAAC,EAAE;SACxC;QACD,IAAI,CAAC,YAAY,EAAE;IACvB,CAAC;IAED;;;;;;;;OAQG;IACH,iDAAiD;IACjD,aAAa;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;QACvC,OAAO,MAAM,CAAC,IAAI,CAAC,oDAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,oDAAe,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,SAAS;;QACL,OAAO,iBAAW,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,mCAAI,KAAK;IACxE,CAAC;IAED,SAAS;QACL,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;QACvC,IAAI,GAAG,CAAC,WAAW,KAAK,KAAK,IAAI,GAAG,CAAC,WAAW,KAAK,QAAQ,EAAE;YAC3D,OAAO,KAAK,GAAG,GAAG,CAAC,aAAa,GAAG,IAAI;SAC1C;QACD,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM;IACrE,CAAC;IAED;;;;;OAKG;IACH,WAAW;QACP,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,oDAAe,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;IACtB,CAAC;IAED,KAAK,CAAC,OAAO;QACT,MAAM,MAAM,GAAG,MAAO,IAAI,CAAC,QAAgB,CAAC,aAAa,CAAC,UAAU,CAAC;QACrE,IAAI,CAAC,MAAM,EAAE;YACT,OAAM;SACT;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QAC/E,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;IACtB,CAAC;CACJ;AA9FY,6BAA6B;IAvHzC,wDAAS,CAAC;QACP,QAAQ,EAAE,wBAAwB;QAClC,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmHb;KACA,CAAC;qCAUqB,qDAAa;QACV,uDAAe;GAV5B,6BAA6B,CA8FzC;AA9FyC;;;;;;;;;;;;;;;;;;;;;;;;;;AC/IA;AACU;AAEgB;AAEpE;;;GAGG;AAEI,IAAM,4BAA4B,GAAlC,MAAM,4BAA6B,SAAQ,+DAAmB;IAA9D;;QACH,OAAE,GAAG,WAAW;QAChB,SAAI,GAAG,aAAa;QACpB,UAAK,GAAG,WAAW;IAKvB,CAAC;IAHG,gBAAgB;QACZ,OAAO,8EAA6B;IACxC,CAAC;CACJ;AARY,4BAA4B;IADxC,yDAAU,EAAE;GACA,4BAA4B,CAQxC;AARwC;;;;;;;;;;;;;;;;;;;;;;;;;ACVC;AACA;AAI1C;;;;GAIG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAAvB;QACK,WAAM,GAAG,IAAI,GAAG,EAA8B;QAC9C,YAAO,GAAG,IAAI,yCAAO,EAAQ;QAErC,qDAAqD;QACrD,UAAK,GAAG;YACJ,QAAQ,EAAE,CAAC;YACX,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,CAAC;SACf;IA+FL,CAAC;IA7FG,IAAI,QAAQ,KAAwB,OAAO,IAAI,CAAC,OAAO,EAAC,CAAC;IAEzD,GAAG,CAAE,GAAqB;QACtB,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;QAC5B,IAAI,CAAC,CAAC,EAAE;YACJ,CAAC,GAAG;gBACA,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK;gBAC3D,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;aAC9C;YACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;SAC1B;QACD,OAAO,CAAC;IACZ,CAAC;IAED,mCAAmC;IACnC,OAAO,CAAE,GAAqB,EAAE,MAAkB;QAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,EAAE;YACjC,OAAM;SACT;QACD,CAAC,CAAC,MAAM,GAAG,MAAM;QACjB,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;QACpB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;IACvB,CAAC;IAED,gCAAgC;IAChC,SAAS,CAAE,GAAqB,EAAE,MAAkB,EAAE,KAAc;QAChE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QACvB,CAAC,CAAC,MAAM,GAAG,MAAM;QACjB,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;QACpB,CAAC,CAAC,MAAM,GAAG,IAAI;QACf,IAAI,KAAK,KAAK,SAAS,EAAE;YACrB,CAAC,CAAC,KAAK,GAAG,KAAK;SAClB;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;IACvB,CAAC;IAED,QAAQ,CAAE,GAAqB,EAAE,KAAa;QAC1C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,KAAK;QAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;IACvB,CAAC;IAED,4BAA4B;IAC5B,KAAK,CAAE,GAAqB;QACxB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QACvB,CAAC,CAAC,MAAM,GAAG,KAAK;QAChB,CAAC,CAAC,MAAM,GAAG,MAAM;QACjB,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;QACpB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;IACvB,CAAC;IAED,UAAU,CAAE,GAAqB;QAC7B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE;IACzC,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAE,GAAqB;QAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QACvB,CAAC,CAAC,QAAQ,GAAG,IAAI;QACjB,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE;IAC3B,CAAC;IAED,gDAAgD;IAChD,UAAU,CAAE,GAAqB;QAC7B,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ;IACjC,CAAC;IAED,MAAM,CAAE,GAAqB;QACzB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;IACvB,CAAC;IAED,qDAAqD;IACrD,QAAQ,CAAE,GAAqB,EAAE,WAAmB;QAChD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,EAAE;YACpC,OAAO,KAAK;SACf;QACD,iCAAiC;QACjC,2CAA2C;QAC3C,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU;QACnD,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,WAAW,EAAE;YACzC,CAAC,CAAC,MAAM,GAAG,MAAM;YACjB,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;YACpB,OAAO,IAAI;SACd;QACD,OAAO,KAAK;IAChB,CAAC;CACJ;AAzGY,iBAAiB;IAD7B,yDAAU,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;GACtB,iBAAiB,CAyG7B;AAzG6B;;;;;;;;;;;ACX9B,gC;;;;;;;;;;ACAA,6D;;;;;;;;;;ACAA,2D;;;;;;;;;;ACAA,4D;;;;;;;;;;ACAA,kEAAkE,sDAAsD,6BAA6B;;AAErJ,sD;;;;;;;;;;ACFA,gD;;;;;;;;;;ACAA,gD;;;;;;;;;;ACAA,kD;;;;;;;;;;ACAA,kD;;;;;;;;;;ACAA,wD;;;;;;;;;;ACAA,4D;;;;;;;;;;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;;;;UC5BA;UACA;UACA;UACA;UACA;UACA,iCAAiC,WAAW;UAC5C;UACA,E;;;UCPA;UACA;UACA;UACA;UACA,yCAAyC,wCAAwC;UACjF;UACA;UACA,E;;;UCPA,yF;;;UCAA;UACA;UACA,sDAAsD,iBAAiB;UACvE,gDAAgD,aAAa;UAC7D,E;;;UCJA,mC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACAwC;AACM;AACF;AACgC;AACxB;AACF;AAEA;AACC;AACH;AACC;AACU;AACP;AACK;AACW;AAE9C;AAED;AAmBN,IAAM,eAAe,GAArB,MAAM,eAAe;IAChC,YACI,IAAsB,EACtB,QAAiC,EACjC,MAAyB;QAEzB,sCAAsC;QACtC,IAAI,CAAC,IAAI,EAAE;QACX,QAAQ,CAAC,IAAI,EAAE;QACf,MAAM,CAAC,IAAI,EAAE;IACjB,CAAC;CACJ;AAXoB,eAAe;IAjBnC,uDAAQ,CAAC;QACN,OAAO,EAAE;YACL,yDAAY;YACZ,oDAAoD;YACpD,uDAAW;YACX,mDAAe;SAClB;QACD,SAAS,EAAE;YACP,EAAE,OAAO,EAAE,sDAAc,EAAE,QAAQ,EAAE,4DAAuB,EAAE,KAAK,EAAE,IAAI,EAAE;YAC3E,EAAE,OAAO,EAAE,sDAAc,EAAE,QAAQ,EAAE,6DAAuB,EAAE,KAAK,EAAE,IAAI,EAAE;YAC3E,EAAE,OAAO,EAAE,6DAAiB,EAAE,QAAQ,EAAE,0DAAkB,EAAE,KAAK,EAAE,IAAI,EAAE;YACzE,EAAE,OAAO,EAAE,+DAAmB,EAAE,QAAQ,EAAE,oEAA4B,EAAE,KAAK,EAAE,IAAI,EAAE;SACxF;QACD,YAAY,EAAE;YACV,+EAA6B;SAChC;KACJ,CAAC;qCAGY,2DAAgB;QACZ,sEAAuB;QACzB,+DAAiB;GAJZ,eAAe,CAWnC;iEAXoB,eAAe","sources":["webpack-tabby-agentdeck:///webpack/universalModuleDefinition","webpack-tabby-agentdeck:///./src/styles.scss","webpack-tabby-agentdeck:///./node_modules/css-loader/dist/runtime/api.js","webpack-tabby-agentdeck:///./node_modules/css-loader/dist/runtime/sourceMaps.js","webpack://tabby-agentdeck/./src/styles.scss?a609","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/insertBySelector.js","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/insertStyleElement.js","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/styleDomAPI.js","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/styleTagTransform.js","webpack-tabby-agentdeck:///./src/api.ts","webpack-tabby-agentdeck:///./src/bind.ts","webpack-tabby-agentdeck:///./src/claudeHooks.ts","webpack-tabby-agentdeck:///./src/config.ts","webpack-tabby-agentdeck:///./src/deck.service.ts","webpack-tabby-agentdeck:///./src/decorator.ts","webpack-tabby-agentdeck:///./src/detect.ts","webpack-tabby-agentdeck:///./src/dock.ts","webpack-tabby-agentdeck:///./src/hotkeys.ts","webpack-tabby-agentdeck:///./src/notify.service.ts","webpack-tabby-agentdeck:///./src/profile.service.ts","webpack-tabby-agentdeck:///./src/prompt.ts","webpack-tabby-agentdeck:///./src/screen.ts","webpack-tabby-agentdeck:///./src/settings.component.ts","webpack-tabby-agentdeck:///./src/settings.ts","webpack-tabby-agentdeck:///./src/status.service.ts","webpack-tabby-agentdeck:///external node-commonjs \"net\"","webpack-tabby-agentdeck:///external umd \"@angular/common\"","webpack-tabby-agentdeck:///external umd \"@angular/core\"","webpack-tabby-agentdeck:///external umd \"@angular/forms\"","webpack-tabby-agentdeck:///external umd \"electron\"","webpack-tabby-agentdeck:///external umd \"fs\"","webpack-tabby-agentdeck:///external umd \"os\"","webpack-tabby-agentdeck:///external umd \"path\"","webpack-tabby-agentdeck:///external umd \"rxjs\"","webpack-tabby-agentdeck:///external umd \"tabby-core\"","webpack-tabby-agentdeck:///external umd \"tabby-settings\"","webpack-tabby-agentdeck:///external umd \"tabby-terminal\"","webpack-tabby-agentdeck:///webpack/bootstrap","webpack-tabby-agentdeck:///webpack/runtime/compat get default export","webpack-tabby-agentdeck:///webpack/runtime/define property getters","webpack-tabby-agentdeck:///webpack/runtime/hasOwnProperty shorthand","webpack-tabby-agentdeck:///webpack/runtime/make namespace object","webpack-tabby-agentdeck:///webpack/runtime/nonce","webpack-tabby-agentdeck:///./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/core\"), require(\"@angular/forms\"), (function webpackLoadOptionalExternalModule() { try { return require(\"electron\"); } catch(e) {} }()), require(\"fs\"), require(\"os\"), require(\"path\"), require(\"rxjs\"), require(\"tabby-core\"), require(\"tabby-settings\"), require(\"tabby-terminal\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"@angular/common\", \"@angular/core\", \"@angular/forms\", \"electron\", \"fs\", \"os\", \"path\", \"rxjs\", \"tabby-core\", \"tabby-settings\", \"tabby-terminal\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"@angular/common\"), require(\"@angular/core\"), require(\"@angular/forms\"), (function webpackLoadOptionalExternalModule() { try { return require(\"electron\"); } catch(e) {} }()), require(\"fs\"), require(\"os\"), require(\"path\"), require(\"rxjs\"), require(\"tabby-core\"), require(\"tabby-settings\"), require(\"tabby-terminal\")) : factory(root[\"@angular/common\"], root[\"@angular/core\"], root[\"@angular/forms\"], root[\"electron\"], root[\"fs\"], root[\"os\"], root[\"path\"], root[\"rxjs\"], root[\"tabby-core\"], root[\"tabby-settings\"], root[\"tabby-terminal\"]);\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_core__, __WEBPACK_EXTERNAL_MODULE__angular_forms__, __WEBPACK_EXTERNAL_MODULE_electron__, __WEBPACK_EXTERNAL_MODULE_fs__, __WEBPACK_EXTERNAL_MODULE_os__, __WEBPACK_EXTERNAL_MODULE_path__, __WEBPACK_EXTERNAL_MODULE_rxjs__, __WEBPACK_EXTERNAL_MODULE_tabby_core__, __WEBPACK_EXTERNAL_MODULE_tabby_settings__, __WEBPACK_EXTERNAL_MODULE_tabby_terminal__) => {\nreturn ","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `body.agentdeck-active.ad-bg-clip .content-tab-active::before {\n left: var(--ad-bg-left) !important;\n top: var(--ad-bg-top) !important;\n right: auto !important;\n bottom: auto !important;\n width: var(--ad-bg-width) !important;\n height: var(--ad-bg-height) !important;\n}\n\n#agentdeck-sidebar {\n display: flex;\n flex-direction: column;\n z-index: 5;\n overflow: hidden;\n background: var(--ad-panel-bg, var(--bs-body-bg, #1e2127));\n font-size: 12px;\n user-select: none;\n -webkit-app-region: no-drag;\n}\n#agentdeck-sidebar.ad-dock-right {\n border-left: 1px solid rgba(255, 255, 255, 0.08);\n}\n#agentdeck-sidebar.ad-dock-left {\n border-right: 1px solid rgba(255, 255, 255, 0.08);\n}\n#agentdeck-sidebar.ad-dock-top {\n border-bottom: 1px solid rgba(255, 255, 255, 0.08);\n}\n#agentdeck-sidebar.ad-dock-bottom {\n border-top: 1px solid rgba(255, 255, 255, 0.08);\n}\n#agentdeck-sidebar.ad-dock-top .ad-list, #agentdeck-sidebar.ad-dock-bottom .ad-list {\n display: flex;\n flex-wrap: wrap;\n align-content: flex-start;\n gap: 0 6px;\n overflow-y: auto;\n}\n#agentdeck-sidebar.ad-dock-top .ad-tab, #agentdeck-sidebar.ad-dock-bottom .ad-tab {\n flex: 0 0 220px;\n}\n#agentdeck-sidebar .ad-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px 8px;\n letter-spacing: 0.12em;\n font-size: 10px;\n font-weight: 700;\n color: rgba(255, 255, 255, 0.4);\n -webkit-app-region: no-drag;\n cursor: grab;\n}\n#agentdeck-sidebar .ad-head:active {\n cursor: grabbing;\n}\n#agentdeck-sidebar .ad-resize {\n position: absolute;\n z-index: 6;\n background: transparent;\n transition: background 0.12s ease;\n}\n#agentdeck-sidebar .ad-resize:hover, body.ad-resizing #agentdeck-sidebar .ad-resize {\n background: rgba(97, 175, 239, 0.5);\n}\n#agentdeck-sidebar .ad-resize-right,\n#agentdeck-sidebar .ad-resize-left {\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: col-resize;\n}\n#agentdeck-sidebar .ad-resize-right {\n left: 0;\n}\n#agentdeck-sidebar .ad-resize-left {\n right: 0;\n}\n#agentdeck-sidebar .ad-resize-top,\n#agentdeck-sidebar .ad-resize-bottom {\n left: 0;\n right: 0;\n height: 6px;\n cursor: row-resize;\n}\n#agentdeck-sidebar .ad-resize-bottom {\n top: 0;\n}\n#agentdeck-sidebar .ad-resize-top {\n bottom: 0;\n}\n#agentdeck-sidebar .ad-head-count {\n -webkit-app-region: no-drag;\n padding: 1px 6px;\n border-radius: 8px;\n background: rgba(255, 255, 255, 0.08);\n color: rgba(255, 255, 255, 0.55);\n}\n#agentdeck-sidebar .ad-list {\n flex: 1 1 auto;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 2px 6px 8px;\n}\n#agentdeck-sidebar .ad-list::-webkit-scrollbar {\n width: 8px;\n}\n#agentdeck-sidebar .ad-list::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.14);\n border-radius: 4px;\n}\n#agentdeck-sidebar .ad-list::-webkit-scrollbar-thumb:hover {\n background: rgba(255, 255, 255, 0.24);\n}\n#agentdeck-sidebar .ad-tab {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: 8px;\n margin-bottom: 3px;\n padding: 7px 6px 7px 0;\n border-radius: 5px;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n#agentdeck-sidebar .ad-tab:hover {\n background: rgba(255, 255, 255, 0.05);\n}\n#agentdeck-sidebar .ad-tab:hover .ad-close {\n opacity: 0.65;\n}\n#agentdeck-sidebar .ad-tab.active {\n background: rgba(255, 255, 255, 0.1);\n}\n#agentdeck-sidebar .ad-tab.active .ad-title {\n color: #fff;\n}\n#agentdeck-sidebar .ad-bar {\n flex: 0 0 3px;\n border-radius: 2px;\n background: var(--ad-color, #6b727d);\n}\n#agentdeck-sidebar .ad-body {\n flex: 1 1 auto;\n min-width: 0;\n}\n#agentdeck-sidebar .ad-title {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: rgba(255, 255, 255, 0.82);\n font-size: 12.5px;\n line-height: 1.35;\n}\n#agentdeck-sidebar .ad-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 2px;\n font-size: 10.5px;\n line-height: 1.4;\n color: rgba(255, 255, 255, 0.45);\n}\n#agentdeck-sidebar .ad-badge {\n flex: 0 0 auto;\n color: var(--ad-color, #6b727d);\n font-weight: 600;\n}\n#agentdeck-sidebar .ad-badge.pinned {\n text-decoration: underline dotted;\n text-underline-offset: 2px;\n}\n#agentdeck-sidebar .ad-prompt {\n display: flex;\n align-items: center;\n margin-top: 2px;\n min-width: 0;\n font-size: 11px;\n line-height: 1.4;\n}\n#agentdeck-sidebar .ad-label {\n flex: 1 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: rgba(255, 255, 255, 0.6);\n}\n#agentdeck-sidebar .ad-label.empty {\n color: rgba(255, 255, 255, 0.25);\n}\n#agentdeck-sidebar .ad-elapsed {\n flex: 0 0 auto;\n margin-left: auto;\n font-variant-numeric: tabular-nums;\n opacity: 0.55;\n}\n#agentdeck-sidebar .ad-label-input {\n flex: 1 1 auto;\n min-width: 0;\n padding: 0 4px;\n border: 1px solid rgba(255, 255, 255, 0.25);\n border-radius: 3px;\n background: rgba(0, 0, 0, 0.35);\n color: #fff;\n font-size: 10.5px;\n outline: none;\n}\n#agentdeck-sidebar .ad-label-input:focus {\n border-color: var(--ad-color, #61afef);\n}\n#agentdeck-sidebar .ad-close {\n flex: 0 0 auto;\n align-self: center;\n width: 18px;\n height: 18px;\n padding: 0;\n border: 0;\n border-radius: 3px;\n opacity: 0;\n background: transparent;\n color: rgba(255, 255, 255, 0.8);\n font-size: 15px;\n line-height: 1;\n cursor: pointer;\n transition: opacity 0.1s ease, background 0.1s ease;\n}\n#agentdeck-sidebar .ad-close:hover {\n opacity: 1 !important;\n background: rgba(255, 80, 80, 0.35);\n}\n#agentdeck-sidebar .ad-foot {\n display: flex;\n gap: 6px;\n padding: 8px;\n border-top: 1px solid rgba(255, 255, 255, 0.07);\n}\n#agentdeck-sidebar .ad-btn {\n flex: 1 1 auto;\n padding: 5px 8px;\n border: 1px solid rgba(255, 255, 255, 0.12);\n border-radius: 4px;\n background: transparent;\n color: rgba(255, 255, 255, 0.6);\n font-size: 11px;\n cursor: pointer;\n}\n#agentdeck-sidebar .ad-btn:hover {\n background: rgba(255, 255, 255, 0.08);\n color: #fff;\n}\n#agentdeck-sidebar .ad-repair {\n flex: 0 0 auto;\n min-width: 28px;\n font-size: 13px;\n line-height: 1;\n}\n\n.ad-menu {\n position: fixed;\n z-index: 10000;\n min-width: 130px;\n padding: 4px;\n border: 1px solid rgba(255, 255, 255, 0.12);\n border-radius: 6px;\n background: #262a31;\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);\n font-size: 12px;\n user-select: none;\n}\n.ad-menu .ad-menu-item {\n padding: 6px 10px;\n border-radius: 4px;\n color: rgba(255, 255, 255, 0.75);\n cursor: pointer;\n}\n.ad-menu .ad-menu-item:hover {\n background: rgba(255, 255, 255, 0.1);\n color: #fff;\n}\n\n.ad-dock-overlay {\n position: fixed;\n inset: 0;\n z-index: 9998;\n pointer-events: none;\n}\n\n.ad-dock-preview {\n position: fixed;\n display: none;\n border: 1px solid rgba(97, 175, 239, 0.9);\n background: rgba(97, 175, 239, 0.22);\n box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.18);\n transition: left 0.08s ease, top 0.08s ease, width 0.08s ease, height 0.08s ease;\n}\n\n.ad-dock-zone {\n position: fixed;\n width: 46px;\n height: 46px;\n margin: -23px 0 0 -23px;\n border: 1px solid rgba(255, 255, 255, 0.35);\n border-radius: 6px;\n background: rgba(38, 42, 49, 0.92);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.ad-dock-zone .ad-dock-mark {\n width: 26px;\n height: 26px;\n border: 1px solid rgba(255, 255, 255, 0.45);\n border-radius: 3px;\n}\n.ad-dock-zone.active {\n border-color: rgba(97, 175, 239, 0.95);\n background: rgba(97, 175, 239, 0.35);\n}\n.ad-dock-zone.ad-dock-zone-left .ad-dock-mark {\n border-left: 4px solid rgba(97, 175, 239, 0.95);\n}\n.ad-dock-zone.ad-dock-zone-right .ad-dock-mark {\n border-right: 4px solid rgba(97, 175, 239, 0.95);\n}\n.ad-dock-zone.ad-dock-zone-top .ad-dock-mark {\n border-top: 4px solid rgba(97, 175, 239, 0.95);\n}\n.ad-dock-zone.ad-dock-zone-bottom .ad-dock-mark {\n border-bottom: 4px solid rgba(97, 175, 239, 0.95);\n}\n\nbody.ad-resizing {\n cursor: inherit;\n}\nbody.ad-resizing .content.main {\n pointer-events: none;\n}\n\nbody.agentdeck-active .content.main > .tab-bar {\n display: none !important;\n}\nbody.agentdeck-active .window {\n display: flex;\n flex-direction: row;\n position: relative;\n background: var(--ad-panel-bg, var(--bs-body-bg, #1e2127));\n}`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/styles.scss\"],\"names\":[],\"mappings\":\"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\",\"sourcesContent\":[\"// AgentDeck 사이드바 스타일\\r\\n// Tabby 테마 변수(--bs-*)를 우선 쓰되, 없을 때를 대비해 폴백 색을 함께 준다.\\r\\n\\r\\n// tabby-background 의 배경 이미지 레이어(.content-tab-active::before)를 터미널 영역으로 자른다.\\r\\n// 좌표 변수(--ad-bg-*)는 deck.service 의 syncBackgroundClip 이 relayout 마다 내려준다.\\r\\n// 그 플러그인은 런타임에 <style> 을 만들어 head 뒤쪽에 붙이므로 순서로는 못 이긴다 — !important 필수.\\r\\nbody.agentdeck-active.ad-bg-clip .content-tab-active::before {\\r\\n left: var(--ad-bg-left) !important;\\r\\n top: var(--ad-bg-top) !important;\\r\\n right: auto !important;\\r\\n bottom: auto !important;\\r\\n width: var(--ad-bg-width) !important;\\r\\n height: var(--ad-bg-height) !important;\\r\\n}\\r\\n\\r\\n#agentdeck-sidebar {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n // 실제 위치와 크기는 deck.service 의 relayout 이 인라인으로 준다 (도킹 방향에 따라 달라짐)\\r\\n z-index: 5;\\r\\n overflow: hidden;\\r\\n // --ad-panel-bg 는 agentdeck 이 sidebarOpacity 로 내려준다 (배경 이미지가 비치게)\\r\\n background: var(--ad-panel-bg, var(--bs-body-bg, #1e2127));\\r\\n font-size: 12px;\\r\\n user-select: none;\\r\\n -webkit-app-region: no-drag;\\r\\n\\r\\n // 붙어 있는 쪽 반대편에만 경계선을 그린다\\r\\n &.ad-dock-right { border-left: 1px solid rgba(255, 255, 255, 0.08); }\\r\\n &.ad-dock-left { border-right: 1px solid rgba(255, 255, 255, 0.08); }\\r\\n &.ad-dock-top { border-bottom: 1px solid rgba(255, 255, 255, 0.08); }\\r\\n &.ad-dock-bottom { border-top: 1px solid rgba(255, 255, 255, 0.08); }\\r\\n\\r\\n // 상/하 도킹은 세로가 짧으므로 목록을 가로로 흘린다\\r\\n &.ad-dock-top,\\r\\n &.ad-dock-bottom {\\r\\n .ad-list {\\r\\n display: flex;\\r\\n flex-wrap: wrap;\\r\\n align-content: flex-start;\\r\\n gap: 0 6px;\\r\\n overflow-y: auto;\\r\\n }\\r\\n\\r\\n .ad-tab {\\r\\n flex: 0 0 220px;\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-head {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n padding: 10px 12px 8px;\\r\\n letter-spacing: 0.12em;\\r\\n font-size: 10px;\\r\\n font-weight: 700;\\r\\n color: rgba(255, 255, 255, 0.4);\\r\\n // 헤더를 잡아 끌면 도킹 방향을 바꾼다 (OS 창 이동에 뺏기면 안 되므로 no-drag)\\r\\n -webkit-app-region: no-drag;\\r\\n cursor: grab;\\r\\n\\r\\n &:active {\\r\\n cursor: grabbing;\\r\\n }\\r\\n }\\r\\n\\r\\n // 경계선 — 잡아 끌면 크기가 바뀐다. 붙어 있는 쪽 반대편 가장자리에 놓는다\\r\\n .ad-resize {\\r\\n position: absolute;\\r\\n z-index: 6;\\r\\n background: transparent;\\r\\n transition: background 0.12s ease;\\r\\n\\r\\n &:hover,\\r\\n body.ad-resizing & {\\r\\n background: rgba(97, 175, 239, 0.5);\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-resize-right,\\r\\n .ad-resize-left {\\r\\n top: 0;\\r\\n bottom: 0;\\r\\n width: 6px;\\r\\n cursor: col-resize;\\r\\n }\\r\\n\\r\\n .ad-resize-right { left: 0; }\\r\\n .ad-resize-left { right: 0; }\\r\\n\\r\\n .ad-resize-top,\\r\\n .ad-resize-bottom {\\r\\n left: 0;\\r\\n right: 0;\\r\\n height: 6px;\\r\\n cursor: row-resize;\\r\\n }\\r\\n\\r\\n .ad-resize-bottom { top: 0; }\\r\\n .ad-resize-top { bottom: 0; }\\r\\n\\r\\n .ad-head-count {\\r\\n -webkit-app-region: no-drag;\\r\\n padding: 1px 6px;\\r\\n border-radius: 8px;\\r\\n background: rgba(255, 255, 255, 0.08);\\r\\n color: rgba(255, 255, 255, 0.55);\\r\\n }\\r\\n\\r\\n // 요구 2-1: 탭이 많아지면 이 영역만 스크롤된다\\r\\n .ad-list {\\r\\n flex: 1 1 auto;\\r\\n overflow-y: auto;\\r\\n overflow-x: hidden;\\r\\n padding: 2px 6px 8px;\\r\\n\\r\\n &::-webkit-scrollbar {\\r\\n width: 8px;\\r\\n }\\r\\n\\r\\n &::-webkit-scrollbar-thumb {\\r\\n background: rgba(255, 255, 255, 0.14);\\r\\n border-radius: 4px;\\r\\n\\r\\n &:hover {\\r\\n background: rgba(255, 255, 255, 0.24);\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-tab {\\r\\n position: relative;\\r\\n display: flex;\\r\\n align-items: stretch;\\r\\n gap: 8px;\\r\\n margin-bottom: 3px;\\r\\n padding: 7px 6px 7px 0;\\r\\n border-radius: 5px;\\r\\n cursor: pointer;\\r\\n transition: background 0.1s ease;\\r\\n\\r\\n &:hover {\\r\\n background: rgba(255, 255, 255, 0.05);\\r\\n\\r\\n .ad-close {\\r\\n opacity: 0.65;\\r\\n }\\r\\n }\\r\\n\\r\\n &.active {\\r\\n background: rgba(255, 255, 255, 0.1);\\r\\n\\r\\n .ad-title {\\r\\n color: #fff;\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n // 상태색 표시 바\\r\\n .ad-bar {\\r\\n flex: 0 0 3px;\\r\\n border-radius: 2px;\\r\\n background: var(--ad-color, #6b727d);\\r\\n }\\r\\n\\r\\n .ad-body {\\r\\n flex: 1 1 auto;\\r\\n min-width: 0;\\r\\n }\\r\\n\\r\\n .ad-title {\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n color: rgba(255, 255, 255, 0.82);\\r\\n font-size: 12.5px;\\r\\n line-height: 1.35;\\r\\n }\\r\\n\\r\\n .ad-meta {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 6px;\\r\\n margin-top: 2px;\\r\\n font-size: 10.5px;\\r\\n line-height: 1.4;\\r\\n color: rgba(255, 255, 255, 0.45);\\r\\n }\\r\\n\\r\\n .ad-badge {\\r\\n flex: 0 0 auto;\\r\\n color: var(--ad-color, #6b727d);\\r\\n font-weight: 600;\\r\\n\\r\\n // 수동/훅으로 고정된 상태는 밑줄로 구분\\r\\n &.pinned {\\r\\n text-decoration: underline dotted;\\r\\n text-underline-offset: 2px;\\r\\n }\\r\\n }\\r\\n\\r\\n // 두 번째 줄 — 마지막으로 보낸 프롬프트\\r\\n .ad-prompt {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n margin-top: 2px;\\r\\n min-width: 0;\\r\\n font-size: 11px;\\r\\n line-height: 1.4;\\r\\n }\\r\\n\\r\\n .ad-label {\\r\\n flex: 1 1 auto;\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n color: rgba(255, 255, 255, 0.6);\\r\\n\\r\\n // 아직 프롬프트가 없는 탭 — 자리는 지키되 눈에 덜 걸리게\\r\\n &.empty {\\r\\n color: rgba(255, 255, 255, 0.25);\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-elapsed {\\r\\n flex: 0 0 auto;\\r\\n margin-left: auto;\\r\\n font-variant-numeric: tabular-nums;\\r\\n opacity: 0.55;\\r\\n }\\r\\n\\r\\n .ad-label-input {\\r\\n flex: 1 1 auto;\\r\\n min-width: 0;\\r\\n padding: 0 4px;\\r\\n border: 1px solid rgba(255, 255, 255, 0.25);\\r\\n border-radius: 3px;\\r\\n background: rgba(0, 0, 0, 0.35);\\r\\n color: #fff;\\r\\n font-size: 10.5px;\\r\\n outline: none;\\r\\n\\r\\n &:focus {\\r\\n border-color: var(--ad-color, #61afef);\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-close {\\r\\n flex: 0 0 auto;\\r\\n align-self: center;\\r\\n width: 18px;\\r\\n height: 18px;\\r\\n padding: 0;\\r\\n border: 0;\\r\\n border-radius: 3px;\\r\\n opacity: 0;\\r\\n background: transparent;\\r\\n color: rgba(255, 255, 255, 0.8);\\r\\n font-size: 15px;\\r\\n line-height: 1;\\r\\n cursor: pointer;\\r\\n transition: opacity 0.1s ease, background 0.1s ease;\\r\\n\\r\\n &:hover {\\r\\n opacity: 1 !important;\\r\\n background: rgba(255, 80, 80, 0.35);\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-foot {\\r\\n display: flex;\\r\\n gap: 6px;\\r\\n padding: 8px;\\r\\n border-top: 1px solid rgba(255, 255, 255, 0.07);\\r\\n }\\r\\n\\r\\n .ad-btn {\\r\\n flex: 1 1 auto;\\r\\n padding: 5px 8px;\\r\\n border: 1px solid rgba(255, 255, 255, 0.12);\\r\\n border-radius: 4px;\\r\\n background: transparent;\\r\\n color: rgba(255, 255, 255, 0.6);\\r\\n font-size: 11px;\\r\\n cursor: pointer;\\r\\n\\r\\n &:hover {\\r\\n background: rgba(255, 255, 255, 0.08);\\r\\n color: #fff;\\r\\n }\\r\\n }\\r\\n\\r\\n // 복구 버튼은 글자가 한 자뿐이라 나머지 버튼과 같은 비율로 늘어나면 허전하다\\r\\n .ad-repair {\\r\\n flex: 0 0 auto;\\r\\n min-width: 28px;\\r\\n font-size: 13px;\\r\\n line-height: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n// 우클릭 상태 메뉴\\r\\n.ad-menu {\\r\\n position: fixed;\\r\\n z-index: 10000;\\r\\n min-width: 130px;\\r\\n padding: 4px;\\r\\n border: 1px solid rgba(255, 255, 255, 0.12);\\r\\n border-radius: 6px;\\r\\n background: #262a31;\\r\\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);\\r\\n font-size: 12px;\\r\\n user-select: none;\\r\\n\\r\\n .ad-menu-item {\\r\\n padding: 6px 10px;\\r\\n border-radius: 4px;\\r\\n color: rgba(255, 255, 255, 0.75);\\r\\n cursor: pointer;\\r\\n\\r\\n &:hover {\\r\\n background: rgba(255, 255, 255, 0.1);\\r\\n color: #fff;\\r\\n }\\r\\n }\\r\\n}\\r\\n\\r\\n// 도킹 가이드 — 헤더를 끌고 있는 동안만 창 위에 뜬다\\r\\n.ad-dock-overlay {\\r\\n position: fixed;\\r\\n inset: 0;\\r\\n z-index: 9998;\\r\\n // 커서 판정은 좌표로 직접 하므로 오버레이가 이벤트를 가로채면 안 된다\\r\\n pointer-events: none;\\r\\n}\\r\\n\\r\\n// 놓으면 사이드바가 자리잡을 영역\\r\\n.ad-dock-preview {\\r\\n position: fixed;\\r\\n display: none;\\r\\n border: 1px solid rgba(97, 175, 239, 0.9);\\r\\n background: rgba(97, 175, 239, 0.22);\\r\\n box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.18);\\r\\n transition: left 0.08s ease, top 0.08s ease, width 0.08s ease, height 0.08s ease;\\r\\n}\\r\\n\\r\\n// 네 가장자리에 뜨는 도킹 표적\\r\\n.ad-dock-zone {\\r\\n position: fixed;\\r\\n width: 46px;\\r\\n height: 46px;\\r\\n margin: -23px 0 0 -23px;\\r\\n border: 1px solid rgba(255, 255, 255, 0.35);\\r\\n border-radius: 6px;\\r\\n background: rgba(38, 42, 49, 0.92);\\r\\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n\\r\\n .ad-dock-mark {\\r\\n width: 26px;\\r\\n height: 26px;\\r\\n border: 1px solid rgba(255, 255, 255, 0.45);\\r\\n border-radius: 3px;\\r\\n }\\r\\n\\r\\n &.active {\\r\\n border-color: rgba(97, 175, 239, 0.95);\\r\\n background: rgba(97, 175, 239, 0.35);\\r\\n }\\r\\n\\r\\n // 표적 안의 작은 사각형이 \\\"어느 쪽 절반에 붙는지\\\" 를 그대로 보여준다\\r\\n &.ad-dock-zone-left .ad-dock-mark { border-left: 4px solid rgba(97, 175, 239, 0.95); }\\r\\n &.ad-dock-zone-right .ad-dock-mark { border-right: 4px solid rgba(97, 175, 239, 0.95); }\\r\\n &.ad-dock-zone-top .ad-dock-mark { border-top: 4px solid rgba(97, 175, 239, 0.95); }\\r\\n &.ad-dock-zone-bottom .ad-dock-mark { border-bottom: 4px solid rgba(97, 175, 239, 0.95); }\\r\\n}\\r\\n\\r\\n// 경계선을 끄는 동안에는 터미널이 커서를 뺏지 않게 한다\\r\\nbody.ad-resizing {\\r\\n cursor: inherit;\\r\\n\\r\\n .content.main {\\r\\n pointer-events: none;\\r\\n }\\r\\n}\\r\\n\\r\\n// AgentDeck 이 켜져 있을 때만 순정 탭바를 감춘다 (사이드바가 그 역할을 대신함)\\r\\nbody.agentdeck-active {\\r\\n .content.main > .tab-bar {\\r\\n display: none !important;\\r\\n }\\r\\n\\r\\n .window {\\r\\n display: flex;\\r\\n flex-direction: row;\\r\\n // 사이드바를 창 안에 절대 배치하므로 기준점이 필요하다\\r\\n position: relative;\\r\\n // 터미널 옆에 남는 여백이 밝은 기본 배경으로 튀지 않게 한다\\r\\n // (--ad-panel-bg 가 있으면 배경 이미지가 이 여백으로도 비친다)\\r\\n background: var(--ad-panel-bg, var(--bs-body-bg, #1e2127));\\r\\n }\\r\\n}\\r\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};","\"use strict\";\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [content].concat([sourceMapping]).join(\"\\n\");\n }\n return [content].join(\"\\n\");\n};","\n import API from \"!../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../node_modules/css-loader/dist/cjs.js!../node_modules/sass-loader/dist/cjs.js!./styles.scss\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../node_modules/css-loader/dist/cjs.js!../node_modules/sass-loader/dist/cjs.js!./styles.scss\";\n export default content && content.locals ? content.locals : undefined;\n","\"use strict\";\n\nvar stylesInDOM = [];\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n return result;\n}\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n identifiers.push(identifier);\n }\n return identifiers;\n}\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n return updater;\n}\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n var newLastIdentifiers = modulesToDom(newList, options);\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n var _index = getIndexByIdentifier(_identifier);\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n stylesInDOM.splice(_index, 1);\n }\n }\n lastIdentifiers = newLastIdentifiers;\n };\n};","\"use strict\";\n\nvar memo = {};\n\n/* istanbul ignore next */\nfunction getTarget(target) {\n if (typeof memo[target] === \"undefined\") {\n var styleTarget = document.querySelector(target);\n\n // Special case to return head of iframe instead of iframe itself\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n memo[target] = styleTarget;\n }\n return memo[target];\n}\n\n/* istanbul ignore next */\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n target.appendChild(style);\n}\nmodule.exports = insertBySelector;","\"use strict\";\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement(\"style\");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\nmodule.exports = insertStyleElement;","\"use strict\";\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = typeof __webpack_nonce__ !== \"undefined\" ? __webpack_nonce__ : null;\n if (nonce) {\n styleElement.setAttribute(\"nonce\", nonce);\n }\n}\nmodule.exports = setAttributesWithoutAttributes;","\"use strict\";\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = \"\";\n if (obj.supports) {\n css += \"@supports (\".concat(obj.supports, \") {\");\n }\n if (obj.media) {\n css += \"@media \".concat(obj.media, \" {\");\n }\n var needLayer = typeof obj.layer !== \"undefined\";\n if (needLayer) {\n css += \"@layer\".concat(obj.layer.length > 0 ? \" \".concat(obj.layer) : \"\", \" {\");\n }\n css += obj.css;\n if (needLayer) {\n css += \"}\";\n }\n if (obj.media) {\n css += \"}\";\n }\n if (obj.supports) {\n css += \"}\";\n }\n var sourceMap = obj.sourceMap;\n if (sourceMap && typeof btoa !== \"undefined\") {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n }\n\n // For old IE\n /* istanbul ignore if */\n options.styleTagTransform(css, styleElement, options.options);\n}\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n styleElement.parentNode.removeChild(styleElement);\n}\n\n/* istanbul ignore next */\nfunction domAPI(options) {\n if (typeof document === \"undefined\") {\n return {\n update: function update() {},\n remove: function remove() {}\n };\n }\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\nmodule.exports = domAPI;","\"use strict\";\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n styleElement.appendChild(document.createTextNode(css));\n }\n}\nmodule.exports = styleTagTransform;","/** 사이드바에 표시되는 작업 상태 */\nexport type WorkStatus = 'idle' | 'running' | 'waiting' | 'done' | 'error'\n\nexport interface StatusStyle {\n icon: string\n label: string\n color: string\n}\n\n/** 상태별 표시 규칙 — 사이드바 배지와 좌측 컬러바에 함께 쓰인다 */\nexport const STATUS_STYLES: Record<WorkStatus, StatusStyle> = {\n running: { icon: '●', label: '진행중', color: '#e5c07b' },\n waiting: { icon: '⏸', label: '승인대기', color: '#61afef' },\n done: { icon: '✔', label: '완료', color: '#98c379' },\n error: { icon: '✖', label: '오류', color: '#e06c75' },\n idle: { icon: '○', label: '대기', color: '#6b727d' },\n}\n\nexport interface TabState {\n /** 현재 상태 */\n status: WorkStatus\n /** 작업 이름 (사용자 지정 또는 훅이 보낸 값) */\n label: string\n /** 상태가 마지막으로 바뀐 시각 */\n since: number\n /** true = 수동/훅 지정. 자동 감지가 덮어쓰지 않는다 */\n pinned: boolean\n /** 마지막 PTY 출력 시각 */\n lastOutput: number\n /**\n * 이 탭에서 에이전트의 \"작업 중\" 신호를 본 적이 있나.\n *\n * 본 적이 있으면 그 탭은 에이전트 TUI 로 보고, 그 뒤로는 신호가 있을 때만 진행중으로 친다.\n * Claude Code 는 놀고 있을 때도 하단 상태줄을 매초 다시 그리기 때문에\n * \"출력이 있다 = 진행중\" 으로 보면 영원히 진행중에서 내려오지 않는다 (2026-09-01 실측).\n */\n busyMode: boolean\n /** 마지막으로 \"작업 중\" 신호를 본 시각 — 진행중에서 내려올 시점을 이걸로 잰다 */\n lastBusy: number\n}\n","/**\r\n * 훅 보고를 어느 탭에 붙일지 고르는 순수 규칙 — Angular/Tabby 에 기대지 않아 단위 테스트가 된다.\r\n *\r\n * 왜 PID 인가 — 예전 규칙 \"처음 보고할 때의 활성 탭\" 은 사용자가 방금 프롬프트를 넣은 탭이\r\n * 곧 활성 탭이라는 가정인데, 파일 폴링이 400ms 마다 못 묶은 보고를 다시 시도하는 탓에\r\n * **끝난 세션의 done 이 다음에 열리는 빈 탭을 붙잡았다** (2026-09-02 실측: 작업 중인 탭이\r\n * \"완료\" 로, 그 탭의 진짜 세션은 주인이 있다며 거절돼 running 이 버려졌다).\r\n *\r\n * 훅은 자기 조상 프로세스 PID 를 함께 보낸다 — claude.exe → 탭 셸 → Tabby.exe 순서다.\r\n * 탭마다 pty 가 띄운 셸 PID 를 알고 있으면 어느 탭의 보고인지 추측 없이 확정된다.\r\n */\r\nexport type BindMode = 'pid' | 'pid-miss' | 'legacy'\r\n\r\nexport interface BindPick<T> {\r\n tab: T | null\r\n /**\r\n * pid — 조상 PID 가 어떤 탭의 셸 PID 와 맞았다 (확정)\r\n * pid-miss — pids 도 왔고 탭 PID 표도 있는데 맞는 탭이 없다. 활성 탭으로 추측하지 **않는다**\r\n * (탭 PID 표가 아직 안 채워진 것일 수 있으니 호출자는 다음 폴링에 다시 본다)\r\n * legacy — pids 가 없거나(옛 훅·수동 호출) 탭 PID 를 하나도 모른다. 호출자가 예전 활성 탭 규칙을 쓴다\r\n */\r\n mode: BindMode\r\n}\r\n\r\nexport function pickTabByPids<T> (pids: number[] | undefined, tabPids: Map<T, number[]>): BindPick<T> {\r\n const wanted = (pids ?? []).filter(n => Number.isInteger(n) && n > 0)\r\n let anyInfo = false\r\n for (const list of tabPids.values()) {\r\n if (list.length) {\r\n anyInfo = true\r\n break\r\n }\r\n }\r\n if (!wanted.length || !anyInfo) {\r\n return { tab: null, mode: 'legacy' }\r\n }\r\n const set = new Set(wanted)\r\n for (const [tab, list] of tabPids) {\r\n if (list.some(p => set.has(p))) {\r\n return { tab, mode: 'pid' }\r\n }\r\n }\r\n return { tab: null, mode: 'pid-miss' }\r\n}\r\n","import * as fs from 'fs'\r\nimport * as os from 'os'\r\nimport * as path from 'path'\r\n\r\n/**\r\n * Claude Code 상태 통보 훅을 사용자의 Claude 설정에 등록/해제한다.\r\n *\r\n * 왜 플러그인이 남의 설정 파일을 만지나 — 훅은 Claude Code 쪽 설정(`~/.claude/settings.json`)에\r\n * 있어야 하고, npm 으로 배포되는 Tabby 플러그인은 그 파일에 손댈 방법이 달리 없다.\r\n * 그래서 \"설치할지\" 를 사용자가 설정 창에서 직접 고르게 하고, 고른 순간에만 쓴다.\r\n * 쓰기 전에 항상 백업을 남기고, 남의 훅은 건드리지 않는다.\r\n *\r\n * 훅이 있으면 상태 판정이 정확해진다. 에이전트가 \"지시를 받았다 / 승인을 기다린다 / 끝났다\" 를\r\n * 직접 알려주기 때문이다. 훅이 없으면 화면에 그려진 글자로 추측하는 폴백(detect.ts)이 도는데,\r\n * 그건 TUI 가 화면을 어떻게 그리는지에 기대는 만큼 흔들린다.\r\n */\r\n\r\n/** 우리 훅인지 알아보는 표식 — 파일 이름이 그대로 명령줄에 들어간다 */\r\nconst MARK = 'agentdeck-notify'\r\n\r\n/**\r\n * 어떤 순간에 무엇을 보고할지.\r\n *\r\n * **상태만 보낸다 — 작업 이름은 여기서 보내지 않는다.** 라벨은 플러그인이 Enter 시점에\r\n * 입력창을 읽어 매번 갱신하는 경로(`claimEnterLabel`)가 전담한다. 예전에는 여기에\r\n * `-PromptAsLabel` 이 붙어 있었는데, 훅이 상태 파일의 직전 라벨을 도로 써 넣는 바람에\r\n * 플러그인이 방금 넣은 최신 프롬프트를 옛 값으로 되돌렸다 (2026-09-01 실측).\r\n */\r\nconst PLAN: { event: string, args: string }[] = [\r\n // 지시를 받았다\r\n { event: 'UserPromptSubmit', args: '-Status running' },\r\n // 승인을 기다린다\r\n { event: 'Notification', args: '-Status waiting' },\r\n // 답이 끝났다\r\n { event: 'Stop', args: '-Status done' },\r\n]\r\n\r\nexport function claudeSettingsPath (): string {\r\n return path.join(os.homedir(), '.claude', 'settings.json')\r\n}\r\n\r\n/** 훅 스크립트의 실제 경로. dist/index.js 기준으로 한 단계 위가 패키지 뿌리다 */\r\nexport function notifyScriptPath (): string {\r\n return path.join(__dirname, '..', 'hooks', 'agentdeck-notify.ps1')\r\n}\r\n\r\n/** 이 환경에서 훅을 걸 수 있나 — 통보 스크립트가 PowerShell 이라 Windows 전용이다 */\r\nexport function hooksSupported (): boolean {\r\n return process.platform === 'win32' && fs.existsSync(notifyScriptPath())\r\n}\r\n\r\nfunction readSettings (): any {\r\n try {\r\n const raw = fs.readFileSync(claudeSettingsPath(), 'utf8')\r\n return raw.trim() ? JSON.parse(raw) : {}\r\n } catch {\r\n // 파일이 없거나 아직 JSON 이 아니다 — 새로 만드는 것으로 본다\r\n return {}\r\n }\r\n}\r\n\r\n/** 이 이벤트에 걸린 훅 중 우리 것이 아닌 것만 남긴다 */\r\nfunction withoutOurs (entries: any): any[] {\r\n return (Array.isArray(entries) ? entries : [])\r\n .filter(e => !JSON.stringify(e ?? '').includes(MARK))\r\n}\r\n\r\n/**\r\n * 우리 훅이 세 이벤트에 모두 걸려 있나 — 파일을 읽지 않는 순수 판정.\r\n * 파일 접근과 분리해 둔 이유는 이 판단을 테스트로 묶어 두기 위해서다.\r\n */\r\nexport function isMerged (settings: any): boolean {\r\n const hooks = settings?.hooks ?? {}\r\n return PLAN.every(p => {\r\n const entries = Array.isArray(hooks[p.event]) ? hooks[p.event] : []\r\n return entries.some((e: any) => JSON.stringify(e ?? '').includes(MARK))\r\n })\r\n}\r\n\r\n/**\r\n * 설정 객체에 우리 훅을 더한 새 객체를 돌려준다 (원본은 건드리지 않는다).\r\n * 이미 우리 것이 있으면 명령줄만 지금 경로로 갈아끼우고, 남이 걸어 둔 훅은 그대로 둔다.\r\n */\r\nexport function mergeHooks (settings: any, script: string): any {\r\n const next = { ...(settings ?? {}) }\r\n next.hooks = { ...(next.hooks ?? {}) }\r\n for (const p of PLAN) {\r\n const command = `powershell -NoProfile -ExecutionPolicy Bypass -File \"${script}\" ${p.args}`\r\n next.hooks[p.event] = [\r\n ...withoutOurs(next.hooks[p.event]),\r\n { matcher: '*', hooks: [{ type: 'command', command, timeout: 5 }] },\r\n ]\r\n }\r\n return next\r\n}\r\n\r\n/** 우리 훅만 걷어낸 새 객체. 비어 버린 이벤트 키는 지워서 설정을 깨끗하게 남긴다 */\r\nexport function stripHooks (settings: any): any {\r\n const next = { ...(settings ?? {}) }\r\n if (!next.hooks) {\r\n return next\r\n }\r\n next.hooks = { ...next.hooks }\r\n for (const p of PLAN) {\r\n const kept = withoutOurs(next.hooks[p.event])\r\n if (kept.length) {\r\n next.hooks[p.event] = kept\r\n } else {\r\n delete next.hooks[p.event]\r\n }\r\n }\r\n return next\r\n}\r\n\r\nexport function hooksInstalled (): boolean {\r\n return isMerged(readSettings())\r\n}\r\n\r\n/** 훅을 등록한다 */\r\nexport function installHooks (): void {\r\n const script = notifyScriptPath()\r\n if (!fs.existsSync(script)) {\r\n throw new Error(`훅 스크립트를 찾지 못했다: ${script}`)\r\n }\r\n writeSettings(mergeHooks(readSettings(), script))\r\n}\r\n\r\n/** 훅을 뗀다 */\r\nexport function uninstallHooks (): void {\r\n writeSettings(stripHooks(readSettings()))\r\n}\r\n\r\nfunction writeSettings (settings: any): void {\r\n const file = claudeSettingsPath()\r\n fs.mkdirSync(path.dirname(file), { recursive: true })\r\n // 남의 설정을 고치는 일이라 되돌릴 수 있게 한 벌 남긴다\r\n if (fs.existsSync(file)) {\r\n fs.copyFileSync(file, file + '.agentdeck-backup')\r\n }\r\n fs.writeFileSync(file, JSON.stringify(settings, null, 2) + '\\n', 'utf8')\r\n}\r\n","import { ConfigProvider } from 'tabby-core'\r\n\r\n/**\r\n * 마우스로 만진 배치만 따로 모아 둔다 — 설정 탭의 \"배치 초기화\" 가 이 값으로 되돌린다.\r\n * 기본값 정의와 초기화 대상이 어긋나지 않도록 아래 defaults 도 이걸 펼쳐 쓴다.\r\n */\r\nexport const LAYOUT_DEFAULTS = {\r\n /**\r\n * 사이드바가 붙는 방향. 헤더를 잡고 창 가장자리로 끌어다 놓으면 바뀐다.\r\n * 'left' | 'right' | 'top' | 'bottom'\r\n */\r\n sidebarDock: 'right',\r\n /**\r\n * 좌/우 도킹일 때의 사이드바 폭 (px). 0 이면 자동 —\r\n * 화면비(aspectW:aspectH)로 터미널 폭을 역산하고 남는 만큼을 사이드바가 갖는다.\r\n * 경계선을 드래그하는 순간 그 폭이 여기 박히고, 그 뒤로는 자동 계산을 쓰지 않는다.\r\n */\r\n sidebarWidth: 0,\r\n /** 상/하 도킹일 때의 사이드바 높이 (px). 경계선 드래그로 바뀐다 */\r\n sidebarHeight: 200,\r\n}\r\n\r\n/** @hidden */\r\nexport class AgentDeckConfigProvider extends ConfigProvider {\r\n defaults = {\r\n agentDeck: {\r\n /** 레이아웃/사이드바 전체 on-off */\r\n enabled: true,\r\n /** 터미널 뷰포트 가로:세로 비율 */\r\n aspectW: 4,\r\n aspectH: 3,\r\n /**\r\n * 사이드바 폭 제한 (px).\r\n * sidebarMax 를 키우면 사이드바가 그만큼 넓어지고, 그래도 남는 폭은 터미널이 흡수한다\r\n * (4:3 보다 \"창을 꽉 채운다\" 가 우선). config.yaml 의 agentDeck 아래에서 조절한다.\r\n */\r\n sidebarMin: 200,\r\n sidebarMax: 560,\r\n // 마우스로 만지는 배치 (도킹 방향 / 폭 / 높이) — 정의는 LAYOUT_DEFAULTS 에 있다\r\n ...LAYOUT_DEFAULTS,\r\n /**\r\n * 훅이 상태를 밀어 넣는 TCP 채널의 포트 (127.0.0.1 전용).\r\n *\r\n * Windows 임시 포트 범위(49152~65535) 아래로 잡는다 — 그 위 번호는 OS 가\r\n * 다른 프로세스에 먼저 내줄 수 있어 기동 순서에 따라 충돌한다.\r\n * 이 번호가 물려 있으면 0(임의 포트)으로 물러나고, 실제 번호는 어느 쪽이든\r\n * `%LOCALAPPDATA%\\tabby-agentdeck\\port` 에 적히므로 훅은 그 파일만 보면 된다.\r\n */\r\n notifyPort: 47500,\r\n /**\r\n * 외부 통보 채널(TCP + 상태 파일 폴링)을 열지.\r\n *\r\n * 기본으로 켠다. 에이전트 훅이 보내 주는 상태가 가장 정확한 원천이기 때문이다 —\r\n * 출력 패턴으로 추측하는 경로(detect.ts)는 훅이 없는 환경을 위한 폴백일 뿐이고,\r\n * TUI 가 화면을 어떻게 그리는지에 기대는 만큼 판정이 흔들린다\r\n * (2026-09-01: Claude Code 가 놀 때도 상태줄을 매초 갱신해 진행중이 안 풀렸다).\r\n * 훅을 안 쓰더라도 비용은 유휴 포트 하나와 400ms 폴링뿐이다.\r\n */\r\n notifyChannel: true,\r\n /**\r\n * 훅 설치 안내를 다시 띄우지 않는다.\r\n *\r\n * 기동할 때 훅이 안 걸려 있으면 한 번 물어보는데, \"다시 묻지 않기\" 를 고르면 켜진다.\r\n * 설정 창의 설치 버튼은 이 값과 무관하게 언제든 쓸 수 있다.\r\n */\r\n hookPromptDismissed: false,\r\n /** PTY 출력이 이 시간(ms) 이상 없으면 running -> idle */\r\n idleAfterMs: 2500,\r\n /** 출력 패턴으로 상태를 자동 추론할지 */\r\n autoDetect: true,\r\n /** 사이드바에 경과 시간 표시 */\r\n showElapsed: true,\r\n /**\r\n * 창이 가려져 있어도 사이드바를 계속 갱신한다 (Electron backgroundThrottling 해제).\r\n *\r\n * 끄면 Chromium 기본 동작으로 돌아간다 — 창이 hidden 이면 rAF 가 멈추고 타이머가\r\n * 1초, 5분 이상 가려지면 분당 1회까지 느려져서 훅이 보낸 done 이 화면에 늦게 뜬다.\r\n * 켜 두면 훅 보고가 바로 보이는 대신 가려진 동안에도 렌더 비용이 조금 든다\r\n * (사이드바 DOM 갱신뿐이라 미미하다).\r\n */\r\n keepRenderingWhenHidden: true,\r\n // labelAsTitle 은 없앴다 — 사이드바가 제목/프롬프트/상태를 각자 줄에 보여주게 되면서\r\n // (deck.service renderTab) 둘 중 하나를 고를 이유가 사라졌다.\r\n /**\r\n * Enter 로 프롬프트를 보낼 때 그 원문을 작업 라벨로 삼는다 (claimEnterLabel 주석 참고).\r\n * 훅도 콘솔 제목도 못 믿는 배포 환경에서 라벨을 최신으로 유지하는 유일한 경로다.\r\n * Shift+Enter / Ctrl+Enter(줄바꿈)는 잡지 않는다.\r\n */\r\n enterAsLabel: true,\r\n /**\r\n * Ctrl+V 를 agentdeck 이 직접 받는다 (document 캡처 단계에서 한 번만).\r\n *\r\n * 핫키(`agentdeck-paste`)로 받던 시절에는 Tabby 가 같은 keydown 을 두 경로로\r\n * HotkeysService 에 밀어 넣어 한 번 눌러 두 번 붙는 일이 남아 있었다\r\n * (deck.service.ts `ensurePasteHotkey` 주석에 원인). 캡처로 옮기고 전파를 끊으면서\r\n * 경로가 하나로 정리됐다.\r\n *\r\n * false 로 두면 터미널 앱에 리터럴 Ctrl+V(0x16, quoted-insert)를 보낼 수 있다\r\n */\r\n claimCtrlV: true,\r\n /**\r\n * 클립보드에 이미지만 있으면 Ctrl+V 로도 이미지가 들어가게 한다.\r\n *\r\n * 터미널 붙여넣기는 \"클립보드 텍스트를 PTY 에 써넣는\" 동작이라 이미지는 지나갈 수가 없다.\r\n * 대신 에이전트 CLI 는 자기가 OS 클립보드를 직접 읽는 키를 따로 두므로,\r\n * 이미지일 때만 그 키를 흘려보낸다 (어떤 키인지는 `imagePasteKey`).\r\n */\r\n pasteImageWithCtrlV: true,\r\n /**\r\n * 이미지 전용 클립보드일 때 흘려보낼 키의 **기본값**. `'alt-v'`(ESC v) | `'ctrl-v'`(0x16).\r\n *\r\n * 평소에는 이 값이 쓰이지 않는다 — 탭에서 도는 앱을 보고 자동으로 갈라 보내기 때문이다\r\n * (Claude Code = ESC v / Codex = 0x16, `deck.service.ts` `sendImagePasteKey` 주석에 실측).\r\n * 앱을 못 알아낼 때(SSH 세션 등)의 폴백으로만 쓴다.\r\n *\r\n * Claude Code 는 PTY 로 들어온 0x16 에 반응하지 않는 것이 실측됐으므로\r\n * (`.agentdeck-diag.log` 2026-08-28T09:33:47~48 에 `paste image (ctrl-v)` 5줄, 이미지 미삽입)\r\n * 폴백은 더 널리 먹히는 ESC v 로 둔다.\r\n */\r\n imagePasteKey: 'alt-v',\r\n /**\r\n * 우클릭(붙여넣기 / 선택 시 복사)을 agentdeck 이 직접 처리한다.\r\n * Tabby 자체 처리를 끄고(terminal.rightClick = 'off') 캡처 단계에서 한 번만\r\n * 처리하므로, 핸들러가 두 번 걸려 붙여넣기가 2중으로 들어가던 문제가 사라진다.\r\n * false 로 두면 Tabby 순정 동작으로 되돌아간다\r\n */\r\n claimRightClick: true,\r\n /** 우클릭을 이 시간(ms) 이상 누르고 있으면 붙여넣기 대신 컨텍스트 메뉴 */\r\n rightClickMenuMs: 250,\r\n\r\n /**\r\n * 터미널 배경 불투명도 (%). 100 이면 순정(완전 불투명).\r\n *\r\n * tabby-background 플러그인은 배경 이미지를 `.content-tab-active::before`\r\n * (position:fixed, z-index:-1) 로 **모든 내용 뒤에** 깐다. 그런데 xterm 은\r\n * 컬러스킴의 `background` 색으로 셀을 직접 칠하므로, 그 색에 알파가 없으면\r\n * 이미지는 터미널 영역에서 100% 가려진다 — \"배경 이미지를 넣었는데 아무 데도 안 보인다\"\r\n * 의 정체가 이것이다(2026-08-28 실측: colorScheme.background = '#171717' 불투명).\r\n * Tabby 는 xterm 을 `allowTransparency: true` 로 만들기 때문에 알파만 넣어주면 비친다.\r\n *\r\n * 그래서 agentdeck 이 기동 시 `terminal.colorScheme.background` 를 8자리 hex 로 바꿔준다.\r\n * 100 으로 되돌리면 알파를 떼어 원래 색으로 복구한다 (되돌리기 가능).\r\n */\r\n terminalOpacity: 75,\r\n /** 사이드바 배경 불투명도 (%). 터미널과 같은 이유로 배경 이미지가 비치게 한다 */\r\n sidebarOpacity: 75,\r\n /**\r\n * tabby-background 의 배경 이미지를 **터미널 영역(`.content.main`) 안에만** 그린다.\r\n *\r\n * 그 플러그인은 이미지를 `.content-tab-active::before` 에 `position:fixed; 100%x100%`\r\n * 로 깔아 창 전체를 덮으므로, 사이드바가 반투명이면 이미지가 사이드바 밑까지 비친다\r\n * (2026-09-02 유저 지적: \"배경이 agentdeck 사이드바를 침범한다\").\r\n * true 면 relayout 때마다 터미널 영역 좌표를 CSS 변수(`--ad-bg-*`)로 내려\r\n * 그 레이어의 위치·크기를 터미널 영역으로 잘라 붙인다. false 면 순정(창 전체).\r\n */\r\n clipBackgroundToTerminal: true,\r\n // 크기 보정 설정(`sizeWatchMs` / `sizeWatchIntervalMs` / `redrawKickMs` /\r\n // `startupWindowKickMs`)은 그 장치들과 함께 폐지했다 (2026-09-02).\r\n // 줄맞춤은 Tabby 순정이 한다 — xterm `ResizeObserver` → `fitAddon.fit()` →\r\n // `session.resize()`. agentdeck 은 폭만 정해 `.content.main` 에 적는다.\r\n // 자세한 경위는 `deck.service.ts` 의 relayout 주석 참고.\r\n\r\n /**\r\n * 화면 복구(사이드바 `↻` / `agentdeck-repair` 핫키)가 **스크롤백까지 지우고**\r\n * 터미널 상태를 초기화한다(`xterm.reset()`).\r\n *\r\n * true 인 이유: 깨진 화면에는 옛 폭으로 그려진 잔상이 셀에 남아 있는데, 앱이 다시\r\n * 그려도 자기가 쓰는 자리만 덮으므로 그 바깥은 지워지지 않는다. 지난 대화를 남기고\r\n * 싶으면 false — 그때는 크기 정합 + 흔들기까지만 한다(그것만으로는 안 고쳐지는\r\n * 경우가 있다, 2026-09-01 확인).\r\n */\r\n /**\r\n * 화면이 깨졌는지 **주기적으로 직접 보고**, 깨졌으면 조용히 복구한다.\r\n *\r\n * 이게 필요한 이유 — 크기 감시(`sizeWatchMs`)는 \"우리가 pty 에 보낸 값\" 과\r\n * \"xterm 이 가진 값\" 을 비교한다. 그런데 세션이 막 열린 직후의 `session.resize()` 는\r\n * **pty 에 도달하지 못하고 유실된다**(2026-09-01 실측: 진단 로그에\r\n * `pty resize 254x78 -> 280x78` 을 찍고 `pane.size` 도 280 으로 남겼는데,\r\n * 같은 탭에서 셸에 물어보니 `PTYW=254 xtermCols=280`). 보낸 값을 낙관적으로\r\n * 기록하기 때문에 감시는 \"이제 맞다\" 고 보고 손을 뗀다. 그 뒤에 뜨는 TUI 는\r\n * 254 폭으로 그리고, 오른쪽 26칸에는 옛 프레임(`Try \"how do I …\"` 힌트)이 남는다.\r\n *\r\n * 그래서 판정 기준을 **화면 자체**로 바꾼다. 입력창 테두리 길이가 화면 폭과 다르거나,\r\n * 가로선과 입력 텍스트가 한 줄에 섞였거나, 입력창 머리가 둘 보이면 깨진 것이다\r\n * (`screen.ts` 의 `judgeScreen` — 정상/깨짐 실측 케이스로 유닛 테스트가 걸려 있다).\r\n * 원인이 무엇이든 결과를 보고 고치므로, 원인 하나를 쫓다 다른 것이 깨지는 일이 없다.\r\n */\r\n /**\r\n * **다시 켬 (2026-09-02).** 껐던 근거가 오진이었다.\r\n *\r\n * 껐을 때의 이유는 \"Claude Code 는 테두리를 `cols - 1` 로 그리는데 판정이\r\n * `== cols` 를 정상으로 봐서 멀쩡한 화면을 깨짐으로 친다\" 였다. **그 전제가 틀렸다.**\r\n * 격리 인스턴스에서 실물 claude 를 띄워 xterm 버퍼를 직접 덤프해 보니\r\n * (2026-09-02, cols=271):\r\n *\r\n * 71 len=271 wrap=0 \"────…\" ← 테두리는 cols 를 꽉 채운다\r\n * 72 len=2 wrap=1 \"❯ \" ← 꽉 찼기 때문에 autowrap 으로 넘어온 행이다\r\n * 73 len=271 wrap=0 \"────…\"\r\n *\r\n * 즉 `len == cols` 가 정상이고, `len == cols - 1` 은 **앱이 폭을 1 작게 알고 있는**\r\n * 진짜 깨짐이다. 그때는 테두리가 폭을 못 채워 autowrap 이 안 걸리므로 `❯` 가\r\n * 윗줄에 붙어버리고 **입력행이 통째로 사라진다**(항목 25 의 ④ 증상이 이것이다).\r\n * 껐던 탓에 실사용에서 깨져도 아무도 고치지 않고 방치됐다.\r\n *\r\n * 예전 자동복구가 화면을 흔들어 놓은 진짜 이유는 판정이 아니라 **조건이 없어서**였다.\r\n * 프레임을 그리는 도중을 한 번 잡아도 바로 복구를 때렸다. 그래서 이번에는\r\n * `autoRepairMinStreak` 로 \"몇 초 넘게 깨진 채로 있을 때만\" 손대게 한다.\r\n */\r\n /**\r\n * **다시 끔 (2026-09-02, 실사용 실측 4/4 실패).** 위 판정 근거는 여전히 맞지만\r\n * **복구 수단이 이 유형에 안 듣는다.** 실사용 로그 06:02:27~06:03:12 —\r\n * `redraw nudge 277x78` → `pty resize 276x78 -> 277x78` → `Ctrl+L` 을 다 보내고도\r\n * 네 번 모두 `auto-after 아직 깨짐 rule@73 len=276 != cols=277`.\r\n * 그동안 10초마다 화면이 흔들려 유저 체감만 나빠졌다(\"최대화됐다 다시 깨지네\").\r\n *\r\n * 격리에서 한 번에 복구됐던 건 `session.resize(cols-1)` 로 **pty 를 직접 좁혀** 만든\r\n * 표본이라, 흔들기가 되돌릴 대상이 실제로 있었다. 실사용은 pty 가 이미 277 로 맞고\r\n * **앱만 276** 이라 되돌릴 것이 없다 — 항목 27 이 이 유형을 정확히 짚었던 것이고,\r\n * 항목 28 의 반전은 그 표본에는 해당하지 않았다.\r\n * 되살리려면 \"앱이 pty 폭을 다시 읽게 만드는\" 수단부터 찾을 것. 감지·채증(`screenWatch`)은 계속 돈다.\r\n */\r\n autoRepairScreen: false,\r\n /**\r\n * 화면을 **보고 기록만** 한다 (복구는 하지 않는다).\r\n *\r\n * `autoRepairScreen` 을 끄면서 감지·채증까지 같이 꺼진 게 문제였다 —\r\n * 실사용에서 깨져도 `~/.agentdeck-screen.log` 에 한 줄도 안 남아,\r\n * \"고쳤다고 했는데 또 깨진다\" 를 확인할 증거가 없었다\r\n * (2026-09-02 실측: Tabby 재시작 11:21 이후 기록 0줄, 그 사이 화면은 깨져 있었다).\r\n * 그래서 **관측과 조치를 분리한다.** 이 값이 켜져 있으면 깨짐을 판정해\r\n * 화면 원문을 남기기만 하고 키는 쏘지 않는다 — 부작용이 없으니 기본으로 켠다.\r\n */\r\n screenWatch: true,\r\n /** 자동 복구를 한 번 한 뒤 이만큼은 다시 하지 않는다 (ms) */\r\n autoRepairCooldownMs: 10000,\r\n /**\r\n * 깨짐이 이만큼 **연속으로** 보여야 복구한다 (화면 검사는 2초 그물이므로 2 면 2초 이상).\r\n * TUI 는 한 프레임을 여러 번의 write 로 그리므로 그 도중을 읽으면 멀쩡한 화면도\r\n * 한 번은 깨져 보인다 — 그 중간 프레임에 키를 쏘지 않기 위한 조건이다.\r\n */\r\n autoRepairMinStreak: 2,\r\n /**\r\n * 한 탭에서 자동 복구를 최대 몇 번까지 할지. 판정이 오탐이거나 앱이 정말\r\n * 그렇게 그리는 경우에 무한히 흔드는 것을 막는 안전장치다. 0 이면 무제한.\r\n */\r\n autoRepairMaxPerTab: 3,\r\n /**\r\n * 복구 때 `xterm.reset()` 까지 한다 — **스크롤백(지난 대화)이 날아간다.**\r\n * 기본은 끔. 잔상은 `clearInputArea`(화면만 비우고 스크롤백은 보존)로 지우므로\r\n * 여기까지 갈 일이 거의 없다. 그걸로도 안 풀리는 화면을 만나면 그때 켠다.\r\n */\r\n repairHard: false,\r\n /**\r\n * 복구 마지막에 `Ctrl+L`(0x0C)을 보내 TUI 에게 전체 재렌더를 시킨다.\r\n * 입력 중이던 글자는 유지된다. 이걸 다른 뜻으로 쓰는 앱을 만나면 끈다.\r\n */\r\n repairSendRedrawKey: true,\r\n\r\n /**\r\n * 작업 루트 전용 프로필을 만들고 기본 프로필로 삼는다.\r\n *\r\n * 에이전트 CLI 는 \"어느 폴더에서 떴는가\" 가 곧 작업 대상이라 새 탭마다 cd 하게 되는데,\r\n * 그걸 없애려는 기능이다. 기본은 꺼져 있다 — 남의 PC 에 설치되자마자 프로필을 만들고\r\n * 기본값을 가로채면 곤란하므로, 쓰려는 사람이 `rootProfileCwd` 를 채우고 켜야 한다.\r\n */\r\n rootProfile: false,\r\n rootProfileName: 'Agent Root',\r\n // 백슬래시 이스케이프 함정을 피하려고 슬래시로 적는다 (Windows 도 그대로 받는다)\r\n // 빈 값이면 프로필을 만들지 않는다\r\n rootProfileCwd: '',\r\n rootProfileCommand: 'powershell.exe',\r\n /**\r\n * -ExecutionPolicy Bypass 가 필요한 이유: npm 전역 명령(claude 등)은 .ps1 래퍼인데\r\n * 기본 실행 정책(Restricted)에서는 로드가 막힌다. 이 인자는 해당 세션에만 적용되고\r\n * 시스템/사용자 정책은 건드리지 않는다.\r\n */\r\n rootProfileArgs: ['-NoLogo', '-ExecutionPolicy', 'Bypass'],\r\n /**\r\n * 탭에 주입할 환경변수. Claude Code 등 TUI 는 이 값들이 없으면 색 지원을 낮게 잡아\r\n * 흑백에 가깝게 렌더된다 (Windows 는 TERM 이 기본으로 비어 있다).\r\n */\r\n rootProfileEnv: {\r\n TERM: 'xterm-256color',\r\n COLORTERM: 'truecolor',\r\n FORCE_COLOR: '3',\r\n },\r\n /** 기본 프로필 지정을 이미 했는지 — 사용자 선택을 매번 덮어쓰지 않기 위한 플래그 */\r\n rootProfileClaimed: false,\r\n },\r\n hotkeys: {\r\n 'agentdeck-toggle': [],\r\n /**\r\n * Claude Code 는 0x0A(Ctrl+J)를 줄바꿈으로 받는다. Tabby 로 옮겨 왔으니\r\n * Ctrl+Enter / Shift+Enter 로도 같은 바이트를 보낸다\r\n */\r\n 'agentdeck-newline': ['Ctrl-Enter', 'Shift-Enter'],\r\n /**\r\n * Tabby 순정 `paste` 대신 이걸 쓴다 — 클립보드가 이미지인지 텍스트인지 보고\r\n * 갈라야 하는데 순정 paste 는 텍스트만 알기 때문\r\n */\r\n 'agentdeck-paste': ['Ctrl-V'],\r\n },\r\n }\r\n}\r\n","import { Injectable, NgZone } from '@angular/core'\r\nimport { AppService, ConfigService, BaseTabComponent, HostWindowService, HotkeysService, ProfilesService } from 'tabby-core'\r\nimport { SettingsTabComponent } from 'tabby-settings'\r\nimport * as fs from 'fs'\r\nimport * as os from 'os'\r\nimport * as path from 'path'\r\nimport { WorkStatusService } from './status.service'\r\nimport { applyOutput, applyTitle, stripTitleMarker } from './detect'\r\nimport { STATUS_STYLES, WorkStatus } from './api'\r\nimport { extractPrompt } from './prompt'\r\nimport { judgeScreen, ScreenLine } from './screen'\r\nimport { DockController, DockSide, DOCK_SIDES, isDockSide, isHorizontalDock } from './dock'\r\n\r\nconst SIDEBAR_ID = 'agentdeck-sidebar'\r\nconst BODY_CLASS = 'agentdeck-active'\r\n/** 배경 이미지 레이어를 터미널 영역으로 자르는 중일 때 body 에 붙는 클래스 (styles.scss 참조) */\r\nconst BG_CLIP_CLASS = 'ad-bg-clip'\r\n\r\n/** 터미널이 이보다 좁아지거나 낮아지지 않게 막는다 — 드래그로 사이드바를 끝까지 밀어도 */\r\nconst MIN_TERM_W = 320\r\nconst MIN_TERM_H = 160\r\n/** 사이드바가 이보다 작아지면 목록을 읽을 수 없다 — 드래그로도 이 밑으로는 안 내려간다 */\r\nconst MIN_SIDEBAR_W = 140\r\nconst MIN_SIDEBAR_H = 90\r\n\r\n/** Ctrl+V 를 눌렀을 때 xterm 의 네이티브 paste 가 오는지 기다려보는 시간 */\r\nconst PASTE_NATIVE_WAIT_MS = 60\r\n/**\r\n * 같은 한 번의 붙여넣기가 여러 경로로 들어왔을 때 뒤엣것을 버리는 창(ms).\r\n *\r\n * 사람이 Ctrl+V 를 연타해도 이보다 빠를 수 없다(실측된 중복은 1ms 간격이었다).\r\n * claimCtrlVKey 로 경로를 하나로 모았어도, 그게 안 먹는 상황(포커스가 xterm 밖 등)을\r\n * 대비한 마지막 보험이다.\r\n */\r\nconst PASTE_DEDUPE_MS = 80\r\n/** 붙여넣기 계측 창 — 두 번째 write 가 늦게 와도 놓치지 않게 넉넉히 둔다 */\r\nconst PASTE_PROBE_MS = 5000\r\n/** 입력창을 찾으려고 화면 아래에서 훑어 올라갈 줄 수 — 여러 줄 프롬프트를 덮을 만큼만 */\r\nconst PROMPT_SCAN_ROWS = 14\r\n\r\n/**\r\n * 복구할 때 Ctrl+L 을 보내기까지 기다리는 시간.\r\n * 앞선 흔들기(`nudgePtyRedraw`)가 60ms 뒤에 폭을 되돌리므로, 앱이 그 두 번째 SIGWINCH 로\r\n * 새 폭을 받아들인 다음에 \"다시 그려라\" 가 도착해야 한다. 순서가 뒤집히면 옛 폭으로 다시 그린다.\r\n */\r\nconst REPAIR_REDRAW_DELAY_MS = 180\r\n/** 복구 뒤 화면을 다시 재는 시각 — 앱이 새 프레임을 다 그릴 만큼은 기다린다 */\r\nconst SNAP_AFTER_MS = 1500\r\n/** 진단 로그 — devtools 를 못 여는 상황에서도 밖에서 읽을 수 있게 파일로 남긴다 */\r\n/**\r\n * 화면 깨짐 검사를 출력이 멈춘 뒤 이만큼 기다렸다 한다.\r\n * TUI 가 한 프레임을 여러 번의 write 로 그리므로, 그리는 도중에 읽으면 멀쩡한 화면도 깨져 보인다.\r\n */\r\nconst SCREEN_CHECK_DEBOUNCE_MS = 700\r\n/**\r\n * pty 크기를 고친 뒤 같은 값을 다시 보내는 시점 (ms).\r\n * 세션 초기화 직후의 resize 는 유실되므로(syncPtySize 주석) 시간을 벌려 몇 번 더 던진다.\r\n */\r\nconst PTY_RESIZE_RETRY_MS = [150, 400, 900, 1800, 3000]\r\n/**\r\n * 탭이 열린 뒤 \"지금 xterm 이 쓰는 크기\" 를 pty 에 알려 주는 시점 (ms).\r\n *\r\n * 순정이 못 메우는 구멍이 딱 하나 남아 있다 — **새 탭.** Tabby 는 프론트엔드의 첫 `resize$`\r\n * 값으로 세션을 스폰하므로(tabby-local `initializeSession(this.size…)`), 그 스냅샷이\r\n * 레이아웃 확정보다 이르면 pty 만 좁게 태어난다. 그 뒤 xterm 이 넓어져도 **크기 변화\r\n * 이벤트가 나지 않으므로** ResizeObserver 도 fit() 도 아무것도 보내지 않는다(fit 은 열/행이\r\n * 이미 맞으면 no-op). 아무도 pty 에 알려주지 않아 그대로 굳는다.\r\n *\r\n * 실측(2026-09-02, 격리 인스턴스): 평범하게 연 새 탭 3개가 전부 `xterm=88 / pane.size=88`\r\n * 인데 pty 는 72 였고, TUI 는 72 폭으로 그려 테두리 두 줄이 73·88 로 어긋났다.\r\n * 같은 값(`session.resize(88, 39)`)을 **한 번** 보내자 즉시 정상으로 돌아왔다.\r\n *\r\n * 그래서 되살린 개입은 이것 하나뿐이다 — \"현재 크기를 몇 번 알려준다\". 흔들기(cols-1 ↔ cols)도,\r\n * 250ms 감시 루프도, fit 강제도 아니다. 값이 이미 맞으면 SIGWINCH 가 나지 않아 무해하고,\r\n * xterm 을 건드리지 않으므로 그리는 중인 프레임과 경쟁하지도 않는다.\r\n */\r\nconst TAB_OPEN_ANNOUNCE_MS = [250, 800, 1800]\r\n/** 화면 깨짐 주기 검사 간격 (ms) — 출력 구독이 없는 탭도 잡기 위한 그물 */\r\nconst SCREEN_SWEEP_MS = 2000\r\n/** 자식이 아직 없는 래퍼 탭을 다시 훑는 간격과 횟수 */\r\nconst EMPTY_TAB_RETRY_MS = 400\r\nconst EMPTY_TAB_RETRY_MAX = 20\r\nconst DIAG_PATH = path.join(os.homedir(), '.agentdeck-diag.log')\r\n/**\r\n * 깨진 화면의 **원문**을 남기는 곳. 진단 로그(한 줄 요약)와 따로 두는 이유 —\r\n * 원인을 못 찾는 이유가 늘 \"깨졌을 때의 화면을 아무도 안 봐 뒀다\" 여서다.\r\n * 감지 직후(before)와 복구 뒤(after)를 같이 남기므로, 다음에 깨지면 추측 없이\r\n * \"무엇이 깨졌나 / 복구가 실제로 고쳤나\" 를 이 파일 하나로 가른다.\r\n */\r\nconst SNAP_PATH = path.join(os.homedir(), '.agentdeck-screen.log')\r\n\r\n/** 우리가 쓰는 부분만 추린 Electron clipboard — electron 패키지를 devDependency 로 끌어오지 않으려고 */\r\ninterface ElectronClipboard {\r\n readImage (): { isEmpty (): boolean }\r\n readText (): string\r\n}\r\n\r\nlet cachedClipboard: ElectronClipboard | null | undefined\r\n\r\n/**\r\n * Electron 의 clipboard 를 런타임에 가져온다.\r\n *\r\n * `import { clipboard } from 'electron'` 을 쓰면 타입 때문에 electron 패키지(200MB+)를\r\n * devDependency 로 받아야 한다. Tabby 렌더러는 nodeIntegration 이 켜져 있어(`fs` 를 그냥 import 한다)\r\n * window.require 로 바로 집을 수 있으므로 그쪽을 쓴다.\r\n */\r\nfunction getClipboard (): ElectronClipboard | null {\r\n if (cachedClipboard !== undefined) {\r\n return cachedClipboard\r\n }\r\n // webpack externals 에 'electron' 이 있어(webpack.config.js) 이 require 는 번들되지 않고\r\n // 런타임에 Tabby 가 그대로 넘겨준다 — 위쪽 `import * as fs` 와 같은 경로다.\r\n // window.require 는 contextIsolation 이 켜지면 사라지므로 폴백으로만 둔다.\r\n try {\r\n cachedClipboard = require('electron')?.clipboard ?? null\r\n } catch {\r\n cachedClipboard = null\r\n }\r\n if (!cachedClipboard) {\r\n try {\r\n const req = (window as any).require ?? (globalThis as any).require\r\n cachedClipboard = req?.('electron')?.clipboard ?? null\r\n } catch {\r\n cachedClipboard = null\r\n }\r\n }\r\n return cachedClipboard\r\n}\r\n\r\nfunction clampPct (value: unknown): number {\r\n const n = typeof value === 'number' && isFinite(value) ? value : 100\r\n return Math.min(100, Math.max(0, Math.round(n)))\r\n}\r\n\r\n/**\r\n * `#RRGGBB` / `#RRGGBBAA` 에 불투명도(%)를 입힌다.\r\n * 100% 면 알파를 떼어 원래 6자리로 되돌린다 — 설정을 되돌리면 원상복구되게 하려는 것.\r\n * 해석할 수 없는 형식(rgb(), 색이름 등)은 건드리지 않고 그대로 돌려준다.\r\n */\r\nfunction withAlpha (color: string, pct: number): string {\r\n const m = /^#([0-9a-fA-F]{6})(?:[0-9a-fA-F]{2})?$/.exec(color.trim())\r\n if (!m) {\r\n return color\r\n }\r\n const rgb = '#' + m[1]\r\n if (pct >= 100) {\r\n return rgb\r\n }\r\n const alpha = Math.round(pct * 255 / 100).toString(16).padStart(2, '0')\r\n return rgb + alpha\r\n}\r\n\r\n/**\r\n * AgentDeck 본체.\r\n *\r\n * 하는 일 두 가지 —\r\n * 1) 터미널 뷰포트(.content.main)를 창 높이 기준 4:3 폭으로 고정하고\r\n * 2) 그때 남는 왼쪽 공간에 탭 목록 + 작업 상태 사이드바를 그린다.\r\n *\r\n * Tabby 순정 탭바는 CSS 로 감추고 이 사이드바가 탭 관리를 대신한다.\r\n * Angular 컴포넌트 대신 순수 DOM 을 쓰는 이유는 appRoot 템플릿에 컴포넌트를\r\n * 꽂는 공식 확장점이 없기 때문 — DOM 직접 조작이 Tabby 버전 변화에 더 견딘다.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class AgentDeckService {\r\n private sidebar: HTMLElement | null = null\r\n private listEl: HTMLElement | null = null\r\n private windowEl: HTMLElement | null = null\r\n private mainEl: HTMLElement | null = null\r\n private observer: ResizeObserver | null = null\r\n private editing: BaseTabComponent | null = null\r\n private renderQueued = false\r\n /** rAF 가 멈춘 상황(창 가려짐)을 대비한 렌더 폴백 타이머 */\r\n private renderTimer: any = null\r\n /** 직전에 적용한 폭 — 같은 값이면 DOM 을 다시 건드리지 않는다 */\r\n private lastTermW = -1\r\n private lastSidebarW = -1\r\n /** 직전에 적용한 도킹 방향 — 크기가 같아도 방향이 바뀌면 다시 그려야 한다 */\r\n private lastDock: DockSide | null = null\r\n /** 경계선 드래그(크기)와 헤더 드래그(도킹 방향)를 맡는다 */\r\n private dock: DockController | null = null\r\n private refitQueued = false\r\n /** 이미 감시를 건 래퍼 탭 / pane — 중복 구독 방지 */\r\n private watched = new WeakSet<BaseTabComponent>()\r\n private watchedPanes = new WeakSet<BaseTabComponent>()\r\n /** 화면 깨짐 검사 예약 타이머 — pane 당 하나만 돈다 */\r\n private screenCheckTimers = new WeakMap<BaseTabComponent, any>()\r\n /** 빈 래퍼 탭을 다시 훑은 횟수 */\r\n private emptyTabRetries = new WeakMap<BaseTabComponent, number>()\r\n /** 마지막 화면 판정 결과 — 상태가 바뀔 때만 채증하려고 들고 있는다 */\r\n private screenObs = new WeakMap<BaseTabComponent, { broken: boolean, reason: string, streak?: number }>()\r\n /** 마지막 자동 복구 시각 — 쿨다운 판정용 */\r\n private autoRepairAt = new WeakMap<BaseTabComponent, number>()\r\n /** 자동 복구 횟수 — 오탐으로 무한히 흔드는 것을 막는다 */\r\n private autoRepairCount = new WeakMap<BaseTabComponent, number>()\r\n /** 진단 기록 — devtools 의 `__agentdeck.kickLog` 와 DIAG_PATH 파일에 함께 남는다 */\r\n private kickLog: string[] = []\r\n /** diagOnce 가 이미 남긴 키 */\r\n private diagOnceKeys = new Set<string>()\r\n /** 우클릭 누른 시각 — 길게 누르면 컨텍스트 메뉴로 분기 */\r\n private rightDownAt = 0\r\n /** 직전 우클릭 처리 시각 — 같은 클릭이 두 번 들어오는 걸 막는다 */\r\n private lastRightHandledAt = 0\r\n /** xterm 이 네이티브 paste 로 붙여넣은 마지막 시각 — Ctrl+V 이중 입력 방지 */\r\n private nativePasteAt = 0\r\n /** 직전에 붙여넣기를 처리한 시각 — 같은 클릭/키가 여러 경로로 들어와도 한 번만 붙인다 */\r\n private lastPasteAt = 0\r\n /** 이 시각까지는 PTY 로 나가는 입력을 진단 로그에 남긴다 (붙여넣기가 두 번 들어가는지 보려고) */\r\n private pasteProbeUntil = 0\r\n\r\n constructor (\r\n private app: AppService,\r\n private config: ConfigService,\r\n private status: WorkStatusService,\r\n private hotkeys: HotkeysService,\r\n private profiles: ProfilesService,\r\n private hostWindow: HostWindowService,\r\n private zone: NgZone,\r\n ) { }\r\n\r\n init (): void {\r\n this.app.ready$.subscribe(() => this.zone.runOutsideAngular(() => {\r\n // setup 도중 예외가 나면 그 뒤 배선(탭 감시, 흔들기 예약)이 통째로 죽는데\r\n // 콘솔을 안 보면 알 길이 없다. 진단 파일에 남겨 밖에서 읽을 수 있게 한다\r\n try {\r\n this.setup()\r\n } catch (e: any) {\r\n this.diag(`${new Date().toISOString()} setup ERROR ${e?.message ?? e}`)\r\n throw e\r\n }\r\n }))\r\n }\r\n\r\n /**\r\n * 같은 키로는 한 번만 남기는 진단.\r\n * relayout 처럼 초당 여러 번 불리는 자리에서 조기 return 사유를 남길 때 쓴다\r\n */\r\n private diagOnce (key: string, line: string): void {\r\n if (this.diagOnceKeys.has(key)) {\r\n return\r\n }\r\n this.diagOnceKeys.add(key)\r\n this.diag(`${new Date().toISOString()} ${line}`)\r\n }\r\n\r\n /** 진단 한 줄 — 메모리와 파일에 함께 남긴다. 파일이 안 써져도 동작에는 영향이 없다 */\r\n private diag (line: string): void {\r\n this.kickLog.push(line)\r\n try {\r\n fs.appendFileSync(DIAG_PATH, line + '\\n')\r\n } catch {\r\n // 디스크가 막혀 있다 — 진단일 뿐이라 무시한다\r\n }\r\n }\r\n\r\n private setup (): void {\r\n this.windowEl = document.querySelector('.window')\r\n this.mainEl = document.querySelector('.content.main')\r\n if (!this.windowEl) {\r\n console.warn('[agentdeck] .window 를 찾지 못해 레이아웃을 적용하지 않는다')\r\n return\r\n }\r\n\r\n try {\r\n fs.writeFileSync(DIAG_PATH, '')\r\n } catch {\r\n // 진단 파일을 못 열어도 그냥 간다\r\n }\r\n this.diag(`${new Date().toISOString()} setup start tabs=${this.app.tabs.length}`)\r\n\r\n this.buildSidebar()\r\n this.applyEnabled()\r\n this.applyOpacity()\r\n this.disableBackgroundThrottling()\r\n this.ensurePasteHotkey()\r\n this.ensureNewlineHotkey()\r\n this.claimCtrlVKey()\r\n this.claimEnterLabel()\r\n this.claimRightClick()\r\n\r\n // xterm 의 네이티브 paste 를 관측만 한다 (doPaste 의 이중 입력 방지용).\r\n // 캡처 단계라 xterm 핸들러의 stopPropagation 보다 먼저 돈다.\r\n document.addEventListener('paste', () => {\r\n this.nativePasteAt = Date.now()\r\n this.diag(`${new Date().toISOString()} native-paste`)\r\n }, true)\r\n\r\n // 탭 변화 -> 사이드바 다시 그림\r\n // 탭 복원은 ready$ 보다 늦게 끝나므로 목록이 바뀔 때마다 감시 대상을 다시 훑는다\r\n // (watched WeakSet 이 중복 구독을 막는다)\r\n this.app.tabsChanged$.subscribe(() => {\r\n for (const tab of this.app.tabs) {\r\n this.watchTab(tab)\r\n }\r\n this.scheduleRender()\r\n })\r\n // 탭을 바꾸면 그 탭은 숨어 있던 동안 폭 0 이라 refit 을 건너뛰었다 — 지금 맞춰준다\r\n this.app.activeTabChange$.subscribe(() => {\r\n this.scheduleRender()\r\n this.scheduleRefit()\r\n })\r\n this.app.tabOpened$.subscribe(tab => {\r\n this.watchTab(tab)\r\n // 새 탭은 xterm 은 맞는 폭으로 열리는데 pty 만 옛 폭으로 남는 일이 있다 (syncPtySize 주석)\r\n this.scheduleRefit()\r\n this.scheduleRender()\r\n })\r\n this.app.tabClosed$.subscribe(() => this.scheduleRender())\r\n\r\n // 세션이 이미 열린 채 복원된 탭들도 감시 대상에 넣는다\r\n for (const tab of this.app.tabs) {\r\n this.watchTab(tab)\r\n }\r\n this.status.changed$.subscribe(() => this.scheduleRender())\r\n this.config.changed$.subscribe(() => {\r\n this.applyEnabled()\r\n this.applyOpacity()\r\n this.relayout()\r\n this.scheduleRender()\r\n })\r\n\r\n // 화면 깨짐 주기 검사. 출력 구독(scheduleScreenCheck)이 더 정밀하지만, 구독이 붙지\r\n // 못한 탭에서는 아무도 보지 않게 되므로 그물을 하나 더 둔다. 활성 탭만 본다 —\r\n // 숨은 탭은 폭이 0 이라 판정할 근거가 없다.\r\n setInterval(() => this.sweepScreens(), SCREEN_SWEEP_MS)\r\n\r\n // 창 크기 변화 -> 4:3 폭 재계산\r\n this.observer = new ResizeObserver(() => this.relayout())\r\n this.observer.observe(this.windowEl)\r\n window.addEventListener('resize', () => this.relayout())\r\n\r\n // 핫키 처리는 여기서 — provider 쪽에서 하면 HotkeysService 와 순환 의존이 된다\r\n this.hotkeys.hotkey$.subscribe(hotkey => {\r\n if (hotkey === 'agentdeck-toggle') {\r\n this.config.store.agentDeck.enabled = !this.config.store.agentDeck.enabled\r\n this.config.save()\r\n }\r\n if (hotkey === 'agentdeck-newline') {\r\n this.sendNewline()\r\n }\r\n if (hotkey === 'agentdeck-paste') {\r\n this.doPaste('hotkey')\r\n }\r\n if (hotkey === 'agentdeck-repair') {\r\n this.repair('all')\r\n }\r\n })\r\n\r\n // 경과 시간 갱신 + running -> idle 자동 복귀\r\n setInterval(() => this.tick(), 1000)\r\n\r\n this.relayout()\r\n this.render()\r\n this.diag(`${new Date().toISOString()} setup done tabs=${this.app.tabs.length} enabled=${this.enabled} mainEl=${!!this.mainEl}`)\r\n\r\n // 개발/진단용 — devtools 나 CDP 에서 내부 상태를 들여다볼 수 있게 노출한다\r\n ;(window as any).__agentdeck = {\r\n app: this.app,\r\n config: this.config,\r\n status: this.status,\r\n relayout: () => this.relayout(),\r\n render: () => this.render(),\r\n repair: (scope: 'active' | 'all' = 'all') => this.repair(scope),\r\n kickLog: this.kickLog,\r\n }\r\n }\r\n\r\n // ---------- 화면 복구 ----------\r\n\r\n /**\r\n * 깨진 화면을 사람이 직접 되살린다 — 창을 복원→최대화로 흔드는 것을 코드로 대신한다.\r\n *\r\n * 자동 경로(`watchSize`)는 \"xterm 과 pty 의 크기가 어긋났다\" 를 보고 고치는데, 그 감시는\r\n * 탭이 열리고 `sizeWatchMs`(기본 6초) 동안만 돈다. 그 뒤에 깨지는 경우가 남는다 —\r\n * 두 크기는 서로 맞는데 **TUI 가 들고 있는 프레임만** 옛것인 상황이다. 크기가 이미 같으니\r\n * 커널은 SIGWINCH 를 내지 않고, 앱은 다시 그릴 이유를 영영 못 받는다. 증상은\r\n * \"statusline 이 사라지고 입력창 구분선이 중간에서 끊긴다\" (2026-09-01 실측).\r\n *\r\n * 그래서 복구는 크기를 맞추는 것으로 끝내지 않고 **항상 한 번 흔든다**(`nudgePtyRedraw`).\r\n * 어긋남이 없어도 무해하다 — 폭이 한 칸 줄었다 돌아올 뿐이고 xterm 은 건드리지 않는다.\r\n *\r\n * @param scope `active` = 지금 보고 있는 탭만, `all` = 열려 있는 모든 탭\r\n */\r\n repair (scope: 'active' | 'all' = 'all'): void {\r\n const targets = scope === 'active' && this.app.activeTab\r\n ? [this.app.activeTab]\r\n : this.app.tabs\r\n this.diag(`${new Date().toISOString()} repair scope=${scope} tabs=${targets.length}`)\r\n\r\n // 1) 사이드바 폭부터 다시 잰다 — 어긋남의 출발점이 대개 여기다\r\n this.relayout()\r\n\r\n // 2) 레이아웃이 실제로 반영된 다음에 재야 한다 (scheduleRefit 과 같은 이유로 두 프레임)\r\n requestAnimationFrame(() => requestAnimationFrame(() => {\r\n for (const tab of targets) {\r\n const anyTab = tab as any\r\n const panes: BaseTabComponent[] = typeof anyTab.getAllTabs === 'function'\r\n ? anyTab.getAllTabs()\r\n : [tab]\r\n for (const pane of panes) {\r\n this.repairPane(pane)\r\n }\r\n }\r\n }))\r\n }\r\n\r\n /**\r\n * 복구 한 pane 분 — **화면을 지우고 앱에게 처음부터 다시 그리게 한다.**\r\n *\r\n * 흔들기(`nudgePtyRedraw`)만으로는 안 고쳐지는 경우가 실제로 있다(2026-09-01 유저 확인).\r\n * 이유는 흔들기가 고치는 대상이 하나뿐이라서다 — 그건 \"앱이 폭을 잘못 알고 있다\" 를 푼다.\r\n * 그런데 깨진 화면에는 그 말고도 두 가지가 더 얹혀 있다.\r\n *\r\n * - **xterm 쪽 잔상**: 옛 폭으로 그려진 글자가 셀에 그대로 남아 있다. 앱이 다시 그려도\r\n * 앱은 자기가 쓴 자리만 덮으므로, 그 바깥(옛 프레임의 오른쪽·아래)은 영영 안 지워진다.\r\n * - **터미널 상태**: 스크롤 영역(DECSTBM)·줄바꿈 모드·속성이 옛 크기 기준으로 잡혀 있으면\r\n * 새로 그린 것까지 어긋난 자리에 들어간다.\r\n *\r\n * 그래서 순서가 있다 — ① 크기를 맞추고 ② `reset()` 으로 터미널 상태와 화면을 비우고\r\n * ③ 그래도 앱은 자기가 이미 그렸다고 믿고 있으니 흔들어 SIGWINCH 를 주고\r\n * ④ 마지막으로 `Ctrl+L`(0x0C) 을 보내 \"전부 다시 그려라\" 를 명시로 시킨다.\r\n * ③ 만으로 부족했던 이유가 ①②④ 가 빠져서였다.\r\n *\r\n * `reset()` 은 스크롤백을 함께 지운다. 지난 대화를 남기고 싶으면 `repairHard: false` —\r\n * 그때는 예전처럼 크기 정합 + 흔들기까지만 한다.\r\n */\r\n private repairPane (pane: BaseTabComponent): void {\r\n const cfg = this.config.store.agentDeck\r\n const anyPane = pane as any\r\n const frontend = anyPane.frontend\r\n const xterm = frontend?.xterm\r\n // 숨겨진 탭은 컨테이너 폭이 0 이라 fit 하면 1열로 줄어든다 — 크기는 건드리지 않고\r\n // 다시 선택될 때 Tabby 가 재측정하게 둔다\r\n const host = xterm?.element?.parentElement\r\n if (!host?.clientWidth || !host?.clientHeight) {\r\n return\r\n }\r\n\r\n const before = this.readScreen(pane)\r\n const beforeVerdict = before ? judgeScreen(before.lines, before.cols) : null\r\n this.snapshot(pane, `manual-before ${beforeVerdict\r\n ? (beforeVerdict.broken ? beforeVerdict.reasons.join(' / ') : '판정=정상')\r\n : '읽을 수 없음'}`)\r\n\r\n // ① 크기 정합 — 여기가 어긋나 있으면 뒤 단계가 전부 헛돈다\r\n try {\r\n frontend?.fitAddon?.fit?.()\r\n } catch {\r\n // 아직 붙는 중이다 — 아래 단계만이라도 태운다\r\n }\r\n this.syncPtySize(pane, frontend)\r\n\r\n // ② 잔상 지우기 — 입력창 영역만 비운다 (대화는 남는다)\r\n if (before) {\r\n this.clearInputArea(pane, before)\r\n }\r\n\r\n // ②-b 그래도 안 되면 터미널 상태까지 초기화 (스크롤백이 날아가므로 기본은 끔)\r\n if (cfg.repairHard === true) {\r\n try {\r\n xterm?.reset?.()\r\n } catch {\r\n // 프론트엔드가 막 떨어졌다\r\n }\r\n }\r\n try {\r\n xterm?.refresh?.(0, (xterm.rows ?? 1) - 1)\r\n } catch { }\r\n\r\n // ③ 크기가 이미 맞아도 무조건 흔든다 — 이 함수를 부르는 이유 자체가 \"맞는데 깨졌다\" 다\r\n this.nudgePtyRedraw(pane)\r\n\r\n // ④ 앱에게 직접 \"다시 그려라\". 흔들기가 도착해 앱이 새 폭을 받은 뒤에 보내야 하므로\r\n // nudge 의 되돌리기(60ms)보다 확실히 뒤에 둔다.\r\n if (cfg.repairSendRedrawKey !== false) {\r\n setTimeout(() => this.sendRedrawKey(pane), REPAIR_REDRAW_DELAY_MS)\r\n }\r\n\r\n // ⑤ 채증 — \"↻ 를 눌렀는데 안 고쳐진다\" 를 감이 아니라 파일로 가른다.\r\n // 누른 직후와 다시 그려진 뒤를 짝으로 남긴다.\r\n setTimeout(() => {\r\n const after = this.readScreen(pane)\r\n const still = after ? judgeScreen(after.lines, after.cols) : null\r\n this.snapshot(pane, `manual-after ${still ? (still.broken ? '아직 깨짐: ' + still.reasons.join(' / ') : '복구됨') : '읽을 수 없음'}`)\r\n }, SNAP_AFTER_MS)\r\n }\r\n\r\n /**\r\n * TUI 에 \"화면을 전부 다시 그려라\" 를 보낸다 — `Ctrl+L`(0x0C).\r\n *\r\n * Claude Code·Codex 를 포함해 거의 모든 TUI 와 셸이 이걸 전체 재렌더로 받는다.\r\n * 입력 중이던 글자는 건드리지 않는다(readline·TUI 모두 입력 버퍼는 유지하고 화면만 다시 그린다).\r\n */\r\n private sendRedrawKey (pane: BaseTabComponent): void {\r\n const anyPane = pane as any\r\n if (typeof anyPane.sendInput !== 'function' || !anyPane.session?.open) {\r\n return\r\n }\r\n this.diag(`${new Date().toISOString()} repair redraw-key ctrl-l`)\r\n try {\r\n anyPane.sendInput('\\x0c')\r\n } catch {\r\n // 세션이 막 닫혔다\r\n }\r\n }\r\n\r\n /**\r\n * 입력창 영역에 남은 **옛 프레임 잔상만** 지운다 (대화 = 스크롤백은 그대로 둔다).\r\n *\r\n * 복구가 계속 실패하던 진짜 이유가 여기 있었다 (2026-09-02 실측).\r\n * `nudge` 도 `Ctrl+L` 도 하는 일은 \"앱아 다시 그려라\" 뿐인데, **앱은 자기가 쓰는 자리만 덮는다.**\r\n * 그래서 옛 폭으로 그려진 줄이 `❯` 자리를 차지하고 있으면 아무도 그걸 못 지운다 —\r\n * 채증 원문이 그 모양이었다 (`.agentdeck-screen.log` 06:02:27):\r\n *\r\n * 72 len=275 \" \" ← 위 테두리가 있어야 할 자리, 공백\r\n * 73 len=276 \"────…\" ← ❯ 자리에 옛 프레임(276) 잔상\r\n * 74 len=277 \"────…\" ← 앱이 새로 그린 아래 테두리(277, 정상)\r\n *\r\n * 앱은 이미 277 로 제대로 그리고 있는데 73 행 잔상 때문에 계속 깨짐으로 남았다.\r\n * `auto-after 아직 깨짐` 이 두 번 연속 찍힌 게 이것이다.\r\n *\r\n * 그래서 **터미널 쪽에서 직접 지운다** — 입력창 첫 테두리 행으로 커서를 옮기고\r\n * `ESC[J`(커서부터 화면 끝까지)로 비운다. 이건 화면만 비우고 스크롤백은 건드리지 않으므로\r\n * `xterm.reset()`(스크롤백까지 날아감)과 다르다. 커서는 `ESC7`/`ESC8` 로 저장·복원해\r\n * 앱이 들고 있는 커서 위치와 어긋나지 않게 한다. 지운 뒤 `Ctrl+L` 을 보내면 앱이\r\n * 자기 UI 를 그 빈 자리에 다시 그린다.\r\n */\r\n private clearInputArea (pane: BaseTabComponent, read: { lines: ScreenLine[], cols: number }): boolean {\r\n const xterm = (pane as any).frontend?.xterm\r\n if (!xterm || typeof xterm.write !== 'function') {\r\n return false\r\n }\r\n const lines = read.lines\r\n // 하단 16행 안에서만 본다 — 대화 이력에 남아 있는 옛 입력창까지 지우면 안 된다\r\n const from = Math.max(0, lines.length - 16)\r\n let last = -1\r\n for (let i = lines.length - 1; i >= from; i--) {\r\n if (/^[─━═]{2,}$/.test(lines[i].text.trim())) {\r\n last = i\r\n break\r\n }\r\n }\r\n if (last < 0) {\r\n return false\r\n }\r\n // 마지막 테두리에서 위로 최대 4행까지만 같은 입력창 블록으로 본다\r\n let start = last\r\n for (let i = last - 1; i >= Math.max(from, last - 4); i--) {\r\n if (/^[─━═]{2,}$/.test(lines[i].text.trim())) {\r\n start = i\r\n }\r\n }\r\n const row = start + 1\r\n this.diag(`${new Date().toISOString()} clear input area row=${row}/${lines.length}`)\r\n try {\r\n xterm.write(`\u001b7\u001b[${row};1H\u001b[J\u001b8`)\r\n } catch {\r\n return false\r\n }\r\n return true\r\n }\r\n\r\n // ---------- 화면 깨짐 자동 감지 ----------\r\n\r\n /**\r\n * 출력이 잠잠해지면 화면이 온전한지 본다.\r\n *\r\n * TUI 는 한 프레임을 여러 번의 write 로 그리므로, 그리는 도중에 읽으면 멀쩡한 화면도\r\n * 깨져 보인다. 그래서 마지막 출력에서 `SCREEN_CHECK_DEBOUNCE_MS` 만큼 조용해진 뒤에만 본다.\r\n */\r\n private scheduleScreenCheck (pane: BaseTabComponent): void {\r\n // 감지·채증은 복구와 분리한다 — `autoRepairScreen` 이 꺼져 있어도 관측은 계속한다.\r\n // (2026-09-02: 이 게이트가 채증까지 막아 실사용 재현이 통째로 증거 없이 지나갔다)\r\n if (!this.screenObservingEnabled()) {\r\n return\r\n }\r\n const prev = this.screenCheckTimers.get(pane)\r\n if (prev) {\r\n clearTimeout(prev)\r\n }\r\n this.screenCheckTimers.set(pane, setTimeout(() => {\r\n this.screenCheckTimers.delete(pane)\r\n this.checkScreen(pane)\r\n }, SCREEN_CHECK_DEBOUNCE_MS))\r\n }\r\n\r\n /** 감지·채증이 켜져 있나 — 복구(`autoRepairScreen`)와는 별개다 */\r\n private screenObservingEnabled (): boolean {\r\n const cfg = this.config.store.agentDeck\r\n return cfg.screenWatch !== false || !!cfg.autoRepairScreen\r\n }\r\n\r\n /** 화면을 판정해 채증하고, 복구가 켜져 있으면 조용히 고친다 */\r\n private checkScreen (pane: BaseTabComponent): void {\r\n const cfg = this.config.store.agentDeck\r\n const read = this.readScreen(pane)\r\n if (!read) {\r\n return\r\n }\r\n const verdict = judgeScreen(read.lines, read.cols)\r\n\r\n // ---- 관측 (복구와 무관하게 항상) ----\r\n // 상태가 바뀔 때만 남긴다 — 2초마다 도는 그물이라 매번 찍으면 파일이 같은 줄로 찬다.\r\n const prevObs = this.screenObs.get(pane)\r\n const reason = verdict.reasons.join(' / ')\r\n // 같은 깨짐이 몇 번 연속으로 보였나 — TUI 가 한 프레임을 여러 write 로 그리는 도중을\r\n // 잡으면 멀쩡한 화면도 한 번은 깨져 보인다. 그 중간 프레임에 손대지 않으려고 센다.\r\n const streak = verdict.broken ? ((prevObs?.broken ? (prevObs.streak ?? 0) : 0) + 1) : 0\r\n const changed = !prevObs || prevObs.broken !== verdict.broken || prevObs.reason !== reason\r\n this.screenObs.set(pane, { broken: verdict.broken, reason, streak })\r\n if (changed) {\r\n if (verdict.broken) {\r\n this.snapshot(pane, `detect 깨짐 ${reason}`)\r\n } else if (prevObs?.broken) {\r\n // 우리가 아무것도 안 했는데 스스로 돌아왔다 — 트리거를 가르는 중요한 단서다\r\n this.snapshot(pane, 'detect 스스로 복구됨')\r\n }\r\n }\r\n\r\n if (!verdict.broken) {\r\n return\r\n }\r\n if (!cfg.autoRepairScreen) {\r\n return\r\n }\r\n // 한 번 스친 중간 프레임은 건드리지 않는다 — 2초 그물이므로 기본값 2 는 \"2초 넘게\r\n // 깨진 채로 있다\" 는 뜻이다. 예전에 자동복구가 타이핑 중에 튀어나와 체감을 망친 것이\r\n // 이 조건이 없어서였다 (2026-09-02 항목 27).\r\n if (streak < (cfg.autoRepairMinStreak ?? 2)) {\r\n return\r\n }\r\n\r\n const anyPane = pane as any\r\n const now = Date.now()\r\n const last = this.autoRepairAt.get(pane) ?? 0\r\n const count = this.autoRepairCount.get(pane) ?? 0\r\n const max = cfg.autoRepairMaxPerTab ?? 5\r\n const cooldown = cfg.autoRepairCooldownMs ?? 4000\r\n\r\n // 쿨다운/한도에 걸려 아무것도 하지 않을 때는 로그도 남기지 않는다 —\r\n // 주기 검사가 2초마다 돌므로 판정이 오탐이면 진단 파일이 같은 줄로 가득 찬다\r\n if (now - last < cooldown) {\r\n return\r\n }\r\n if (max > 0 && count >= max) {\r\n this.diagOnce(`auto-repair-cap`,\r\n `screen auto-repair 한도 도달 (${count}/${max}) — 더 고치지 않는다.`\r\n + ` 사이드바 ↻ 로 직접 복구할 것. 마지막 판정: ${verdict.reasons.join(' / ')}`)\r\n return\r\n }\r\n this.diag(`${new Date().toISOString()} screen BROKEN cols=${read.cols}`\r\n + ` sent=${anyPane.size?.columns}x${anyPane.size?.rows} ${verdict.reasons.join(' / ')}`)\r\n // 고치기 **전에** 화면 원문을 남긴다 — 복구가 덮어쓰면 증거가 사라진다\r\n this.snapshot(pane, `auto-before ${verdict.reasons.join(' / ')}`)\r\n this.autoRepairAt.set(pane, now)\r\n this.autoRepairCount.set(pane, count + 1)\r\n this.diag(`${new Date().toISOString()} screen auto-repair #${count + 1}`)\r\n\r\n // 스크롤백을 지우는 hard 복구는 하지 않는다 — 자동으로 도는 경로에서 오탐 한 번에\r\n // 지난 대화가 날아가면 손해가 크다. 크기 재동기 + pty 흔들기 + Ctrl+L 까지만 한다.\r\n // 실측(2026-09-01): 세션이 열린 직후 유실됐던 resize 도 이 흔들기로는 pty 에 도달한다.\r\n const frontend = anyPane.frontend\r\n // 크기를 건드리는 건 **실제로 어긋났을 때만.** 이번에 실사용에서 잡힌 유형은\r\n // xterm 도 pty 도 277 로 맞는데 화면만 깨져 있었다 — 거기에 흔들기를 때리면\r\n // 고치지도 못하면서 화면만 흔든다(`auto-after 아직 깨짐` 2연속이 그 결과다).\r\n const xcols = frontend?.xterm?.cols\r\n const xrows = frontend?.xterm?.rows\r\n if (xcols > 1 && (anyPane.size?.columns !== xcols || anyPane.size?.rows !== xrows)) {\r\n try {\r\n frontend?.fitAddon?.fit?.()\r\n } catch {\r\n // 붙는 중이다 — 아래 단계만이라도 태운다\r\n }\r\n this.syncPtySize(pane, frontend)\r\n this.nudgePtyRedraw(pane)\r\n }\r\n // 잔상을 **먼저** 지우고 그 다음에 앱에게 다시 그리라고 한다.\r\n // 앱은 자기가 쓰는 자리만 덮으므로, 지우지 않으면 옛 줄이 `❯` 자리를 계속 차지한다.\r\n this.clearInputArea(pane, read)\r\n if (cfg.repairSendRedrawKey !== false) {\r\n setTimeout(() => this.sendRedrawKey(pane), REPAIR_REDRAW_DELAY_MS)\r\n }\r\n // 복구가 실제로 먹혔는지 같은 파일에 이어 남긴다 — 앱이 다시 그릴 시간을 준다\r\n setTimeout(() => {\r\n const after = this.readScreen(pane)\r\n const still = after ? judgeScreen(after.lines, after.cols) : null\r\n this.snapshot(pane, `auto-after ${still ? (still.broken ? '아직 깨짐: ' + still.reasons.join(' / ') : '복구됨') : '읽을 수 없음'}`)\r\n }, SNAP_AFTER_MS)\r\n }\r\n\r\n /** 활성 탭의 pane 들을 한 번씩 본다 (주기 그물) */\r\n private sweepScreens (): void {\r\n if (!this.enabled || !this.screenObservingEnabled()) {\r\n return\r\n }\r\n const tab = this.app.activeTab\r\n if (!tab) {\r\n return\r\n }\r\n const anyTab = tab as any\r\n const panes: BaseTabComponent[] = typeof anyTab.getAllTabs === 'function'\r\n ? anyTab.getAllTabs()\r\n : [tab]\r\n for (const pane of panes) {\r\n this.checkScreen(pane)\r\n }\r\n }\r\n\r\n /** 판정에 넣을 화면 줄과 폭 — 숨겨진 탭이나 아직 안 붙은 프론트엔드는 건너뛴다 */\r\n private readScreen (pane: BaseTabComponent): { lines: ScreenLine[], cols: number } | null {\r\n const anyPane = pane as any\r\n const xterm = anyPane.frontend?.xterm\r\n const buf = xterm?.buffer?.active\r\n if (!buf || typeof buf.getLine !== 'function' || !(xterm.cols > 1)) {\r\n return null\r\n }\r\n // 숨겨진 탭은 컨테이너 폭이 0 이라 xterm 이 1열로 줄어 있다 — 판정 대상이 아니다\r\n const host = xterm.element?.parentElement\r\n if (!host?.clientWidth) {\r\n return null\r\n }\r\n const lines: ScreenLine[] = []\r\n for (let y = buf.baseY; y <= buf.baseY + xterm.rows - 1; y++) {\r\n const line = buf.getLine(y)\r\n lines.push({\r\n text: line?.translateToString(false) ?? '',\r\n wrapped: !!line?.isWrapped,\r\n })\r\n }\r\n return { lines, cols: xterm.cols }\r\n }\r\n\r\n /**\r\n * 화면 원문을 통째로 남긴다 — 깨짐 채증용.\r\n *\r\n * 판정 이유만 남기면 다음에 또 \"왜 그렇게 됐는지\" 를 추측하게 된다. 행 번호·wrap 플래그·\r\n * 길이까지 그대로 적어 두면 `❯` 가 어느 행에 있었는지, 테두리가 몇 칸이었는지가 확정된다.\r\n * before/after 를 짝으로 남기므로 복구가 실제로 먹혔는지도 이 파일에서 바로 갈린다.\r\n */\r\n private snapshot (pane: BaseTabComponent, tag: string): void {\r\n const read = this.readScreen(pane)\r\n if (!read) {\r\n return\r\n }\r\n const anyPane = pane as any\r\n const xterm = anyPane.frontend?.xterm\r\n const head = `\\n===== ${new Date().toISOString()} ${tag}`\r\n + ` cols=${read.cols} rows=${xterm?.rows} sent=${anyPane.size?.columns}x${anyPane.size?.rows}`\r\n + ` title=${JSON.stringify(pane.title ?? '')} =====`\r\n const body = read.lines\r\n .map((l, i) => ({ i, t: l.text.replace(/\\s+$/, ''), w: l.wrapped }))\r\n .filter(l => l.t)\r\n .map(l => `${String(l.i).padStart(3)} w=${l.w ? 1 : 0} len=${l.t.length} ${JSON.stringify(l.t)}`)\r\n try {\r\n fs.appendFileSync(SNAP_PATH, [head, ...body, ''].join('\\n'))\r\n } catch {\r\n // 진단일 뿐이라 실패해도 동작에는 영향이 없다\r\n }\r\n }\r\n\r\n // ---------- 세션 감시 ----------\r\n\r\n /**\r\n * 탭(그리고 그 안의 모든 pane)의 PTY 출력을 구독한다.\r\n *\r\n * TerminalDecorator 는 프론트엔드 첫 리사이즈 시점에만 붙어서 복원된 탭 등을\r\n * 놓치는 경우가 있다. 이쪽은 탭이 목록에 들어오는 즉시 붙으므로 그 빈틈을 메운다.\r\n * 같은 출력을 decorator 와 둘 다 먹어도 상태 설정이 멱등이라 결과는 같다.\r\n */\r\n private watchTab (root: BaseTabComponent): void {\r\n const anyRoot = root as any\r\n\r\n if (!this.watched.has(root)) {\r\n this.watched.add(root)\r\n\r\n // 제목은 래퍼 탭이 자식 것을 위임받으므로 여기서 받는 게 가장 확실하다\r\n if (anyRoot.titleChange$) {\r\n anyRoot.titleChange$.subscribe((title: string) => {\r\n applyTitle(this.status, root, title, this.config.store.agentDeck.autoDetect)\r\n })\r\n }\r\n if (anyRoot.title) {\r\n applyTitle(this.status, root, anyRoot.title, this.config.store.agentDeck.autoDetect)\r\n }\r\n // 나중에 분할로 추가되는 pane 도 따라간다\r\n if (anyRoot.tabAdded$) {\r\n anyRoot.tabAdded$.subscribe((pane: BaseTabComponent) => this.watchPane(root, pane))\r\n }\r\n }\r\n\r\n // pane 은 래퍼보다 늦게 붙는 경우가 있으므로 호출될 때마다 다시 훑는다\r\n // (래퍼만 보고 한 번에 끝내면 목록에 먼저 들어온 빈 SplitTab 을 잡고 끝나버린다)\r\n const panes: BaseTabComponent[] = typeof anyRoot.getAllTabs === 'function'\r\n ? anyRoot.getAllTabs()\r\n : [root]\r\n this.diag(`${new Date().toISOString()} watchTab panes=${panes.length}`)\r\n for (const pane of panes) {\r\n this.watchPane(root, pane)\r\n }\r\n\r\n // 래퍼(SplitTabComponent)가 자식보다 먼저 목록에 들어오는 경우가 있다. 그때 여기서\r\n // panes=0 을 보고 물러나면, 자식이 붙어도 다시 훑을 계기가 없어 그 탭은 영영\r\n // 감시 밖에 남는다 — 상태 감지·Enter 라벨·화면 검사가 전부 안 돈다\r\n // (2026-09-01 실측: 기동 직후 첫 탭에서 `watchTab panes=0` 만 두 번 찍히고\r\n // `session bind` 가 한 번도 없었다). 그래서 비어 있으면 잠시 뒤 다시 본다.\r\n if (!panes.length) {\r\n const tries = (this.emptyTabRetries.get(root) ?? 0) + 1\r\n this.emptyTabRetries.set(root, tries)\r\n if (tries <= EMPTY_TAB_RETRY_MAX) {\r\n setTimeout(() => {\r\n if (this.app.tabs.includes(root)) {\r\n this.watchTab(root)\r\n }\r\n }, EMPTY_TAB_RETRY_MS)\r\n }\r\n }\r\n }\r\n\r\n private watchPane (root: BaseTabComponent, pane: BaseTabComponent): void {\r\n if (this.watchedPanes.has(pane)) {\r\n return\r\n }\r\n this.watchedPanes.add(pane)\r\n this.diag(`${new Date().toISOString()} watchPane ${(pane as any).constructor?.name}`)\r\n const anyPane = pane as any\r\n const bind = (session: any) => {\r\n if (!session || !session.output$) {\r\n return\r\n }\r\n // pty 가 어떤 폭으로 태어났는지 남긴다. Tabby 는 프론트엔드의 **첫** resize$ 값으로\r\n // 세션을 스폰하므로(tabby-local: initializeSession(this.size...) -> spawn cols),\r\n // 그 스냅샷이 우리 레이아웃보다 이르면 pty 만 옛 폭으로 굳는다 — 그 순간이 여기 찍힌다.\r\n this.diag(`${new Date().toISOString()} session bind`\r\n + ` xterm=${anyPane.frontend?.xterm?.cols}x${anyPane.frontend?.xterm?.rows}`\r\n + ` paneSize=${anyPane.size?.columns}x${anyPane.size?.rows}`)\r\n session.output$.subscribe((data: string) => {\r\n applyOutput(this.status, root, pane, data, this.config.store.agentDeck.autoDetect)\r\n // 출력이 멈춘 뒤 화면이 온전한지 본다 (그리는 도중에 읽으면 멀쩡한 화면도 깨져 보인다)\r\n this.scheduleScreenCheck(pane)\r\n })\r\n }\r\n bind(anyPane.session)\r\n if (anyPane.sessionChanged$) {\r\n anyPane.sessionChanged$.subscribe((session: any) => bind(session))\r\n }\r\n\r\n // 프론트엔드가 붙는 도중에 우리가 폭을 바꿨으면 그 변경은 유실될 수 있다\r\n // (Tabby 는 attach() 맨 끝에서야 ResizeObserver 를 건다) — 준비되면 fit 한 번으로 깨워 준다.\r\n // 여기서 하는 건 `fitAddon.fit()` 뿐이다. 그 뒤는 순정 경로가 이어받는다\r\n // (fit → xterm onResize → Tabby 가 session.resize). 우리가 pty 에 직접 쏘지 않는다.\r\n if (anyPane.frontendReady$) {\r\n anyPane.frontendReady$.subscribe(() => {\r\n this.scheduleRefit()\r\n this.announceSizeOnOpen(pane)\r\n })\r\n }\r\n // frontendReady 는 replay 가 없는 맨 Subject 라, 복원된 탭의 프론트엔드가 우리보다\r\n // 먼저 붙어버리면 위 구독은 영영 못 받는다. 이벤트와 무관하게 한 번 더 예약한다 —\r\n // 같은 크기를 두 번 알려도 SIGWINCH 가 안 나므로 무해하다.\r\n this.announceSizeOnOpen(pane)\r\n }\r\n\r\n /**\r\n * 탭이 열린 뒤 몇 차례, **지금 xterm 이 쓰는 크기를 pty 에 알려준다.**\r\n *\r\n * 순정이 유일하게 못 메우는 구멍(새 탭에서 pty 만 좁게 태어남)을 메우는 최소 개입이다.\r\n * 자세한 근거와 실측은 `TAB_OPEN_ANNOUNCE_MS` 주석에 있다.\r\n *\r\n * 하지 않는 것 — xterm 은 건드리지 않고(fit 도 resize 도), 폭을 흔들지 않으며,\r\n * 감시 루프도 돌지 않는다. 그 셋이 예전에 화면을 깨뜨린 장본인이다.\r\n */\r\n private announceSizeOnOpen (pane: BaseTabComponent): void {\r\n const anyPane = pane as any\r\n for (const delay of TAB_OPEN_ANNOUNCE_MS) {\r\n setTimeout(() => {\r\n const x = anyPane.frontend?.xterm\r\n const session = anyPane.session\r\n if (!session?.open || typeof session.resize !== 'function' || !(x?.cols > 1)) {\r\n return\r\n }\r\n const prev = anyPane.size\r\n if (prev?.columns !== x.cols || prev?.rows !== x.rows) {\r\n this.diag(`${new Date().toISOString()} announce size ${prev?.columns}x${prev?.rows}`\r\n + ` -> ${x.cols}x${x.rows} (+${delay}ms)`)\r\n }\r\n try {\r\n session.resize(x.cols, x.rows)\r\n anyPane.size = { columns: x.cols, rows: x.rows }\r\n } catch {\r\n // 세션이 막 닫혔다\r\n }\r\n }, delay)\r\n }\r\n }\r\n\r\n // 흔들기 장치는 전부 폐지했다 (2026-09-02).\r\n //\r\n // 여기에 있던 것들 — `scheduleWindowKick`(기동 시 창 복원→최대화), `scheduleRedrawKick`,\r\n // `kickPtySize`(탭당 한 번 cols-1 ↔ cols) — 는 모두 \"순정이 크기를 못 맞춘다\" 는 전제에서\r\n // 나온 우회책이었다. 전제가 틀렸다: Tabby 는 xterm `ResizeObserver` → `fitAddon.fit()` →\r\n // `session.resize()` 로 스스로 맞춘다. 우리가 폭만 정해 주면 된다.\r\n // 이 흔들기들은 순정 수렴과 경쟁하며 프레임을 반쯤 그린 상태를 남겨 화면을 깨뜨렸다.\r\n // 수동 복구(`repairPane`)는 여전히 흔든다 — 거기는 사용자가 명시로 요청한 경로다.\r\n\r\n /**\r\n * Ctrl+V 를 **핫키 테이블에서 걷어낸다** (실제 처리는 claimCtrlVKey 가 한다).\r\n *\r\n * 예전에는 여기서 `agentdeck-paste` 에 Ctrl-V 를 등록했는데, 그러면 한 번 눌러 두 번 붙는\r\n * 경우가 남았다. Tabby 는 같은 keydown 을 **두 경로**로 HotkeysService 에 밀어 넣기 때문이다 —\r\n * xterm 의 커스텀 키 핸들러(`tabby-terminal/dist/index.js:40789` keyboardEventHandler →\r\n * `hotkeysService.pushKeyEvent`)와, document 에 걸린 core 리스너(`tabby-core:21425`).\r\n * `pushKeyEvent` 앞에 `timeStamp` 중복 가드가 있지만(`tabby-core:21451`) 그건 **같은**\r\n * 이벤트 객체일 때만 먹고, 두 경로가 서로 다른 이벤트(keydown/keyup 등)로 들어오면\r\n * `emitHotkeyOn` 이 두 번 나간다(실측: hotkey-paste 가 1ms 간격 2회, `.agentdeck-diag.log`).\r\n *\r\n * 그래서 핫키에 기대지 않고 캡처 단계에서 직접 한 번만 처리한다 — 우클릭을 claimRightClick\r\n * 으로 가져온 것과 같은 이유·같은 방식이다. 순정 `paste` 쪽에 Ctrl-V 가 남아 있어도 캡처가\r\n * 먼저 먹고 전파를 끊으므로 발화하지 않지만, 설정 화면이 헷갈리지 않게 양쪽 모두에서 뺀다.\r\n *\r\n * 대가: 터미널 앱에 리터럴 Ctrl+V(0x16, quoted-insert)를 보낼 수 없다.\r\n * 그게 필요하면 `agentDeck.claimCtrlV: false`.\r\n */\r\n private ensurePasteHotkey (): void {\r\n const hotkeys = this.config.store.hotkeys\r\n if (!hotkeys) {\r\n return\r\n }\r\n let changed = false\r\n\r\n // 옛 이름(workdeck-*)으로 저장된 핫키가 config.yaml 에 남아 있으면 Ctrl-V 가 그쪽에\r\n // 먼저 매칭돼 우리 핸들러가 통째로 죽는다 — HotkeysService.matchActiveHotkey 는\r\n // 길이가 같은 후보 중 config 삽입 순서로 앞선 것 하나만 고르고, 옛 항목이 먼저 저장돼 있다\r\n // (tabby-core/dist/index.js:21558 matches.sort → matches[0].id).\r\n for (const legacy of ['workdeck-paste', 'workdeck-newline', 'workdeck-toggle']) {\r\n if (legacy in hotkeys) {\r\n delete hotkeys[legacy]\r\n changed = true\r\n }\r\n }\r\n\r\n // 지난 버전이 넣어둔 Ctrl-V 를 회수한다. 남겨두면 캡처 경로와 겹쳐 다시 2중이 될 수 있다\r\n for (const id of ['agentdeck-paste', 'paste']) {\r\n const keys: string[] = Array.isArray(hotkeys[id]) ? hotkeys[id] : []\r\n if (keys.includes('Ctrl-V')) {\r\n hotkeys[id] = keys.filter(k => k !== 'Ctrl-V')\r\n changed = true\r\n }\r\n }\r\n\r\n if (changed) {\r\n this.config.save()\r\n }\r\n this.diag(`${new Date().toISOString()} hotkeys paste=${JSON.stringify(hotkeys.paste)} `\r\n + `agentdeck-paste=${JSON.stringify(hotkeys['agentdeck-paste'])} `\r\n + `legacy=${Object.keys(hotkeys).filter(k => k.startsWith('workdeck')).join(',') || 'none'}`)\r\n }\r\n\r\n /**\r\n * Ctrl+V 를 document **캡처 단계**에서 한 번만 처리한다.\r\n *\r\n * 캡처는 xterm 의 textarea 리스너보다도 먼저 돌기 때문에, 여기서 전파를 끊으면\r\n * 그 뒤에 있는 경로(xterm 커스텀 키 핸들러 → pushKeyEvent, core 의 document 리스너,\r\n * xterm 이 Ctrl+V 를 0x16 으로 바꿔 PTY 에 흘리는 기본 동작, 브라우저 네이티브 paste)가\r\n * 통째로 죽는다. 몇 개가 겹쳐 걸려 있든 붙여넣기는 정확히 한 번이 된다 —\r\n * 핫키로 받던 시절 남아 있던 2중 입력의 해법이다(ensurePasteHotkey 주석에 원인).\r\n *\r\n * 단, 설정 화면 같은 **평범한 입력 필드**에서는 손대지 않는다. 거기서는 Ctrl+V 가\r\n * 브라우저 기본 붙여넣기여야 하고, 우리가 가로채면 아예 못 붙여넣게 된다.\r\n */\r\n private claimCtrlVKey (): void {\r\n document.addEventListener('keydown', (event: KeyboardEvent) => {\r\n if (!this.config.store.agentDeck.claimCtrlV) {\r\n return\r\n }\r\n if (!event.ctrlKey || event.shiftKey || event.altKey || event.metaKey) {\r\n return\r\n }\r\n // 한글 입력 상태에서는 key 가 'ㅍ' 로 오기도 한다 — 물리 키(code)를 같이 본다\r\n if ((event.key || '').toLowerCase() !== 'v' && event.code !== 'KeyV') {\r\n return\r\n }\r\n if (this.isPlainInput(event.target)) {\r\n return\r\n }\r\n event.preventDefault()\r\n event.stopPropagation()\r\n this.zone.runOutsideAngular(() => this.doPaste('ctrl-v'))\r\n }, true)\r\n }\r\n\r\n /**\r\n * Enter 를 눌러 프롬프트를 보낼 때, 그 프롬프트 원문을 작업 라벨로 삼는다.\r\n *\r\n * 왜 이게 필요한가 — 라벨을 채우는 다른 경로(훅·콘솔 제목)는 둘 다 배포판에서 못 믿는다.\r\n * 훅은 사용자가 `~/.claude/settings.json` 을 손봐야 돌고, 플러그인이 그걸 대신 깔아줄 수도 없다.\r\n * 콘솔 제목은 Claude Code 가 세션 첫 작업을 요약해 한 번 박고 그 뒤로 갱신하지 않는다\r\n * (2026-08-28 실측: 작업이 네 번 바뀌는 동안 `◑ sendInput 한 줄 vs 두 줄 원인 파악` 그대로).\r\n * 그래서 설정이 하나도 없는 상태에서 라벨을 최신으로 유지할 수 있는 건 이 경로뿐이다.\r\n *\r\n * **Enter 만 잡는다.** Shift+Enter / Ctrl+Enter 는 줄바꿈이라(agentdeck-newline) 아직 전송이\r\n * 아니고, 그때 라벨을 바꾸면 쓰다 만 문장이 박힌다. 수식키가 하나라도 눌려 있으면 그냥 흘린다.\r\n * IME 조합 중의 Enter(한글 확정)도 전송이 아니므로 제외한다.\r\n *\r\n * 관측만 하고 이벤트는 절대 막지 않는다 — 여기서 preventDefault 하면 프롬프트가 안 보내진다.\r\n */\r\n private claimEnterLabel (): void {\r\n document.addEventListener('keydown', (event: KeyboardEvent) => {\r\n if (!this.config.store.agentDeck.enterAsLabel) {\r\n return\r\n }\r\n if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey) {\r\n return // 줄바꿈이지 전송이 아니다\r\n }\r\n if (event.key !== 'Enter' && event.code !== 'Enter' && event.code !== 'NumpadEnter') {\r\n return\r\n }\r\n if (event.isComposing || event.keyCode === 229) {\r\n return // 한글 조합 확정용 Enter\r\n }\r\n if (this.isPlainInput(event.target)) {\r\n return\r\n }\r\n const pane = this.focusedPane()\r\n if (!pane) {\r\n this.diag(`${new Date().toISOString()} enter-label skipped (no pane)`)\r\n return\r\n }\r\n // 화면은 아직 프롬프트가 지워지기 전이다 — 캡처 단계라 앱이 Enter 를 보기 전에 읽는다\r\n const text = this.readPromptLine(pane)\r\n // 상태는 루트 탭 단위로 관리한다 (watchTab 이 app.tabs 로 감시하는 것과 같은 단위)\r\n const tab = this.app.activeTab\r\n this.diag(`${new Date().toISOString()} enter-label text=\"${text}\" tab=${tab ? 'yes' : 'no'}`)\r\n if (!text || !tab) {\r\n return\r\n }\r\n this.status.setLabel(tab, text)\r\n }, true)\r\n }\r\n\r\n /**\r\n * xterm 화면 버퍼에서 지금 입력창에 쓰여 있는 프롬프트를 읽는다 (판정은 extractPrompt).\r\n *\r\n * 화면 맨 아래가 아니라 **커서 줄**을 기준점으로 잡는다. Claude Code 는 대화가 짧으면\r\n * 입력창을 화면 위쪽에 두고 그 아래를 전부 빈 줄로 남기는데(2026-08-28 실측), 아래 14줄만\r\n * 읽으면 빈 줄만 걸려 프롬프트를 영영 못 찾는다 — 라벨이 안 바뀌던 원인이 이것이다.\r\n * 커서는 항상 입력 중인 줄에 있고, 여러 줄 프롬프트면 마지막 줄에 있으니 거기서 위로 훑으면\r\n * `> ` 머리를 만난다. 커서 아래는 힌트 줄이라 애초에 읽지 않는 편이 정확하다.\r\n */\r\n private readPromptLine (pane: any): string {\r\n const xterm = pane.frontend?.xterm\r\n const buf = xterm?.buffer?.active\r\n if (!buf || typeof buf.getLine !== 'function') {\r\n this.diag(`${new Date().toISOString()} enter-label no-buffer frontend=${pane.frontend ? 'yes' : 'no'} xterm=${xterm ? 'yes' : 'no'}`)\r\n return ''\r\n }\r\n const read = (from: number, to: number): string[] => {\r\n const lines: string[] = []\r\n for (let y = Math.max(0, from); y <= to; y++) {\r\n lines.push(buf.getLine(y)?.translateToString(true) ?? '')\r\n }\r\n return lines\r\n }\r\n const cursor = buf.baseY + (buf.cursorY ?? 0)\r\n const nearCursor = read(cursor - PROMPT_SCAN_ROWS, cursor)\r\n const byCursor = extractPrompt(nearCursor)\r\n if (byCursor) {\r\n return byCursor\r\n }\r\n // 커서가 입력창 밖에 있을 때의 폴백 — 화면 전체를 아래에서 위로 훑는다\r\n const byScreen = extractPrompt(read(buf.baseY, buf.baseY + xterm.rows - 1))\r\n if (!byScreen) {\r\n // 두 경로가 다 빈손이면 화면이 어떻게 생겼는지 남긴다.\r\n // 이게 없어서 \"입력창 못 찾음\" 과 \"버퍼를 못 읽음\" 을 못 갈랐다 (2026-09-01).\r\n const dump = nearCursor.slice(-4)\r\n .map(l => JSON.stringify(l.slice(0, 60)))\r\n .join(' | ')\r\n this.diag(`${new Date().toISOString()} enter-label miss baseY=${buf.baseY} cursorY=${buf.cursorY} rows=${xterm.rows} tail=${dump}`)\r\n }\r\n return byScreen\r\n }\r\n\r\n /** 터미널이 아닌 보통 입력 필드(설정 화면 등)인지 — 거기서는 Ctrl+V 를 건드리지 않는다 */\r\n private isPlainInput (target: EventTarget | null): boolean {\r\n const el = target as HTMLElement | null\r\n if (!el || typeof el.closest !== 'function') {\r\n return false\r\n }\r\n // xterm 이 키 입력을 받는 숨은 textarea 는 터미널이지 입력 필드가 아니다\r\n if (el.classList?.contains('xterm-helper-textarea') || el.closest('.xterm')) {\r\n return false\r\n }\r\n return el.isContentEditable || ['INPUT', 'TEXTAREA'].includes(el.tagName)\r\n }\r\n\r\n /**\r\n * Ctrl+V 붙여넣기 — 클립보드가 이미지면 Alt+V 로 넘긴다.\r\n *\r\n * 터미널 붙여넣기는 \"클립보드 텍스트를 키 입력처럼 PTY 에 써넣는\" 동작이다\r\n * (`tabby-terminal/dist/index.js:41842` paste() → readClipboard() → sendInput).\r\n * PTY 는 바이트 스트림이라 이미지가 지나갈 방법 자체가 없고, 클립보드는 OS 자원이라\r\n * 터미널 안에서 도는 앱은 손댈 수 없다 — 그래서 이미지는 조용히 사라진다.\r\n *\r\n * Claude Code 는 이걸 자기가 OS 클립보드를 직접 읽어서 푼다. Alt+V(= ESC v)가 그\r\n * \"지금 클립보드를 읽어라\" 신호다. 즉 Ctrl+V 와 Alt+V 는 붙여넣는 주체가 다르다\r\n * (Ctrl+V = 터미널이 넣어줌 / Alt+V = 앱이 직접 읽음). 사용자가 그걸 구분할 이유는 없으니\r\n * 클립보드에 이미지만 있을 때 Ctrl+V 가 알아서 ESC v 를 대신 보낸다.\r\n *\r\n * 텍스트가 같이 들어 있으면(엑셀·워드 복사 등) 텍스트 붙여넣기를 유지한다 — 그쪽이 의도이므로.\r\n */\r\n private doPaste (source: string): void {\r\n // 한 번의 Ctrl+V / 우클릭이 여러 경로로 들어오는 일이 있다 (ensurePasteHotkey 주석 참고).\r\n // 어느 경로가 먼저 오든 처음 것만 살린다 — 사람 연타는 이 창보다 느리다.\r\n const now = Date.now()\r\n if (now - this.lastPasteAt < PASTE_DEDUPE_MS) {\r\n this.diag(`${new Date().toISOString()} paste ignored (dup ${now - this.lastPasteAt}ms, ${source})`)\r\n return\r\n }\r\n this.lastPasteAt = now\r\n\r\n const pane = this.focusedPane()\r\n if (!pane) {\r\n return\r\n }\r\n const imageOnly = this.clipboardHasImageOnly()\r\n this.diag(`${new Date().toISOString()} paste probe enabled=${this.config.store.agentDeck.pasteImageWithCtrlV} imageOnly=${imageOnly} sendInput=${typeof pane.sendInput}`)\r\n if (this.config.store.agentDeck.pasteImageWithCtrlV\r\n && imageOnly\r\n && typeof pane.sendInput === 'function') {\r\n // 이미지 전용 클립보드 — 텍스트 붙여넣기는 어차피 아무것도 못 넣으므로\r\n // \"네가 직접 클립보드를 읽어라\" 키를 흘려보낸다 (sendImagePasteKey 주석 참고)\r\n void this.sendImagePasteKey(pane)\r\n return\r\n }\r\n if (typeof pane.paste !== 'function') {\r\n return\r\n }\r\n // 붙여넣기 한 번이 PTY 에 몇 번 써지는지 본다 (우클릭 2중 입력 추적용).\r\n // 창을 열어둔 동안의 입력만 남긴다 — 상시 켜두면 사람이 타이핑한 것까지 다 찍힌다.\r\n this.pasteProbeUntil = Date.now() + PASTE_PROBE_MS\r\n this.probeSendInput(pane)\r\n this.probeWrite(pane)\r\n // 텍스트 붙여넣기는 xterm 이 네이티브 paste 이벤트로 이미 처리한다\r\n // (tabby-terminal/dist/index.js:5383 에서 textarea/element 에 handlePasteEvent 등록).\r\n // 그런데도 우리가 무조건 paste() 를 부르면 한 번 눌러 두 번 붙는다.\r\n // 그래서 네이티브가 오는지 잠깐 보고, 안 오면(터미널 textarea 가 포커스를 못 잡은 경우 등)\r\n // 그제야 우리가 붙인다 — 어느 쪽이든 정확히 한 번이 된다.\r\n this.diag(`${new Date().toISOString()} paste (${source})`)\r\n if (source === 'ctrl-v') {\r\n // 캡처 단계에서 이미 preventDefault 했으므로 네이티브 paste 는 오지 않는다 — 기다릴 것 없이 바로 붙인다\r\n void pane.paste()\r\n return\r\n }\r\n const startedAt = Date.now()\r\n setTimeout(() => {\r\n if (this.nativePasteAt >= startedAt) {\r\n this.diag(`${new Date().toISOString()} paste skipped (native handled)`)\r\n return\r\n }\r\n this.diag(`${new Date().toISOString()} paste fallback`)\r\n void pane.paste()\r\n }, PASTE_NATIVE_WAIT_MS)\r\n }\r\n\r\n /**\r\n * 이미지 전용 클립보드일 때 터미널 앱에 \"네가 클립보드를 직접 읽어라\" 키를 흘려보낸다.\r\n *\r\n * 어떤 키인지는 앱마다 다르다 (2026-08-28 실측):\r\n * - Claude Code: ESC v 만 받는다. 리터럴 0x16 은 5회 보내도 이미지가 들어가지 않았다\r\n * (`.agentdeck-diag.log` 09:33:47~48 `paste image (ctrl-v)` 5줄, 화면에는 아무 변화 없음).\r\n * claude.exe 안의 `ctrl+v ... paste images` 문구는 자기가 키 이벤트를 직접 볼 때의 안내였고,\r\n * PTY 로 들어온 0x16 에는 반응하지 않는다.\r\n * - Codex: 0x16 을 자기 붙여넣기로 받고, ESC v 는 모른다.\r\n * 그래서 탭에서 도는 앱을 보고 갈라 보내고, 못 알아내면 설정값(`imagePasteKey`)을 쓴다.\r\n */\r\n private async sendImagePasteKey (pane: any): Promise<void> {\r\n const app = await this.detectAgentApp(pane)\r\n const configured = this.config.store.agentDeck.imagePasteKey\r\n const mode = app === 'claude' ? 'alt-v'\r\n : app === 'codex' ? 'ctrl-v'\r\n : configured\r\n const key = mode === 'ctrl-v' ? '\u0016' : '\u001bv'\r\n this.diag(`${new Date().toISOString()} paste image app=${app} mode=${mode} `\r\n + `bytes=${[...key].map(c => c.charCodeAt(0)).join(',')}`)\r\n pane.sendInput(key)\r\n }\r\n\r\n /**\r\n * 이 탭에서 도는 에이전트 CLI 가 뭔지 — 이미지 붙여넣기 키가 앱마다 달라서 필요하다.\r\n *\r\n * 프로세스 트리를 먼저 본다 (`session.getChildProcesses()`). npm 전역 래퍼를 거치면\r\n * 커맨드가 node/pwsh 로만 보일 수 있어서, 그때는 탭 제목으로 한 번 더 본다.\r\n */\r\n private async detectAgentApp (pane: any): Promise<'claude' | 'codex' | 'unknown'> {\r\n try {\r\n const procs: any[] = await pane.session?.getChildProcesses?.() ?? []\r\n const names = procs.map(x => `${x?.command ?? ''} ${x?.name ?? ''}`).join(' ').toLowerCase()\r\n if (names.includes('codex')) {\r\n return 'codex'\r\n }\r\n if (names.includes('claude')) {\r\n return 'claude'\r\n }\r\n } catch {\r\n // 프로세스 트리를 못 읽는 세션(SSH 등) — 제목으로 떨어진다\r\n }\r\n const title = `${pane.title ?? ''} ${pane.customTitle ?? ''}`.toLowerCase()\r\n if (title.includes('codex')) {\r\n return 'codex'\r\n }\r\n if (title.includes('claude')) {\r\n return 'claude'\r\n }\r\n return 'unknown'\r\n }\r\n\r\n /**\r\n * pane.sendInput 을 한 번 감싸 PTY 로 나간 입력을 진단 로그에 남긴다.\r\n *\r\n * 붙여넣기 한 번에 텍스트가 두 번 들어가는 증상은 \"우리가 두 번 불렀는지\" 와\r\n * \"한 번 불렀는데 PTY 에 두 번 써졌는지\" 를 갈라야 원인이 잡힌다. 이 계측이 그 경계다.\r\n * `pasteProbeUntil` 창 안에서만 기록하므로 평소 타이핑은 남지 않는다.\r\n */\r\n private probeSendInput (pane: any): void {\r\n if (!pane || pane.__adSendInputProbe || typeof pane.sendInput !== 'function') {\r\n return\r\n }\r\n const orig = pane.sendInput.bind(pane)\r\n pane.__adSendInputProbe = true\r\n pane.sendInput = (data: any, ...rest: any[]) => {\r\n if (Date.now() < this.pasteProbeUntil) {\r\n const text = typeof data === 'string' ? data : String(data)\r\n this.diag(`${new Date().toISOString()} sendInput len=${text.length} `\r\n + `head=${JSON.stringify(text.slice(0, 24))} from=${this.callSite()}`)\r\n }\r\n return orig(data, ...rest)\r\n }\r\n }\r\n\r\n /**\r\n * PTY 로 나가는 최종 관문(session.write)을 랩핑한다.\r\n *\r\n * pane.sendInput 만 보면 그걸 거치지 않는 경로를 놓친다 — 실측(2026-08-28 09:44:03)에서\r\n * 우클릭 한 번에 sendInput 은 154바이트 1회뿐인데 화면에는 두 번 들어갔다. 즉 두 번째는\r\n * 우리 계측 밖의 경로다. session.write 는 어느 경로든 마지막에 지나가므로 여기서 잡힌다.\r\n */\r\n private probeWrite (pane: any): void {\r\n const session = pane?.session\r\n if (!session || session.__adWriteProbe || typeof session.write !== 'function') {\r\n return\r\n }\r\n const orig = session.write.bind(session)\r\n session.__adWriteProbe = true\r\n session.write = (data: any, ...rest: any[]) => {\r\n if (Date.now() < this.pasteProbeUntil) {\r\n const text = typeof data === 'string' ? data : String(data)\r\n this.diag(`${new Date().toISOString()} write len=${text.length} `\r\n + `head=${JSON.stringify(text.slice(0, 24))} from=${this.callSite()}`)\r\n }\r\n return orig(data, ...rest)\r\n }\r\n }\r\n\r\n /** 호출 지점 몇 프레임 — 두 번째 붙여넣기를 누가 넣는지 보려고 */\r\n private callSite (): string {\r\n return (new Error().stack ?? '').split(String.fromCharCode(10)).slice(3, 7)\r\n .map(l => l.trim().replace(/^at\\s+/, '')).join(' <- ')\r\n }\r\n\r\n /** 클립보드에 이미지가 있고 텍스트는 비어 있는지 */\r\n private clipboardHasImageOnly (): boolean {\r\n const cb = getClipboard()\r\n if (!cb) {\r\n // Electron clipboard 를 못 쓰는 환경(웹 빌드 등) — 텍스트 붙여넣기로 떨어진다\r\n this.diag(`${new Date().toISOString()} clipboard unavailable`)\r\n return false\r\n }\r\n try {\r\n const hasImage = !cb.readImage().isEmpty()\r\n const text = cb.readText()\r\n this.diag(`${new Date().toISOString()} clipboard hasImage=${hasImage} textLen=${text.length}`)\r\n return hasImage && text.trim() === ''\r\n } catch (err) {\r\n this.diag(`${new Date().toISOString()} clipboard read failed: ${err}`)\r\n return false\r\n }\r\n }\r\n\r\n /** 분할된 탭이면 래퍼가 아니라 실제 포커스된 pane 을 돌려준다 */\r\n private focusedPane (): any {\r\n const active = this.app.activeTab as any\r\n if (!active) {\r\n return null\r\n }\r\n return typeof active.getFocusedTab === 'function'\r\n ? (active.getFocusedTab() ?? active)\r\n : active\r\n }\r\n\r\n /**\r\n * 줄바꿈 핫키에 Shift+Enter 를 보정해 넣는다.\r\n *\r\n * config.yaml 에 이미 `agentdeck-newline` 이 저장돼 있으면 ConfigProvider 의 defaults 는\r\n * 무시되므로(저장값이 이긴다) 기동 시 코드로 채워 넣어야 한다 — ensurePasteHotkey 와 같은 이유.\r\n */\r\n private ensureNewlineHotkey (): void {\r\n const hotkeys = this.config.store.hotkeys\r\n if (!hotkeys || !Array.isArray(hotkeys['agentdeck-newline'])) {\r\n return\r\n }\r\n const list: string[] = hotkeys['agentdeck-newline']\r\n if (list.includes('Shift-Enter')) {\r\n return\r\n }\r\n hotkeys['agentdeck-newline'] = [...list, 'Shift-Enter']\r\n this.config.save()\r\n }\r\n\r\n // ---------- 우클릭 ----------\r\n\r\n /**\r\n * 우클릭 처리를 agentdeck 이 가져온다.\r\n *\r\n * 증상: 우클릭 한 번에 클립보드가 두 번 들어갔다.\r\n * 원인: Tabby 의 우클릭 처리는 터미널 host 엘리먼트에 건 버블 단계 mouseup 리스너인데\r\n * (`tabby-terminal/dist/index.js:40972` 에서 등록, `detach()` 는 이 리스너를 떼지 않는다)\r\n * 프론트엔드가 같은 host 에 다시 attach 되면 리스너가 겹쳐 붙어 mouseEvent$ 가 한 클릭에\r\n * 두 번 발화한다. 그러면 `handleRightMouseUp` 이 두 번 돌아 paste() 도 두 번 나간다.\r\n *\r\n * 해결: Tabby 쪽 처리를 끄고(terminal.rightClick = 'off') document 캡처 단계에서\r\n * 우리가 한 번만 처리한다. 캡처는 host 리스너보다 먼저 돌기 때문에 몇 개가 겹쳐 붙어 있든\r\n * stopPropagation 으로 전부 차단된다. 동작 자체는 Tabby 의 'clipboard' 모드와 동일하게 —\r\n * 선택이 있으면 복사, 없으면 붙여넣기, 길게 누르면 컨텍스트 메뉴 — 유지한다.\r\n */\r\n private claimRightClick (): void {\r\n if (!this.config.store.agentDeck.claimRightClick) {\r\n return\r\n }\r\n // Tabby 자체 처리를 꺼서 리스너가 겹쳐도 아무 일이 없게 만든다 (이중 안전장치)\r\n if (this.config.store.terminal && this.config.store.terminal.rightClick !== 'off') {\r\n this.config.store.terminal.rightClick = 'off'\r\n this.config.save()\r\n }\r\n\r\n document.addEventListener('mousedown', ev => {\r\n if (ev.button !== 2 || !this.inTerminalArea(ev)) {\r\n return\r\n }\r\n this.rightDownAt = Date.now()\r\n // mouseup 만 막으면 mousedown 이 xterm 까지 내려가 마우스 리포트가 PTY 로 나간다.\r\n // Claude Code 처럼 마우스 트래킹을 켠 앱은 그 우클릭 리포트(ESC [ < 2 ; x ; y M)를\r\n // 자기 붙여넣기 신호로 받아 스스로 클립보드를 읽는다 — 우리 paste 와 합쳐 두 번 붙는다\r\n // (2026-08-28 실측: .agentdeck-diag.log 09:49:08.616 에 \"\u001b[<2;172;35M\" 전송,\r\n // 플러그인 write 는 클릭당 1회뿐인데 화면에는 2회 들어감).\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n }, { capture: true })\r\n\r\n // 우클릭에 딸려오는 contextmenu 도 캡처에서 끊는다 (메뉴는 길게 누를 때 우리가 직접 띄운다)\r\n document.addEventListener('contextmenu', ev => {\r\n if (this.inTerminalArea(ev)) {\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n }\r\n }, { capture: true })\r\n\r\n document.addEventListener('mouseup', ev => {\r\n if (ev.button !== 2 || !this.inTerminalArea(ev)) {\r\n return\r\n }\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n\r\n // 같은 물리 클릭이 두 번 들어오면(리스너 중복) 뒤엣것은 버린다\r\n const now = Date.now()\r\n if (now - this.lastRightHandledAt < 150) {\r\n return\r\n }\r\n this.lastRightHandledAt = now\r\n\r\n const held = now - this.rightDownAt\r\n void this.handleRightClick(ev, held)\r\n }, { capture: true })\r\n }\r\n\r\n /** 사이드바가 아니라 터미널 뷰포트 안에서 일어난 이벤트인지 */\r\n private inTerminalArea (ev: MouseEvent): boolean {\r\n const target = ev.target as HTMLElement | null\r\n if (!target || typeof target.closest !== 'function') {\r\n return false\r\n }\r\n return !!target.closest('.content.main') && !target.closest(`#${SIDEBAR_ID}`)\r\n }\r\n\r\n private async handleRightClick (ev: MouseEvent, heldMs: number): Promise<void> {\r\n const pane = this.focusedPane()\r\n if (!pane) {\r\n return\r\n }\r\n\r\n const menuMs = this.config.store.agentDeck.rightClickMenuMs ?? 250\r\n if (heldMs >= menuMs) {\r\n if (typeof pane.buildContextMenu === 'function' && pane.platform) {\r\n pane.platform.popupContextMenu(await pane.buildContextMenu(), ev)\r\n }\r\n return\r\n }\r\n\r\n const selection = typeof pane.frontend?.getSelection === 'function'\r\n ? pane.frontend.getSelection()\r\n : ''\r\n if (selection) {\r\n pane.frontend.copySelection()\r\n pane.frontend.clearSelection()\r\n } else {\r\n // 우클릭 붙여넣기도 Ctrl+V 와 같은 경로를 타게 한다 (이미지면 Alt+V 위임)\r\n this.doPaste('rightclick')\r\n }\r\n }\r\n\r\n /**\r\n * 포커스된 pane 에 0x0A(LF) 를 보낸다 — Ctrl+J 가 보내는 것과 같은 바이트다.\r\n * Claude Code 는 이걸 줄바꿈으로 받고, Enter(0x0D) 는 전송으로 받는다.\r\n * Enter 를 눌러 줄을 넘기지 않으려는 것이므로 CR 을 섞으면 안 된다.\r\n */\r\n private sendNewline (): void {\r\n const pane = this.focusedPane()\r\n if (!pane) {\r\n return\r\n }\r\n if (typeof pane.sendInput === 'function') {\r\n pane.sendInput('\\n')\r\n }\r\n }\r\n\r\n // ---------- 레이아웃 ----------\r\n\r\n private get enabled (): boolean {\r\n return this.config.store.agentDeck.enabled\r\n }\r\n\r\n private applyEnabled (): void {\r\n document.body.classList.toggle(BODY_CLASS, this.enabled)\r\n if (this.sidebar) {\r\n this.sidebar.style.display = this.enabled ? '' : 'none'\r\n }\r\n if (!this.enabled && this.mainEl) {\r\n for (const prop of ['flex', 'width', 'max-width', 'height',\r\n 'margin-left', 'margin-right', 'margin-top', 'margin-bottom']) {\r\n this.mainEl.style.removeProperty(prop)\r\n }\r\n // 폭을 되돌렸으니 메모도 무효화하고 터미널에 새 폭을 알린다\r\n this.lastTermW = -1\r\n this.lastSidebarW = -1\r\n this.lastDock = null\r\n this.scheduleRefit()\r\n }\r\n this.syncBackgroundClip()\r\n }\r\n\r\n /**\r\n * tabby-background 의 이미지 레이어를 터미널 영역(`.content.main`)에 맞춰 자른다.\r\n *\r\n * 그 레이어는 `position: fixed` 라 viewport 좌표를 쓰므로 `getBoundingClientRect()` 값을\r\n * 그대로 CSS 변수로 내리면 된다 (styles.scss 가 `!important` 로 덮어쓴다).\r\n * relayout 직후에는 인라인 폭이 아직 레이아웃에 반영되지 않았을 수 있어 rAF 한 번 뒤에 잰다.\r\n * 꺼져 있으면(또는 agentdeck 비활성) 클래스와 변수를 걷어 순정(창 전체)으로 되돌린다.\r\n */\r\n private syncBackgroundClip (): void {\r\n const root = document.documentElement\r\n const clear = (): void => {\r\n document.body.classList.remove(BG_CLIP_CLASS)\r\n for (const v of ['--ad-bg-left', '--ad-bg-top', '--ad-bg-width', '--ad-bg-height']) {\r\n root.style.removeProperty(v)\r\n }\r\n }\r\n if (!this.enabled || !this.config.store.agentDeck.clipBackgroundToTerminal || !this.mainEl) {\r\n clear()\r\n return\r\n }\r\n requestAnimationFrame(() => {\r\n if (!this.enabled || !this.mainEl) {\r\n clear()\r\n return\r\n }\r\n const r = this.mainEl.getBoundingClientRect()\r\n if (r.width <= 0 || r.height <= 0) {\r\n return\r\n }\r\n root.style.setProperty('--ad-bg-left', Math.round(r.left) + 'px')\r\n root.style.setProperty('--ad-bg-top', Math.round(r.top) + 'px')\r\n root.style.setProperty('--ad-bg-width', Math.round(r.width) + 'px')\r\n root.style.setProperty('--ad-bg-height', Math.round(r.height) + 'px')\r\n document.body.classList.add(BG_CLIP_CLASS)\r\n })\r\n }\r\n\r\n /**\r\n * 터미널/사이드바 배경에 알파를 넣어 tabby-background 의 배경 이미지가 비치게 한다.\r\n *\r\n * 배경 이미지는 `.content-tab-active::before` 로 **모든 내용 뒤에** 깔린다. 그래서\r\n * 그 위를 덮는 두 면이 불투명하면 이미지는 어디에도 보이지 않는다 —\r\n * (1) 터미널: xterm 이 컬러스킴 background 색으로 셀을 직접 칠한다 (CSS 로는 못 뚫는다)\r\n * (2) 사이드바 / .window: 우리가 넣은 불투명 배경\r\n * (1) 은 Tabby 가 xterm 을 `allowTransparency: true` 로 만들기 때문에 색에 알파만 넣으면 된다.\r\n * config.yaml 을 손으로 고쳐도 Tabby 가 종료할 때 메모리 값으로 덮어써 되돌아가므로,\r\n * ensurePasteHotkey 와 같은 이유로 여기서 코드로 보정한다.\r\n */\r\n private applyOpacity (): void {\r\n const cfg = this.config.store.agentDeck\r\n const termPct = clampPct(cfg.terminalOpacity)\r\n const sidePct = clampPct(cfg.sidebarOpacity)\r\n\r\n // 사이드바 / 창 여백 — CSS 변수로 내려보낸다 (styles.scss 가 폴백을 들고 있다)\r\n const root = document.documentElement\r\n if (sidePct >= 100) {\r\n root.style.removeProperty('--ad-panel-bg')\r\n } else {\r\n root.style.setProperty('--ad-panel-bg', `rgba(30, 33, 39, ${sidePct / 100})`)\r\n }\r\n\r\n // 터미널 — 컬러스킴 배경색에 알파를 붙인다\r\n const scheme = this.config.store.terminal?.colorScheme\r\n if (!scheme?.background) {\r\n return\r\n }\r\n const next = withAlpha(scheme.background, termPct)\r\n // 컬러스킴 기반 배경을 쓰도록 못 박는다 — 테마 배경으로 떨어지면 알파가 무시된다\r\n const wantMode = termPct < 100 ? 'colorScheme' : this.config.store.terminal.background\r\n if (next === scheme.background && wantMode === this.config.store.terminal.background) {\r\n // 이미 적용돼 있다. 여기서 save 를 부르면 changed$ 가 다시 우리를 부른다\r\n return\r\n }\r\n scheme.background = next\r\n this.config.store.terminal.background = wantMode\r\n this.config.save()\r\n }\r\n\r\n /** 지금 사이드바가 붙어 있는 방향 (설정값이 망가져 있으면 오른쪽으로 본다) */\r\n private get dockSide (): DockSide {\r\n const v = this.config.store.agentDeck.sidebarDock\r\n return isDockSide(v) ? v : 'right'\r\n }\r\n\r\n /**\r\n * 사이드바가 차지할 크기를 px 로 정한다 — 좌/우면 폭, 상/하면 높이.\r\n *\r\n * 사용자가 경계선을 한 번이라도 끌었으면 그 값(`sidebarWidth`/`sidebarHeight`)이 진실이다.\r\n * 아직 안 끌었다면(폭이 0) 예전처럼 화면비로 터미널 폭을 역산해 남는 만큼을 사이드바가 갖는다.\r\n */\r\n private sidebarExtent (availW: number, availH: number, winH: number): number {\r\n const cfg = this.config.store.agentDeck\r\n if (isHorizontalDock(this.dockSide)) {\r\n const minSidebar = cfg.sidebarMin || 200\r\n const maxSidebar = Math.max(cfg.sidebarMax || 560, minSidebar)\r\n let want = cfg.sidebarWidth || 0\r\n if (!want) {\r\n // 화면비를 지킨다는 가정에서 터미널 폭을 높이로 역산하고 남는 폭을 사이드바에 준다\r\n const ratio = (cfg.aspectW || 4) / (cfg.aspectH || 3)\r\n let termW = Math.round(availH * ratio)\r\n termW = Math.min(termW, availW - minSidebar)\r\n termW = Math.max(termW, MIN_TERM_W)\r\n want = availW - termW\r\n }\r\n // 손으로 끈 값은 설정의 min/max 를 넘어설 수 있다 — 마우스가 우선이므로\r\n // 목록이 읽히는 최소 폭과 터미널이 남을 최대 폭까지만 막는다\r\n const hardMin = cfg.sidebarWidth ? MIN_SIDEBAR_W : minSidebar\r\n const hardMax = Math.max(availW - MIN_TERM_W, hardMin)\r\n const softMax = cfg.sidebarWidth ? Math.max(maxSidebar, cfg.sidebarWidth) : maxSidebar\r\n return Math.min(Math.max(want, hardMin), softMax, hardMax)\r\n }\r\n // 세로 도킹은 창 높이를 기준으로 잡는다 — 터미널 높이(availH)는 사이드바를 뺀 값이라\r\n // 그걸로 클램프하면 잴 때마다 값이 줄어드는 되먹임이 생긴다\r\n const want = cfg.sidebarHeight || 200\r\n return Math.min(Math.max(want, MIN_SIDEBAR_H), Math.max(winH - MIN_TERM_H, MIN_SIDEBAR_H))\r\n }\r\n\r\n /** 사이드바를 창 한쪽에 붙이고, 남는 자리를 `.content.main` 이 갖게 한다 */\r\n private relayout (): void {\r\n if (!this.enabled || !this.windowEl) {\r\n this.diagOnce('relayout-skip-enabled', `relayout skipped enabled=${this.enabled} windowEl=${!!this.windowEl}`)\r\n return\r\n }\r\n // appRoot 가 늦게 렌더되는 경우가 있어 매번 다시 찾는다\r\n if (!this.mainEl) {\r\n this.mainEl = document.querySelector('.content.main')\r\n }\r\n if (!this.mainEl) {\r\n this.diagOnce('relayout-skip-mainel', 'relayout skipped mainEl=null')\r\n return\r\n }\r\n\r\n const availW = this.windowEl.clientWidth\r\n // 화면비로 폭을 역산할 때 쓰는 높이는 터미널이 실제로 쓰는 높이여야 한다.\r\n // 창 높이를 쓰면 탭바 등을 뺀 만큼 폭이 과대 계산돼 사이드바가 좁아진다\r\n const availH = this.mainEl.clientHeight || this.windowEl.clientHeight\r\n if (!availW || !availH) {\r\n return\r\n }\r\n\r\n const side = this.dockSide\r\n const horizontal = isHorizontalDock(side)\r\n let extent = Math.round(this.sidebarExtent(availW, availH, this.windowEl.clientHeight))\r\n // 터미널이 갖는 폭 — 가로 도킹일 때만 의미가 있다 (세로 도킹이면 폭 전체를 쓴다)\r\n let termW = horizontal ? availW - extent : availW\r\n\r\n // 터미널 폭을 문자 셀의 정수배로 깎는다.\r\n //\r\n // 셀 폭으로 나누어떨어지지 않으면 오른쪽에 셀 하나가 안 되는 자투리가 남는데,\r\n // fit() 은 그 자투리를 두고 창이 몇 px 만 흔들려도 열 수가 오르내린다. 열 수가 바뀔 때마다\r\n // pty 에 새 크기가 나가고 TUI 는 전체를 다시 그린다 — 화면이 깜빡이고 어긋날 틈이 생긴다.\r\n // 정수배로 맞춰 두면 자투리가 사라져 열 수가 흔들리지 않는다. 깎아 낸 픽셀은 사이드바가 갖는다.\r\n // 한때 이 자리에서 터미널 폭을 문자 셀의 정수배로 깎았다. 자투리 픽셀을 없애려던 건데\r\n // 오히려 화면이 계속 밀리는 원인이 됐다 — 셀 폭은 폰트가 자리를 잡는 동안 조금씩 다르게\r\n // 잡히고(2026-09-01 실측: 같은 창에서 termW 가 1977 -> 1970 -> 1974 로 진동),\r\n // 폭이 바뀔 때마다 pty 를 다시 맞추고 TUI 를 다시 그리게 만들었다.\r\n // 폭은 사용자가 정한 사이드바 크기에서 곧장 나오는 값 하나로 고정하는 편이 안정적이다.\r\n // 남는 자투리는 어차피 배경색이라 눈에 띄지 않는다.\r\n extent = Math.round(extent)\r\n termW = Math.round(termW)\r\n\r\n // 값이 그대로면 DOM 을 건드리지 않는다 — relayout 은 탭/상태가 바뀔 때마다 불리므로\r\n // 매번 스타일을 다시 쓰면 xterm 이 불필요하게 재측정한다\r\n if (termW === this.lastTermW && extent === this.lastSidebarW && side === this.lastDock) {\r\n return\r\n }\r\n const prevTermW = this.lastTermW\r\n this.lastTermW = termW\r\n this.lastSidebarW = extent\r\n this.lastDock = side\r\n\r\n // 기동 직후 흔들기(rearm kick)는 폐지했다 — 아래 relayout 주석 참고.\r\n\r\n // 사이드바는 창 위에 절대 배치한다. flex 자식으로 두면 도킹 방향을 바꿀 때마다\r\n // `.window` 의 flex-direction 을 뒤집어야 하고, 그러면 같은 줄에 있는 profile-tree 까지\r\n // 따라 움직인다. 절대 배치면 우리 것만 옮기면 된다.\r\n if (this.sidebar) {\r\n const s = this.sidebar.style\r\n s.position = 'absolute'\r\n s.left = side === 'right' ? 'auto' : '0'\r\n s.right = side === 'left' ? 'auto' : '0'\r\n s.top = side === 'bottom' ? 'auto' : '0'\r\n s.bottom = side === 'top' ? 'auto' : '0'\r\n s.width = horizontal ? extent + 'px' : 'auto'\r\n s.height = horizontal ? 'auto' : extent + 'px'\r\n for (const d of DOCK_SIDES) {\r\n this.sidebar.classList.toggle('ad-dock-' + d, d === side)\r\n }\r\n }\r\n\r\n // 터미널이 차지할 자리.\r\n //\r\n // 가로 도킹에서는 폭을 px 로 못 박는다. margin 만 주고 flex 에게 남는 폭을 맡겨 봤더니\r\n // (2026-09-01) xterm 이 fit 할 때 잡는 폭과 TUI 가 아는 폭이 어긋나 입력창이 깨졌다 —\r\n // 가로선과 입력 텍스트가 한 줄에 섞여 wrap 되는 그 증상이다. 폭을 직접 주면 xterm host 가\r\n // 재는 값이 곧 우리가 정한 값이라 어긋날 여지가 없다.\r\n // 세로 도킹은 폭을 건드릴 필요가 없고, `h-100`(height:100%) 때문에 margin 만으로는\r\n // 그만큼 창 밖으로 넘치므로 높이를 대신 깎는다.\r\n const m = this.mainEl.style\r\n if (horizontal) {\r\n m.flex = '0 0 ' + termW + 'px'\r\n m.width = termW + 'px'\r\n m.maxWidth = termW + 'px'\r\n m.removeProperty('height')\r\n m.marginTop = '0'\r\n m.marginBottom = '0'\r\n // 왼쪽 도킹일 때만 앞자리를 비운다 (오른쪽 도킹은 고정폭만으로 자리가 남는다)\r\n m.marginLeft = side === 'left' ? extent + 'px' : '0'\r\n m.marginRight = '0'\r\n } else {\r\n m.removeProperty('flex')\r\n m.removeProperty('width')\r\n m.removeProperty('max-width')\r\n m.marginLeft = '0'\r\n m.marginRight = '0'\r\n m.marginTop = side === 'top' ? extent + 'px' : '0'\r\n m.marginBottom = side === 'bottom' ? extent + 'px' : '0'\r\n // **`important` 가 필요하다.** `.content.main` 에는 부트스트랩 `h-100` 클래스가 붙어\r\n // 있고 그 규칙이 `height: 100% !important` 라, 평범한 인라인 스타일은 진다.\r\n // 그래서 상하 도킹에서 터미널 높이가 전혀 줄지 않았다 — bottom 이면 아래쪽이\r\n // 사이드바에 가리고, top 이면 그만큼 창 밖으로 넘쳤다\r\n // (2026-09-02 실측, 창 1100x700 / 사이드바 200: 인라인은 `calc(100% - 200px)` 인데\r\n // computed 는 `700px`, host 는 top 에서 `1070x670@y=215` 로 하단 185px 가 잘렸다).\r\n m.setProperty('height', 'calc(100% - ' + extent + 'px)', 'important')\r\n }\r\n\r\n this.dock?.syncHandle()\r\n this.syncBackgroundClip()\r\n // 우리가 하는 일은 여기까지다 — **폭을 정해 `.content.main` 에 적고 fit 한 번.**\r\n //\r\n // 2026-09-02 방향 전환(유저 지적): \"Tabby 는 창 크기가 어떻든 알아서 줄맞춤 되잖아?\" 맞다.\r\n // 순정 경로는 xterm `ResizeObserver` → `fitAddon.fit()` → `session.resize()` 이고,\r\n // 우리가 폭만 정해 주면 그 뒤는 Tabby 가 스스로 계산한다.\r\n // 예전에는 \"순정이 우리 CSS 변경을 못 따라온다\"고 보고 보정을 4겹 쌓았다 —\r\n // relayout 시 fit / `watchSize`(250ms 마다 fit+resize, 6초) / `syncPtySize` 재전송 사슬 /\r\n // `nudgePtyRedraw`(cols-1↔cols 흔들기). 그 겹침이 순정 수렴과 경쟁하면서\r\n // 프레임을 반쯤 그린 상태를 남겼고, 그게 실사용 깨짐의 정체였다(항목 24~28 은 전부 그 부작용).\r\n // 전제도 로그로 반박됐다 — 폭은 탭이 생기기 전에 이미 확정돼 있는데도\r\n // (`rearm kick termW -1->2000 panes=0`) 새 탭 xterm 이 254 로 뜬다. 그건 레이아웃 확정 전의\r\n // 초기 측정값일 뿐이고 순정 옵저버가 어차피 수렴시킨다.\r\n // 그래서 자동 보정은 전부 걷어냈다. 남은 건 이 fit 하나(순정 경로를 깨우는 용도)다.\r\n this.scheduleRefit()\r\n // 폭이 어긋나는 사고를 다시 만나면 이 줄이 실제 값을 알려 준다 —\r\n // 우리가 정한 값(termW)과 브라우저가 실제로 준 폭(clientWidth)이 다르면 그게 원인이다\r\n this.diag(`${new Date().toISOString()} relayout dock=${side} avail=${availW}x${availH}`\r\n + ` extent=${extent} termW=${termW} mainW=${this.mainEl.clientWidth}`)\r\n }\r\n\r\n /**\r\n * 폭을 바꿨으면 터미널에 반드시 알려야 한다.\r\n *\r\n * Tabby 의 xterm 프론트엔드는 창(OS 창) 리사이즈에 맞춰 재측정하지만,\r\n * 우리처럼 CSS 로만 `.content.main` 폭을 바꾸면 그 경로를 타지 않는다.\r\n * 그러면 xterm 의 열 수는 넓어졌는데 pty 는 옛 폭 그대로라, Claude Code 같은\r\n * 전체화면 TUI 가 화면보다 좁게 그리고 오른쪽에 지워지지 않은 잔상이 남는다\r\n * (2026-08-28 실측: 입력창 구분선이 화면 중간에서 끊기고 옛 statusline 이 우측에 박혀 있었다.\r\n * 창을 복원→최대화로 흔들면 OS 리사이즈 경로를 타서 즉시 정상 복구됐다).\r\n *\r\n * fitAddon.fit() 이 xterm 의 onResize 를 발화시키고, Tabby 가 그걸 받아\r\n * session.resize() 로 pty 까지 내려보낸다. 값이 같으면 xterm 이 이벤트를 내지 않으므로\r\n * 여분 호출은 무해하다.\r\n */\r\n private scheduleRefit (): void {\r\n if (this.refitQueued) {\r\n return\r\n }\r\n this.refitQueued = true\r\n // 레이아웃이 실제로 반영된 뒤에 재야 한다 — 한 프레임으로는 아직 옛 폭이 잡힌다\r\n requestAnimationFrame(() => requestAnimationFrame(() => {\r\n this.refitQueued = false\r\n this.refitTerminals()\r\n }))\r\n // attach() 가 아직 진행 중이면 위 fit 이 무시될 수 있다. fit 은 크기가 같으면\r\n // 아무 일도 안 하므로 한 번 더 늦게 때려도 무해하다\r\n setTimeout(() => this.refitTerminals(), 500)\r\n }\r\n\r\n private refitTerminals (): void {\r\n for (const tab of this.app.tabs) {\r\n const anyTab = tab as any\r\n const panes: BaseTabComponent[] = typeof anyTab.getAllTabs === 'function'\r\n ? anyTab.getAllTabs()\r\n : [tab]\r\n for (const pane of panes) {\r\n const frontend = (pane as any).frontend\r\n const fitAddon = frontend?.fitAddon\r\n if (!fitAddon || typeof fitAddon.fit !== 'function') {\r\n continue\r\n }\r\n // 숨겨진 탭은 컨테이너 폭이 0 이라 fit 하면 1열짜리로 줄어든다 — 건너뛴다.\r\n // 그 탭은 다시 선택될 때 Tabby 가 알아서 재측정한다\r\n const host = frontend.xterm?.element?.parentElement\r\n if (!host || !host.clientWidth || !host.clientHeight) {\r\n continue\r\n }\r\n try {\r\n fitAddon.fit()\r\n } catch {\r\n // 아직 붙지 않은 프론트엔드 — 다음 relayout 때 다시 잡힌다\r\n }\r\n // 여기서 끝낸다. 예전에는 뒤이어 `syncPtySize` 로 pty 에 직접 크기를 쐈는데,\r\n // fit() 이 이미 순정 경로(onResize → session.resize)를 태우므로 중복이고,\r\n // 그 중복이 순정 수렴과 경쟁해 화면을 깨뜨렸다 (2026-09-02).\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * pty 크기를 xterm 이 실제로 그리고 있는 크기에 강제로 맞춘다.\r\n *\r\n * `fitAddon.fit()` 은 xterm 의 열/행이 이미 맞으면 onResize 를 내지 않는다. 그런데 새 탭은\r\n * xterm 은 우리가 줄여 놓은 폭으로 제대로 열리는데 **세션(pty)만** 생성 시점의 옛 폭으로 남는\r\n * 경우가 있다. 이때 fit() 은 no-op 이라 pty 가 영영 안 고쳐지고, TUI 가 처음 화면을 다시\r\n * 그리는 순간(줄바꿈 등) 오른쪽에 옛 폭 잔상이 남는다 — 창 복원→최대화로 흔들면 OS 리사이즈\r\n * 경로를 타서 그제야 맞는다(2026-08-28 실측, 새 탭에서 재현).\r\n *\r\n * 그래서 fit() 뒤에 pty 로 직접 한 번 더 내려보낸다. 같은 값이면 pty 쪽에서 무시되므로 무해하다.\r\n */\r\n private syncPtySize (pane: BaseTabComponent, frontend: any): void {\r\n const cols = frontend?.xterm?.cols\r\n const rows = frontend?.xterm?.rows\r\n if (!cols || !rows) {\r\n return\r\n }\r\n const anyPane = pane as any\r\n const session = anyPane.session\r\n if (!session || !session.open || typeof session.resize !== 'function') {\r\n return\r\n }\r\n // 이 경로는 지금까지 조용했다. 그래서 \"언제 pty 폭이 바뀌었나\" 가 로그에 안 남아\r\n // 어긋남 사고를 만나도 발생 지점을 못 짚었다 (watchSize 의 `size fix` 만 남았다).\r\n // 값이 실제로 달라질 때만 남긴다 — 같은 값 재전송은 매 refit 마다 일어나므로 시끄럽다.\r\n const prev = anyPane.size\r\n if (prev?.columns !== cols || prev?.rows !== rows) {\r\n this.diag(`${new Date().toISOString()} pty resize ${prev?.columns}x${prev?.rows}`\r\n + ` -> ${cols}x${rows}`)\r\n }\r\n try {\r\n session.resize(cols, rows)\r\n anyPane.size = { columns: cols, rows }\r\n } catch {\r\n // 세션이 막 닫혔다 — 다음 refit 때 다시 잡힌다\r\n return\r\n }\r\n\r\n // **보냈다고 도착한 것이 아니다.**\r\n //\r\n // 세션이 막 열린 직후의 `session.resize()` 는 pty 에 닿지 못하고 유실된다\r\n // (2026-09-01 실측: `size fix 254x78 -> 280x78` + `pty resize` + `redraw nudge` 가\r\n // 모두 돌고 `pane.size` 도 280 으로 남았는데, 같은 탭 셸에 물어보니 `PTYW=254`.\r\n // 같은 호출을 몇 초 뒤에 CDP 로 하면 그때는 정상 반영된다 — 초기화 경합이다).\r\n // 그런데 `pane.size` 에 낙관적으로 280 을 적어 두므로, 크기 감시(watchSize)는\r\n // \"이제 맞다\" 고 보고 손을 뗀다. 그 뒤에 뜨는 TUI 는 254 폭으로 첫 화면을 그린다.\r\n //\r\n // 그래서 값이 실제로 바뀐 경우에만 같은 크기를 몇 번 더 보낸다. pty 크기가 이미\r\n // 그 값이면 아무 일도 일어나지 않으므로(SIGWINCH 도 안 난다) 재전송은 무해하다.\r\n if (prev?.columns !== cols || prev?.rows !== rows) {\r\n for (const delay of PTY_RESIZE_RETRY_MS) {\r\n setTimeout(() => {\r\n const now = anyPane.frontend?.xterm\r\n // 그동안 폭이 또 바뀌었으면 그쪽 경로가 새 값을 보낸다 — 옛 값을 덮어쓰지 않는다\r\n if (!anyPane.session?.open || now?.cols !== cols || now?.rows !== rows) {\r\n return\r\n }\r\n try {\r\n anyPane.session.resize(cols, rows)\r\n } catch {\r\n // 세션이 닫혔다\r\n }\r\n }, delay)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * pty 크기만 한 칸 줄였다 되돌려 TUI 가 화면을 다시 그리게 한다. **수동 복구 전용.**\r\n *\r\n * 자동 경로에서는 전부 걷어냈다 — 이 흔들기가 순정 수렴과 경쟁하며 깨진 화면을\r\n * 만들어 왔다(2026-09-02). 남겨 둔 이유는 `repairPane`(사이드바 `↻` / `agentdeck-repair`)\r\n * 때문이다. 거기서는 사용자가 \"지금 깨졌으니 고쳐라\" 를 명시로 눌렀고, 크기를 맞추는\r\n * 것만으로는 앱이 다시 그리지 않는 경우가 실제로 있다 — 폭이 **실제로 바뀌어야**\r\n * SIGWINCH 가 나가므로 한 칸 흔들어 두 번 내보낸다. 뒤이어 `Ctrl+L` 이 따라간다.\r\n *\r\n * 좁힌 값을 `pane.size` 에 그대로 적는다. 되돌리기가 유실됐는데 낙관적으로 `cols` 를\r\n * 적어 두면 아무도 어긋남을 못 보고 한 열 좁은 채로 굳는다(옛 버그).\r\n */\r\n private nudgePtyRedraw (pane: BaseTabComponent): void {\r\n const anyPane = pane as any\r\n const session = anyPane.session\r\n const cols = anyPane.frontend?.xterm?.cols\r\n const rows = anyPane.frontend?.xterm?.rows\r\n if (!session?.open || typeof session.resize !== 'function' || !(cols > 1) || !(rows > 1)) {\r\n return\r\n }\r\n this.diag(`${new Date().toISOString()} redraw nudge ${cols}x${rows}`)\r\n try {\r\n session.resize(cols - 1, rows)\r\n anyPane.size = { columns: cols - 1, rows }\r\n setTimeout(() => {\r\n if (!anyPane.session?.open) {\r\n return\r\n }\r\n // 되돌릴 값은 \"지금\" 의 xterm 폭이다 — 흔드는 사이 사이드바가 움직였을 수 있다\r\n this.syncPtySize(pane, anyPane.frontend)\r\n }, 60)\r\n } catch {\r\n // 세션이 막 닫혔다\r\n }\r\n }\r\n\r\n // 크기 감시(`watchSize` / `watchAllSizes`)도 폐지했다 (2026-09-02).\r\n //\r\n // 250ms 마다 `fitAddon.fit()` + `session.resize()` 를 6초간 쏘던 장치다. 목적은\r\n // \"xterm 은 넓어졌는데 pty 는 옛 폭\" 을 잡는 것이었는데, 그 어긋남은 순정\r\n // ResizeObserver 가 이미 수렴시킨다. 우리 감시는 그 수렴 도중의 중간값을 보고\r\n // 계속 끼어들었고, 끝에 `nudgePtyRedraw` 흔들기까지 붙여 화면을 깨뜨렸다.\r\n // 순정이 정말 못 맞추는 경우가 나오면 `screenWatch` 채증에 남는다 — 그때 근거를 갖고 되켠다.\r\n\r\n // ---------- 사이드바 DOM ----------\r\n\r\n private buildSidebar (): void {\r\n const el = document.createElement('div')\r\n el.id = SIDEBAR_ID\r\n el.innerHTML = [\r\n '<div class=\"ad-head\">',\r\n ' <span class=\"ad-head-title\">AGENT DECK</span>',\r\n ' <span class=\"ad-head-count\"></span>',\r\n '</div>',\r\n '<div class=\"ad-list\"></div>',\r\n '<div class=\"ad-foot\">',\r\n ' <button class=\"ad-btn ad-new\" title=\"새 탭\">+ 새 탭</button>',\r\n ' <button class=\"ad-btn ad-settings\" title=\"설정\">설정</button>',\r\n // 화면이 깨졌을 때 누르는 자리 — 창을 복원→최대화로 흔들던 것을 대신한다.\r\n // 자주 쓰는 두 버튼(새 탭·설정) 뒤에 둔다 (2026-09-01 유저 요청)\r\n ' <button class=\"ad-btn ad-repair\" title=\"화면 복구 (모든 탭 다시 그리기)\">↻</button>',\r\n '</div>',\r\n ].join('\\n')\r\n\r\n // 순정 탭바보다 뒤(오른쪽)에 놓는다 — 왼쪽에 두면 세로로 길어 허전하다는 피드백(2026-08-28)\r\n this.windowEl.appendChild(el)\r\n this.sidebar = el\r\n this.listEl = el.querySelector('.ad-list')\r\n\r\n el.querySelector('.ad-new').addEventListener('click', () => {\r\n this.zone.run(() => { void this.openNewTab() })\r\n })\r\n el.querySelector('.ad-repair').addEventListener('click', () => {\r\n this.zone.run(() => this.repair('all'))\r\n })\r\n el.querySelector('.ad-settings').addEventListener('click', () => {\r\n this.zone.run(() => this.openSettings())\r\n })\r\n\r\n // 크기/도킹은 설정 창이 아니라 마우스로 맞춘다.\r\n // 드래그 중에는 relayout 이 초당 수십 번 불리므로 config.save() 는 손을 뗄 때만 부른다.\r\n this.dock = new DockController({\r\n sidebar: el,\r\n windowEl: this.windowEl,\r\n getDock: () => this.dockSide,\r\n setDock: side => {\r\n this.config.store.agentDeck.sidebarDock = side\r\n },\r\n getSize: side => {\r\n const cfg = this.config.store.agentDeck\r\n if (!isHorizontalDock(side)) {\r\n return cfg.sidebarHeight || 0\r\n }\r\n // 지금 좌/우로 붙어 있다면 화면에 실제로 적용된 폭이 가장 정확하다\r\n // (자동 계산 상태면 sidebarWidth 가 0 이라 물어봐야 소용이 없다)\r\n return isHorizontalDock(this.dockSide) && this.lastSidebarW > 0\r\n ? this.lastSidebarW\r\n : (cfg.sidebarWidth || 0)\r\n },\r\n setSize: px => {\r\n const cfg = this.config.store.agentDeck\r\n if (isHorizontalDock(this.dockSide)) {\r\n cfg.sidebarWidth = px\r\n } else {\r\n cfg.sidebarHeight = px\r\n }\r\n },\r\n commit: () => this.zone.run(() => this.config.save()),\r\n relayout: () => this.relayout(),\r\n })\r\n this.dock.install()\r\n }\r\n\r\n /** 설정에 지정된 기본 프로필(기본값 agentdeck:root)로 새 탭을 연다 */\r\n private async openNewTab (): Promise<void> {\r\n const wanted = this.config.store.terminal.profile\r\n const profiles = await this.profiles.getProfiles()\r\n const profile = profiles.find(p => p.id === wanted) ?? profiles[0]\r\n if (profile) {\r\n await this.profiles.openNewTabForProfile(profile)\r\n }\r\n }\r\n\r\n private openSettings (): void {\r\n this.app.openNewTabRaw({ type: SettingsTabComponent })\r\n }\r\n\r\n /**\r\n * 사이드바 다시 그리기를 한 번으로 모은다.\r\n *\r\n * rAF 만 쓰면 **창이 가려졌을 때 상태가 늦게 반영된다.** Chromium 은 창이 hidden\r\n * (최소화·완전 가려짐) 이 되면 rAF 를 아예 멈추고 타이머도 스로틀한다. 그러면\r\n * 훅이 보낸 done 은 메모리에 즉시 반영됐는데 화면만 옛 상태로 남아 있다가,\r\n * 1초 tick(그것도 스로틀되면 더 늦게)이 와야 그려진다 — \"작업중이 한참 뒤에야 완료로 바뀐다\"\r\n * 의 정체가 이것이다(2026-08-28). 시작 쪽이 빨라 보이는 건 그때는 사용자가 방금\r\n * 창에 입력해서 창이 떠 있기 때문일 뿐이다.\r\n *\r\n * 그래서 rAF 와 짧은 타이머를 같이 걸고 **먼저 오는 쪽이 그린다**. 창이 떠 있으면\r\n * 지금까지와 똑같이 다음 프레임에, 가려져 있으면 타이머가 대신 그린다.\r\n */\r\n private scheduleRender (): void {\r\n if (this.renderQueued) {\r\n return\r\n }\r\n this.renderQueued = true\r\n const run = () => {\r\n if (!this.renderQueued) {\r\n return\r\n }\r\n this.renderQueued = false\r\n if (this.renderTimer) {\r\n clearTimeout(this.renderTimer)\r\n this.renderTimer = null\r\n }\r\n this.render()\r\n this.relayout()\r\n }\r\n requestAnimationFrame(run)\r\n this.renderTimer = setTimeout(run, 50)\r\n }\r\n\r\n /**\r\n * 창이 가려져 있어도 타이머·rAF 가 계속 돌게 한다.\r\n *\r\n * 위 scheduleRender 의 타이머 폴백은 \"타이머가 제때 돈다\" 를 전제로 하는데,\r\n * Chromium 은 hidden 페이지의 타이머를 1초로 묶고 5분 넘게 가려져 있으면\r\n * **분당 1회**까지 떨어뜨린다. 그 상태에서는 폴백조차 늦다.\r\n * Electron 의 backgroundThrottling 을 꺼서 이 계층을 통째로 없앤다.\r\n */\r\n private disableBackgroundThrottling (): void {\r\n if (!this.config.store.agentDeck.keepRenderingWhenHidden) {\r\n return\r\n }\r\n try {\r\n const req = (window as any).require ?? (globalThis as any).require\r\n const win = req?.('@electron/remote')?.getCurrentWindow?.()\r\n win?.webContents?.setBackgroundThrottling?.(false)\r\n } catch {\r\n // remote 를 못 잡아도 위 타이머 폴백은 살아 있다 (조금 늦을 뿐)\r\n }\r\n }\r\n\r\n private tick (): void {\r\n if (!this.enabled) {\r\n return\r\n }\r\n let dirty = false\r\n const idleAfter = this.config.store.agentDeck.idleAfterMs || 2500\r\n for (const tab of this.app.tabs) {\r\n if (this.status.tickIdle(tab, idleAfter)) {\r\n dirty = true\r\n }\r\n }\r\n if (dirty || this.config.store.agentDeck.showElapsed) {\r\n this.render()\r\n }\r\n }\r\n\r\n private render (): void {\r\n if (!this.listEl || !this.enabled || this.editing) {\r\n return\r\n }\r\n const tabs = this.app.tabs\r\n const countEl = this.sidebar.querySelector('.ad-head-count')\r\n countEl.textContent = String(tabs.length)\r\n\r\n this.listEl.innerHTML = ''\r\n for (const tab of tabs) {\r\n this.listEl.appendChild(this.renderTab(tab))\r\n }\r\n }\r\n\r\n private renderTab (tab: BaseTabComponent): HTMLElement {\r\n const st = this.status.get(tab)\r\n const style = STATUS_STYLES[st.status]\r\n const active = tab === this.app.activeTab\r\n\r\n const row = document.createElement('div')\r\n row.className = active ? 'ad-tab active' : 'ad-tab'\r\n row.style.setProperty('--ad-color', style.color)\r\n\r\n // [AD:...] 표식은 상태로 이미 반영했으니 제목에서는 지운다\r\n const tabTitle = stripTitleMarker(tab.customTitle || tab.title || '')\r\n // 세 줄은 서로 다른 것을 말한다 —\r\n // 1) 제목: 에이전트가 세션에 붙인 이름. 세션이 사는 동안 거의 안 바뀐다\r\n // (Claude Code 는 시작 때 붙인 콘솔 제목을 계속 들고 있다, 2026-08-28 실측)\r\n // 2) 프롬프트: 마지막으로 보낸 지시. 작업이 넘어갈 때마다 바뀐다\r\n // 3) 상태: 지금 돌고 있는지 / 얼마나 됐는지\r\n // 예전에는 1과 2를 한 줄에 겹쳐 놓느라 둘 중 하나를 못 봤다.\r\n const title = tabTitle || '(제목 없음)'\r\n const elapsed = this.config.store.agentDeck.showElapsed\r\n ? this.formatElapsed(Date.now() - st.since)\r\n : ''\r\n\r\n row.innerHTML = [\r\n '<div class=\"ad-bar\"></div>',\r\n '<div class=\"ad-body\">',\r\n ' <div class=\"ad-title\"></div>',\r\n // 라벨은 더블클릭하면 입력창으로 바뀐다(startLabelEdit) — 그때 줄이 무너지지 않게\r\n // 감싸는 줄을 따로 둔다\r\n ' <div class=\"ad-prompt\"><span class=\"ad-label\"></span></div>',\r\n ' <div class=\"ad-meta\">',\r\n ' <span class=\"ad-badge\"></span>',\r\n ' <span class=\"ad-elapsed\"></span>',\r\n ' </div>',\r\n '</div>',\r\n '<button class=\"ad-close\" title=\"탭 닫기\">&times;</button>',\r\n ].join('\\n')\r\n\r\n // textContent 로만 넣는다 — 탭 제목에 어떤 문자가 와도 마크업으로 해석되지 않게\r\n row.querySelector('.ad-title').textContent = title\r\n const labelEl = row.querySelector('.ad-label')\r\n // 아직 프롬프트가 없어도 줄은 남겨 둔다 — 줄 수가 들쭉날쭉하면 목록이 어지럽고,\r\n // 더블클릭으로 이름을 붙일 자리도 사라진다\r\n labelEl.textContent = st.label || '—'\r\n labelEl.classList.toggle('empty', !st.label)\r\n row.querySelector('.ad-elapsed').textContent = elapsed\r\n const badge = row.querySelector('.ad-badge')\r\n badge.textContent = style.icon + ' ' + style.label\r\n if (st.pinned) {\r\n badge.classList.add('pinned')\r\n }\r\n\r\n row.addEventListener('click', ev => {\r\n if ((ev.target as HTMLElement).closest('.ad-close')) {\r\n return\r\n }\r\n this.zone.run(() => this.app.selectTab(tab))\r\n })\r\n row.addEventListener('dblclick', ev => {\r\n ev.preventDefault()\r\n this.startLabelEdit(row, tab)\r\n })\r\n row.addEventListener('contextmenu', ev => {\r\n ev.preventDefault()\r\n this.showStatusMenu(ev, tab)\r\n })\r\n row.querySelector('.ad-close').addEventListener('click', ev => {\r\n ev.stopPropagation()\r\n this.zone.run(() => { void this.app.closeTab(tab, true) })\r\n })\r\n return row\r\n }\r\n\r\n /** 더블클릭 -> 작업 이름 인라인 편집 */\r\n private startLabelEdit (row: HTMLElement, tab: BaseTabComponent): void {\r\n this.editing = tab\r\n const holder = row.querySelector('.ad-label') as HTMLElement\r\n const input = document.createElement('input')\r\n input.className = 'ad-label-input'\r\n input.value = this.status.get(tab).label\r\n input.placeholder = '작업 이름'\r\n holder.replaceWith(input)\r\n input.focus()\r\n input.select()\r\n\r\n const finish = (commit: boolean) => {\r\n if (this.editing !== tab) {\r\n return\r\n }\r\n this.editing = null\r\n if (commit) {\r\n this.status.setLabel(tab, input.value.trim())\r\n }\r\n this.render()\r\n }\r\n // 터미널로 키가 새지 않도록 이벤트를 여기서 끊는다\r\n input.addEventListener('keydown', ev => {\r\n ev.stopPropagation()\r\n if (ev.key === 'Enter') {\r\n finish(true)\r\n }\r\n if (ev.key === 'Escape') {\r\n finish(false)\r\n }\r\n })\r\n input.addEventListener('blur', () => finish(true))\r\n }\r\n\r\n /** 우클릭 -> 상태 직접 지정 */\r\n private showStatusMenu (ev: MouseEvent, tab: BaseTabComponent): void {\r\n const old = document.querySelector('.ad-menu')\r\n if (old) {\r\n old.remove()\r\n }\r\n const menu = document.createElement('div')\r\n menu.className = 'ad-menu'\r\n\r\n const statuses: WorkStatus[] = ['running', 'waiting', 'done', 'error', 'idle']\r\n const items: Array<[string, () => void]> = statuses.map(s => {\r\n const label = STATUS_STYLES[s].icon + ' ' + STATUS_STYLES[s].label\r\n const action = () => this.status.setManual(tab, s)\r\n return [label, action] as [string, () => void]\r\n })\r\n items.push(['↺ 자동 감지로', () => this.status.unpin(tab)])\r\n // 이 탭만 다시 그리기 — 사이드바 아래 ↻ 는 모든 탭이 대상이라 무거울 때가 있다\r\n items.push(['↻ 화면 복구', () => {\r\n this.app.selectTab(tab)\r\n this.repair('active')\r\n }])\r\n\r\n for (const [label, action] of items) {\r\n const item = document.createElement('div')\r\n item.className = 'ad-menu-item'\r\n item.textContent = label\r\n item.addEventListener('click', () => {\r\n action()\r\n menu.remove()\r\n })\r\n menu.appendChild(item)\r\n }\r\n\r\n document.body.appendChild(menu)\r\n menu.style.left = ev.clientX + 'px'\r\n menu.style.top = Math.min(ev.clientY, window.innerHeight - menu.offsetHeight - 8) + 'px'\r\n\r\n const close = (e: MouseEvent) => {\r\n if (!menu.contains(e.target as Node)) {\r\n menu.remove()\r\n document.removeEventListener('mousedown', close)\r\n }\r\n }\r\n setTimeout(() => document.addEventListener('mousedown', close), 0)\r\n }\r\n\r\n private formatElapsed (ms: number): string {\r\n const s = Math.floor(ms / 1000)\r\n if (s < 60) {\r\n return s + '초'\r\n }\r\n const m = Math.floor(s / 60)\r\n if (m < 60) {\r\n return m + '분'\r\n }\r\n return Math.floor(m / 60) + '시간 ' + (m % 60) + '분'\r\n }\r\n}\r\n","import { Injectable } from '@angular/core'\nimport { AppService, BaseTabComponent, ConfigService } from 'tabby-core'\nimport { TerminalDecorator, BaseTerminalTabComponent, BaseSession } from 'tabby-terminal'\nimport { WorkStatusService } from './status.service'\nimport { applyOutput, forgetOutputBuffer } from './detect'\n\n/**\n * PTY 출력을 훔쳐보며 탭 상태를 추론한다.\n *\n * Tabby 는 프론트엔드(xterm)가 첫 리사이즈를 보고할 때 decorator 를 붙이므로\n * (tabby-terminal/src/api/baseTerminalTab.component.ts:386) 그 시점을 놓친 탭은\n * 여기로 들어오지 않는다. 그 빈틈은 AgentDeckService 의 세션 워처가 메운다.\n */\n@Injectable()\nexport class AgentDeckDecorator extends TerminalDecorator {\n constructor (\n private status: WorkStatusService,\n private config: ConfigService,\n private app: AppService,\n ) {\n super()\n }\n\n /**\n * 상태를 기록할 키를 사이드바가 보는 것과 같은 탭으로 맞춘다.\n *\n * Tabby 는 모든 탭을 SplitTabComponent 로 감싸므로 app.tabs 에 들어있는 것은\n * 그 래퍼이고, decorator 가 받는 것은 그 안의 터미널 탭이다. 정규화하지 않으면\n * 상태를 자식에 쓰고 사이드바는 부모를 읽어 영영 매칭되지 않는다.\n * 분할된 pane 여러 개는 하나의 탭 상태를 공유한다.\n */\n private rootOf (tab: BaseTerminalTabComponent<any>): BaseTabComponent {\n return this.app.getParentTab(tab) ?? tab\n }\n\n attach (tab: BaseTerminalTabComponent<any>): void {\n this.status.debug.attached++\n if (tab.session) {\n this.attachToSession(tab, tab.session)\n }\n this.subscribeUntilDetached(tab, tab.sessionChanged$.subscribe(session => {\n if (session) {\n this.attachToSession(tab, session)\n }\n }))\n }\n\n detach (tab: BaseTerminalTabComponent<any>): void {\n const root = this.rootOf(tab)\n super.detach(tab)\n forgetOutputBuffer(tab)\n // 분할 pane 중 하나만 닫힌 경우라면 탭 상태는 남겨둔다\n if (root === tab || !this.app.tabs.includes(root)) {\n this.status.forget(root)\n }\n }\n\n private attachToSession (tab: BaseTerminalTabComponent<any>, session: BaseSession): void {\n this.subscribeUntilDetached(tab, session.output$.subscribe(data => {\n applyOutput(\n this.status,\n this.rootOf(tab),\n tab,\n data,\n this.config.store.agentDeck.autoDetect,\n )\n }))\n }\n}\n","import { BaseTabComponent } from 'tabby-core'\nimport { WorkStatusService } from './status.service'\nimport { WorkStatus } from './api'\n\n/** 훅이 상태를 직접 통보하는 커스텀 OSC — ESC ] 1337 ; AgentDeck=<status>;<label> BEL */\nconst OSC_RE = /\\x1b\\]1337;AgentDeck=([a-z]+)(?:;([^\\x07\\x1b]*))?(?:\\x07|\\x1b\\\\)/gi\n\n/** Claude Code 등 TUI 가 사용자 입력을 기다릴 때 나타나는 패턴 */\nconst WAITING_RE = [\n /Do you want to\\b/i,\n /❯\\s*1\\.\\s*Yes/,\n /\\(y\\/n\\)/i,\n /\\[y\\/N\\]/i,\n /Press Enter to continue/i,\n]\n\n/**\n * 에이전트가 작업 중일 때만 화면에 내보내는 문구.\n *\n * 상태줄 갱신 같은 평시 출력과 구분하는 근거다 — 이 문구는 일을 붙잡고 있는 동안에만 뜨고\n * 끝나면 사라지므로, 사라진 시점부터 시간을 재면 진행중에서 정확히 내려올 수 있다.\n */\nconst BUSY_RE = [\n /esc to interrupt/i,\n /ctrl\\+c to (?:interrupt|cancel|stop)/i,\n /\\btokens?\\b.{0,20}\\besc\\b/i,\n]\n\nconst VALID: WorkStatus[] = ['idle', 'running', 'waiting', 'done', 'error']\n\n/** OSC 가 청크 경계에 걸리는 것을 막기 위한 잔여 버퍼 */\nconst tails = new WeakMap<object, string>()\n\n/**\n * PTY 출력 한 조각을 보고 탭 상태를 갱신한다.\n *\n * 우선순위: OSC 통보 > 대기 패턴 > \"출력이 있다 = 진행중\".\n * idle 로의 복귀는 사이드바 타이머(tickIdle)가 담당한다.\n *\n * decorator 와 deck 의 세션 워처 양쪽에서 호출된다 — 같은 조각을 두 번 먹어도\n * 결과가 같도록 상태 설정은 모두 멱등하게 만들어 두었다.\n */\nexport function applyOutput (\n status: WorkStatusService,\n root: BaseTabComponent,\n owner: object,\n data: string,\n autoDetect: boolean,\n): void {\n status.debug.outputs++\n status.markOutput(root)\n\n const buf = (tails.get(owner) ?? '') + data\n let matched = false\n let m: RegExpExecArray | null\n // 이미 처리한 OSC 가 어디까지인지 — 그 뒤만 다음 조각으로 넘긴다\n let consumed = 0\n OSC_RE.lastIndex = 0\n while ((m = OSC_RE.exec(buf)) !== null) {\n consumed = OSC_RE.lastIndex\n const s = m[1].toLowerCase() as WorkStatus\n if (VALID.includes(s)) {\n status.setManual(root, s, m[2])\n status.debug.oscHits++\n matched = true\n }\n }\n // 미완성 OSC 가 남아있을 수 있으므로 꼬리만 보관한다.\n // 단 이미 처리한 부분은 반드시 버린다 — 완결된 OSC 가 짧으면 꼬리 안에 통째로 남고,\n // 그러면 다음 출력마다 같은 시퀀스가 또 매치돼 상태가 그 값에 박혀 버린다\n // (2026-09-01, detect 테스트에서 드러남).\n tails.set(owner, buf.slice(Math.max(consumed, buf.length - 256)))\n if (matched || !autoDetect) {\n return\n }\n\n if (WAITING_RE.some(re => re.test(data))) {\n status.setAuto(root, 'waiting')\n return\n }\n\n // 에이전트가 \"지금 일하는 중\" 이라고 스스로 밝히는 표시를 찾는다\n if (BUSY_MARKS.some(mark => data.includes(mark)) || BUSY_RE.some(re => re.test(data))) {\n status.markBusy(root)\n status.setAuto(root, 'running')\n return\n }\n\n // 그 표시를 내는 탭(에이전트 TUI)이라면, 표시가 없는 출력은 진행중의 근거가 아니다.\n // Claude Code 는 놀고 있을 때도 하단 상태줄을 매초 다시 그리기 때문에, 이 갈래가 없으면\n // 사이드바가 영원히 \"진행중\" 에 박혀 있게 된다 (2026-09-01 실측 — 세 탭 모두 진행중).\n if (status.isBusyMode(root)) {\n return\n }\n // 신호를 낼 줄 모르는 보통 셸 — 예전처럼 \"출력이 있다 = 진행중\" 으로 본다\n status.setAuto(root, 'running')\n}\n\nexport function forgetOutputBuffer (owner: object): void {\n tails.delete(owner)\n}\n\n/**\n * 탭 제목에 실려 온 상태 표식 — `[AD:running] 결제 버그 수정` 형태.\n *\n * Windows 에서 이 경로를 쓰는 이유: ConPTY 는 자기가 모르는 OSC 를 삼켜서\n * 커스텀 이스케이프가 PTY 스트림까지 오지 못한다(2026-08-28 실측 — 출력에 남은 건\n * 입력 에코뿐이었다). 반면 콘솔 제목은 ConPTY 가 API 로 변환해 전달하므로 확실히 통과한다.\n */\nconst TITLE_RE = /\\[AD:([a-z]+)\\]\\s*(.*)$/i\n\n/**\n * Claude Code 가 작업 중일 때 제목에 넣는 표식.\n * 별 모양과 원형 스피너 두 계열을 모두 쓴다 (2026-08-28 실측: \"◐ WindowTitle 설정\").\n */\nconst BUSY_MARKS = ['✳', '✻', '✽', '✶', '✢', '◐', '◓', '◑', '◒']\n\nexport function stripTitleMarker (title: string): string {\n return title.replace(/\\[AD:[a-z]+\\]\\s*/i, '')\n}\n\nexport function applyTitle (\n status: WorkStatusService,\n root: BaseTabComponent,\n title: string,\n autoDetect: boolean,\n): void {\n const m = TITLE_RE.exec(title)\n if (m) {\n const s = m[1].toLowerCase() as WorkStatus\n if (VALID.includes(s)) {\n status.setManual(root, s, m[2].trim())\n status.debug.titleHits++\n return\n }\n }\n // 명시 표식이 없으면 Claude Code 의 작업중 표식이라도 읽는다\n if (autoDetect && BUSY_MARKS.some(mark => title.includes(mark))) {\n status.setAuto(root, 'running')\n }\n}\n","/**\n * 사이드바를 마우스로 조절하는 부분 — 경계선 드래그로 크기, 헤더 드래그로 붙는 방향.\n *\n * 설정 창에서 숫자를 넣게 하지 않고 Visual Studio 의 도킹처럼 직접 끌어서 맞추게 한다.\n * DOM 을 직접 만지는 코드라 deck.service 밖으로 빼 두고, 값을 읽고 쓰는 통로만\n * `DockHost` 로 받는다 (deck.service 가 config 와 relayout 을 쥐고 있으므로).\n */\n\nexport type DockSide = 'left' | 'right' | 'top' | 'bottom'\n\nexport const DOCK_SIDES: DockSide[] = ['left', 'right', 'top', 'bottom']\n\nexport function isDockSide (v: any): v is DockSide {\n return DOCK_SIDES.includes(v)\n}\n\n/** 좌/우 도킹이면 폭, 상/하 도킹이면 높이를 다룬다 */\nexport function isHorizontalDock (side: DockSide): boolean {\n return side === 'left' || side === 'right'\n}\n\nexport interface DockHost {\n /** 사이드바 엘리먼트 */\n sidebar: HTMLElement\n /** 사이드바가 얹혀 있는 `.window` */\n windowEl: HTMLElement\n getDock (): DockSide\n setDock (side: DockSide): void\n /**\n * 그 방향으로 붙였을 때의 크기 — 좌/우면 폭, 상/하면 높이.\n * 방향마다 저장된 값이 다르므로 미리보기도 물어보는 방향 기준으로 그린다.\n */\n getSize (side: DockSide): number\n setSize (px: number): void\n /** 드래그가 끝났을 때 한 번 — config.save() 를 부르라는 뜻 */\n commit (): void\n /** 값이 바뀌었으니 다시 그리라는 뜻 */\n relayout (): void\n}\n\n/** 드래그로 오해하지 않을 최소 이동 거리 (px) */\nconst DRAG_THRESHOLD = 5\n/** 존 버튼 밖에서 놓았을 때 가장자리로 인정하는 여백 비율 */\nconst EDGE_RATIO = 0.25\n\nexport class DockController {\n private handle: HTMLElement | null = null\n private overlay: HTMLElement | null = null\n private preview: HTMLElement | null = null\n private zones = new Map<DockSide, HTMLElement>()\n\n private resizing = false\n private dragging = false\n private dragArmed = false\n private dragFrom = { x: 0, y: 0 }\n private hoverSide: DockSide | null = null\n\n constructor (private host: DockHost) { }\n\n /** 사이드바가 만들어진 뒤 한 번 부른다 */\n install (): void {\n this.installResizeHandle()\n this.installDockDrag()\n }\n\n /** 도킹 방향이 바뀌면 핸들 위치도 반대편으로 옮겨야 한다 */\n syncHandle (): void {\n if (!this.handle) {\n return\n }\n const side = this.host.getDock()\n this.handle.className = 'ad-resize ad-resize-' + side\n }\n\n // ---------- 경계선 드래그 (크기) ----------\n\n private installResizeHandle (): void {\n const handle = document.createElement('div')\n handle.className = 'ad-resize'\n this.host.sidebar.appendChild(handle)\n this.handle = handle\n this.syncHandle()\n\n handle.addEventListener('pointerdown', (ev: PointerEvent) => {\n // 왼쪽 버튼만\n if (ev.button !== 0) {\n return\n }\n ev.preventDefault()\n ev.stopPropagation()\n this.resizing = true\n handle.setPointerCapture(ev.pointerId)\n document.body.classList.add('ad-resizing')\n })\n\n handle.addEventListener('pointermove', (ev: PointerEvent) => {\n if (!this.resizing) {\n return\n }\n const side = this.host.getDock()\n const rect = this.host.windowEl.getBoundingClientRect()\n // 커서와 창 가장자리 사이의 거리가 곧 사이드바 크기다\n let size: number\n if (side === 'right') {\n size = rect.right - ev.clientX\n } else if (side === 'left') {\n size = ev.clientX - rect.left\n } else if (side === 'bottom') {\n size = rect.bottom - ev.clientY\n } else {\n size = ev.clientY - rect.top\n }\n this.host.setSize(Math.round(size))\n this.host.relayout()\n })\n\n const end = (ev: PointerEvent) => {\n if (!this.resizing) {\n return\n }\n this.resizing = false\n try {\n handle.releasePointerCapture(ev.pointerId)\n } catch {\n // 이미 놓쳤다 — 무시해도 상태는 위에서 정리됐다\n }\n document.body.classList.remove('ad-resizing')\n this.host.commit()\n }\n handle.addEventListener('pointerup', end)\n handle.addEventListener('pointercancel', end)\n }\n\n // ---------- 헤더 드래그 (도킹 방향) ----------\n\n private installDockDrag (): void {\n const head = this.host.sidebar.querySelector('.ad-head') as HTMLElement | null\n if (!head) {\n return\n }\n\n head.addEventListener('pointerdown', (ev: PointerEvent) => {\n if (ev.button !== 0) {\n return\n }\n // 헤더 안의 버튼류를 누른 것이면 건드리지 않는다\n if ((ev.target as HTMLElement).closest('button, input')) {\n return\n }\n this.dragArmed = true\n this.dragFrom = { x: ev.clientX, y: ev.clientY }\n head.setPointerCapture(ev.pointerId)\n })\n\n head.addEventListener('pointermove', (ev: PointerEvent) => {\n if (!this.dragArmed) {\n return\n }\n if (!this.dragging) {\n const dx = ev.clientX - this.dragFrom.x\n const dy = ev.clientY - this.dragFrom.y\n if (Math.hypot(dx, dy) < DRAG_THRESHOLD) {\n return\n }\n // 여기서부터 도킹 드래그다 — 가이드를 띄운다\n this.dragging = true\n this.showOverlay()\n }\n this.updateHover(ev.clientX, ev.clientY)\n })\n\n const end = (ev: PointerEvent) => {\n if (!this.dragArmed) {\n return\n }\n this.dragArmed = false\n try {\n head.releasePointerCapture(ev.pointerId)\n } catch {\n // 무시\n }\n if (!this.dragging) {\n return\n }\n this.dragging = false\n const side = this.hoverSide\n this.hideOverlay()\n if (side && side !== this.host.getDock()) {\n this.host.setDock(side)\n this.host.relayout()\n this.syncHandle()\n this.host.commit()\n }\n }\n head.addEventListener('pointerup', end)\n head.addEventListener('pointercancel', end)\n }\n\n // ---------- 드롭 가이드 ----------\n\n private showOverlay (): void {\n if (this.overlay) {\n return\n }\n const overlay = document.createElement('div')\n overlay.className = 'ad-dock-overlay'\n\n const preview = document.createElement('div')\n preview.className = 'ad-dock-preview'\n overlay.appendChild(preview)\n\n for (const side of DOCK_SIDES) {\n const zone = document.createElement('div')\n zone.className = 'ad-dock-zone ad-dock-zone-' + side\n zone.innerHTML = '<span class=\"ad-dock-mark\"></span>'\n overlay.appendChild(zone)\n this.zones.set(side, zone)\n }\n\n document.body.appendChild(overlay)\n this.overlay = overlay\n this.preview = preview\n this.positionZones()\n }\n\n /** 존 버튼을 `.window` 네 가장자리 안쪽에 놓는다 (창이 전체화면이 아닐 수도 있으므로 매번 잰다) */\n private positionZones (): void {\n const rect = this.host.windowEl.getBoundingClientRect()\n const cx = rect.left + rect.width / 2\n const cy = rect.top + rect.height / 2\n const inset = 56\n const place: Record<DockSide, [number, number]> = {\n left: [rect.left + inset, cy],\n right: [rect.right - inset, cy],\n top: [cx, rect.top + inset],\n bottom: [cx, rect.bottom - inset],\n }\n for (const side of DOCK_SIDES) {\n const zone = this.zones.get(side)\n if (!zone) {\n continue\n }\n const [x, y] = place[side]\n zone.style.left = x + 'px'\n zone.style.top = y + 'px'\n }\n }\n\n /** 커서 위치로 어느 쪽에 붙일지 정하고 미리보기를 그린다 */\n private updateHover (x: number, y: number): void {\n const side = this.hitTest(x, y)\n if (side !== this.hoverSide) {\n this.hoverSide = side\n for (const [s, zone] of this.zones) {\n zone.classList.toggle('active', s === side)\n }\n }\n this.drawPreview(side)\n }\n\n /**\n * 존 버튼 위에 있으면 그쪽, 아니면 커서가 창의 어느 가장자리 띠에 들어와 있는지로 정한다.\n * 가운데에 있으면 null — 놓아도 아무 일이 없다.\n */\n private hitTest (x: number, y: number): DockSide | null {\n for (const [side, zone] of this.zones) {\n const r = zone.getBoundingClientRect()\n if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom) {\n return side\n }\n }\n const rect = this.host.windowEl.getBoundingClientRect()\n const dx = (x - rect.left) / rect.width\n const dy = (y - rect.top) / rect.height\n if (dx < EDGE_RATIO && dx <= dy && dx <= 1 - dy) {\n return 'left'\n }\n if (dx > 1 - EDGE_RATIO && 1 - dx <= dy && 1 - dx <= 1 - dy) {\n return 'right'\n }\n if (dy < EDGE_RATIO) {\n return 'top'\n }\n if (dy > 1 - EDGE_RATIO) {\n return 'bottom'\n }\n return null\n }\n\n /** 놓으면 사이드바가 어디에 얼마만큼 자리잡는지 반투명 박스로 미리 보여준다 */\n private drawPreview (side: DockSide | null): void {\n if (!this.preview) {\n return\n }\n if (!side) {\n this.preview.style.display = 'none'\n return\n }\n const rect = this.host.windowEl.getBoundingClientRect()\n const horizontal = isHorizontalDock(side)\n // 방향마다 기억된 크기가 다르다 — 지금 붙어 있는 쪽이 아니라 놓으려는 쪽 값을 물어본다\n const current = this.host.getSize(side)\n const size = horizontal\n ? Math.min(Math.max(current || 320, 180), rect.width * 0.6)\n : Math.min(Math.max(current || 200, 120), rect.height * 0.6)\n\n const s = this.preview.style\n s.display = 'block'\n s.left = (side === 'right' ? rect.right - size : rect.left) + 'px'\n s.top = (side === 'bottom' ? rect.bottom - size : rect.top) + 'px'\n s.width = (horizontal ? size : rect.width) + 'px'\n s.height = (horizontal ? rect.height : size) + 'px'\n }\n\n private hideOverlay (): void {\n this.overlay?.remove()\n this.overlay = null\n this.preview = null\n this.zones.clear()\n this.hoverSide = null\n }\n}\n","import { Injectable } from '@angular/core'\nimport { HotkeyDescription, HotkeyProvider } from 'tabby-core'\n\n/**\n * 핫키 \"선언\"만 한다.\n *\n * 여기서 HotkeysService 를 주입하면 안 된다 — HotkeysService 자신이\n * HotkeyProvider 목록을 주입받으므로(tabby-core/src/services/hotkeys.service.ts:85)\n * 순환 의존이 되어 부분 초기화된 인스턴스가 넘어온다.\n * 실제 핫키 처리는 AgentDeckService 에서 구독한다.\n */\n@Injectable()\nexport class AgentDeckHotkeyProvider extends HotkeyProvider {\n async provide (): Promise<HotkeyDescription[]> {\n return [\n {\n id: 'agentdeck-toggle',\n name: 'AgentDeck 사이드바 / 4:3 전환',\n },\n {\n id: 'agentdeck-newline',\n name: 'AgentDeck 줄바꿈 (Ctrl+Enter / Shift+Enter, 0x0A 전송)',\n },\n {\n id: 'agentdeck-paste',\n name: 'AgentDeck 붙여넣기 (텍스트는 그대로, 이미지는 Alt+V 로 위임)',\n },\n {\n id: 'agentdeck-repair',\n name: 'AgentDeck 화면 복구 (깨진 TUI 다시 그리기)',\n },\n ]\n }\n}\n","import { Injectable } from '@angular/core'\r\nimport { AppService, BaseTabComponent, ConfigService, PlatformService } from 'tabby-core'\r\nimport * as fs from 'fs'\r\nimport * as net from 'net'\r\nimport * as os from 'os'\r\nimport * as path from 'path'\r\nimport { WorkStatusService } from './status.service'\r\nimport { WorkStatus } from './api'\r\nimport { claudeSettingsPath, hooksInstalled, hooksSupported, installHooks } from './claudeHooks'\r\nimport { pickTabByPids } from './bind'\r\n\r\nconst DIAG_PATH = path.join(os.homedir(), '.agentdeck-diag.log')\r\n\r\n/** 훅이 남기는 파일 하나의 내용 */\r\ninterface NotifyFile {\r\n sessionId: string\r\n /** 없으면 지금 상태를 유지한다 (라벨만 바꾸는 보고) */\r\n status?: WorkStatus\r\n /** 없으면 지금 라벨을 유지한다 (상태만 바꾸는 보고) */\r\n label?: string\r\n /** 훅이 쓴 시각 (epoch ms) — 같은 값을 두 번 적용하지 않기 위한 판별자 */\r\n ts: number\r\n /**\r\n * 훅 프로세스의 조상 PID — claude.exe 부터 위로(탭 셸, Tabby.exe …).\r\n * 어느 탭의 보고인지 이걸로 확정한다 (bind.ts). 없으면 옛 훅이거나 셸에서 사람이 부른 것\r\n */\r\n pids?: number[]\r\n}\r\n\r\n/**\r\n * 에이전트 훅 -> 사이드바 상태 채널. **기본으로 켜져 있다** (`notifyChannel`).\r\n *\r\n * 이쪽이 상태의 정확한 원천이다 — 에이전트가 \"지시를 받았다 / 승인을 기다린다 / 끝났다\" 를\r\n * 직접 알려준다. 출력 패턴으로 추측하는 경로(detect.ts)는 훅이 없는 환경을 위한 폴백이고,\r\n * TUI 가 화면을 어떻게 그리는지에 기대는 만큼 흔들린다 (2026-09-01: Claude Code 가 놀 때도\r\n * 상태줄을 매초 갱신해 진행중이 안 풀렸다).\r\n *\r\n * 훅은 Claude Code 쪽 설정에 있어야 해서 플러그인 설치만으로는 걸리지 않는다. 그래서\r\n * 기동할 때 한 번 물어보고(promptHooksOnce), 설정 창에도 설치 버튼을 둔다(claudeHooks.ts).\r\n *\r\n * 왜 파일인가 — 콘솔 제목 방식(`hooks/agentdeck-status.ps1`)은 **훅에서는 통하지 않는다**.\r\n * Claude Code 는 훅을 파이프 stdio 로 띄우기 때문에 그 자식 프로세스는 터미널의 콘솔에\r\n * 붙어 있지 않고, 제목을 바꿔도 pty 까지 오지 않는다 (2026-08-28 실측: 훅으로\r\n * `[AD:waiting] ...` 을 걸어도 사이드바가 그대로였다). 셸 안에서 직접 실행할 때는\r\n * 제목 방식이 여전히 유효하므로 그 경로는 남겨 둔다.\r\n *\r\n * 전달 경로는 두 가닥이다.\r\n *\r\n * 1. **TCP (기본)** — 이쪽이 `127.0.0.1` 임의 포트로 듣고, 실제 포트를\r\n * `%LOCALAPPDATA%\\tabby-agentdeck\\port` 에 적어 둔다. 훅은 그 포트로 JSON 한 줄을\r\n * 보내고 끊는다. 폴링 지연이 없고 상태 파일도 남지 않는다.\r\n * 2. **파일 (폴백)** — TCP 연결이 안 되면(Tabby 미기동, 포트 파일 없음, 방화벽)\r\n * 훅이 `...\\status\\<sessionId>.json` 에 쓰고 이쪽이 400ms 마다 읽는다.\r\n *\r\n * 두 경로 모두 `apply()` 로 모이고, `applied` 의 ts 대조가 중복 적용을 막으므로\r\n * 같은 보고가 양쪽으로 들어와도 결과는 같다.\r\n *\r\n * 세션 -> 탭 매칭: 어떤 Claude 세션이 **처음** 보고할 때의 활성 탭에 묶는다.\r\n * 사용자가 프롬프트를 넣은 탭이 곧 활성 탭이므로 이 규칙이면 탭이 여러 개여도 맞다.\r\n * 한 번 묶으면 그 뒤로는 활성 탭이 바뀌어도 같은 탭을 따라간다.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class WorkNotifyService {\r\n private root = path.join(\r\n process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'),\r\n 'tabby-agentdeck',\r\n )\r\n private dir = path.join(this.root, 'status')\r\n /** 훅이 접속할 포트를 알려주는 파일 */\r\n private portFile = path.join(this.root, 'port')\r\n private server: net.Server | null = null\r\n private sessionTab = new Map<string, BaseTabComponent>()\r\n /** 역방향 — 한 탭을 두 세션이 나눠 쓰지 못하게 막는다 */\r\n private tabSession = new Map<BaseTabComponent, string>()\r\n /** 이미 적용한 (sessionId -> ts) — 같은 파일을 반복 적용하지 않는다 */\r\n private applied = new Map<string, number>()\r\n private timer: any = null\r\n /** 폴링을 시작한 시각 — 이보다 오래된 파일은 지난 실행의 잔재다 */\r\n private startedAt = 0\r\n /**\r\n * 탭(루트) -> 그 안 패널들의 셸 PID. 훅이 보낸 조상 PID 와 맞춰 어느 탭의 보고인지 확정한다.\r\n * pty 에 물어보는 비동기 작업이라 표로 들고 있고, 탭이 열릴 때와 2초마다 새로 채운다\r\n */\r\n private tabPids = new Map<BaseTabComponent, number[]>()\r\n private pidRefreshing = false\r\n private pollCount = 0\r\n /** 같은 매칭 실패를 폴링마다 diag 에 찍지 않기 위한 마지막 메시지 */\r\n private lastBindLog = new Map<string, string>()\r\n\r\n constructor (\r\n private app: AppService,\r\n private config: ConfigService,\r\n private status: WorkStatusService,\r\n private platform: PlatformService,\r\n ) { }\r\n\r\n /**\r\n * 훅이 안 걸려 있으면 기동할 때 한 번 물어본다.\r\n *\r\n * 훅은 Claude Code 쪽 설정(`~/.claude/settings.json`)에 있어야 해서 플러그인을 설치하는 것만으로는\r\n * 걸리지 않는다. 그렇다고 말없이 남의 설정을 고칠 수는 없으니, 한 번 묻고 고른 대로 한다.\r\n * \"다시 묻지 않기\" 를 고르면 그 뒤로는 조용하고, 설정 창의 설치 버튼은 언제든 그대로 쓸 수 있다.\r\n */\r\n private async promptHooksOnce (): Promise<void> {\r\n const cfg = this.config.store.agentDeck\r\n if (cfg.hookPromptDismissed || !hooksSupported()) {\r\n return\r\n }\r\n try {\r\n if (hooksInstalled()) {\r\n return\r\n }\r\n } catch {\r\n // 설정을 못 읽었다 — 그 상태로 남의 파일을 고치자고 권할 수는 없다\r\n return\r\n }\r\n\r\n const r = await this.platform.showMessageBox({\r\n // 이 타입에는 'question' 이 없다 (tabby-core MessageBoxOptions) — 경고로 띄우면\r\n // 필요 이상으로 겁을 주므로 'warning' 대신 형만 맞추고 문구로 성격을 드러낸다\r\n type: 'warning',\r\n message: 'AgentDeck — Claude Code 상태 통보를 연결할까요?',\r\n detail: [\r\n '연결하면 에이전트가 \"지시를 받았다 / 승인을 기다린다 / 끝났다\" 를 사이드바에 직접 알려줍니다.',\r\n '연결하지 않아도 동작은 하지만, 화면에 그려진 글자를 보고 추측하는 방식이라 상태가 부정확할 수 있습니다.',\r\n '',\r\n `설치 위치: ${claudeSettingsPath()}`,\r\n '기존 훅은 건드리지 않고, 쓰기 전에 같은 폴더에 백업을 남깁니다. 설정 창에서 언제든 제거할 수 있습니다.',\r\n ].join('\\n'),\r\n buttons: ['연결한다', '나중에', '다시 묻지 않기'],\r\n defaultId: 0,\r\n cancelId: 1,\r\n })\r\n\r\n if (r.response === 0) {\r\n try {\r\n installHooks()\r\n if (!cfg.notifyChannel) {\r\n cfg.notifyChannel = true\r\n }\r\n this.config.save()\r\n } catch (e: any) {\r\n await this.platform.showMessageBox({\r\n type: 'error',\r\n message: 'AgentDeck — 훅을 설치하지 못했습니다.',\r\n detail: `${e?.message ?? e}`,\r\n buttons: ['확인'],\r\n })\r\n }\r\n return\r\n }\r\n if (r.response === 2) {\r\n cfg.hookPromptDismissed = true\r\n this.config.save()\r\n }\r\n }\r\n\r\n init (): void {\r\n this.app.ready$.subscribe(() => {\r\n // 훅이 안 걸려 있으면 기동할 때 한 번 물어본다. 통로만 열려 있고 보고자가 없으면\r\n // 아무 일도 일어나지 않는데, 사용자 눈에는 그냥 \"상태가 이상하다\" 로만 보인다.\r\n // 기동 직후는 화면이 정신없으니 조금 뒤에 띄운다\r\n setTimeout(() => { void this.promptHooksOnce() }, 3000)\r\n\r\n // 채널이 닫혀 있으면 훅이 보낸 보고가 어디에도 닿지 않는다.\r\n // 기본은 열려 있고, 비용은 유휴 포트 하나와 400ms 폴링뿐이다\r\n if (!this.config.store.agentDeck.notifyChannel) {\r\n return\r\n }\r\n this.startedAt = Date.now()\r\n this.listen()\r\n this.timer = setInterval(() => this.poll(), 400)\r\n void this.refreshPids()\r\n })\r\n // 새 탭의 셸 PID 는 세션이 붙은 뒤에야 나온다 — 조금 뒤에 한 번 더 채운다 (2초 주기 폴링도 있다)\r\n this.app.tabOpened$.subscribe(() => {\r\n setTimeout(() => { void this.refreshPids() }, 1500)\r\n })\r\n // 탭이 닫히면 점유를 풀어야 그 자리를 다음 세션이 쓸 수 있다\r\n this.app.tabClosed$.subscribe(tab => {\r\n this.tabPids.delete(tab)\r\n const sid = this.tabSession.get(tab)\r\n if (sid) {\r\n this.tabSession.delete(tab)\r\n this.sessionTab.delete(sid)\r\n }\r\n })\r\n }\r\n\r\n /** 진단 한 줄 — deck.service 와 같은 파일(`~/.agentdeck-diag.log`)에 남긴다 */\r\n private diag (line: string): void {\r\n try {\r\n fs.appendFileSync(DIAG_PATH, `${new Date().toISOString()} ${line}\\n`)\r\n } catch {\r\n // 진단일 뿐이다\r\n }\r\n }\r\n\r\n private tabName (tab: BaseTabComponent): string {\r\n const anyTab = tab as any\r\n return JSON.stringify(String(anyTab.customTitle || anyTab.title || '').slice(0, 40))\r\n }\r\n\r\n /**\r\n * 탭별 셸 PID 표를 새로 채운다. 로컬 pty 는 `session.pty.getPID()` 로 셸 PID 를 준다\r\n * (tabby-local Session — gracefullyKillProcess 가 쓰는 그 경로). SSH 등 PID 가 없는 탭은 빈 목록.\r\n */\r\n private async refreshPids (): Promise<void> {\r\n if (this.pidRefreshing) {\r\n return\r\n }\r\n this.pidRefreshing = true\r\n try {\r\n for (const root of [...this.app.tabs]) {\r\n const anyRoot = root as any\r\n const panes: any[] = typeof anyRoot.getAllTabs === 'function' ? anyRoot.getAllTabs() : [root]\r\n const pids: number[] = []\r\n for (const pane of panes) {\r\n const pty = pane?.session?.pty\r\n if (!pty || typeof pty.getPID !== 'function') {\r\n continue\r\n }\r\n try {\r\n const pid = await pty.getPID()\r\n if (Number.isInteger(pid) && pid > 0) {\r\n pids.push(pid)\r\n }\r\n } catch {\r\n // 세션이 닫히는 중이다\r\n }\r\n }\r\n const prev = this.tabPids.get(root)\r\n if (!prev || prev.join(',') !== pids.join(',')) {\r\n this.tabPids.set(root, pids)\r\n this.diag(`pid-map tab=${this.tabName(root)} pids=[${pids.join(',')}]`)\r\n }\r\n }\r\n } finally {\r\n this.pidRefreshing = false\r\n }\r\n }\r\n\r\n /** 진단용 */\r\n get debugDir (): string { return this.dir }\r\n /** 진단용 — 듣고 있는 포트 (0 = TCP 채널이 안 떴다) */\r\n get debugPort (): number {\r\n const addr = this.server?.address()\r\n return addr && typeof addr === 'object' ? addr.port : 0\r\n }\r\n\r\n /**\r\n * 훅이 상태를 바로 밀어 넣을 TCP 채널을 연다.\r\n *\r\n * 기본은 `agentDeck.notifyPort` 고정 포트다 — 번호가 늘 같아야 훅이나 진단 도구가\r\n * 바로 붙을 수 있다. Windows 임시 포트 범위(49152~65535) 아래로 잡아 두어야\r\n * OS 가 그 번호를 다른 프로세스에 먼저 내주는 일이 없다.\r\n *\r\n * 그 번호가 이미 물려 있으면(Tabby 두 개, 다른 프로그램) 0 으로 다시 시도한다 —\r\n * OS 가 빈 포트를 골라 준다. 어느 쪽이든 실제 번호는 port 파일에 적어 두므로\r\n * 훅은 고정/임의를 구분할 필요가 없다. 둘 다 실패해도 파일 폴백이 살아 있다.\r\n */\r\n private listen (): void {\r\n const server = net.createServer(socket => {\r\n let buf = ''\r\n socket.setEncoding('utf8')\r\n socket.on('data', chunk => {\r\n buf += chunk\r\n // 훅이 여러 건을 몰아 보낼 수도 있으니 줄 단위로 끊어 처리한다\r\n let nl: number\r\n while ((nl = buf.indexOf('\\n')) >= 0) {\r\n const line = buf.slice(0, nl)\r\n buf = buf.slice(nl + 1)\r\n this.accept(line)\r\n }\r\n })\r\n // 개행 없이 끊는 훅도 받아 준다\r\n socket.on('end', () => this.accept(buf))\r\n socket.on('error', () => { /* 훅이 먼저 끊어도 Tabby 가 죽으면 안 된다 */ })\r\n })\r\n let fellBack = false\r\n server.on('error', () => {\r\n if (!fellBack) {\r\n // 고정 포트가 물려 있다 — OS 가 골라 주는 번호로 한 번 더 시도한다\r\n fellBack = true\r\n server.listen(0, '127.0.0.1')\r\n return\r\n }\r\n this.server = null\r\n // 지난 실행의 포트 번호를 남겨 두면 훅이 그 번호로 접속을 시도한다.\r\n // 그 사이 다른 프로그램이 같은 번호를 잡았다면 엉뚱한 곳으로 JSON 을 쏘게 되므로 지운다\r\n try {\r\n fs.unlinkSync(this.portFile)\r\n } catch {\r\n // 이미 없으면 그만이다\r\n }\r\n })\r\n server.on('listening', () => {\r\n this.server = server\r\n try {\r\n fs.mkdirSync(this.root, { recursive: true })\r\n fs.writeFileSync(this.portFile, String(this.debugPort), 'utf8')\r\n } catch {\r\n // 포트를 못 알리면 훅은 파일 경로로 떨어진다\r\n }\r\n })\r\n server.listen(this.config.store.agentDeck.notifyPort || 0, '127.0.0.1')\r\n }\r\n\r\n /** TCP 로 들어온 JSON 한 줄 */\r\n private accept (line: string): void {\r\n const text = line.trim()\r\n if (!text) {\r\n return\r\n }\r\n try {\r\n this.apply(JSON.parse(text))\r\n } catch {\r\n // 깨진 줄은 버린다 — 다음 보고가 곧 온다\r\n }\r\n }\r\n\r\n private poll (): void {\r\n // 셸 PID 표는 2초마다 — 탭 안에서 셸을 다시 띄우거나 분할하면 바뀐다\r\n if (++this.pollCount % 5 === 0) {\r\n void this.refreshPids()\r\n }\r\n let names: string[]\r\n try {\r\n names = fs.readdirSync(this.dir)\r\n } catch {\r\n return // 폴더 없음 = 훅이 아직 한 번도 안 돌았다\r\n }\r\n for (const name of names) {\r\n if (!name.endsWith('.json')) {\r\n continue\r\n }\r\n const full = path.join(this.dir, name)\r\n let data: NotifyFile\r\n try {\r\n data = JSON.parse(fs.readFileSync(full, 'utf8'))\r\n } catch {\r\n continue // 훅이 쓰는 중 — 다음 폴링에서 다시 읽는다\r\n }\r\n\r\n // 지난 Tabby 실행 때 남은 파일 — 이걸 읽으면 죽은 세션들이 전부 \"지금 활성 탭\" 에\r\n // 묶여 버려서(resolveTab 규칙) 실제 세션이 엉뚱한 탭에 붙는다. 실제로 완료된 세션의\r\n // done 이 작업 중인 탭에 찍히는 증상이 이것이었다 (2026-08-28 실측). 읽지 말고 지운다\r\n if (data.ts < this.startedAt && !this.sessionTab.has(data.sessionId)) {\r\n try {\r\n fs.unlinkSync(full)\r\n } catch {\r\n // 지우기 실패해도 아래 apply 를 타지 않으므로 해는 없다\r\n }\r\n continue\r\n }\r\n\r\n this.apply(data)\r\n }\r\n }\r\n\r\n /**\r\n * 보고 한 건을 반영한다. `status` / `label` 은 **각각 선택**이고, 빠진 쪽은 지금 값을 유지한다.\r\n *\r\n * 병합 규칙을 여기(플러그인)에 둔 이유 — 예전에는 훅 스크립트가 status 파일을 읽어\r\n * 직전 값과 합친 뒤 다시 쓰는 read-modify-write 를 했다. 그러면 진짜 상태가 파일과\r\n * 플러그인 메모리 두 곳에 살고 병합 규칙이 PowerShell 안에 숨는다. 라벨만 바꾸려 해도\r\n * 직전 status 를 채워 넣어야 했고(안 채우면 여기서 통째로 버려졌다), 파일이 밀리면\r\n * 표시가 어긋났다. 보내는 쪽은 \"자기가 아는 것만\" 보내고 합치는 건 상태를 실제로\r\n * 들고 있는 이쪽이 한다 — 그래야 어느 경로로 들어오든 결과가 같다.\r\n */\r\n private apply (data: NotifyFile): void {\r\n if (!data || !data.sessionId) {\r\n return\r\n }\r\n const hasStatus = !!data.status\r\n const hasLabel = typeof data.label === 'string' && !!data.label.trim()\r\n if (!hasStatus && !hasLabel) {\r\n return\r\n }\r\n if (this.applied.get(data.sessionId) === data.ts) {\r\n return\r\n }\r\n\r\n const tab = this.resolveTab(data.sessionId, data.pids)\r\n if (!tab) {\r\n // pids 없는 보고(옛 훅·수동 호출)는 다시 봐도 결과가 같다. 그런데 폴링이 400ms 마다\r\n // 되풀이하면 \"활성 탭에 묶는다\" 규칙이 다음에 열리는 빈 탭을 붙잡는다 — 끝난 세션의\r\n // done 이 새 탭에 박히고, 그 탭의 진짜 세션은 주인이 있다며 거절됐다 (2026-09-02 실측).\r\n // 적용한 것으로 쳐서 멈춘다. 다음 보고(새 ts)가 오면 그때 다시 시도한다.\r\n // pids 가 있는 보고는 탭 PID 표가 채워지면 맞을 수 있으니 다음 폴링에 다시 본다.\r\n if (!data.pids?.length) {\r\n this.applied.set(data.sessionId, data.ts)\r\n }\r\n return\r\n }\r\n this.applied.set(data.sessionId, data.ts)\r\n\r\n const label = (data.label || '').trim()\r\n if (hasStatus) {\r\n // 라벨이 안 왔으면 undefined 를 넘겨 기존 라벨을 지키게 한다 (setManual 규약)\r\n this.status.setManual(tab, data.status!, hasLabel ? label : undefined)\r\n } else {\r\n // 라벨만 온 보고 — 상태도 고정 여부도 건드리지 않는다\r\n this.status.setLabel(tab, label)\r\n }\r\n\r\n // 탭 제목(customTitle)은 건드리지 않는다.\r\n // 제목을 라벨 원천으로 쓸 수 있는지 보려고 한동안 비워 뒀고, 판정은 났다 —\r\n // Claude Code 는 세션 첫 작업을 요약해 제목에 한 번 박고 그 뒤로 갱신하지 않는다.\r\n // 그래서 라벨은 Enter 시점 입력창에서 직접 읽고(claimEnterLabel), 사이드바는\r\n // 제목과 그 라벨을 각자 줄에 나눠 그린다(renderTab). 여기서 제목을 덮어쓸 이유가 없다.\r\n }\r\n\r\n /**\r\n * 세션에 묶인 탭을 찾는다.\r\n *\r\n * 1순위는 **프로세스 계보**다 — 훅이 보낸 조상 PID(claude.exe → 탭 셸 → Tabby) 에 어떤 탭의\r\n * 셸 PID 가 들어 있으면 그 탭이다(bind.ts). 이미 다른 세션이 그 탭을 갖고 있어도 넘겨받는다:\r\n * 같은 탭에서 claude 를 다시 띄우면 세션 id 가 바뀌는 게 정상이고, 이전 주인은 이미 죽은 세션이다.\r\n * 알던 탭과 다른 탭이 맞으면 옮긴다 (`claude --resume` 을 다른 탭에서 띄운 경우).\r\n *\r\n * pids 가 왔는데 맞는 탭이 없으면 **추측하지 않고** null 이다 — 탭 PID 표가 아직 안 채워진 것일 수\r\n * 있고, 그 경우 다음 폴링(400ms)에 다시 온다. 활성 탭으로 떨어지던 예전 규칙이 낸 사고가\r\n * \"끝난 세션의 done 이 새 탭에 박힘\" 이었다 (2026-09-02 실측).\r\n *\r\n * pids 가 없는 보고(옛 훅·셸에서 사람이 부른 것)만 예전 규칙을 탄다 — 처음 보는 세션이면 지금 활성 탭.\r\n * 단 그 탭을 이미 다른 세션이 점유했으면 묶지 않는다 (여러 세션이 한 탭에 겹쳐 붙어 서로의\r\n * 상태를 덮어쓰던 2026-08-28 사고의 방지책).\r\n */\r\n private resolveTab (sessionId: string, pids?: number[]): BaseTabComponent | null {\r\n const known = this.sessionTab.get(sessionId)\r\n const alive = known && this.app.tabs.includes(known) ? known : null\r\n\r\n const pick = pickTabByPids(pids, this.tabPids)\r\n if (pick.mode === 'pid' && pick.tab) {\r\n if (pick.tab !== alive) {\r\n this.bind(sessionId, pick.tab, alive ? 'pid-move' : 'pid')\r\n }\r\n return pick.tab\r\n }\r\n if (alive) {\r\n return alive\r\n }\r\n if (pick.mode === 'pid-miss') {\r\n const table = [...this.tabPids.entries()]\r\n .map(([tab, list]) => `${this.tabName(tab)}:[${list.join(',')}]`)\r\n .join(' ')\r\n this.bindLog(sessionId, `unbound (pid-miss) pids=[${(pids ?? []).join(',')}] tabs=${table}`)\r\n return null\r\n }\r\n\r\n const active = this.app.activeTab\r\n if (!active) {\r\n return null\r\n }\r\n const owner = this.tabSession.get(active)\r\n if (owner && owner !== sessionId) {\r\n this.bindLog(sessionId, `unbound (legacy: active tab owned by ${owner.slice(0, 8)})`)\r\n return null\r\n }\r\n this.bind(sessionId, active, 'legacy')\r\n return active\r\n }\r\n\r\n /** 세션 <-> 탭 을 묶고, 그 탭의 이전 주인과 이 세션의 이전 탭은 풀어 준다 */\r\n private bind (sessionId: string, tab: BaseTabComponent, how: string): void {\r\n const prevOwner = this.tabSession.get(tab)\r\n if (prevOwner && prevOwner !== sessionId) {\r\n this.sessionTab.delete(prevOwner)\r\n }\r\n const prevTab = this.sessionTab.get(sessionId)\r\n if (prevTab && prevTab !== tab && this.tabSession.get(prevTab) === sessionId) {\r\n this.tabSession.delete(prevTab)\r\n }\r\n this.sessionTab.set(sessionId, tab)\r\n this.tabSession.set(tab, sessionId)\r\n this.lastBindLog.delete(sessionId)\r\n this.diag(`bind sid=${sessionId.slice(0, 8)} via=${how} tab=${this.tabName(tab)}`\r\n + (prevOwner && prevOwner !== sessionId ? ` (took over from ${prevOwner.slice(0, 8)})` : ''))\r\n }\r\n\r\n /** 매칭 실패는 폴링마다 반복되므로 같은 내용은 한 번만 남긴다 */\r\n private bindLog (sessionId: string, msg: string): void {\r\n if (this.lastBindLog.get(sessionId) === msg) {\r\n return\r\n }\r\n this.lastBindLog.set(sessionId, msg)\r\n this.diag(`bind sid=${sessionId.slice(0, 8)} ${msg}`)\r\n }\r\n}\r\n","import { Injectable } from '@angular/core'\nimport { AppService, ConfigService } from 'tabby-core'\n\nexport const ROOT_PROFILE_ID = 'agentdeck:root'\n\n/**\n * 새 탭이 항상 작업 루트에서 열리게 한다.\n *\n * Tabby 프로필을 하나 만들어 config 에 심고, 사용자가 아직 기본 프로필을\n * 직접 고른 적이 없으면 이것을 기본으로 지정한다.\n * 한 번 심은 뒤에는 사용자가 설정에서 바꾼 값을 존중한다 (매 기동 덮어쓰지 않음).\n */\n@Injectable({ providedIn: 'root' })\nexport class AgentDeckProfileService {\n constructor (\n private app: AppService,\n private config: ConfigService,\n ) { }\n\n init (): void {\n this.app.ready$.subscribe(() => this.ensureProfile())\n }\n\n private ensureProfile (): void {\n const cfg = this.config.store.agentDeck\n // 경로를 안 정했으면 만들지 않는다 — 남의 홈 디렉토리에 엉뚱한 프로필을 심지 않기 위해\n if (!cfg.rootProfile || !cfg.rootProfileCwd) {\n return\n }\n\n const profiles = this.config.store.profiles || []\n const existing = profiles.find((p: any) => p.id === ROOT_PROFILE_ID)\n\n const profile = {\n id: ROOT_PROFILE_ID,\n type: 'local',\n name: cfg.rootProfileName || 'Agent Root',\n options: {\n command: cfg.rootProfileCommand || 'powershell.exe',\n args: [...(cfg.rootProfileArgs || [])],\n cwd: cfg.rootProfileCwd,\n env: { ...(cfg.rootProfileEnv || {}) },\n // 권한 승격(runAsAdministrator)은 이 플러그인이 다루지 않는다 — Tabby 를 어떤 권한으로\n // 띄울지는 사용자의 몫이다. 단 프로필에 runAsAdministrator 를 켜면 Tabby 가 셸을\n // UAC.exe 릴레이로 감싸고 그 릴레이가 폭 1칸을 잃어 TUI 입력창이 깨진다(README 알려진 문제).\n },\n }\n\n if (existing) {\n // 사용자가 설정 UI 에서 손댔을 수 있으므로 비어 있는 값만 보정한다\n if (!existing.options) {\n existing.options = profile.options\n this.config.save()\n } else {\n let dirty = false\n if (!existing.options.cwd) {\n existing.options.cwd = profile.options.cwd\n dirty = true\n }\n // npm 전역 .ps1 래퍼(claude 등)가 기본 실행 정책에 막히지 않도록 인자를 보정한다.\n // 사용자가 직접 인자를 넣어 뒀다면 건드리지 않는다.\n if (!existing.options.args || existing.options.args.length === 0) {\n existing.options.args = [...profile.options.args]\n dirty = true\n }\n // 색 지원 환경변수는 사용자가 지정한 값을 덮지 않고 빠진 것만 채운다\n existing.options.env = existing.options.env || {}\n for (const [k, v] of Object.entries(profile.options.env)) {\n if (existing.options.env[k] === undefined) {\n existing.options.env[k] = v\n dirty = true\n }\n }\n if (dirty) {\n this.config.save()\n }\n }\n } else {\n profiles.push(profile)\n this.config.store.profiles = profiles\n // 최초 1회만 기본 프로필로 지정\n if (!cfg.rootProfileClaimed) {\n this.config.store.terminal.profile = ROOT_PROFILE_ID\n cfg.rootProfileClaimed = true\n }\n this.config.save()\n }\n }\n}\n","/**\n * 터미널 화면에 그려진 입력창에서 지금 쓰여 있는 프롬프트를 뽑아낸다.\n *\n * 타이핑을 따로 세지 않고 화면을 읽는 이유 — 붙여넣기·↑ 히스토리·자동완성·IME 로 들어온 글자는\n * 키 이벤트로 안 오거나 원문과 다르다. 화면에 실제로 그려진 것이 곧 보낼 내용이다.\n *\n * 입력창 모양은 앱·버전마다 다르다. 옛 Claude Code / Codex 는 테두리 상자였고\n * ╭────────────────────╮\n * │ > 프롬프트 내용 │\n * ╰────────────────────╯\n * Claude Code 2.1.x 는 상자를 버리고 위아래 가로선 사이에 한 줄만 그린다.\n * ────────────────────────\n * ❯ 프롬프트 내용\n * ────────────────────────\n * ? for shortcuts\n * 머리글자도 ASCII `>` 가 아니라 `❯`(U+276F) 다 — 2026-09-01 화면 캡처로 확인.\n * `>` 만 찾던 정규식이 이걸 못 잡아 라벨이 한 번도 안 바뀌었다.\n *\n * 머리를 못 찾으면 빈 문자열을 준다 — 일반 셸이나 y/n 확인 같은 데서 엉뚱한 라벨이 박히느니\n * 라벨을 그대로 두는 편이 낫다.\n *\n * 화면 버퍼를 직접 받지 않고 줄 배열만 받는 순수 함수로 둔다 (xterm 없이 검증할 수 있게).\n */\n\n/** 입력창의 첫 줄 표식 — ASCII `>` 와 꺾쇠 계열(❯ › ➜ ❭) 을 모두 받는다 */\nconst PROMPT_HEAD_RE = /^[>❯›❭➜]\\s*/\n/**\n * 같은 꺾쇠를 선택지 커서로도 쓴다 (`❯ 1. Yes`). 그건 프롬프트가 아니다.\n * 번호 목록뿐 아니라 Yes/No 같은 무번호 선택지도 배제한다.\n */\nconst CHOICE_RE = /^[>❯›❭➜]\\s*(\\d+[.)]\\s|(?:Yes|No)\\b)/i\n/** 입력창 아래 테두리 — 상자 모서리(╰└) 또는 가로선만으로 된 줄 */\nconst BOX_BOTTOM_RE = /^[\\s│┃|]*[─━═-]{3,}[\\s│┃|]*$|[╰└]/\n/** 이보다 짧으면 라벨로 쓰지 않는다 (y/n 응답 등) */\nconst MIN_PROMPT_LEN = 2\n/** 사이드바에 들어가는 라벨 길이 */\nexport const MAX_LABEL_LEN = 40\n\n/** 입력창 테두리(│ ┃ 등)와 좌우 여백을 떼어낸 알맹이 */\nfunction stripBox (line: string): string {\n return line.replace(/^[\\s│┃|╭╰┌└─╮╯┐┘]+/, '').replace(/[\\s│┃|╮╯┐┘─]+$/, '').trim()\n}\n\nexport function extractPrompt (lines: string[]): string {\n // 아래에서 위로 머리 줄을 찾는다 (마지막 입력창이 곧 지금 입력창)\n let head = -1\n for (let i = lines.length - 1; i >= 0; i--) {\n const body = stripBox(lines[i])\n if (!PROMPT_HEAD_RE.test(body)) {\n continue\n }\n if (CHOICE_RE.test(body)) {\n return '' // 선택지 커서 — 여기서 위로 더 올라가면 옛 프롬프트를 주워온다\n }\n head = i\n break\n }\n if (head < 0) {\n return ''\n }\n const parts = [stripBox(lines[head]).replace(PROMPT_HEAD_RE, '')]\n for (let i = head + 1; i < lines.length; i++) {\n if (BOX_BOTTOM_RE.test(lines[i])) {\n break // 입력창 끝 — 그 아래는 힌트 줄이라 프롬프트가 아니다\n }\n const body = stripBox(lines[i])\n if (body) {\n parts.push(body)\n }\n }\n const text = parts.join(' ').replace(/\\s+/g, ' ').trim()\n if (text.length < MIN_PROMPT_LEN) {\n return '' // y/n 같은 한 글자 응답 — 라벨로 쓸 것이 못 된다\n }\n return text.length > MAX_LABEL_LEN ? text.slice(0, MAX_LABEL_LEN).trimEnd() + '...' : text\n}\n","/**\n * 터미널 화면이 깨졌는지 판정한다.\n *\n * \"깨졌다\" 의 정체는 하나다 — **TUI 가 아는 폭과 xterm 이 가진 폭이 다르다.**\n * 그러면 TUI 가 그린 한 행이 xterm 에서 두 행으로 접히거나(폭이 더 크다),\n * 행 오른쪽에 옛 프레임이 남는다(폭이 더 작다). 눈으로는 \"입력창 구분선이 중간에서 끊긴다\",\n * \"가로선과 입력 텍스트가 한 줄에 섞인다\" 로 보인다.\n *\n * 정상 화면의 모양은 실측해서 확정했다 (2026-09-01, Claude Code 2.1.x, CDP 로 xterm 버퍼 원문).\n * 사이드바를 켠 창(cols=280)과 순정 창(cols=360) 양쪽에서 완전히 같은 구조가 나왔다.\n *\n * 71 wrapped=0 len=278 \" … ● high · /effort\" ← 오른쪽 정렬 힌트\n * 72 wrapped=0 len=280 \"──────────────────────────────────────────────────\" ← len == cols\n * 73 wrapped=1 len= 1 \"❯\" ← wrapped=1 이 정상\n * 74 wrapped=0 len=280 \"──────────────────────────────────────────────────\" ← len == cols\n * 75 wrapped=0 len=155 \" ⚠ Transcript saving is off — …\"\n * 76 wrapped=0 len= 58 \" ⏱ 1s 컨텍스트 사용량: …\"\n * 77 wrapped=0 len= 38 \" ⏵⏵ auto mode on (shift+tab to cycle)\"\n *\n * 여기서 놓치기 쉬운 세 가지 —\n * - 가로선은 **cols 를 정확히 꽉 채운다**. 그래서 그 다음 줄에 `wrapped=1` 이 붙는 것은\n * xterm 의 pending-wrap 이고 **정상이다**. `wrapped` 만 보고 깨졌다고 판정하면 안 된다.\n * - 프롬프트 오른쪽에 오는 힌트(`● high · /effort`, `Try \"how does …\"`)는 **별도 줄**이다.\n * 프롬프트 줄과 같은 줄에 두 개의 머리(`❯`/`>`)가 보이면 그것이 깨진 화면이다.\n * - **폭이 다 맞아도 깨진 화면이 있다.** 테두리 두 줄이 맞붙어 `❯` 가 들어갈 행이\n * 사라지는 모양인데, 두 테두리 모두 cols 를 꽉 채우므로 폭 기준 판정은 전부 통과한다\n * (2026-09-02: 사람 눈으로도 이 도구로도 \"정상\" 이라고 오판했다). 그래서 폭만이 아니라\n * **입력할 자리가 있는가**(테두리 사이 간격 ≥ 2)를 같이 본다.\n *\n * xterm 없이 검증할 수 있도록 줄 배열만 받는 순수 함수로 둔다.\n */\n\n/** 판정에 필요한 한 줄 — 오른쪽 공백을 떼어낸 본문과 xterm 의 wrap 플래그 */\nexport interface ScreenLine {\n text: string\n wrapped: boolean\n}\n\nexport interface ScreenVerdict {\n broken: boolean\n /** 왜 깨졌다고 보는지 — 진단 로그에 그대로 남긴다 */\n reasons: string[]\n}\n\n/**\n * 가로선만으로 된 줄 (입력창 위/아래 테두리).\n * 두 글자까지 내려 잡는 이유 — 테두리가 화면 폭을 넘치면 다음 줄에 한두 칸짜리\n * 자투리로 떨어진다 (실측: cols=280 화면에 280칸 + `──` 2칸).\n */\nconst RULE_RE = /^[─━═]{2,}$/\n/** 입력창 머리글자 — prompt.ts 와 같은 집합. 뒤가 줄 끝이어도(빈 입력창) 머리다 */\nconst HEAD_RE = /^[>❯›❭➜](\\s|$)/\n/** 줄 어딘가에 있는 머리글자 — 가로선과 섞였는지 볼 때 쓴다 */\nconst HEAD_ANYWHERE_RE = /[>❯›❭➜](\\s|$)/\n/** 선택지 커서(`❯ 1. Yes`)는 입력창 머리가 아니다 */\nconst CHOICE_RE = /^[>❯›❭➜]\\s*(\\d+[.)]\\s|(?:Yes|No)\\b)/i\n/** 가로선 문자 */\nconst RULE_CHAR_RE = /[─━═]/\n\nexport function judgeScreen (lines: ScreenLine[], cols: number): ScreenVerdict {\n const reasons: string[] = []\n if (!(cols > 1) || !lines.length) {\n return { broken: false, reasons: [] }\n }\n\n const rules: number[] = []\n const heads: number[] = []\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]\n const body = line.text.replace(/\\s+$/, '')\n if (!body) {\n continue\n }\n\n if (RULE_RE.test(body)) {\n rules.push(i)\n // 테두리는 화면 폭을 꽉 채운다. 짧으면 TUI 가 더 좁은 폭으로 그린 것이고,\n // 그보다 짧은 자투리 줄이면 넘쳐 접힌 꼬리다 — 어느 쪽이든 폭이 어긋났다.\n //\n // 2026-09-02: `cols - 1` 도 정상으로 봐주도록 한 번 완화했다가 되돌렸다.\n // 근거로 삼은 `len=279` 스냅샷이 **전부 깨짐으로 판정된 화면**이었고,\n // 같은 로그의 정상 표본(`auto-after 복구됨`)은 `len == cols == 280` 이었다.\n // 병상 표본을 정상 기준으로 삼으면 안 된다.\n if (body.length !== cols) {\n reasons.push(`rule@${i} len=${body.length} != cols=${cols}`)\n }\n continue\n }\n\n // 가로선과 다른 글자가 한 줄에 섞였다.\n // 상자형 입력창(`╭──╮` / `│ > … │`)을 쓰는 앱도 있으므로, 머리글자가 같은 줄에\n // 함께 있을 때만 깨진 것으로 본다 — 그것이 \"가로선과 입력 텍스트가 섞인\" 그 증상이다.\n if (RULE_CHAR_RE.test(body) && HEAD_ANYWHERE_RE.test(body)) {\n reasons.push(`mixed@${i} ${JSON.stringify(body.slice(0, 40))}`)\n }\n\n if (HEAD_RE.test(body) && !CHOICE_RE.test(body)) {\n heads.push(i)\n }\n }\n\n // 입력창 **안에** 머리가 두 개 이상 보인다 = 옛 프레임이 지워지지 않았다.\n //\n // 화면 전체의 머리 수를 세면 안 된다 — Claude Code 는 지난 사용자 프롬프트를\n // `❯ 내가 보낸 말` 로 대화 이력에 남기고, 큐에 쌓인 메시지도 같은 모양으로 나열한다.\n // 그래서 정상 화면에도 머리가 예사로 일곱 개 보인다 (2026-09-01 실측: `heads=7` 오탐으로\n // 자동 복구가 2초마다 헛돌았다). 판정은 입력창 테두리(가로선) 사이 구간에서만 한다.\n //\n // 판정은 **맨 아래 두 테두리** 사이에서만 한다. 위쪽 테두리를 `rules[0]` 으로 잡으면\n // 대화 이력에 스크롤되어 남은 옛 입력창의 테두리를 물어, 그 사이의 지난 프롬프트가\n // 전부 머리로 세어진다. 입력창은 언제나 화면 맨 아래에 있다.\n // 자투리 테두리(폭이 안 맞는 줄)는 위치 기준이 못 되므로 **화면 폭을 꽉 채운 것**만 쓴다.\n const fullRules = rules.filter(i => lines[i].text.replace(/\\s+$/, '').length === cols)\n if (fullRules.length >= 2) {\n const bottom = fullRules[fullRules.length - 1]\n const top = fullRules[fullRules.length - 2]\n\n // **입력할 자리가 없다** — 테두리 두 줄이 맞붙어 `❯` 가 들어갈 행이 사라졌다.\n //\n // 이것이 2026-09-02 에 사람 눈으로도 도구로도 놓친 그 증상이다. 폭은 멀쩡해서\n // (테두리 둘 다 cols 를 꽉 채운다) 폭 기준 판정은 전부 통과해 버린다. 실측 픽셀:\n // 가로선 y=59 와 y=76 이 행높이(17px) 1행 간격, 그 사이 커서 글리프가 아래 선을 관통.\n // 정상이라면 두 테두리는 최소 한 행(입력줄)을 사이에 두므로 간격이 2 이상이다.\n if (bottom - top < 2) {\n reasons.push(`입력창에 자리가 없다 (테두리 ${top}·${bottom} 이 맞붙었다)`)\n } else {\n const inside = heads.filter(i => i > top && i < bottom).length\n // 머리가 0 개인 것은 깨짐으로 보지 않는다 — 선택지 커서(`❯ 1. Yes`)만 있는\n // 정상 화면이 그렇게 보인다 (CHOICE_RE 로 빼고 나면 머리가 0 이 된다).\n if (inside > 1) {\n reasons.push(`입력창 안 머리=${inside} (기대 1)`)\n }\n }\n }\n // **아래 테두리가 통째로 사라졌다.**\n //\n // 2026-09-02 실사용 실측(창 캡처 픽셀 스캔, 행높이 17px): 가로선이 `y=1295` 하나뿐이고\n // 프롬프트 글리프(y≈1304~1320) 아래 `y≈1329` 에 있어야 할 두 번째 가로선이 없었다.\n // 이 모양은 위 규칙들이 전부 통과한다 — 남은 테두리 하나는 폭을 꽉 채우고(폭 규칙 통과),\n // 테두리가 하나뿐이라 `fullRules.length >= 2` 가 거짓이라 자리 규칙도 건너뛰고,\n // `rules.length > 1` 도 거짓이라 섞임 규칙도 안 본다. 판정의 구멍이었다.\n //\n // 머리 **바로 위** 가 폭을 꽉 채운 테두리일 때만 본다. 그래야 3줄 입력창(`──/❯/──`)을\n // 쓰는 화면에만 적용되고, 테두리가 없는 일반 셸이나 상자형 입력창은 건드리지 않는다.\n // 대화 이력에 남은 옛 `❯ 내가 보낸 말` 도 안전하다 — 그 아래에는 현재 입력창의\n // 테두리가 있으므로 \"아래에 테두리가 없다\" 조건에 걸리지 않는다.\n if (heads.length && fullRules.length) {\n const head = heads[heads.length - 1]\n const topAttached = fullRules.includes(head - 1)\n const belowHead = fullRules.some(i => i > head)\n if (topAttached && !belowHead) {\n reasons.push(`입력창 아래 테두리가 없다 (머리@${head}, 위 테두리@${head - 1})`)\n }\n }\n\n // 테두리 길이가 서로 다르면 두 폭이 화면에 공존한다\n if (rules.length > 1) {\n const lens = new Set(rules.map(i => lines[i].text.replace(/\\s+$/, '').length))\n if (lens.size > 1) {\n reasons.push(`rule lens=${[...lens].join(',')} (섞임)`)\n }\n }\n\n return { broken: reasons.length > 0, reasons }\n}\n","import { Component } from '@angular/core'\nimport { ConfigService, PlatformService } from 'tabby-core'\n\nimport { LAYOUT_DEFAULTS } from './config'\nimport { hooksInstalled, hooksSupported, installHooks, uninstallHooks } from './claudeHooks'\n\nconst DOCK_LABELS: Record<string, string> = {\n left: '왼쪽',\n right: '오른쪽',\n top: '위쪽',\n bottom: '아래쪽',\n}\n\n/**\n * 설정 > AgentDeck 탭.\n *\n * 사용자가 실제로 바꿀 일이 있는 두 가지만 노출한다 — 레이아웃 on/off 와 작업 루트 프로필.\n * 나머지(화면비, 사이드바 폭, 투명도, 상태 감지, 입력 가로채기, 렌더 보정, 통보 채널)는\n * 손댈 이유가 거의 없고 잘못 만지면 화면이 깨지는 값이라 `config.ts` 의 기본값으로 고정하고\n * 설정 창에서는 뺐다. 정말 필요하면 설정 파일의 `agentDeck.*` 를 직접 고친다.\n *\n * `enabled` 는 deck.service 가 `config.changed$` 를 구독해 즉시 반영한다(deck.service.ts:256).\n * 루트 프로필은 기동 시 한 번만 읽으므로 재시작이 필요하다고 적어 둔다.\n */\n@Component({\n selector: 'agentdeck-settings-tab',\n template: `\n<h3 class=\"mb-3\">AgentDeck</h3>\n\n<div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">레이아웃 사용</div>\n <div class=\"description\">끄면 사이드바와 고정폭 레이아웃이 사라지고 Tabby 순정 화면으로 돌아간다.</div>\n </div>\n <toggle [(ngModel)]=\"config.store.agentDeck.enabled\" (ngModelChange)=\"config.save()\"></toggle>\n</div>\n\n<div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">UI 배치 초기화</div>\n <div class=\"description\">\n 마우스로 바꾼 사이드바 위치와 크기를 처음 상태로 되돌린다 —\n 오른쪽 도킹 + 화면비로 자동 계산한 폭.\n <span *ngIf=\"layoutChanged()\">지금: {{dockLabel()}} 도킹, {{sizeLabel()}}.</span>\n <span *ngIf=\"!layoutChanged()\">지금은 기본 상태다.</span>\n </div>\n </div>\n <button class=\"btn btn-secondary\" type=\"button\" [disabled]=\"!layoutChanged()\" (click)=\"resetLayout()\">\n <i class=\"fas fa-undo me-2\"></i>초기화\n </button>\n</div>\n\n<h3 class=\"mt-4 mb-3\">Claude Code 연동</h3>\n<div class=\"text-muted mb-3\">\n 에이전트가 \"지시를 받았다 / 승인을 기다린다 / 끝났다\" 를 직접 알려주게 한다.\n 이게 사이드바 상태의 가장 정확한 원천이다 — 걸지 않으면 화면에 그려진 글자를 보고\n 추측하는 방식으로 동작하고, 그만큼 판정이 흔들린다.\n</div>\n\n<div class=\"form-line\" *ngIf=\"!hooksSupported\">\n <div class=\"header\">\n <div class=\"title\">이 환경에서는 걸 수 없다</div>\n <div class=\"description\">통보 스크립트가 PowerShell 이라 Windows 에서만 동작한다. 상태는 출력 패턴으로 추측한다.</div>\n </div>\n</div>\n\n<div class=\"form-line\" *ngIf=\"hooksSupported\">\n <div class=\"header\">\n <div class=\"title\">상태 통보 훅</div>\n <div class=\"description\">\n {{hooksOn ? '설치됨' : '설치 안 됨'}} — <code>~/.claude/settings.json</code> 의\n UserPromptSubmit / Notification / Stop 에 걸린다. 다른 훅은 건드리지 않고,\n 쓰기 전에 같은 폴더에 백업을 남긴다.\n <span *ngIf=\"hookError\" class=\"text-danger d-block mt-1\">{{hookError}}</span>\n </div>\n </div>\n <button class=\"btn\" type=\"button\"\n [class.btn-secondary]=\"!hooksOn\" [class.btn-outline-danger]=\"hooksOn\"\n (click)=\"toggleHooks()\">\n <i class=\"fas me-2\" [class.fa-plug]=\"!hooksOn\" [class.fa-trash]=\"hooksOn\"></i>\n {{hooksOn ? '제거' : '설치'}}\n </button>\n</div>\n\n<div class=\"form-line\" *ngIf=\"hooksSupported && hooksOn\">\n <div class=\"header\">\n <div class=\"title\">통보 채널</div>\n <div class=\"description\">훅이 보낸 상태를 받는 통로. 꺼져 있으면 훅을 걸어도 전달되지 않는다. 변경은 Tabby 재시작 후 적용된다.</div>\n </div>\n <toggle [(ngModel)]=\"config.store.agentDeck.notifyChannel\" (ngModelChange)=\"config.save()\"></toggle>\n</div>\n\n<h3 class=\"mt-4 mb-3\">작업 루트 프로필</h3>\n<div class=\"text-muted mb-3\">새 탭이 항상 같은 작업 폴더에서 뜨도록 전용 프로필을 만든다. 변경은 Tabby 재시작 후 적용된다.</div>\n\n<div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">루트 프로필 사용</div>\n <div class=\"description\">켜고 작업 폴더를 채우면 해당 프로필을 만들어 기본 프로필로 삼는다.</div>\n </div>\n <toggle [(ngModel)]=\"config.store.agentDeck.rootProfile\" (ngModelChange)=\"config.save()\"></toggle>\n</div>\n\n<ng-container *ngIf=\"config.store.agentDeck.rootProfile\">\n <div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">프로필 이름</div>\n </div>\n <input class=\"form-control w-50\" type=\"text\"\n [(ngModel)]=\"config.store.agentDeck.rootProfileName\" (change)=\"config.save()\">\n </div>\n\n <div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">작업 폴더</div>\n <div class=\"description\">비우면 프로필을 만들지 않는다. 직접 적을 때는 백슬래시 이스케이프 함정을 피하려고 슬래시로 적는다 (예: D:/Project).</div>\n </div>\n <div class=\"input-group w-50\">\n <input class=\"form-control\" type=\"text\" placeholder=\"D:/Project\"\n [(ngModel)]=\"config.store.agentDeck.rootProfileCwd\" (change)=\"config.save()\">\n <button class=\"btn btn-secondary\" type=\"button\" (click)=\"pickCwd()\">\n <i class=\"fas fa-folder-open me-2\"></i>찾아보기\n </button>\n </div>\n </div>\n\n <div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">실행 명령</div>\n </div>\n <input class=\"form-control w-50\" type=\"text\"\n [(ngModel)]=\"config.store.agentDeck.rootProfileCommand\" (change)=\"config.save()\">\n </div>\n\n</ng-container>\n\n<div class=\"text-muted mt-4\">\n 화면비·사이드바 폭·투명도·상태 감지·입력 처리 등 나머지 값은 기본값으로 고정돼 있다.\n 바꿔야 한다면 설정 파일의 <code>agentDeck.*</code> 를 직접 고친다.\n 단축키는 <b>단축키</b> 탭의 <code>agentdeck-*</code> 항목에서 바꾼다.\n</div>\n`,\n})\nexport class AgentDeckSettingsTabComponent {\n /** 이 환경에서 훅을 걸 수 있나 (통보 스크립트가 PowerShell 이라 Windows 전용) */\n hooksSupported = hooksSupported()\n /** 지금 걸려 있나 — 파일을 매번 읽지 않도록 화면용으로 들고 있는다 */\n hooksOn = false\n /** 훅을 쓰다 실패한 이유 — 조용히 삼키면 사용자는 버튼이 먹통인 줄 안다 */\n hookError = ''\n\n constructor (\n public config: ConfigService,\n private platform: PlatformService,\n ) {\n this.refreshHooks()\n }\n\n private refreshHooks (): void {\n try {\n this.hooksOn = this.hooksSupported && hooksInstalled()\n } catch (e: any) {\n this.hooksOn = false\n this.hookError = `설정을 읽지 못했다: ${e?.message ?? e}`\n }\n }\n\n /**\n * 훅을 걸거나 뗀다.\n *\n * 걸 때는 통보 채널도 같이 켠다 — 훅만 걸고 채널이 닫혀 있으면 보고가 어디에도 닿지 않는데,\n * 사용자 입장에서는 \"설치했는데 아무 일도 안 일어난다\" 로만 보인다.\n */\n toggleHooks (): void {\n this.hookError = ''\n try {\n if (this.hooksOn) {\n uninstallHooks()\n } else {\n installHooks()\n if (!this.config.store.agentDeck.notifyChannel) {\n this.config.store.agentDeck.notifyChannel = true\n this.config.save()\n }\n }\n } catch (e: any) {\n this.hookError = `${e?.message ?? e}`\n }\n this.refreshHooks()\n }\n\n /**\n * OS 폴더 선택 창을 띄워 작업 폴더를 고른다.\n *\n * `pickDirectory` 는 취소하면 null/undefined 를 주므로 그때는 기존 값을 건드리지 않는다.\n * 다이얼로그 제목은 Tabby 버전에 따라 인자를 받기도 하고 안 받기도 해서 any 로 넘긴다 —\n * 안 받는 쪽은 그냥 무시하므로 어느 쪽에서도 깨지지 않는다.\n * 돌려받은 경로는 백슬래시를 슬래시로 바꿔 저장한다. 설정 파일에 그대로 적히는 값이라\n * 손으로 고칠 때 이스케이프 사고가 나지 않게 하려는 것이고, Windows 도 슬래시 경로를 받는다.\n */\n /** 배치가 기본값에서 벗어나 있나 — 벗어나 있을 때만 초기화 버튼이 살아 있다 */\n layoutChanged (): boolean {\n const cfg = this.config.store.agentDeck\n return Object.keys(LAYOUT_DEFAULTS).some(k => cfg[k] !== LAYOUT_DEFAULTS[k])\n }\n\n dockLabel (): string {\n return DOCK_LABELS[this.config.store.agentDeck.sidebarDock] ?? '오른쪽'\n }\n\n sizeLabel (): string {\n const cfg = this.config.store.agentDeck\n if (cfg.sidebarDock === 'top' || cfg.sidebarDock === 'bottom') {\n return '높이 ' + cfg.sidebarHeight + 'px'\n }\n return cfg.sidebarWidth ? '폭 ' + cfg.sidebarWidth + 'px' : '폭 자동'\n }\n\n /**\n * 도킹 방향과 크기만 기본값으로 되돌린다.\n *\n * 되돌리기 쉬운 조작이라 확인 창은 두지 않는다. `config.save()` 가 `changed$` 를 발화시키고\n * deck.service 가 그걸 받아 곧바로 다시 배치하므로(deck.service.ts:256) 재시작도 필요 없다.\n */\n resetLayout (): void {\n Object.assign(this.config.store.agentDeck, LAYOUT_DEFAULTS)\n this.config.save()\n }\n\n async pickCwd (): Promise<void> {\n const picked = await (this.platform as any).pickDirectory('작업 폴더 선택')\n if (!picked) {\n return\n }\n this.config.store.agentDeck.rootProfileCwd = String(picked).replace(/\\\\/g, '/')\n this.config.save()\n }\n}\n","import { Injectable } from '@angular/core'\nimport { SettingsTabProvider } from 'tabby-settings'\n\nimport { AgentDeckSettingsTabComponent } from './settings.component'\n\n/**\n * 설정 창 왼쪽 목록에 AgentDeck 탭을 끼워 넣는다.\n * `weight` 를 주지 않으면 등록 순서 뒤쪽에 붙는다 — 순정 탭들 아래로 가도록 그대로 둔다.\n */\n@Injectable()\nexport class AgentDeckSettingsTabProvider extends SettingsTabProvider {\n id = 'agentdeck'\n icon = 'layer-group'\n title = 'AgentDeck'\n\n getComponentType (): any {\n return AgentDeckSettingsTabComponent\n }\n}\n","import { Injectable } from '@angular/core'\r\nimport { Subject, Observable } from 'rxjs'\r\nimport { BaseTabComponent } from 'tabby-core'\r\nimport { TabState, WorkStatus } from './api'\r\n\r\n/**\r\n * 탭별 작업 상태 보관소.\r\n * 상태의 출처는 3가지 — 자동 감지(decorator), OSC 시퀀스(Claude Code 훅), 사이드바에서의 수동 지정.\r\n * pinned 가 true 면 자동 감지가 값을 덮어쓰지 않는다.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class WorkStatusService {\r\n private states = new Map<BaseTabComponent, TabState>()\r\n private changed = new Subject<void>()\r\n\r\n /** 진단용 카운터 — decorator 가 실제로 붙었는지, 출력이 흘러오는지 확인한다 */\r\n debug = {\r\n attached: 0,\r\n outputs: 0,\r\n oscHits: 0,\r\n titleHits: 0,\r\n }\r\n\r\n get changed$ (): Observable<void> { return this.changed }\r\n\r\n get (tab: BaseTabComponent): TabState {\r\n let s = this.states.get(tab)\r\n if (!s) {\r\n s = {\r\n status: 'idle', label: '', since: Date.now(), pinned: false,\r\n lastOutput: 0, busyMode: false, lastBusy: 0,\r\n }\r\n this.states.set(tab, s)\r\n }\r\n return s\r\n }\r\n\r\n /** 자동 감지용 — pinned 상태는 건드리지 않는다 */\r\n setAuto (tab: BaseTabComponent, status: WorkStatus): void {\r\n const s = this.get(tab)\r\n if (s.pinned || s.status === status) {\r\n return\r\n }\r\n s.status = status\r\n s.since = Date.now()\r\n this.changed.next()\r\n }\r\n\r\n /** 수동/훅 지정 — 이후 자동 감지보다 우선한다 */\r\n setManual (tab: BaseTabComponent, status: WorkStatus, label?: string): void {\r\n const s = this.get(tab)\r\n s.status = status\r\n s.since = Date.now()\r\n s.pinned = true\r\n if (label !== undefined) {\r\n s.label = label\r\n }\r\n this.changed.next()\r\n }\r\n\r\n setLabel (tab: BaseTabComponent, label: string): void {\r\n this.get(tab).label = label\r\n this.changed.next()\r\n }\r\n\r\n /** 수동 고정을 풀고 자동 감지로 되돌린다 */\r\n unpin (tab: BaseTabComponent): void {\r\n const s = this.get(tab)\r\n s.pinned = false\r\n s.status = 'idle'\r\n s.since = Date.now()\r\n this.changed.next()\r\n }\r\n\r\n markOutput (tab: BaseTabComponent): void {\r\n this.get(tab).lastOutput = Date.now()\r\n }\r\n\r\n /**\r\n * 에이전트가 \"작업 중\" 이라고 스스로 밝힌 순간 — 스피너나 \"esc to interrupt\" 같은 표시.\r\n *\r\n * 이 신호를 한 번이라도 본 탭은 그 뒤로 신호만 보고 판단한다(busyMode).\r\n * 상태줄을 매초 다시 그리는 TUI 를 \"계속 일하는 중\" 으로 오해하지 않기 위해서다.\r\n */\r\n markBusy (tab: BaseTabComponent): void {\r\n const s = this.get(tab)\r\n s.busyMode = true\r\n s.lastBusy = Date.now()\r\n }\r\n\r\n /** 이 탭을 에이전트 TUI 로 볼지 — 아니면 예전처럼 출력 유무로 판단한다 */\r\n isBusyMode (tab: BaseTabComponent): boolean {\r\n return this.get(tab).busyMode\r\n }\r\n\r\n forget (tab: BaseTabComponent): void {\r\n this.states.delete(tab)\r\n this.changed.next()\r\n }\r\n\r\n /** 사이드바가 매 틱 호출 — idle 전환만 담당하고 화면 갱신 필요 여부를 돌려준다 */\r\n tickIdle (tab: BaseTabComponent, idleAfterMs: number): boolean {\r\n const s = this.get(tab)\r\n if (s.pinned || s.status !== 'running') {\r\n return false\r\n }\r\n // 에이전트 탭은 \"작업 중\" 신호가 끊긴 시점부터 잰다.\r\n // 일반 셸은 예전대로 출력이 끊긴 시점부터 잰다 (신호를 낼 줄 모르므로)\r\n const from = s.busyMode ? s.lastBusy : s.lastOutput\r\n if (from && Date.now() - from > idleAfterMs) {\r\n s.status = 'idle'\r\n s.since = Date.now()\r\n return true\r\n }\r\n return false\r\n }\r\n}\r\n","module.exports = require(\"net\");","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_common__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_forms__;","if(typeof __WEBPACK_EXTERNAL_MODULE_electron__ === 'undefined') { const e = new Error(\"Cannot find module 'electron'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }\n\nmodule.exports = __WEBPACK_EXTERNAL_MODULE_electron__;","module.exports = __WEBPACK_EXTERNAL_MODULE_fs__;","module.exports = __WEBPACK_EXTERNAL_MODULE_os__;","module.exports = __WEBPACK_EXTERNAL_MODULE_path__;","module.exports = __WEBPACK_EXTERNAL_MODULE_rxjs__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_settings__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_terminal__;","// The module cache\nconst __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tconst 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\tconst module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\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\tconst 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\tconst 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/value 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\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nc = undefined;","import { NgModule } from '@angular/core'\nimport { CommonModule } from '@angular/common'\nimport { FormsModule } from '@angular/forms'\nimport TabbyCoreModule, { ConfigProvider, HotkeyProvider } from 'tabby-core'\nimport { SettingsTabProvider } from 'tabby-settings'\nimport { TerminalDecorator } from 'tabby-terminal'\n\nimport { AgentDeckConfigProvider } from './config'\nimport { AgentDeckHotkeyProvider } from './hotkeys'\nimport { AgentDeckDecorator } from './decorator'\nimport { AgentDeckService } from './deck.service'\nimport { AgentDeckProfileService } from './profile.service'\nimport { WorkNotifyService } from './notify.service'\nimport { AgentDeckSettingsTabProvider } from './settings'\nimport { AgentDeckSettingsTabComponent } from './settings.component'\n\nimport './styles.scss'\n\nexport * from './api'\n\n@NgModule({\n imports: [\n CommonModule,\n // 설정 탭이 [(ngModel)] 로 config.store 를 직접 물고 있어서 필요하다\n FormsModule,\n TabbyCoreModule,\n ],\n providers: [\n { provide: ConfigProvider, useClass: AgentDeckConfigProvider, multi: true },\n { provide: HotkeyProvider, useClass: AgentDeckHotkeyProvider, multi: true },\n { provide: TerminalDecorator, useClass: AgentDeckDecorator, multi: true },\n { provide: SettingsTabProvider, useClass: AgentDeckSettingsTabProvider, multi: true },\n ],\n declarations: [\n AgentDeckSettingsTabComponent,\n ],\n})\nexport default class AgentDeckModule {\n constructor (\n deck: AgentDeckService,\n profiles: AgentDeckProfileService,\n notify: WorkNotifyService,\n ) {\n // 세 서비스 모두 app.ready$ 를 기다렸다가 스스로 붙는다\n deck.init()\n profiles.init()\n notify.init()\n }\n}\n"],"names":[],"sourceRoot":""}
1
+ {"version":3,"file":"index.js","mappings":"AAAA;AACA;AACA,4JAA4J,MAAM,8BAA8B,aAAa;AAC7M;AACA;AACA;AACA,iLAAiL,MAAM,8BAA8B,aAAa;AAClO;AACA;AACA,CAAC;AACD,O;;;;;;;;;;;;;;;;;;ACVA;AAC0G;AACjB;AACzF,8BAA8B,mFAA2B,CAAC,4FAAqC;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,OAAO,kFAAkF,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,MAAM,KAAK,UAAU,WAAW,UAAU,WAAW,WAAW,UAAU,WAAW,WAAW,KAAK,KAAK,YAAY,MAAM,KAAK,YAAY,MAAM,KAAK,YAAY,MAAM,KAAK,YAAY,MAAM,KAAK,UAAU,UAAU,WAAW,UAAU,WAAW,KAAK,KAAK,UAAU,KAAK,KAAK,UAAU,WAAW,WAAW,WAAW,WAAW,UAAU,WAAW,WAAW,WAAW,UAAU,KAAK,KAAK,WAAW,KAAK,KAAK,WAAW,UAAU,WAAW,WAAW,KAAK,KAAK,WAAW,KAAK,OAAO,UAAU,UAAU,UAAU,WAAW,KAAK,MAAM,WAAW,MAAM,KAAK,WAAW,MAAM,MAAM,UAAU,UAAU,UAAU,WAAW,KAAK,KAAK,WAAW,MAAM,KAAK,WAAW,MAAM,KAAK,WAAW,UAAU,WAAW,UAAU,UAAU,WAAW,WAAW,WAAW,KAAK,KAAK,WAAW,WAAW,WAAW,WAAW,UAAU,WAAW,WAAW,KAAK,MAAM,UAAU,WAAW,WAAW,WAAW,KAAK,MAAM,UAAU,KAAK,MAAM,WAAW,WAAW,KAAK,MAAM,WAAW,MAAM,MAAM,WAAW,UAAU,WAAW,UAAU,WAAW,WAAW,WAAW,UAAU,WAAW,MAAM,MAAM,WAAW,MAAM,MAAM,UAAU,OAAO,MAAM,WAAW,MAAM,MAAM,UAAU,OAAO,MAAM,UAAU,WAAW,WAAW,MAAM,MAAM,UAAU,UAAU,MAAM,MAAM,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,MAAM,MAAM,UAAU,WAAW,UAAU,UAAU,WAAW,WAAW,WAAW,MAAM,MAAM,UAAU,UAAU,UAAU,WAAW,WAAW,WAAW,WAAW,WAAW,MAAM,MAAM,WAAW,WAAW,MAAM,MAAM,UAAU,WAAW,UAAU,UAAU,UAAU,WAAW,MAAM,MAAM,UAAU,WAAW,WAAW,WAAW,WAAW,MAAM,MAAM,WAAW,MAAM,MAAM,UAAU,WAAW,WAAW,UAAU,MAAM,MAAM,UAAU,UAAU,UAAU,WAAW,WAAW,WAAW,UAAU,WAAW,UAAU,MAAM,MAAM,WAAW,MAAM,MAAM,UAAU,WAAW,UAAU,UAAU,UAAU,UAAU,WAAW,UAAU,WAAW,WAAW,UAAU,UAAU,UAAU,WAAW,MAAM,MAAM,WAAW,WAAW,MAAM,MAAM,UAAU,UAAU,UAAU,WAAW,MAAM,MAAM,UAAU,WAAW,WAAW,WAAW,WAAW,WAAW,UAAU,UAAU,MAAM,MAAM,WAAW,UAAU,MAAM,MAAM,UAAU,UAAU,UAAU,UAAU,OAAO,MAAM,UAAU,UAAU,WAAW,UAAU,WAAW,WAAW,WAAW,WAAW,UAAU,WAAW,MAAM,MAAM,WAAW,WAAW,WAAW,UAAU,MAAM,MAAM,WAAW,UAAU,OAAO,MAAM,UAAU,UAAU,UAAU,WAAW,OAAO,MAAM,UAAU,UAAU,WAAW,WAAW,WAAW,WAAW,OAAO,MAAM,UAAU,UAAU,UAAU,WAAW,WAAW,WAAW,WAAW,WAAW,UAAU,WAAW,WAAW,MAAM,MAAM,UAAU,UA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A;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,iBAAiB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,4BAA4B;AAChD;AACA;AACA;AACA;AACA;AACA,qBAAqB,6BAA6B;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;;;;;ACnFa;;AAEb;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kC;;;;;;;;;;ACjCa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oC;;;;;;;;;;ACTa;;AAEb;AACA;AACA,cAAc,KAAwC,GAAG,sBAAiB,GAAG,CAAI;AACjF;AACA;AACA;AACA;AACA,gD;;;;;;;;;;ACTa;;AAEb;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA,iFAAiF;AACjF;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,yDAAyD;AACzD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,wB;;;;;;;;;;AC5Da;;AAEb;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AA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","sources":["webpack-tabby-agentdeck:///webpack/universalModuleDefinition","webpack-tabby-agentdeck:///./src/styles.scss","webpack-tabby-agentdeck:///./node_modules/css-loader/dist/runtime/api.js","webpack-tabby-agentdeck:///./node_modules/css-loader/dist/runtime/sourceMaps.js","webpack://tabby-agentdeck/./src/styles.scss?a609","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/insertBySelector.js","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/insertStyleElement.js","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/styleDomAPI.js","webpack-tabby-agentdeck:///./node_modules/style-loader/dist/runtime/styleTagTransform.js","webpack-tabby-agentdeck:///./src/alert.service.ts","webpack-tabby-agentdeck:///./src/api.ts","webpack-tabby-agentdeck:///./src/bind.ts","webpack-tabby-agentdeck:///./src/claudeHooks.ts","webpack-tabby-agentdeck:///./src/config.ts","webpack-tabby-agentdeck:///./src/deck.service.ts","webpack-tabby-agentdeck:///./src/decorator.ts","webpack-tabby-agentdeck:///./src/detect.ts","webpack-tabby-agentdeck:///./src/dock.ts","webpack-tabby-agentdeck:///./src/hotkeys.ts","webpack-tabby-agentdeck:///./src/notify.service.ts","webpack-tabby-agentdeck:///./src/order.ts","webpack-tabby-agentdeck:///./src/profile.service.ts","webpack-tabby-agentdeck:///./src/prompt.ts","webpack-tabby-agentdeck:///./src/reason.ts","webpack-tabby-agentdeck:///./src/recovery.service.ts","webpack-tabby-agentdeck:///./src/screen.ts","webpack-tabby-agentdeck:///./src/settings.component.ts","webpack-tabby-agentdeck:///./src/settings.ts","webpack-tabby-agentdeck:///./src/status.service.ts","webpack-tabby-agentdeck:///./src/tabenv.ts","webpack-tabby-agentdeck:///external node-commonjs \"net\"","webpack-tabby-agentdeck:///external umd \"@angular/common\"","webpack-tabby-agentdeck:///external umd \"@angular/core\"","webpack-tabby-agentdeck:///external umd \"@angular/forms\"","webpack-tabby-agentdeck:///external umd \"electron\"","webpack-tabby-agentdeck:///external umd \"fs\"","webpack-tabby-agentdeck:///external umd \"os\"","webpack-tabby-agentdeck:///external umd \"path\"","webpack-tabby-agentdeck:///external umd \"rxjs\"","webpack-tabby-agentdeck:///external umd \"tabby-core\"","webpack-tabby-agentdeck:///external umd \"tabby-settings\"","webpack-tabby-agentdeck:///external umd \"tabby-terminal\"","webpack-tabby-agentdeck:///webpack/bootstrap","webpack-tabby-agentdeck:///webpack/runtime/compat get default export","webpack-tabby-agentdeck:///webpack/runtime/define property getters","webpack-tabby-agentdeck:///webpack/runtime/hasOwnProperty shorthand","webpack-tabby-agentdeck:///webpack/runtime/make namespace object","webpack-tabby-agentdeck:///webpack/runtime/nonce","webpack-tabby-agentdeck:///./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/core\"), require(\"@angular/forms\"), (function webpackLoadOptionalExternalModule() { try { return require(\"electron\"); } catch(e) {} }()), require(\"fs\"), require(\"os\"), require(\"path\"), require(\"rxjs\"), require(\"tabby-core\"), require(\"tabby-settings\"), require(\"tabby-terminal\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"@angular/common\", \"@angular/core\", \"@angular/forms\", \"electron\", \"fs\", \"os\", \"path\", \"rxjs\", \"tabby-core\", \"tabby-settings\", \"tabby-terminal\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"@angular/common\"), require(\"@angular/core\"), require(\"@angular/forms\"), (function webpackLoadOptionalExternalModule() { try { return require(\"electron\"); } catch(e) {} }()), require(\"fs\"), require(\"os\"), require(\"path\"), require(\"rxjs\"), require(\"tabby-core\"), require(\"tabby-settings\"), require(\"tabby-terminal\")) : factory(root[\"@angular/common\"], root[\"@angular/core\"], root[\"@angular/forms\"], root[\"electron\"], root[\"fs\"], root[\"os\"], root[\"path\"], root[\"rxjs\"], root[\"tabby-core\"], root[\"tabby-settings\"], root[\"tabby-terminal\"]);\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_core__, __WEBPACK_EXTERNAL_MODULE__angular_forms__, __WEBPACK_EXTERNAL_MODULE_electron__, __WEBPACK_EXTERNAL_MODULE_fs__, __WEBPACK_EXTERNAL_MODULE_os__, __WEBPACK_EXTERNAL_MODULE_path__, __WEBPACK_EXTERNAL_MODULE_rxjs__, __WEBPACK_EXTERNAL_MODULE_tabby_core__, __WEBPACK_EXTERNAL_MODULE_tabby_settings__, __WEBPACK_EXTERNAL_MODULE_tabby_terminal__) => {\nreturn ","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `body.agentdeck-active.ad-bg-clip .content-tab-active::before {\n left: var(--ad-bg-left) !important;\n top: var(--ad-bg-top) !important;\n right: auto !important;\n bottom: auto !important;\n width: var(--ad-bg-width) !important;\n height: var(--ad-bg-height) !important;\n}\n\n#agentdeck-sidebar {\n display: flex;\n flex-direction: column;\n z-index: 5;\n overflow: hidden;\n background: var(--ad-panel-bg, var(--bs-body-bg, #1e2127));\n font-size: 12px;\n user-select: none;\n -webkit-app-region: no-drag;\n}\n#agentdeck-sidebar.ad-dock-right {\n border-left: 1px solid rgba(255, 255, 255, 0.08);\n}\n#agentdeck-sidebar.ad-dock-left {\n border-right: 1px solid rgba(255, 255, 255, 0.08);\n}\n#agentdeck-sidebar.ad-dock-top {\n border-bottom: 1px solid rgba(255, 255, 255, 0.08);\n}\n#agentdeck-sidebar.ad-dock-bottom {\n border-top: 1px solid rgba(255, 255, 255, 0.08);\n}\n#agentdeck-sidebar.ad-dock-top .ad-list, #agentdeck-sidebar.ad-dock-bottom .ad-list {\n display: flex;\n flex-wrap: wrap;\n align-content: flex-start;\n gap: 0 6px;\n overflow-y: auto;\n}\n#agentdeck-sidebar.ad-dock-top .ad-tab, #agentdeck-sidebar.ad-dock-bottom .ad-tab {\n flex: 0 0 220px;\n}\n#agentdeck-sidebar .ad-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px 8px;\n letter-spacing: 0.12em;\n font-size: 10px;\n font-weight: 700;\n color: rgba(255, 255, 255, 0.4);\n -webkit-app-region: no-drag;\n cursor: grab;\n}\n#agentdeck-sidebar .ad-head:active {\n cursor: grabbing;\n}\n#agentdeck-sidebar .ad-resize {\n position: absolute;\n z-index: 6;\n background: transparent;\n transition: background 0.12s ease;\n}\n#agentdeck-sidebar .ad-resize:hover, body.ad-resizing #agentdeck-sidebar .ad-resize {\n background: rgba(97, 175, 239, 0.5);\n}\n#agentdeck-sidebar .ad-resize-right,\n#agentdeck-sidebar .ad-resize-left {\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: col-resize;\n}\n#agentdeck-sidebar .ad-resize-right {\n left: 0;\n}\n#agentdeck-sidebar .ad-resize-left {\n right: 0;\n}\n#agentdeck-sidebar .ad-resize-top,\n#agentdeck-sidebar .ad-resize-bottom {\n left: 0;\n right: 0;\n height: 6px;\n cursor: row-resize;\n}\n#agentdeck-sidebar .ad-resize-bottom {\n top: 0;\n}\n#agentdeck-sidebar .ad-resize-top {\n bottom: 0;\n}\n#agentdeck-sidebar .ad-head-count {\n -webkit-app-region: no-drag;\n display: flex;\n align-items: center;\n gap: 6px;\n flex: 0 0 auto;\n white-space: nowrap;\n letter-spacing: 0;\n color: rgba(255, 255, 255, 0.55);\n}\n#agentdeck-sidebar .ad-cnt {\n padding: 1px 6px;\n border-radius: 8px;\n background: rgba(255, 255, 255, 0.08);\n color: var(--ad-color, rgba(255, 255, 255, 0.55));\n font-size: 10px;\n line-height: 1.3;\n font-variant-numeric: tabular-nums;\n}\n#agentdeck-sidebar .ad-list {\n flex: 1 1 auto;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 2px 6px 8px;\n}\n#agentdeck-sidebar .ad-list::-webkit-scrollbar {\n width: 8px;\n}\n#agentdeck-sidebar .ad-list::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.14);\n border-radius: 4px;\n}\n#agentdeck-sidebar .ad-list::-webkit-scrollbar-thumb:hover {\n background: rgba(255, 255, 255, 0.24);\n}\n#agentdeck-sidebar .ad-tab {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: 8px;\n margin-bottom: 3px;\n padding: 7px 6px 7px 0;\n border-radius: 5px;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n#agentdeck-sidebar .ad-tab:hover {\n background: rgba(255, 255, 255, 0.05);\n}\n#agentdeck-sidebar .ad-tab:hover .ad-close {\n opacity: 0.65;\n}\n#agentdeck-sidebar .ad-tab.active {\n background: rgba(255, 255, 255, 0.1);\n}\n#agentdeck-sidebar .ad-tab.active .ad-title {\n color: #fff;\n}\n#agentdeck-sidebar .ad-bar {\n flex: 0 0 3px;\n border-radius: 2px;\n background: var(--ad-color, #6b727d);\n}\n#agentdeck-sidebar .ad-body {\n flex: 1 1 auto;\n min-width: 0;\n}\n#agentdeck-sidebar .ad-title {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: rgba(255, 255, 255, 0.82);\n font-size: 12.5px;\n line-height: 1.35;\n}\n#agentdeck-sidebar .ad-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 2px;\n font-size: 10.5px;\n line-height: 1.4;\n color: rgba(255, 255, 255, 0.45);\n}\n#agentdeck-sidebar .ad-badge {\n flex: 0 1 auto;\n min-width: 0;\n max-width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--ad-color, #6b727d);\n font-weight: 600;\n}\n#agentdeck-sidebar .ad-badge.pinned {\n text-decoration: underline dotted;\n text-underline-offset: 2px;\n}\n#agentdeck-sidebar .ad-prompt {\n display: flex;\n align-items: center;\n margin-top: 2px;\n min-width: 0;\n font-size: 11px;\n line-height: 1.4;\n}\n#agentdeck-sidebar .ad-label {\n flex: 1 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: rgba(255, 255, 255, 0.6);\n}\n#agentdeck-sidebar .ad-label.empty {\n color: rgba(255, 255, 255, 0.25);\n}\n#agentdeck-sidebar .ad-elapsed {\n flex: 0 0 auto;\n margin-left: auto;\n font-variant-numeric: tabular-nums;\n opacity: 0.55;\n}\n#agentdeck-sidebar .ad-label-input {\n flex: 1 1 auto;\n min-width: 0;\n padding: 0 4px;\n border: 1px solid rgba(255, 255, 255, 0.25);\n border-radius: 3px;\n background: rgba(0, 0, 0, 0.35);\n color: #fff;\n font-size: 10.5px;\n outline: none;\n}\n#agentdeck-sidebar .ad-label-input:focus {\n border-color: var(--ad-color, #61afef);\n}\n#agentdeck-sidebar .ad-close {\n flex: 0 0 auto;\n align-self: center;\n width: 18px;\n height: 18px;\n padding: 0;\n border: 0;\n border-radius: 3px;\n opacity: 0;\n background: transparent;\n color: rgba(255, 255, 255, 0.8);\n font-size: 15px;\n line-height: 1;\n cursor: pointer;\n transition: opacity 0.1s ease, background 0.1s ease;\n}\n#agentdeck-sidebar .ad-close:hover {\n opacity: 1 !important;\n background: rgba(255, 80, 80, 0.35);\n}\n#agentdeck-sidebar .ad-foot {\n display: flex;\n gap: 6px;\n padding: 8px;\n border-top: 1px solid rgba(255, 255, 255, 0.07);\n}\n#agentdeck-sidebar .ad-btn {\n flex: 1 1 auto;\n padding: 5px 8px;\n border: 1px solid rgba(255, 255, 255, 0.12);\n border-radius: 4px;\n background: transparent;\n color: rgba(255, 255, 255, 0.6);\n font-size: 11px;\n cursor: pointer;\n}\n#agentdeck-sidebar .ad-btn:hover {\n background: rgba(255, 255, 255, 0.08);\n color: #fff;\n}\n#agentdeck-sidebar .ad-repair {\n flex: 0 0 auto;\n min-width: 28px;\n font-size: 13px;\n line-height: 1;\n}\n\n.ad-menu {\n position: fixed;\n z-index: 10000;\n min-width: 130px;\n padding: 4px;\n border: 1px solid rgba(255, 255, 255, 0.12);\n border-radius: 6px;\n background: #262a31;\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);\n font-size: 12px;\n user-select: none;\n}\n.ad-menu .ad-menu-item {\n padding: 6px 10px;\n border-radius: 4px;\n color: rgba(255, 255, 255, 0.75);\n cursor: pointer;\n}\n.ad-menu .ad-menu-item:hover {\n background: rgba(255, 255, 255, 0.1);\n color: #fff;\n}\n\n.ad-dock-overlay {\n position: fixed;\n inset: 0;\n z-index: 9998;\n pointer-events: none;\n}\n\n.ad-dock-preview {\n position: fixed;\n display: none;\n border: 1px solid rgba(97, 175, 239, 0.9);\n background: rgba(97, 175, 239, 0.22);\n box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.18);\n transition: left 0.08s ease, top 0.08s ease, width 0.08s ease, height 0.08s ease;\n}\n\n.ad-dock-zone {\n position: fixed;\n width: 46px;\n height: 46px;\n margin: -23px 0 0 -23px;\n border: 1px solid rgba(255, 255, 255, 0.35);\n border-radius: 6px;\n background: rgba(38, 42, 49, 0.92);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.ad-dock-zone .ad-dock-mark {\n width: 26px;\n height: 26px;\n border: 1px solid rgba(255, 255, 255, 0.45);\n border-radius: 3px;\n}\n.ad-dock-zone.active {\n border-color: rgba(97, 175, 239, 0.95);\n background: rgba(97, 175, 239, 0.35);\n}\n.ad-dock-zone.ad-dock-zone-left .ad-dock-mark {\n border-left: 4px solid rgba(97, 175, 239, 0.95);\n}\n.ad-dock-zone.ad-dock-zone-right .ad-dock-mark {\n border-right: 4px solid rgba(97, 175, 239, 0.95);\n}\n.ad-dock-zone.ad-dock-zone-top .ad-dock-mark {\n border-top: 4px solid rgba(97, 175, 239, 0.95);\n}\n.ad-dock-zone.ad-dock-zone-bottom .ad-dock-mark {\n border-bottom: 4px solid rgba(97, 175, 239, 0.95);\n}\n\nbody.ad-resizing {\n cursor: inherit;\n}\nbody.ad-resizing .content.main {\n pointer-events: none;\n}\n\nbody.agentdeck-active .content.main > .tab-bar {\n display: none !important;\n}\nbody.agentdeck-active .window {\n display: flex;\n flex-direction: row;\n position: relative;\n background: var(--ad-panel-bg, var(--bs-body-bg, #1e2127));\n}`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/styles.scss\"],\"names\":[],\"mappings\":\"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\",\"sourcesContent\":[\"// AgentDeck 사이드바 스타일\\r\\n// Tabby 테마 변수(--bs-*)를 우선 쓰되, 없을 때를 대비해 폴백 색을 함께 준다.\\r\\n\\r\\n// tabby-background 의 배경 이미지 레이어(.content-tab-active::before)를 터미널 영역으로 자른다.\\r\\n// 좌표 변수(--ad-bg-*)는 deck.service 의 syncBackgroundClip 이 relayout 마다 내려준다.\\r\\n// 그 플러그인은 런타임에 <style> 을 만들어 head 뒤쪽에 붙이므로 순서로는 못 이긴다 — !important 필수.\\r\\nbody.agentdeck-active.ad-bg-clip .content-tab-active::before {\\r\\n left: var(--ad-bg-left) !important;\\r\\n top: var(--ad-bg-top) !important;\\r\\n right: auto !important;\\r\\n bottom: auto !important;\\r\\n width: var(--ad-bg-width) !important;\\r\\n height: var(--ad-bg-height) !important;\\r\\n}\\r\\n\\r\\n#agentdeck-sidebar {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n // 실제 위치와 크기는 deck.service 의 relayout 이 인라인으로 준다 (도킹 방향에 따라 달라짐)\\r\\n z-index: 5;\\r\\n overflow: hidden;\\r\\n // --ad-panel-bg 는 agentdeck 이 sidebarOpacity 로 내려준다 (배경 이미지가 비치게)\\r\\n background: var(--ad-panel-bg, var(--bs-body-bg, #1e2127));\\r\\n font-size: 12px;\\r\\n user-select: none;\\r\\n -webkit-app-region: no-drag;\\r\\n\\r\\n // 붙어 있는 쪽 반대편에만 경계선을 그린다\\r\\n &.ad-dock-right { border-left: 1px solid rgba(255, 255, 255, 0.08); }\\r\\n &.ad-dock-left { border-right: 1px solid rgba(255, 255, 255, 0.08); }\\r\\n &.ad-dock-top { border-bottom: 1px solid rgba(255, 255, 255, 0.08); }\\r\\n &.ad-dock-bottom { border-top: 1px solid rgba(255, 255, 255, 0.08); }\\r\\n\\r\\n // 상/하 도킹은 세로가 짧으므로 목록을 가로로 흘린다\\r\\n &.ad-dock-top,\\r\\n &.ad-dock-bottom {\\r\\n .ad-list {\\r\\n display: flex;\\r\\n flex-wrap: wrap;\\r\\n align-content: flex-start;\\r\\n gap: 0 6px;\\r\\n overflow-y: auto;\\r\\n }\\r\\n\\r\\n .ad-tab {\\r\\n flex: 0 0 220px;\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-head {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n padding: 10px 12px 8px;\\r\\n letter-spacing: 0.12em;\\r\\n font-size: 10px;\\r\\n font-weight: 700;\\r\\n color: rgba(255, 255, 255, 0.4);\\r\\n // 헤더를 잡아 끌면 도킹 방향을 바꾼다 (OS 창 이동에 뺏기면 안 되므로 no-drag)\\r\\n -webkit-app-region: no-drag;\\r\\n cursor: grab;\\r\\n\\r\\n &:active {\\r\\n cursor: grabbing;\\r\\n }\\r\\n }\\r\\n\\r\\n // 경계선 — 잡아 끌면 크기가 바뀐다. 붙어 있는 쪽 반대편 가장자리에 놓는다\\r\\n .ad-resize {\\r\\n position: absolute;\\r\\n z-index: 6;\\r\\n background: transparent;\\r\\n transition: background 0.12s ease;\\r\\n\\r\\n &:hover,\\r\\n body.ad-resizing & {\\r\\n background: rgba(97, 175, 239, 0.5);\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-resize-right,\\r\\n .ad-resize-left {\\r\\n top: 0;\\r\\n bottom: 0;\\r\\n width: 6px;\\r\\n cursor: col-resize;\\r\\n }\\r\\n\\r\\n .ad-resize-right { left: 0; }\\r\\n .ad-resize-left { right: 0; }\\r\\n\\r\\n .ad-resize-top,\\r\\n .ad-resize-bottom {\\r\\n left: 0;\\r\\n right: 0;\\r\\n height: 6px;\\r\\n cursor: row-resize;\\r\\n }\\r\\n\\r\\n .ad-resize-bottom { top: 0; }\\r\\n .ad-resize-top { bottom: 0; }\\r\\n\\r\\n // 상태별 집계 칩 한 줄 — `⏸ 2 ● 3 ○ 1`. 헤더 높이는 총 개수만 있던 때와 같게 유지한다\\r\\n .ad-head-count {\\r\\n -webkit-app-region: no-drag;\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 6px;\\r\\n flex: 0 0 auto;\\r\\n white-space: nowrap;\\r\\n letter-spacing: 0;\\r\\n color: rgba(255, 255, 255, 0.55);\\r\\n }\\r\\n\\r\\n .ad-cnt {\\r\\n padding: 1px 6px;\\r\\n border-radius: 8px;\\r\\n background: rgba(255, 255, 255, 0.08);\\r\\n color: var(--ad-color, rgba(255, 255, 255, 0.55));\\r\\n font-size: 10px;\\r\\n line-height: 1.3;\\r\\n font-variant-numeric: tabular-nums;\\r\\n }\\r\\n\\r\\n // 요구 2-1: 탭이 많아지면 이 영역만 스크롤된다\\r\\n .ad-list {\\r\\n flex: 1 1 auto;\\r\\n overflow-y: auto;\\r\\n overflow-x: hidden;\\r\\n padding: 2px 6px 8px;\\r\\n\\r\\n &::-webkit-scrollbar {\\r\\n width: 8px;\\r\\n }\\r\\n\\r\\n &::-webkit-scrollbar-thumb {\\r\\n background: rgba(255, 255, 255, 0.14);\\r\\n border-radius: 4px;\\r\\n\\r\\n &:hover {\\r\\n background: rgba(255, 255, 255, 0.24);\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-tab {\\r\\n position: relative;\\r\\n display: flex;\\r\\n align-items: stretch;\\r\\n gap: 8px;\\r\\n margin-bottom: 3px;\\r\\n padding: 7px 6px 7px 0;\\r\\n border-radius: 5px;\\r\\n cursor: pointer;\\r\\n transition: background 0.1s ease;\\r\\n\\r\\n &:hover {\\r\\n background: rgba(255, 255, 255, 0.05);\\r\\n\\r\\n .ad-close {\\r\\n opacity: 0.65;\\r\\n }\\r\\n }\\r\\n\\r\\n &.active {\\r\\n background: rgba(255, 255, 255, 0.1);\\r\\n\\r\\n .ad-title {\\r\\n color: #fff;\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n // 상태색 표시 바\\r\\n .ad-bar {\\r\\n flex: 0 0 3px;\\r\\n border-radius: 2px;\\r\\n background: var(--ad-color, #6b727d);\\r\\n }\\r\\n\\r\\n .ad-body {\\r\\n flex: 1 1 auto;\\r\\n min-width: 0;\\r\\n }\\r\\n\\r\\n .ad-title {\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n color: rgba(255, 255, 255, 0.82);\\r\\n font-size: 12.5px;\\r\\n line-height: 1.35;\\r\\n }\\r\\n\\r\\n .ad-meta {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 6px;\\r\\n margin-top: 2px;\\r\\n font-size: 10.5px;\\r\\n line-height: 1.4;\\r\\n color: rgba(255, 255, 255, 0.45);\\r\\n }\\r\\n\\r\\n .ad-badge {\\r\\n // 이유가 붙으면(승인대기 · Bash 권한) 길어질 수 있다 — 경과시간을 밀어내지 않게 줄이고 말줄임\\r\\n flex: 0 1 auto;\\r\\n min-width: 0;\\r\\n max-width: 100%;\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n color: var(--ad-color, #6b727d);\\r\\n font-weight: 600;\\r\\n\\r\\n // 수동/훅으로 고정된 상태는 밑줄로 구분\\r\\n &.pinned {\\r\\n text-decoration: underline dotted;\\r\\n text-underline-offset: 2px;\\r\\n }\\r\\n }\\r\\n\\r\\n // 두 번째 줄 — 마지막으로 보낸 프롬프트\\r\\n .ad-prompt {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n margin-top: 2px;\\r\\n min-width: 0;\\r\\n font-size: 11px;\\r\\n line-height: 1.4;\\r\\n }\\r\\n\\r\\n .ad-label {\\r\\n flex: 1 1 auto;\\r\\n overflow: hidden;\\r\\n text-overflow: ellipsis;\\r\\n white-space: nowrap;\\r\\n color: rgba(255, 255, 255, 0.6);\\r\\n\\r\\n // 아직 프롬프트가 없는 탭 — 자리는 지키되 눈에 덜 걸리게\\r\\n &.empty {\\r\\n color: rgba(255, 255, 255, 0.25);\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-elapsed {\\r\\n flex: 0 0 auto;\\r\\n margin-left: auto;\\r\\n font-variant-numeric: tabular-nums;\\r\\n opacity: 0.55;\\r\\n }\\r\\n\\r\\n .ad-label-input {\\r\\n flex: 1 1 auto;\\r\\n min-width: 0;\\r\\n padding: 0 4px;\\r\\n border: 1px solid rgba(255, 255, 255, 0.25);\\r\\n border-radius: 3px;\\r\\n background: rgba(0, 0, 0, 0.35);\\r\\n color: #fff;\\r\\n font-size: 10.5px;\\r\\n outline: none;\\r\\n\\r\\n &:focus {\\r\\n border-color: var(--ad-color, #61afef);\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-close {\\r\\n flex: 0 0 auto;\\r\\n align-self: center;\\r\\n width: 18px;\\r\\n height: 18px;\\r\\n padding: 0;\\r\\n border: 0;\\r\\n border-radius: 3px;\\r\\n opacity: 0;\\r\\n background: transparent;\\r\\n color: rgba(255, 255, 255, 0.8);\\r\\n font-size: 15px;\\r\\n line-height: 1;\\r\\n cursor: pointer;\\r\\n transition: opacity 0.1s ease, background 0.1s ease;\\r\\n\\r\\n &:hover {\\r\\n opacity: 1 !important;\\r\\n background: rgba(255, 80, 80, 0.35);\\r\\n }\\r\\n }\\r\\n\\r\\n .ad-foot {\\r\\n display: flex;\\r\\n gap: 6px;\\r\\n padding: 8px;\\r\\n border-top: 1px solid rgba(255, 255, 255, 0.07);\\r\\n }\\r\\n\\r\\n .ad-btn {\\r\\n flex: 1 1 auto;\\r\\n padding: 5px 8px;\\r\\n border: 1px solid rgba(255, 255, 255, 0.12);\\r\\n border-radius: 4px;\\r\\n background: transparent;\\r\\n color: rgba(255, 255, 255, 0.6);\\r\\n font-size: 11px;\\r\\n cursor: pointer;\\r\\n\\r\\n &:hover {\\r\\n background: rgba(255, 255, 255, 0.08);\\r\\n color: #fff;\\r\\n }\\r\\n }\\r\\n\\r\\n // 복구 버튼은 글자가 한 자뿐이라 나머지 버튼과 같은 비율로 늘어나면 허전하다\\r\\n .ad-repair {\\r\\n flex: 0 0 auto;\\r\\n min-width: 28px;\\r\\n font-size: 13px;\\r\\n line-height: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n// 우클릭 상태 메뉴\\r\\n.ad-menu {\\r\\n position: fixed;\\r\\n z-index: 10000;\\r\\n min-width: 130px;\\r\\n padding: 4px;\\r\\n border: 1px solid rgba(255, 255, 255, 0.12);\\r\\n border-radius: 6px;\\r\\n background: #262a31;\\r\\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);\\r\\n font-size: 12px;\\r\\n user-select: none;\\r\\n\\r\\n .ad-menu-item {\\r\\n padding: 6px 10px;\\r\\n border-radius: 4px;\\r\\n color: rgba(255, 255, 255, 0.75);\\r\\n cursor: pointer;\\r\\n\\r\\n &:hover {\\r\\n background: rgba(255, 255, 255, 0.1);\\r\\n color: #fff;\\r\\n }\\r\\n }\\r\\n}\\r\\n\\r\\n// 도킹 가이드 — 헤더를 끌고 있는 동안만 창 위에 뜬다\\r\\n.ad-dock-overlay {\\r\\n position: fixed;\\r\\n inset: 0;\\r\\n z-index: 9998;\\r\\n // 커서 판정은 좌표로 직접 하므로 오버레이가 이벤트를 가로채면 안 된다\\r\\n pointer-events: none;\\r\\n}\\r\\n\\r\\n// 놓으면 사이드바가 자리잡을 영역\\r\\n.ad-dock-preview {\\r\\n position: fixed;\\r\\n display: none;\\r\\n border: 1px solid rgba(97, 175, 239, 0.9);\\r\\n background: rgba(97, 175, 239, 0.22);\\r\\n box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.18);\\r\\n transition: left 0.08s ease, top 0.08s ease, width 0.08s ease, height 0.08s ease;\\r\\n}\\r\\n\\r\\n// 네 가장자리에 뜨는 도킹 표적\\r\\n.ad-dock-zone {\\r\\n position: fixed;\\r\\n width: 46px;\\r\\n height: 46px;\\r\\n margin: -23px 0 0 -23px;\\r\\n border: 1px solid rgba(255, 255, 255, 0.35);\\r\\n border-radius: 6px;\\r\\n background: rgba(38, 42, 49, 0.92);\\r\\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n\\r\\n .ad-dock-mark {\\r\\n width: 26px;\\r\\n height: 26px;\\r\\n border: 1px solid rgba(255, 255, 255, 0.45);\\r\\n border-radius: 3px;\\r\\n }\\r\\n\\r\\n &.active {\\r\\n border-color: rgba(97, 175, 239, 0.95);\\r\\n background: rgba(97, 175, 239, 0.35);\\r\\n }\\r\\n\\r\\n // 표적 안의 작은 사각형이 \\\"어느 쪽 절반에 붙는지\\\" 를 그대로 보여준다\\r\\n &.ad-dock-zone-left .ad-dock-mark { border-left: 4px solid rgba(97, 175, 239, 0.95); }\\r\\n &.ad-dock-zone-right .ad-dock-mark { border-right: 4px solid rgba(97, 175, 239, 0.95); }\\r\\n &.ad-dock-zone-top .ad-dock-mark { border-top: 4px solid rgba(97, 175, 239, 0.95); }\\r\\n &.ad-dock-zone-bottom .ad-dock-mark { border-bottom: 4px solid rgba(97, 175, 239, 0.95); }\\r\\n}\\r\\n\\r\\n// 경계선을 끄는 동안에는 터미널이 커서를 뺏지 않게 한다\\r\\nbody.ad-resizing {\\r\\n cursor: inherit;\\r\\n\\r\\n .content.main {\\r\\n pointer-events: none;\\r\\n }\\r\\n}\\r\\n\\r\\n// AgentDeck 이 켜져 있을 때만 순정 탭바를 감춘다 (사이드바가 그 역할을 대신함)\\r\\nbody.agentdeck-active {\\r\\n .content.main > .tab-bar {\\r\\n display: none !important;\\r\\n }\\r\\n\\r\\n .window {\\r\\n display: flex;\\r\\n flex-direction: row;\\r\\n // 사이드바를 창 안에 절대 배치하므로 기준점이 필요하다\\r\\n position: relative;\\r\\n // 터미널 옆에 남는 여백이 밝은 기본 배경으로 튀지 않게 한다\\r\\n // (--ad-panel-bg 가 있으면 배경 이미지가 이 여백으로도 비친다)\\r\\n background: var(--ad-panel-bg, var(--bs-body-bg, #1e2127));\\r\\n }\\r\\n}\\r\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};","\"use strict\";\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [content].concat([sourceMapping]).join(\"\\n\");\n }\n return [content].join(\"\\n\");\n};","\n import API from \"!../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../node_modules/css-loader/dist/cjs.js!../node_modules/sass-loader/dist/cjs.js!./styles.scss\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../node_modules/css-loader/dist/cjs.js!../node_modules/sass-loader/dist/cjs.js!./styles.scss\";\n export default content && content.locals ? content.locals : undefined;\n","\"use strict\";\n\nvar stylesInDOM = [];\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n return result;\n}\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n identifiers.push(identifier);\n }\n return identifiers;\n}\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n return updater;\n}\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n var newLastIdentifiers = modulesToDom(newList, options);\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n var _index = getIndexByIdentifier(_identifier);\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n stylesInDOM.splice(_index, 1);\n }\n }\n lastIdentifiers = newLastIdentifiers;\n };\n};","\"use strict\";\n\nvar memo = {};\n\n/* istanbul ignore next */\nfunction getTarget(target) {\n if (typeof memo[target] === \"undefined\") {\n var styleTarget = document.querySelector(target);\n\n // Special case to return head of iframe instead of iframe itself\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n memo[target] = styleTarget;\n }\n return memo[target];\n}\n\n/* istanbul ignore next */\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n target.appendChild(style);\n}\nmodule.exports = insertBySelector;","\"use strict\";\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement(\"style\");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\nmodule.exports = insertStyleElement;","\"use strict\";\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = typeof __webpack_nonce__ !== \"undefined\" ? __webpack_nonce__ : null;\n if (nonce) {\n styleElement.setAttribute(\"nonce\", nonce);\n }\n}\nmodule.exports = setAttributesWithoutAttributes;","\"use strict\";\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = \"\";\n if (obj.supports) {\n css += \"@supports (\".concat(obj.supports, \") {\");\n }\n if (obj.media) {\n css += \"@media \".concat(obj.media, \" {\");\n }\n var needLayer = typeof obj.layer !== \"undefined\";\n if (needLayer) {\n css += \"@layer\".concat(obj.layer.length > 0 ? \" \".concat(obj.layer) : \"\", \" {\");\n }\n css += obj.css;\n if (needLayer) {\n css += \"}\";\n }\n if (obj.media) {\n css += \"}\";\n }\n if (obj.supports) {\n css += \"}\";\n }\n var sourceMap = obj.sourceMap;\n if (sourceMap && typeof btoa !== \"undefined\") {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n }\n\n // For old IE\n /* istanbul ignore if */\n options.styleTagTransform(css, styleElement, options.options);\n}\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n styleElement.parentNode.removeChild(styleElement);\n}\n\n/* istanbul ignore next */\nfunction domAPI(options) {\n if (typeof document === \"undefined\") {\n return {\n update: function update() {},\n remove: function remove() {}\n };\n }\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\nmodule.exports = domAPI;","\"use strict\";\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n styleElement.appendChild(document.createTextNode(css));\n }\n}\nmodule.exports = styleTagTransform;","import { Injectable, NgZone } from '@angular/core'\nimport { AppService, BaseTabComponent, ConfigService } from 'tabby-core'\nimport * as fs from 'fs'\nimport * as os from 'os'\nimport * as path from 'path'\nimport { WorkStatusService } from './status.service'\nimport { STATUS_STYLES, WorkStatus } from './api'\n\nconst DIAG_PATH = path.join(os.homedir(), '.agentdeck-diag.log')\n\n/** 창 밖으로 알려야 하는 상태 — 사람이 손을 대야 진행되는 것들 */\n/** 창이 뒤에 있을 때 알릴 상태 — 사람이 봐야 하는 것: 승인 / 오류 / 한도에 걸려 멈춤 */\nconst ALERT_STATUSES: WorkStatus[] = ['waiting', 'error', 'limited']\n\n/**\n * 창이 뒤로 가 있을 때의 OS 알림.\n *\n * 사이드바는 창이 보일 때만 의미가 있다. 에이전트 탭을 여섯 개쯤 굴리면서 Slack·VS 를 보고\n * 있으면 어느 탭이 `승인대기` 로 멈춰 있어도 알 길이 없어서, 돌아와 보면 몇 분씩 놀고 있던\n * 일이 잦았다. 그래서 상태가 **`waiting` / `error` 로 넘어가는 순간** 창이 포커스를 잃은\n * 상태면 OS 쪽에 세 가지로 알린다.\n *\n * 1. **작업표시줄 깜빡임** (`flashFrame`) — 창이 포커스를 받으면 끈다. `alertFlash`\n * 2. **작업표시줄 뱃지** — 지금 `waiting`+`error` 인 탭 수를 아이콘 위에 얹는다. Windows 에는\n * `setBadgeCount` 가 없어서 `setOverlayIcon` 에 캔버스로 그린 원+숫자를 넣는다.\n * 전이 순간만이 아니라 상태가 바뀔 때마다 갱신해 실제 개수를 따라간다. `alertBadge`\n * 3. **OS 토스트** (`Notification`) — 기본은 끔. 누르면 창을 앞으로 가져오고 그 탭을 고른다. `alertToast`\n *\n * 창이 앞에 있을 때는 아무것도 하지 않는다 — 사이드바가 이미 보이고 있다.\n * Electron 을 만지는 모든 곳은 try/catch 로 감싼다. 알림이 안 되는 것은 불편이지만\n * 예외가 새어 나가 다른 배선을 죽이는 것은 사고다.\n */\n@Injectable({ providedIn: 'root' })\nexport class AgentDeckAlertService {\n /** 탭별로 마지막에 본 상태 — \"전이\" 를 판정하려고 들고 있는다 */\n private last = new WeakMap<BaseTabComponent, WorkStatus>()\n /** flashFrame(true) 를 걸어 둔 상태인가 — 포커스가 오면 끈다 */\n private flashing = false\n /** 마지막으로 그린 뱃지 숫자 (0 = 안 그림). 같은 숫자면 다시 그리지 않는다 */\n private badgeShown = 0\n /** 뱃지 그림 캐시 — key 는 `${count}:${color}` */\n private badgeCache = new Map<string, any>()\n\n /**\n * 진단/검증용 카운터 — CDP 에서 `__agentdeck.alert` 로 읽는다.\n * `forceUnfocused` 를 true 로 두면 포커스 판정을 건너뛰고 \"창이 뒤에 있다\" 로 친다\n * (테스트 인스턴스가 앞에 떠 있는 상태에서 알림 경로를 밟아 보려고)\n */\n debug = {\n flashes: 0,\n badgeCount: 0,\n badgeDraws: 0,\n toasts: 0,\n transitions: 0,\n lastFocused: null as boolean | null,\n forceUnfocused: false,\n }\n\n constructor (\n private app: AppService,\n private config: ConfigService,\n private zone: NgZone,\n private status: WorkStatusService,\n ) { }\n\n init (): void {\n this.app.ready$.subscribe(() => {\n try {\n this.setup()\n } catch (e: any) {\n this.diag(`alert setup ERROR ${e?.message ?? e}`)\n }\n })\n }\n\n private setup (): void {\n // 기동 시점의 상태를 기준선으로 삼는다 — 이미 waiting 인 탭은 \"전이\" 가 아니다\n for (const tab of this.app.tabs) {\n this.last.set(tab, this.status.get(tab).status)\n }\n this.status.changed$.subscribe(() => {\n try {\n this.onChanged()\n } catch (e: any) {\n this.diag(`alert onChanged ERROR ${e?.message ?? e}`)\n }\n })\n // 닫힌 탭은 개수에서 빠져야 한다 — status.changed$ 는 탭 닫힘에 안 울린다\n this.app.tabClosed$.subscribe(tab => {\n this.last.delete(tab)\n try {\n this.updateBadge(this.countAlerting())\n } catch (e: any) {\n this.diag(`alert tabClosed ERROR ${e?.message ?? e}`)\n }\n })\n // 사람이 돌아왔다 — 깜빡임은 여기서 끝난다. 뱃지는 상태가 풀릴 때 따로 지워진다\n window.addEventListener('focus', () => this.stopFlash())\n\n // 개발/진단용 — deck.service 가 만든 __agentdeck 에 붙는다 (없으면 만든다)\n const g = window as any\n g.__agentdeck = g.__agentdeck ?? {}\n g.__agentdeck.alert = this.debug\n this.diag(`alert ready tabs=${this.app.tabs.length}`)\n }\n\n /**\n * 상태가 바뀔 때마다 — 뱃지는 항상 실제 개수로 맞추고,\n * 알림 상태로 **새로 들어온** 탭이 있고 창이 뒤에 있으면 깜빡임/토스트를 낸다\n */\n private onChanged (): void {\n const entered: BaseTabComponent[] = []\n let count = 0\n for (const tab of this.app.tabs) {\n const now = this.status.get(tab).status\n const prev = this.last.get(tab)\n this.last.set(tab, now)\n if (!ALERT_STATUSES.includes(now)) {\n continue\n }\n count++\n // waiting -> error 도 전이로 친다 — 성격이 다른 일이 새로 생긴 것이다\n if (prev !== now) {\n entered.push(tab)\n }\n }\n this.updateBadge(count)\n if (entered.length === 0) {\n return\n }\n this.debug.transitions += entered.length\n const focused = this.isFocused()\n this.debug.lastFocused = focused\n if (focused) {\n return\n }\n this.diag(`alert enter=${entered.length} count=${count} focused=${focused}`)\n if (this.config.store.agentDeck.alertFlash) {\n this.flash()\n }\n if (this.config.store.agentDeck.alertToast) {\n for (const tab of entered) {\n this.toast(tab)\n }\n }\n }\n\n private countAlerting (): number {\n let n = 0\n for (const tab of this.app.tabs) {\n if (ALERT_STATUSES.includes(this.status.get(tab).status)) {\n n++\n }\n }\n return n\n }\n\n // ---------- Electron 접근 ----------\n\n /** `@electron/remote` 의 현재 창. 못 잡으면 null — 호출부는 전부 null 을 감안한다 */\n private win (): any {\n try {\n const req = (window as any).require ?? (globalThis as any).require\n return req?.('@electron/remote')?.getCurrentWindow?.() ?? null\n } catch {\n return null\n }\n }\n\n private nativeImage (): any {\n try {\n const req = (window as any).require ?? (globalThis as any).require\n return req?.('electron')?.nativeImage ?? null\n } catch {\n return null\n }\n }\n\n /**\n * 창이 앞에 있나. Electron 의 판정을 우선하고(devtools 를 따로 띄워도 본창 기준으로 본다),\n * remote 를 못 잡으면 DOM 의 `document.hasFocus()` 로 대신한다\n */\n private isFocused (): boolean {\n if (this.debug.forceUnfocused) {\n return false\n }\n try {\n const win = this.win()\n if (win?.isFocused) {\n return !!win.isFocused()\n }\n } catch {\n // 아래 DOM 판정으로\n }\n return document.hasFocus()\n }\n\n // ---------- 깜빡임 ----------\n\n private flash (): void {\n try {\n const win = this.win()\n if (!win?.flashFrame) {\n return\n }\n win.flashFrame(true)\n this.flashing = true\n this.debug.flashes++\n } catch (e: any) {\n this.diag(`alert flash ERROR ${e?.message ?? e}`)\n }\n }\n\n private stopFlash (): void {\n if (!this.flashing) {\n return\n }\n this.flashing = false\n try {\n this.win()?.flashFrame?.(false)\n } catch {\n // 포커스가 오면 Windows 가 알아서 멈추므로 실패해도 남는 건 없다\n }\n }\n\n // ---------- 뱃지 ----------\n\n /**\n * 작업표시줄 아이콘 위의 숫자를 지금 개수로 맞춘다. 0 이면 지운다.\n * `alertBadge` 가 꺼져 있으면 그려 둔 것이 있을 때만 지우고 끝낸다\n */\n private updateBadge (count: number): void {\n this.debug.badgeCount = count\n const enabled = !!this.config.store.agentDeck.alertBadge\n const want = enabled ? count : 0\n if (want === this.badgeShown) {\n return\n }\n try {\n const win = this.win()\n if (!win?.setOverlayIcon) {\n return\n }\n if (want === 0) {\n win.setOverlayIcon(null, '')\n this.badgeShown = 0\n // 개수가 0 으로 내려왔으면 깜빡일 이유도 사라졌다\n this.stopFlash()\n return\n }\n const img = this.badgeImage(want)\n if (!img) {\n return\n }\n win.setOverlayIcon(img, `승인대기/오류 ${want}개`)\n this.badgeShown = want\n this.debug.badgeDraws++\n } catch (e: any) {\n this.diag(`alert badge ERROR ${e?.message ?? e}`)\n }\n }\n\n /**\n * 원 위에 숫자를 얹은 오버레이 이미지. 오류 탭이 하나라도 있으면 오류색, 아니면 승인대기색.\n * Windows 오버레이는 16px 기준이라 16@1x + 32@2x 두 표현을 넣는다 (고배율에서 흐려지지 않게).\n * `addRepresentation` 을 못 쓰는 빌드면 32px 하나로 물러난다\n */\n private badgeImage (count: number): any {\n const hasError = this.app.tabs.some(t => this.status.get(t).status === 'error')\n const color = hasError ? STATUS_STYLES.error.color : STATUS_STYLES.waiting.color\n const key = `${count}:${color}`\n const cached = this.badgeCache.get(key)\n if (cached) {\n return cached\n }\n const nativeImage = this.nativeImage()\n if (!nativeImage) {\n return null\n }\n const text = count > 9 ? '9+' : String(count)\n let img: any\n try {\n img = nativeImage.createEmpty()\n img.addRepresentation({ scaleFactor: 1, width: 16, height: 16, dataURL: this.drawBadge(16, text, color) })\n img.addRepresentation({ scaleFactor: 2, width: 32, height: 32, dataURL: this.drawBadge(32, text, color) })\n if (img.isEmpty?.()) {\n throw new Error('empty after addRepresentation')\n }\n } catch {\n img = nativeImage.createFromDataURL(this.drawBadge(32, text, color))\n }\n this.badgeCache.set(key, img)\n return img\n }\n\n /** 오프스크린 canvas 에 원+숫자를 그려 data URL 로 돌려준다 */\n private drawBadge (size: number, text: string, color: string): string {\n const canvas = document.createElement('canvas')\n canvas.width = size\n canvas.height = size\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n throw new Error('canvas 2d 미지원')\n }\n const r = size / 2\n ctx.clearRect(0, 0, size, size)\n ctx.beginPath()\n ctx.arc(r, r, r - 0.5, 0, Math.PI * 2)\n ctx.fillStyle = color\n ctx.fill()\n // 어두운 작업표시줄 위에서 원 테두리가 살게 얇은 흰 선\n ctx.lineWidth = Math.max(1, size / 16)\n ctx.strokeStyle = 'rgba(255,255,255,0.85)'\n ctx.stroke()\n ctx.fillStyle = '#ffffff'\n ctx.font = `bold ${Math.round(size * (text.length > 1 ? 0.55 : 0.7))}px \"Segoe UI\", sans-serif`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n // 글리프의 시각적 중심이 살짝 위로 치우쳐서 조금 내린다\n ctx.fillText(text, r, r + size * 0.04)\n return canvas.toDataURL('image/png')\n }\n\n // ---------- 토스트 ----------\n\n /** OS 토스트. 누르면 창을 앞으로 가져오고 그 탭을 고른다 */\n private toast (tab: BaseTabComponent): void {\n try {\n if (typeof Notification === 'undefined') {\n return\n }\n const s = this.status.get(tab)\n const name = s.label || tab.title || '(제목 없음)'\n const style = STATUS_STYLES[s.status]\n const n = new Notification('AgentDeck', {\n body: `${name} — ${style.label}`,\n // 같은 탭의 토스트는 하나로 겹친다 (waiting -> error 가 잇달아 와도 두 장이 쌓이지 않게)\n tag: `agentdeck-${this.tabKey(tab)}`,\n })\n this.debug.toasts++\n n.onclick = () => {\n try {\n const win = this.win()\n win?.show?.()\n win?.focus?.()\n } catch {\n // 창을 못 올려도 탭 선택은 해 둔다\n }\n this.zone.run(() => {\n if (this.app.tabs.includes(tab)) {\n this.app.selectTab(tab)\n }\n })\n n.close()\n }\n } catch (e: any) {\n this.diag(`alert toast ERROR ${e?.message ?? e}`)\n }\n }\n\n /** 토스트 tag 용 탭 식별자 — 객체 자체는 문자열이 안 되니 인덱스로 대신한다 */\n private tabKey (tab: BaseTabComponent): string {\n const i = this.app.tabs.indexOf(tab)\n return i >= 0 ? String(i) : 'x'\n }\n\n // ---------- 진단 ----------\n\n /** deck.service 와 같은 파일(`~/.agentdeck-diag.log`)에 남긴다. 실패해도 동작에는 영향 없다 */\n private diag (line: string): void {\n try {\n fs.appendFileSync(DIAG_PATH, `${new Date().toISOString()} ${line}\\n`)\n } catch {\n console.debug('[agentdeck]', line)\n }\n }\n}\n","/**\n * 사이드바에 표시되는 작업 상태.\n *\n * `limited`(한도 도달)는 에이전트가 사용량 한도에 걸려 턴이 끊긴 상태다 — Claude Code 의\n * `StopFailure` 훅이 `error: rate_limit` 로 알려준다. 사람이 승인할 것은 없고 리셋 시각까지 기다려야\n * 하므로 승인대기와는 구분해서 보여준다 (2026-09-07 요청).\n */\nexport type WorkStatus = 'idle' | 'running' | 'waiting' | 'limited' | 'done' | 'error'\n\nexport interface StatusStyle {\n icon: string\n label: string\n color: string\n}\n\n/** 상태별 표시 규칙 — 사이드바 배지와 좌측 컬러바에 함께 쓰인다 */\nexport const STATUS_STYLES: Record<WorkStatus, StatusStyle> = {\n running: { icon: '●', label: '진행중', color: '#e5c07b' },\n waiting: { icon: '⏸', label: '승인대기', color: '#61afef' },\n limited: { icon: '⛔', label: '한도 도달', color: '#c678dd' },\n done: { icon: '✔', label: '완료', color: '#98c379' },\n error: { icon: '✖', label: '오류', color: '#e06c75' },\n idle: { icon: '○', label: '대기', color: '#6b727d' },\n}\n\nexport interface TabState {\n /** 현재 상태 */\n status: WorkStatus\n /** 작업 이름 (사용자 지정 또는 훅이 보낸 값) */\n label: string\n /**\n * 상태의 부연 — 훅이 보낸 문구를 줄인 것.\n * - waiting: 승인 이유 (예: `Bash 권한`, `입력 대기`) → 배지 `⏸ 승인대기 · Bash 권한`\n * - limited: 리셋 시각 (예: `12pm 리셋`) → 배지 `⛔ 한도 도달 · 12pm 리셋`\n * - error: StopFailure 의 error 코드 (예: `overloaded`)\n * 그 밖의 상태로 바뀌면 비운다 (status.service REASON_STATUSES)\n */\n reason: string\n /** 상태가 마지막으로 바뀐 시각 */\n since: number\n /** true = 수동/훅 지정. 자동 감지가 덮어쓰지 않는다 */\n pinned: boolean\n /** 마지막 PTY 출력 시각 */\n lastOutput: number\n /**\n * 이 탭에서 에이전트의 \"작업 중\" 신호를 본 적이 있나.\n *\n * 본 적이 있으면 그 탭은 에이전트 TUI 로 보고, 그 뒤로는 신호가 있을 때만 진행중으로 친다.\n * Claude Code 는 놀고 있을 때도 하단 상태줄을 매초 다시 그리기 때문에\n * \"출력이 있다 = 진행중\" 으로 보면 영원히 진행중에서 내려오지 않는다 (2026-09-01 실측).\n */\n busyMode: boolean\n /** 마지막으로 \"작업 중\" 신호를 본 시각 — 진행중에서 내려올 시점을 이걸로 잰다 */\n lastBusy: number\n}\n","/**\r\n * 훅 보고를 어느 탭에 붙일지 고르는 순수 규칙 — Angular/Tabby 에 기대지 않아 단위 테스트가 된다.\r\n *\r\n * 왜 PID 인가 — 예전 규칙 \"처음 보고할 때의 활성 탭\" 은 사용자가 방금 프롬프트를 넣은 탭이\r\n * 곧 활성 탭이라는 가정인데, 파일 폴링이 400ms 마다 못 묶은 보고를 다시 시도하는 탓에\r\n * **끝난 세션의 done 이 다음에 열리는 빈 탭을 붙잡았다** (2026-09-02 실측: 작업 중인 탭이\r\n * \"완료\" 로, 그 탭의 진짜 세션은 주인이 있다며 거절돼 running 이 버려졌다).\r\n *\r\n * 훅은 자기 조상 프로세스 PID 를 함께 보낸다 — claude.exe → 탭 셸 → Tabby.exe 순서다.\r\n * 탭마다 pty 가 띄운 셸 PID 를 알고 있으면 어느 탭의 보고인지 추측 없이 확정된다.\r\n */\r\nexport type BindMode = 'pid' | 'pid-miss' | 'legacy'\r\n\r\nexport interface BindPick<T> {\r\n tab: T | null\r\n /**\r\n * pid — 조상 PID 가 어떤 탭의 셸 PID 와 맞았다 (확정)\r\n * pid-miss — pids 도 왔고 탭 PID 표도 있는데 맞는 탭이 없다. 활성 탭으로 추측하지 **않는다**\r\n * (탭 PID 표가 아직 안 채워진 것일 수 있으니 호출자는 다음 폴링에 다시 본다)\r\n * legacy — pids 가 없거나(옛 훅·수동 호출) 탭 PID 를 하나도 모른다. 호출자가 예전 활성 탭 규칙을 쓴다\r\n */\r\n mode: BindMode\r\n}\r\n\r\nexport function pickTabByPids<T> (pids: number[] | undefined, tabPids: Map<T, number[]>): BindPick<T> {\r\n const wanted = (pids ?? []).filter(n => Number.isInteger(n) && n > 0)\r\n let anyInfo = false\r\n for (const list of tabPids.values()) {\r\n if (list.length) {\r\n anyInfo = true\r\n break\r\n }\r\n }\r\n if (!wanted.length || !anyInfo) {\r\n return { tab: null, mode: 'legacy' }\r\n }\r\n const set = new Set(wanted)\r\n for (const [tab, list] of tabPids) {\r\n if (list.some(p => set.has(p))) {\r\n return { tab, mode: 'pid' }\r\n }\r\n }\r\n return { tab: null, mode: 'pid-miss' }\r\n}\r\n","import * as fs from 'fs'\r\nimport * as os from 'os'\r\nimport * as path from 'path'\r\n\r\n/**\r\n * Claude Code 상태 통보 훅을 사용자의 Claude 설정에 등록/해제한다.\r\n *\r\n * 왜 플러그인이 남의 설정 파일을 만지나 — 훅은 Claude Code 쪽 설정(`~/.claude/settings.json`)에\r\n * 있어야 하고, npm 으로 배포되는 Tabby 플러그인은 그 파일에 손댈 방법이 달리 없다.\r\n * 그래서 \"설치할지\" 를 사용자가 설정 창에서 직접 고르게 하고, 고른 순간에만 쓴다.\r\n * 쓰기 전에 항상 백업을 남기고, 남의 훅은 건드리지 않는다.\r\n *\r\n * 훅이 있으면 상태 판정이 정확해진다. 에이전트가 \"지시를 받았다 / 승인을 기다린다 / 끝났다\" 를\r\n * 직접 알려주기 때문이다. 훅이 없으면 화면에 그려진 글자로 추측하는 폴백(detect.ts)이 도는데,\r\n * 그건 TUI 가 화면을 어떻게 그리는지에 기대는 만큼 흔들린다.\r\n */\r\n\r\n/** 우리 훅인지 알아보는 표식 — 파일 이름이 그대로 명령줄에 들어간다 */\r\nconst MARK = 'agentdeck-notify'\r\n\r\n/**\r\n * 어떤 순간에 무엇을 보고할지.\r\n *\r\n * **상태만 보낸다 — 작업 이름은 여기서 보내지 않는다.** 라벨은 플러그인이 Enter 시점에\r\n * 입력창을 읽어 매번 갱신하는 경로(`claimEnterLabel`)가 전담한다. 예전에는 여기에\r\n * `-PromptAsLabel` 이 붙어 있었는데, 훅이 상태 파일의 직전 라벨을 도로 써 넣는 바람에\r\n * 플러그인이 방금 넣은 최신 프롬프트를 옛 값으로 되돌렸다 (2026-09-01 실측).\r\n */\r\nconst PLAN: { event: string, args: string }[] = [\r\n // 지시를 받았다\r\n { event: 'UserPromptSubmit', args: '-Status running' },\r\n // 승인을 기다린다\r\n { event: 'Notification', args: '-Status waiting' },\r\n // 승인 뒤 도구가 돌았다 / 실패했다 / 사람이 거부했다 — 어느 쪽이든 에이전트는 다시 일하는 중이다.\r\n // 이 셋이 없으면 승인대기에서 내려올 훅이 Stop 밖에 없어 승인을 해 줘도 사이드바가 승인대기에\r\n // 박혀 있었다 (2026-09-07 실측). 스크립트는 이미 running 이면 아무것도 쓰지 않아 도구마다 도는 비용이 없다\r\n { event: 'PostToolUse', args: '-Status running' },\r\n { event: 'PostToolUseFailure', args: '-Status running' },\r\n { event: 'PermissionDenied', args: '-Status running' },\r\n // 답이 끝났다\r\n { event: 'Stop', args: '-Status done' },\r\n // 턴이 실패로 끝났다 — 스크립트가 `error` 를 보고 rate_limit(사용량 한도)이면 limited 로 바꿔 보낸다\r\n { event: 'StopFailure', args: '-Status error' },\r\n]\r\n\r\nexport function claudeSettingsPath (): string {\r\n return path.join(os.homedir(), '.claude', 'settings.json')\r\n}\r\n\r\n/** 훅 스크립트의 실제 경로. dist/index.js 기준으로 한 단계 위가 패키지 뿌리다 */\r\nexport function notifyScriptPath (): string {\r\n return path.join(__dirname, '..', 'hooks', 'agentdeck-notify.ps1')\r\n}\r\n\r\n/** 이 환경에서 훅을 걸 수 있나 — 통보 스크립트가 PowerShell 이라 Windows 전용이다 */\r\nexport function hooksSupported (): boolean {\r\n return process.platform === 'win32' && fs.existsSync(notifyScriptPath())\r\n}\r\n\r\nfunction readSettings (): any {\r\n try {\r\n const raw = fs.readFileSync(claudeSettingsPath(), 'utf8')\r\n return raw.trim() ? JSON.parse(raw) : {}\r\n } catch {\r\n // 파일이 없거나 아직 JSON 이 아니다 — 새로 만드는 것으로 본다\r\n return {}\r\n }\r\n}\r\n\r\n/** 이 이벤트에 걸린 훅 중 우리 것이 아닌 것만 남긴다 */\r\nfunction withoutOurs (entries: any): any[] {\r\n return (Array.isArray(entries) ? entries : [])\r\n .filter(e => !JSON.stringify(e ?? '').includes(MARK))\r\n}\r\n\r\n/**\r\n * 우리 훅이 PLAN 의 모든 이벤트에 걸려 있나 — 파일을 읽지 않는 순수 판정.\r\n * 이벤트가 늘어난 버전으로 올라오면 옛 설치는 \"설치 안 됨\" 으로 보인다 — 설정 창에서 설치를 다시 누르면 된다.\r\n * 파일 접근과 분리해 둔 이유는 이 판단을 테스트로 묶어 두기 위해서다.\r\n */\r\nexport function isMerged (settings: any): boolean {\r\n const hooks = settings?.hooks ?? {}\r\n return PLAN.every(p => {\r\n const entries = Array.isArray(hooks[p.event]) ? hooks[p.event] : []\r\n return entries.some((e: any) => JSON.stringify(e ?? '').includes(MARK))\r\n })\r\n}\r\n\r\n/**\r\n * 설정 객체에 우리 훅을 더한 새 객체를 돌려준다 (원본은 건드리지 않는다).\r\n * 이미 우리 것이 있으면 명령줄만 지금 경로로 갈아끼우고, 남이 걸어 둔 훅은 그대로 둔다.\r\n */\r\nexport function mergeHooks (settings: any, script: string): any {\r\n const next = { ...(settings ?? {}) }\r\n next.hooks = { ...(next.hooks ?? {}) }\r\n for (const p of PLAN) {\r\n const command = `powershell -NoProfile -ExecutionPolicy Bypass -File \"${script}\" ${p.args}`\r\n next.hooks[p.event] = [\r\n ...withoutOurs(next.hooks[p.event]),\r\n { matcher: '*', hooks: [{ type: 'command', command, timeout: 5 }] },\r\n ]\r\n }\r\n return next\r\n}\r\n\r\n/** 우리 훅만 걷어낸 새 객체. 비어 버린 이벤트 키는 지워서 설정을 깨끗하게 남긴다 */\r\nexport function stripHooks (settings: any): any {\r\n const next = { ...(settings ?? {}) }\r\n if (!next.hooks) {\r\n return next\r\n }\r\n next.hooks = { ...next.hooks }\r\n for (const p of PLAN) {\r\n const kept = withoutOurs(next.hooks[p.event])\r\n if (kept.length) {\r\n next.hooks[p.event] = kept\r\n } else {\r\n delete next.hooks[p.event]\r\n }\r\n }\r\n return next\r\n}\r\n\r\nexport function hooksInstalled (): boolean {\r\n return isMerged(readSettings())\r\n}\r\n\r\n/** 훅을 등록한다 */\r\nexport function installHooks (): void {\r\n const script = notifyScriptPath()\r\n if (!fs.existsSync(script)) {\r\n throw new Error(`훅 스크립트를 찾지 못했다: ${script}`)\r\n }\r\n writeSettings(mergeHooks(readSettings(), script))\r\n}\r\n\r\n/** 훅을 뗀다 */\r\nexport function uninstallHooks (): void {\r\n writeSettings(stripHooks(readSettings()))\r\n}\r\n\r\nfunction writeSettings (settings: any): void {\r\n const file = claudeSettingsPath()\r\n fs.mkdirSync(path.dirname(file), { recursive: true })\r\n // 남의 설정을 고치는 일이라 되돌릴 수 있게 한 벌 남긴다\r\n if (fs.existsSync(file)) {\r\n fs.copyFileSync(file, file + '.agentdeck-backup')\r\n }\r\n fs.writeFileSync(file, JSON.stringify(settings, null, 2) + '\\n', 'utf8')\r\n}\r\n","import { ConfigProvider } from 'tabby-core'\n\n/**\n * 마우스로 만진 배치만 따로 모아 둔다 — 설정 탭의 \"배치 초기화\" 가 이 값으로 되돌린다.\n * 기본값 정의와 초기화 대상이 어긋나지 않도록 아래 defaults 도 이걸 펼쳐 쓴다.\n */\nexport const LAYOUT_DEFAULTS = {\n /**\n * 사이드바가 붙는 방향. 헤더를 잡고 창 가장자리로 끌어다 놓으면 바뀐다.\n * 'left' | 'right' | 'top' | 'bottom'\n */\n sidebarDock: 'right',\n /**\n * 좌/우 도킹일 때의 사이드바 폭 (px). 0 이면 자동 —\n * 화면비(aspectW:aspectH)로 터미널 폭을 역산하고 남는 만큼을 사이드바가 갖는다.\n * 경계선을 드래그하는 순간 그 폭이 여기 박히고, 그 뒤로는 자동 계산을 쓰지 않는다.\n */\n sidebarWidth: 0,\n /** 상/하 도킹일 때의 사이드바 높이 (px). 경계선 드래그로 바뀐다 */\n sidebarHeight: 200,\n}\n\n/** @hidden */\nexport class AgentDeckConfigProvider extends ConfigProvider {\n defaults = {\n agentDeck: {\n /** 레이아웃/사이드바 전체 on-off */\n enabled: true,\n /** 터미널 뷰포트 가로:세로 비율 */\n aspectW: 4,\n aspectH: 3,\n /**\n * 사이드바 폭 제한 (px).\n * sidebarMax 를 키우면 사이드바가 그만큼 넓어지고, 그래도 남는 폭은 터미널이 흡수한다\n * (4:3 보다 \"창을 꽉 채운다\" 가 우선). config.yaml 의 agentDeck 아래에서 조절한다.\n */\n sidebarMin: 200,\n sidebarMax: 560,\n // 마우스로 만지는 배치 (도킹 방향 / 폭 / 높이) — 정의는 LAYOUT_DEFAULTS 에 있다\n ...LAYOUT_DEFAULTS,\n /**\n * 훅이 상태를 밀어 넣는 TCP 채널의 포트 (127.0.0.1 전용).\n *\n * Windows 임시 포트 범위(49152~65535) 아래로 잡는다 — 그 위 번호는 OS 가\n * 다른 프로세스에 먼저 내줄 수 있어 기동 순서에 따라 충돌한다.\n * 이 번호가 물려 있으면 0(임의 포트)으로 물러나고, 실제 번호는 어느 쪽이든\n * `%LOCALAPPDATA%\\tabby-agentdeck\\port` 에 적히므로 훅은 그 파일만 보면 된다.\n */\n notifyPort: 47500,\n /**\n * 외부 통보 채널(TCP + 상태 파일 폴링)을 열지.\n *\n * 기본으로 켠다. 에이전트 훅이 보내 주는 상태가 가장 정확한 원천이기 때문이다 —\n * 출력 패턴으로 추측하는 경로(detect.ts)는 훅이 없는 환경을 위한 폴백일 뿐이고,\n * TUI 가 화면을 어떻게 그리는지에 기대는 만큼 판정이 흔들린다\n * (2026-09-01: Claude Code 가 놀 때도 상태줄을 매초 갱신해 진행중이 안 풀렸다).\n * 훅을 안 쓰더라도 비용은 유휴 포트 하나와 400ms 폴링뿐이다.\n */\n notifyChannel: true,\n /**\n * 훅 설치 안내를 다시 띄우지 않는다.\n *\n * 기동할 때 훅이 안 걸려 있으면 한 번 물어보는데, \"다시 묻지 않기\" 를 고르면 켜진다.\n * 설정 창의 설치 버튼은 이 값과 무관하게 언제든 쓸 수 있다.\n */\n hookPromptDismissed: false,\n /**\n * 기동 시 지난 탭을 복원하지 않는다 (Tabby `recoverTabs` 를 false 로 강제).\n *\n * 복원되는 건 셸뿐이고 그 안의 Claude Code 세션은 이미 죽어 있어 의미가 없다.\n * 켜면 항상 빈 상태(기본 프로필 새 탭)로 시작하고, 끄면 Tabby 순정 동작으로 돌아간다.\n * 설정 창에서 토글한다 (recovery.service.ts).\n */\n noTabRecovery: false,\n /** PTY 출력이 이 시간(ms) 이상 없으면 running -> idle */\n idleAfterMs: 2500,\n /** 출력 패턴으로 상태를 자동 추론할지 */\n autoDetect: true,\n /** 사이드바에 경과 시간 표시 */\n showElapsed: true,\n /**\n * 사이드바 탭을 상태 우선순위(waiting → error → running → done → idle)로 정렬한다.\n * 같은 상태끼리는 탭 순서를 지킨다. 기본은 끔 — 순정 탭바와 같은 탭 순서로 보인다.\n * 헤더의 상태별 집계는 이 값과 무관하게 항상 보인다.\n */\n sortByStatus: false,\n /**\n * 창이 가려져 있어도 사이드바를 계속 갱신한다 (Electron backgroundThrottling 해제).\n *\n * 끄면 Chromium 기본 동작으로 돌아간다 — 창이 hidden 이면 rAF 가 멈추고 타이머가\n * 1초, 5분 이상 가려지면 분당 1회까지 느려져서 훅이 보낸 done 이 화면에 늦게 뜬다.\n * 켜 두면 훅 보고가 바로 보이는 대신 가려진 동안에도 렌더 비용이 조금 든다\n * (사이드바 DOM 갱신뿐이라 미미하다).\n */\n keepRenderingWhenHidden: true,\n // labelAsTitle 은 없앴다 — 사이드바가 제목/프롬프트/상태를 각자 줄에 보여주게 되면서\n // (deck.service renderTab) 둘 중 하나를 고를 이유가 사라졌다.\n /**\n * Enter 로 프롬프트를 보낼 때 그 원문을 작업 라벨로 삼는다 (claimEnterLabel 주석 참고).\n * 훅도 콘솔 제목도 못 믿는 배포 환경에서 라벨을 최신으로 유지하는 유일한 경로다.\n * Shift+Enter / Ctrl+Enter(줄바꿈)는 잡지 않는다.\n */\n enterAsLabel: true,\n /**\n * Ctrl+V 를 agentdeck 이 직접 받는다 (document 캡처 단계에서 한 번만).\n *\n * 핫키(`agentdeck-paste`)로 받던 시절에는 Tabby 가 같은 keydown 을 두 경로로\n * HotkeysService 에 밀어 넣어 한 번 눌러 두 번 붙는 일이 남아 있었다\n * (deck.service.ts `ensurePasteHotkey` 주석에 원인). 캡처로 옮기고 전파를 끊으면서\n * 경로가 하나로 정리됐다.\n *\n * false 로 두면 터미널 앱에 리터럴 Ctrl+V(0x16, quoted-insert)를 보낼 수 있다\n */\n claimCtrlV: true,\n /**\n * Shift+Enter / Ctrl+Enter 를 캡처 단계에서 직접 줄바꿈으로 처리한다.\n *\n * 핫키(agentdeck-newline)에만 맡기면 한글 조합 중에 눌렀을 때 Shift 가 실리지\n * 않은 Enter 로 도착해 전송돼 버린다 (deck.service.ts `claimShiftEnterKey` 주석).\n * false 로 두면 예전처럼 핫키 경로만 쓴다.\n */\n claimShiftEnter: true,\n /**\n * Home / End 를 Tabby 핫키에서 걷어내 xterm 순정 경로로 돌려준다.\n *\n * 핫키로 두면 한글 조합 중에 눌렀을 때 조합 음절이 커서를 따라간다\n * (deck.service.ts `releaseHomeEndHotkey` 주석에 원인). 방향키가 멀쩡한 이유도 같다 —\n * 방향키는 핫키가 아니라서 xterm 이 조합을 먼저 확정하고 키를 보낸다.\n */\n releaseHomeEnd: true,\n /**\n * 클립보드에 이미지만 있으면 Ctrl+V 로도 이미지가 들어가게 한다.\n *\n * 터미널 붙여넣기는 \"클립보드 텍스트를 PTY 에 써넣는\" 동작이라 이미지는 지나갈 수가 없다.\n * 대신 에이전트 CLI 는 자기가 OS 클립보드를 직접 읽는 키를 따로 두므로,\n * 이미지일 때만 그 키를 흘려보낸다 (어떤 키인지는 `imagePasteKey`).\n */\n pasteImageWithCtrlV: true,\n /**\n * 이미지 전용 클립보드일 때 흘려보낼 키의 **기본값**. `'alt-v'`(ESC v) | `'ctrl-v'`(0x16).\n *\n * 평소에는 이 값이 쓰이지 않는다 — 탭에서 도는 앱을 보고 자동으로 갈라 보내기 때문이다\n * (Claude Code = ESC v / Codex = 0x16, `deck.service.ts` `sendImagePasteKey` 주석에 실측).\n * 앱을 못 알아낼 때(SSH 세션 등)의 폴백으로만 쓴다.\n *\n * Claude Code 는 PTY 로 들어온 0x16 에 반응하지 않는 것이 실측됐으므로\n * (`.agentdeck-diag.log` 2026-08-28T09:33:47~48 에 `paste image (ctrl-v)` 5줄, 이미지 미삽입)\n * 폴백은 더 널리 먹히는 ESC v 로 둔다.\n */\n imagePasteKey: 'alt-v',\n /**\n * 우클릭(붙여넣기 / 선택 시 복사)을 agentdeck 이 직접 처리한다.\n * Tabby 자체 처리를 끄고(terminal.rightClick = 'off') 캡처 단계에서 한 번만\n * 처리하므로, 핸들러가 두 번 걸려 붙여넣기가 2중으로 들어가던 문제가 사라진다.\n * false 로 두면 Tabby 순정 동작으로 되돌아간다\n */\n claimRightClick: true,\n /** 우클릭을 이 시간(ms) 이상 누르고 있으면 붙여넣기 대신 컨텍스트 메뉴 */\n rightClickMenuMs: 250,\n\n /**\n * 터미널 배경 불투명도 (%). 100 이면 순정(완전 불투명).\n *\n * tabby-background 플러그인은 배경 이미지를 `.content-tab-active::before`\n * (position:fixed, z-index:-1) 로 **모든 내용 뒤에** 깐다. 그런데 xterm 은\n * 컬러스킴의 `background` 색으로 셀을 직접 칠하므로, 그 색에 알파가 없으면\n * 이미지는 터미널 영역에서 100% 가려진다 — \"배경 이미지를 넣었는데 아무 데도 안 보인다\"\n * 의 정체가 이것이다(2026-08-28 실측: colorScheme.background = '#171717' 불투명).\n * Tabby 는 xterm 을 `allowTransparency: true` 로 만들기 때문에 알파만 넣어주면 비친다.\n *\n * 그래서 agentdeck 이 기동 시 `terminal.colorScheme.background` 를 8자리 hex 로 바꿔준다.\n * 100 으로 되돌리면 알파를 떼어 원래 색으로 복구한다 (되돌리기 가능).\n */\n terminalOpacity: 75,\n /** 사이드바 배경 불투명도 (%). 터미널과 같은 이유로 배경 이미지가 비치게 한다 */\n sidebarOpacity: 75,\n /**\n * tabby-background 의 배경 이미지를 **터미널 영역(`.content.main`) 안에만** 그린다.\n *\n * 그 플러그인은 이미지를 `.content-tab-active::before` 에 `position:fixed; 100%x100%`\n * 로 깔아 창 전체를 덮으므로, 사이드바가 반투명이면 이미지가 사이드바 밑까지 비친다\n * (2026-09-02 유저 지적: \"배경이 agentdeck 사이드바를 침범한다\").\n * true 면 relayout 때마다 터미널 영역 좌표를 CSS 변수(`--ad-bg-*`)로 내려\n * 그 레이어의 위치·크기를 터미널 영역으로 잘라 붙인다. false 면 순정(창 전체).\n */\n clipBackgroundToTerminal: true,\n // 크기 보정 설정(`sizeWatchMs` / `sizeWatchIntervalMs` / `redrawKickMs` /\n // `startupWindowKickMs`)은 그 장치들과 함께 폐지했다 (2026-09-02).\n // 줄맞춤은 Tabby 순정이 한다 — xterm `ResizeObserver` → `fitAddon.fit()` →\n // `session.resize()`. agentdeck 은 폭만 정해 `.content.main` 에 적는다.\n // 자세한 경위는 `deck.service.ts` 의 relayout 주석 참고.\n\n /**\n * 화면 복구(사이드바 `↻` / `agentdeck-repair` 핫키)가 **스크롤백까지 지우고**\n * 터미널 상태를 초기화한다(`xterm.reset()`).\n *\n * true 인 이유: 깨진 화면에는 옛 폭으로 그려진 잔상이 셀에 남아 있는데, 앱이 다시\n * 그려도 자기가 쓰는 자리만 덮으므로 그 바깥은 지워지지 않는다. 지난 대화를 남기고\n * 싶으면 false — 그때는 크기 정합 + 흔들기까지만 한다(그것만으로는 안 고쳐지는\n * 경우가 있다, 2026-09-01 확인).\n */\n /**\n * 화면이 깨졌는지 **주기적으로 직접 보고**, 깨졌으면 조용히 복구한다.\n *\n * 이게 필요한 이유 — 크기 감시(`sizeWatchMs`)는 \"우리가 pty 에 보낸 값\" 과\n * \"xterm 이 가진 값\" 을 비교한다. 그런데 세션이 막 열린 직후의 `session.resize()` 는\n * **pty 에 도달하지 못하고 유실된다**(2026-09-01 실측: 진단 로그에\n * `pty resize 254x78 -> 280x78` 을 찍고 `pane.size` 도 280 으로 남겼는데,\n * 같은 탭에서 셸에 물어보니 `PTYW=254 xtermCols=280`). 보낸 값을 낙관적으로\n * 기록하기 때문에 감시는 \"이제 맞다\" 고 보고 손을 뗀다. 그 뒤에 뜨는 TUI 는\n * 254 폭으로 그리고, 오른쪽 26칸에는 옛 프레임(`Try \"how do I …\"` 힌트)이 남는다.\n *\n * 그래서 판정 기준을 **화면 자체**로 바꾼다. 입력창 테두리 길이가 화면 폭과 다르거나,\n * 가로선과 입력 텍스트가 한 줄에 섞였거나, 입력창 머리가 둘 보이면 깨진 것이다\n * (`screen.ts` 의 `judgeScreen` — 정상/깨짐 실측 케이스로 유닛 테스트가 걸려 있다).\n * 원인이 무엇이든 결과를 보고 고치므로, 원인 하나를 쫓다 다른 것이 깨지는 일이 없다.\n */\n /**\n * **다시 켬 (2026-09-02).** 껐던 근거가 오진이었다.\n *\n * 껐을 때의 이유는 \"Claude Code 는 테두리를 `cols - 1` 로 그리는데 판정이\n * `== cols` 를 정상으로 봐서 멀쩡한 화면을 깨짐으로 친다\" 였다. **그 전제가 틀렸다.**\n * 격리 인스턴스에서 실물 claude 를 띄워 xterm 버퍼를 직접 덤프해 보니\n * (2026-09-02, cols=271):\n *\n * 71 len=271 wrap=0 \"────…\" ← 테두리는 cols 를 꽉 채운다\n * 72 len=2 wrap=1 \"❯ \" ← 꽉 찼기 때문에 autowrap 으로 넘어온 행이다\n * 73 len=271 wrap=0 \"────…\"\n *\n * 즉 `len == cols` 가 정상이고, `len == cols - 1` 은 **앱이 폭을 1 작게 알고 있는**\n * 진짜 깨짐이다. 그때는 테두리가 폭을 못 채워 autowrap 이 안 걸리므로 `❯` 가\n * 윗줄에 붙어버리고 **입력행이 통째로 사라진다**(항목 25 의 ④ 증상이 이것이다).\n * 껐던 탓에 실사용에서 깨져도 아무도 고치지 않고 방치됐다.\n *\n * 예전 자동복구가 화면을 흔들어 놓은 진짜 이유는 판정이 아니라 **조건이 없어서**였다.\n * 프레임을 그리는 도중을 한 번 잡아도 바로 복구를 때렸다. 그래서 이번에는\n * `autoRepairMinStreak` 로 \"몇 초 넘게 깨진 채로 있을 때만\" 손대게 한다.\n */\n /**\n * **다시 끔 (2026-09-02, 실사용 실측 4/4 실패).** 위 판정 근거는 여전히 맞지만\n * **복구 수단이 이 유형에 안 듣는다.** 실사용 로그 06:02:27~06:03:12 —\n * `redraw nudge 277x78` → `pty resize 276x78 -> 277x78` → `Ctrl+L` 을 다 보내고도\n * 네 번 모두 `auto-after 아직 깨짐 rule@73 len=276 != cols=277`.\n * 그동안 10초마다 화면이 흔들려 유저 체감만 나빠졌다(\"최대화됐다 다시 깨지네\").\n *\n * 격리에서 한 번에 복구됐던 건 `session.resize(cols-1)` 로 **pty 를 직접 좁혀** 만든\n * 표본이라, 흔들기가 되돌릴 대상이 실제로 있었다. 실사용은 pty 가 이미 277 로 맞고\n * **앱만 276** 이라 되돌릴 것이 없다 — 항목 27 이 이 유형을 정확히 짚었던 것이고,\n * 항목 28 의 반전은 그 표본에는 해당하지 않았다.\n * 되살리려면 \"앱이 pty 폭을 다시 읽게 만드는\" 수단부터 찾을 것. 감지·채증(`screenWatch`)은 계속 돈다.\n */\n autoRepairScreen: false,\n /**\n * 화면을 **보고 기록만** 한다 (복구는 하지 않는다).\n *\n * `autoRepairScreen` 을 끄면서 감지·채증까지 같이 꺼진 게 문제였다 —\n * 실사용에서 깨져도 `~/.agentdeck-screen.log` 에 한 줄도 안 남아,\n * \"고쳤다고 했는데 또 깨진다\" 를 확인할 증거가 없었다\n * (2026-09-02 실측: Tabby 재시작 11:21 이후 기록 0줄, 그 사이 화면은 깨져 있었다).\n * 그래서 **관측과 조치를 분리한다.** 이 값이 켜져 있으면 깨짐을 판정해\n * 화면 원문을 남기기만 하고 키는 쏘지 않는다 — 부작용이 없으니 기본으로 켠다.\n */\n screenWatch: true,\n /** 자동 복구를 한 번 한 뒤 이만큼은 다시 하지 않는다 (ms) */\n autoRepairCooldownMs: 10000,\n /**\n * 깨짐이 이만큼 **연속으로** 보여야 복구한다 (화면 검사는 2초 그물이므로 2 면 2초 이상).\n * TUI 는 한 프레임을 여러 번의 write 로 그리므로 그 도중을 읽으면 멀쩡한 화면도\n * 한 번은 깨져 보인다 — 그 중간 프레임에 키를 쏘지 않기 위한 조건이다.\n */\n autoRepairMinStreak: 2,\n /**\n * 한 탭에서 자동 복구를 최대 몇 번까지 할지. 판정이 오탐이거나 앱이 정말\n * 그렇게 그리는 경우에 무한히 흔드는 것을 막는 안전장치다. 0 이면 무제한.\n */\n autoRepairMaxPerTab: 3,\n /**\n * 복구 때 `xterm.reset()` 까지 한다 — **스크롤백(지난 대화)이 날아간다.**\n * 기본은 끔. 잔상은 `clearInputArea`(화면만 비우고 스크롤백은 보존)로 지우므로\n * 여기까지 갈 일이 거의 없다. 그걸로도 안 풀리는 화면을 만나면 그때 켠다.\n */\n repairHard: false,\n /**\n * 복구 마지막에 `Ctrl+L`(0x0C)을 보내 TUI 에게 전체 재렌더를 시킨다.\n * 입력 중이던 글자는 유지된다. 이걸 다른 뜻으로 쓰는 앱을 만나면 끈다.\n */\n repairSendRedrawKey: true,\n\n /**\n * 작업 루트 전용 프로필을 만들고 기본 프로필로 삼는다.\n *\n * 에이전트 CLI 는 \"어느 폴더에서 떴는가\" 가 곧 작업 대상이라 새 탭마다 cd 하게 되는데,\n * 그걸 없애려는 기능이다. 기본은 꺼져 있다 — 남의 PC 에 설치되자마자 프로필을 만들고\n * 기본값을 가로채면 곤란하므로, 쓰려는 사람이 `rootProfileCwd` 를 채우고 켜야 한다.\n */\n rootProfile: false,\n rootProfileName: 'Agent Root',\n // 백슬래시 이스케이프 함정을 피하려고 슬래시로 적는다 (Windows 도 그대로 받는다)\n // 빈 값이면 프로필을 만들지 않는다\n rootProfileCwd: '',\n rootProfileCommand: 'powershell.exe',\n /**\n * -ExecutionPolicy Bypass 가 필요한 이유: npm 전역 명령(claude 등)은 .ps1 래퍼인데\n * 기본 실행 정책(Restricted)에서는 로드가 막힌다. 이 인자는 해당 세션에만 적용되고\n * 시스템/사용자 정책은 건드리지 않는다.\n */\n rootProfileArgs: ['-NoLogo', '-ExecutionPolicy', 'Bypass'],\n /**\n * 탭에 주입할 환경변수. Claude Code 등 TUI 는 이 값들이 없으면 색 지원을 낮게 잡아\n * 흑백에 가깝게 렌더된다 (Windows 는 TERM 이 기본으로 비어 있다).\n */\n rootProfileEnv: {\n TERM: 'xterm-256color',\n COLORTERM: 'truecolor',\n FORCE_COLOR: '3',\n },\n /** 기본 프로필 지정을 이미 했는지 — 사용자 선택을 매번 덮어쓰지 않기 위한 플래그 */\n rootProfileClaimed: false,\n\n /**\n * 창이 뒤에 있을 때(포커스 없음) 탭이 `승인대기`/`오류` 로 넘어가면 OS 쪽에 알린다.\n * 창이 앞에 있으면 세 항목 모두 아무 일도 하지 않는다 — 사이드바가 이미 보이고 있다.\n * 작업표시줄 아이콘을 깜빡인다(`flashFrame`). 창이 포커스를 받으면 멈춘다\n */\n alertFlash: true,\n /**\n * 작업표시줄 아이콘 위에 `승인대기`+`오류` 탭 개수를 뱃지로 얹는다.\n * Windows 는 `setBadgeCount` 가 없어 오버레이 아이콘(원+숫자)으로 그린다.\n * 이 값은 전이 순간이 아니라 상태가 바뀔 때마다 실제 개수로 갱신되고, 0 이면 지운다\n */\n alertBadge: true,\n /**\n * OS 토스트(`Notification`)까지 띄운다. 기본은 끔 — 탭이 여럿이면 시끄럽다.\n * 토스트를 누르면 창을 앞으로 가져오고 그 탭을 고른다\n */\n alertToast: false,\n },\n hotkeys: {\n 'agentdeck-toggle': [],\n /**\n * Claude Code 는 0x0A(Ctrl+J)를 줄바꿈으로 받는다. Tabby 로 옮겨 왔으니\n * Ctrl+Enter / Shift+Enter 로도 같은 바이트를 보낸다\n */\n 'agentdeck-newline': ['Ctrl-Enter', 'Shift-Enter'],\n /**\n * Tabby 순정 `paste` 대신 이걸 쓴다 — 클립보드가 이미지인지 텍스트인지 보고\n * 갈라야 하는데 순정 paste 는 텍스트만 알기 때문\n */\n 'agentdeck-paste': ['Ctrl-V'],\n },\n }\n}\n","import { Injectable, NgZone } from '@angular/core'\r\nimport { AppService, ConfigService, BaseTabComponent, HostWindowService, HotkeysService, ProfilesService } from 'tabby-core'\r\nimport { SettingsTabComponent } from 'tabby-settings'\r\nimport * as fs from 'fs'\r\nimport * as os from 'os'\r\nimport * as path from 'path'\r\nimport { WorkStatusService } from './status.service'\r\nimport { applyOutput, applyTitle, stripTitleMarker } from './detect'\r\nimport { STATUS_STYLES, WorkStatus } from './api'\r\nimport { extractPrompt } from './prompt'\r\nimport { judgeScreen, ScreenLine } from './screen'\r\nimport { DockController, DockSide, DOCK_SIDES, isDockSide, isHorizontalDock } from './dock'\r\nimport { countByStatus, sortTabsByStatus } from './order'\r\n\r\nconst SIDEBAR_ID = 'agentdeck-sidebar'\r\nconst BODY_CLASS = 'agentdeck-active'\r\n/** 배경 이미지 레이어를 터미널 영역으로 자르는 중일 때 body 에 붙는 클래스 (styles.scss 참조) */\r\nconst BG_CLIP_CLASS = 'ad-bg-clip'\r\n\r\n/** 터미널이 이보다 좁아지거나 낮아지지 않게 막는다 — 드래그로 사이드바를 끝까지 밀어도 */\r\nconst MIN_TERM_W = 320\r\nconst MIN_TERM_H = 160\r\n/** 사이드바가 이보다 작아지면 목록을 읽을 수 없다 — 드래그로도 이 밑으로는 안 내려간다 */\r\nconst MIN_SIDEBAR_W = 140\r\nconst MIN_SIDEBAR_H = 90\r\n\r\n/** Ctrl+V 를 눌렀을 때 xterm 의 네이티브 paste 가 오는지 기다려보는 시간 */\r\nconst PASTE_NATIVE_WAIT_MS = 60\r\n/**\r\n * 같은 한 번의 붙여넣기가 여러 경로로 들어왔을 때 뒤엣것을 버리는 창(ms).\r\n *\r\n * 사람이 Ctrl+V 를 연타해도 이보다 빠를 수 없다(실측된 중복은 1ms 간격이었다).\r\n * claimCtrlVKey 로 경로를 하나로 모았어도, 그게 안 먹는 상황(포커스가 xterm 밖 등)을\r\n * 대비한 마지막 보험이다.\r\n */\r\nconst PASTE_DEDUPE_MS = 80\r\n/** 붙여넣기 계측 창 — 두 번째 write 가 늦게 와도 놓치지 않게 넉넉히 둔다 */\r\nconst PASTE_PROBE_MS = 5000\r\n/** 입력창을 찾으려고 화면 아래에서 훑어 올라갈 줄 수 — 여러 줄 프롬프트를 덮을 만큼만 */\r\nconst PROMPT_SCAN_ROWS = 14\r\n\r\n/**\r\n * 복구할 때 Ctrl+L 을 보내기까지 기다리는 시간.\r\n * 앞선 흔들기(`nudgePtyRedraw`)가 60ms 뒤에 폭을 되돌리므로, 앱이 그 두 번째 SIGWINCH 로\r\n * 새 폭을 받아들인 다음에 \"다시 그려라\" 가 도착해야 한다. 순서가 뒤집히면 옛 폭으로 다시 그린다.\r\n */\r\nconst REPAIR_REDRAW_DELAY_MS = 180\r\n/** 복구 뒤 화면을 다시 재는 시각 — 앱이 새 프레임을 다 그릴 만큼은 기다린다 */\r\nconst SNAP_AFTER_MS = 1500\r\n/** 진단 로그 — devtools 를 못 여는 상황에서도 밖에서 읽을 수 있게 파일로 남긴다 */\r\n/**\r\n * 화면 깨짐 검사를 출력이 멈춘 뒤 이만큼 기다렸다 한다.\r\n * TUI 가 한 프레임을 여러 번의 write 로 그리므로, 그리는 도중에 읽으면 멀쩡한 화면도 깨져 보인다.\r\n */\r\nconst SCREEN_CHECK_DEBOUNCE_MS = 700\r\n/**\r\n * pty 크기를 고친 뒤 같은 값을 다시 보내는 시점 (ms).\r\n * 세션 초기화 직후의 resize 는 유실되므로(syncPtySize 주석) 시간을 벌려 몇 번 더 던진다.\r\n */\r\nconst PTY_RESIZE_RETRY_MS = [150, 400, 900, 1800, 3000]\r\n/**\r\n * 탭이 열린 뒤 \"지금 xterm 이 쓰는 크기\" 를 pty 에 알려 주는 시점 (ms).\r\n *\r\n * 순정이 못 메우는 구멍이 딱 하나 남아 있다 — **새 탭.** Tabby 는 프론트엔드의 첫 `resize$`\r\n * 값으로 세션을 스폰하므로(tabby-local `initializeSession(this.size…)`), 그 스냅샷이\r\n * 레이아웃 확정보다 이르면 pty 만 좁게 태어난다. 그 뒤 xterm 이 넓어져도 **크기 변화\r\n * 이벤트가 나지 않으므로** ResizeObserver 도 fit() 도 아무것도 보내지 않는다(fit 은 열/행이\r\n * 이미 맞으면 no-op). 아무도 pty 에 알려주지 않아 그대로 굳는다.\r\n *\r\n * 실측(2026-09-02, 격리 인스턴스): 평범하게 연 새 탭 3개가 전부 `xterm=88 / pane.size=88`\r\n * 인데 pty 는 72 였고, TUI 는 72 폭으로 그려 테두리 두 줄이 73·88 로 어긋났다.\r\n * 같은 값(`session.resize(88, 39)`)을 **한 번** 보내자 즉시 정상으로 돌아왔다.\r\n *\r\n * 그래서 되살린 개입은 이것 하나뿐이다 — \"현재 크기를 몇 번 알려준다\". 흔들기(cols-1 ↔ cols)도,\r\n * 250ms 감시 루프도, fit 강제도 아니다. 값이 이미 맞으면 SIGWINCH 가 나지 않아 무해하고,\r\n * xterm 을 건드리지 않으므로 그리는 중인 프레임과 경쟁하지도 않는다.\r\n */\r\nconst TAB_OPEN_ANNOUNCE_MS = [250, 800, 1800]\r\n/** 화면 깨짐 주기 검사 간격 (ms) — 출력 구독이 없는 탭도 잡기 위한 그물 */\r\nconst SCREEN_SWEEP_MS = 2000\r\n/** 자식이 아직 없는 래퍼 탭을 다시 훑는 간격과 횟수 */\r\nconst EMPTY_TAB_RETRY_MS = 400\r\nconst EMPTY_TAB_RETRY_MAX = 20\r\nconst DIAG_PATH = path.join(os.homedir(), '.agentdeck-diag.log')\r\n/**\r\n * 깨진 화면의 **원문**을 남기는 곳. 진단 로그(한 줄 요약)와 따로 두는 이유 —\r\n * 원인을 못 찾는 이유가 늘 \"깨졌을 때의 화면을 아무도 안 봐 뒀다\" 여서다.\r\n * 감지 직후(before)와 복구 뒤(after)를 같이 남기므로, 다음에 깨지면 추측 없이\r\n * \"무엇이 깨졌나 / 복구가 실제로 고쳤나\" 를 이 파일 하나로 가른다.\r\n */\r\nconst SNAP_PATH = path.join(os.homedir(), '.agentdeck-screen.log')\r\n\r\n/** 우리가 쓰는 부분만 추린 Electron clipboard — electron 패키지를 devDependency 로 끌어오지 않으려고 */\r\ninterface ElectronClipboard {\r\n readImage (): { isEmpty (): boolean }\r\n readText (): string\r\n}\r\n\r\nlet cachedClipboard: ElectronClipboard | null | undefined\r\n\r\n/**\r\n * Electron 의 clipboard 를 런타임에 가져온다.\r\n *\r\n * `import { clipboard } from 'electron'` 을 쓰면 타입 때문에 electron 패키지(200MB+)를\r\n * devDependency 로 받아야 한다. Tabby 렌더러는 nodeIntegration 이 켜져 있어(`fs` 를 그냥 import 한다)\r\n * window.require 로 바로 집을 수 있으므로 그쪽을 쓴다.\r\n */\r\nfunction getClipboard (): ElectronClipboard | null {\r\n if (cachedClipboard !== undefined) {\r\n return cachedClipboard\r\n }\r\n // webpack externals 에 'electron' 이 있어(webpack.config.js) 이 require 는 번들되지 않고\r\n // 런타임에 Tabby 가 그대로 넘겨준다 — 위쪽 `import * as fs` 와 같은 경로다.\r\n // window.require 는 contextIsolation 이 켜지면 사라지므로 폴백으로만 둔다.\r\n try {\r\n cachedClipboard = require('electron')?.clipboard ?? null\r\n } catch {\r\n cachedClipboard = null\r\n }\r\n if (!cachedClipboard) {\r\n try {\r\n const req = (window as any).require ?? (globalThis as any).require\r\n cachedClipboard = req?.('electron')?.clipboard ?? null\r\n } catch {\r\n cachedClipboard = null\r\n }\r\n }\r\n return cachedClipboard\r\n}\r\n\r\nfunction clampPct (value: unknown): number {\r\n const n = typeof value === 'number' && isFinite(value) ? value : 100\r\n return Math.min(100, Math.max(0, Math.round(n)))\r\n}\r\n\r\n/**\r\n * `#RRGGBB` / `#RRGGBBAA` 에 불투명도(%)를 입힌다.\r\n * 100% 면 알파를 떼어 원래 6자리로 되돌린다 — 설정을 되돌리면 원상복구되게 하려는 것.\r\n * 해석할 수 없는 형식(rgb(), 색이름 등)은 건드리지 않고 그대로 돌려준다.\r\n */\r\nfunction withAlpha (color: string, pct: number): string {\r\n const m = /^#([0-9a-fA-F]{6})(?:[0-9a-fA-F]{2})?$/.exec(color.trim())\r\n if (!m) {\r\n return color\r\n }\r\n const rgb = '#' + m[1]\r\n if (pct >= 100) {\r\n return rgb\r\n }\r\n const alpha = Math.round(pct * 255 / 100).toString(16).padStart(2, '0')\r\n return rgb + alpha\r\n}\r\n\r\n/**\r\n * AgentDeck 본체.\r\n *\r\n * 하는 일 두 가지 —\r\n * 1) 터미널 뷰포트(.content.main)를 창 높이 기준 4:3 폭으로 고정하고\r\n * 2) 그때 남는 왼쪽 공간에 탭 목록 + 작업 상태 사이드바를 그린다.\r\n *\r\n * Tabby 순정 탭바는 CSS 로 감추고 이 사이드바가 탭 관리를 대신한다.\r\n * Angular 컴포넌트 대신 순수 DOM 을 쓰는 이유는 appRoot 템플릿에 컴포넌트를\r\n * 꽂는 공식 확장점이 없기 때문 — DOM 직접 조작이 Tabby 버전 변화에 더 견딘다.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class AgentDeckService {\r\n private sidebar: HTMLElement | null = null\r\n private listEl: HTMLElement | null = null\r\n private windowEl: HTMLElement | null = null\r\n private mainEl: HTMLElement | null = null\r\n private observer: ResizeObserver | null = null\r\n private editing: BaseTabComponent | null = null\r\n private renderQueued = false\r\n /** Shift 물리 키가 눌려 있나 — IME 조합을 거친 Enter 는 shiftKey 가 지워져 온다 */\r\n private shiftDownAt = 0\r\n /** rAF 가 멈춘 상황(창 가려짐)을 대비한 렌더 폴백 타이머 */\r\n private renderTimer: any = null\r\n /** 직전에 적용한 폭 — 같은 값이면 DOM 을 다시 건드리지 않는다 */\r\n private lastTermW = -1\r\n private lastSidebarW = -1\r\n /** 직전에 적용한 도킹 방향 — 크기가 같아도 방향이 바뀌면 다시 그려야 한다 */\r\n private lastDock: DockSide | null = null\r\n /** 경계선 드래그(크기)와 헤더 드래그(도킹 방향)를 맡는다 */\r\n private dock: DockController | null = null\r\n private refitQueued = false\r\n /** 이미 감시를 건 래퍼 탭 / pane — 중복 구독 방지 */\r\n private watched = new WeakSet<BaseTabComponent>()\r\n private watchedPanes = new WeakSet<BaseTabComponent>()\r\n /** 화면 깨짐 검사 예약 타이머 — pane 당 하나만 돈다 */\r\n private screenCheckTimers = new WeakMap<BaseTabComponent, any>()\r\n /** 빈 래퍼 탭을 다시 훑은 횟수 */\r\n private emptyTabRetries = new WeakMap<BaseTabComponent, number>()\r\n /** 마지막 화면 판정 결과 — 상태가 바뀔 때만 채증하려고 들고 있는다 */\r\n private screenObs = new WeakMap<BaseTabComponent, { broken: boolean, reason: string, streak?: number }>()\r\n /** 마지막 자동 복구 시각 — 쿨다운 판정용 */\r\n private autoRepairAt = new WeakMap<BaseTabComponent, number>()\r\n /** 자동 복구 횟수 — 오탐으로 무한히 흔드는 것을 막는다 */\r\n private autoRepairCount = new WeakMap<BaseTabComponent, number>()\r\n /** 진단 기록 — devtools 의 `__agentdeck.kickLog` 와 DIAG_PATH 파일에 함께 남는다 */\r\n private kickLog: string[] = []\r\n /** diagOnce 가 이미 남긴 키 */\r\n private diagOnceKeys = new Set<string>()\r\n /** 우클릭 누른 시각 — 길게 누르면 컨텍스트 메뉴로 분기 */\r\n private rightDownAt = 0\r\n /** 직전 우클릭 처리 시각 — 같은 클릭이 두 번 들어오는 걸 막는다 */\r\n private lastRightHandledAt = 0\r\n /** xterm 이 네이티브 paste 로 붙여넣은 마지막 시각 — Ctrl+V 이중 입력 방지 */\r\n private nativePasteAt = 0\r\n /** 직전에 붙여넣기를 처리한 시각 — 같은 클릭/키가 여러 경로로 들어와도 한 번만 붙인다 */\r\n private lastPasteAt = 0\r\n /** 이 시각까지는 PTY 로 나가는 입력을 진단 로그에 남긴다 (붙여넣기가 두 번 들어가는지 보려고) */\r\n private pasteProbeUntil = 0\r\n\r\n constructor (\r\n private app: AppService,\r\n private config: ConfigService,\r\n private status: WorkStatusService,\r\n private hotkeys: HotkeysService,\r\n private profiles: ProfilesService,\r\n private hostWindow: HostWindowService,\r\n private zone: NgZone,\r\n ) { }\r\n\r\n init (): void {\r\n this.app.ready$.subscribe(() => this.zone.runOutsideAngular(() => {\r\n // setup 도중 예외가 나면 그 뒤 배선(탭 감시, 흔들기 예약)이 통째로 죽는데\r\n // 콘솔을 안 보면 알 길이 없다. 진단 파일에 남겨 밖에서 읽을 수 있게 한다\r\n try {\r\n this.setup()\r\n } catch (e: any) {\r\n this.diag(`${new Date().toISOString()} setup ERROR ${e?.message ?? e}`)\r\n throw e\r\n }\r\n }))\r\n }\r\n\r\n /**\r\n * 같은 키로는 한 번만 남기는 진단.\r\n * relayout 처럼 초당 여러 번 불리는 자리에서 조기 return 사유를 남길 때 쓴다\r\n */\r\n private diagOnce (key: string, line: string): void {\r\n if (this.diagOnceKeys.has(key)) {\r\n return\r\n }\r\n this.diagOnceKeys.add(key)\r\n this.diag(`${new Date().toISOString()} ${line}`)\r\n }\r\n\r\n /** 진단 한 줄 — 메모리와 파일에 함께 남긴다. 파일이 안 써져도 동작에는 영향이 없다 */\r\n private diag (line: string): void {\r\n this.kickLog.push(line)\r\n try {\r\n fs.appendFileSync(DIAG_PATH, line + '\\n')\r\n } catch {\r\n // 디스크가 막혀 있다 — 진단일 뿐이라 무시한다\r\n }\r\n }\r\n\r\n private setup (): void {\r\n this.windowEl = document.querySelector('.window')\r\n this.mainEl = document.querySelector('.content.main')\r\n if (!this.windowEl) {\r\n console.warn('[agentdeck] .window 를 찾지 못해 레이아웃을 적용하지 않는다')\r\n return\r\n }\r\n\r\n try {\r\n fs.writeFileSync(DIAG_PATH, '')\r\n } catch {\r\n // 진단 파일을 못 열어도 그냥 간다\r\n }\r\n this.diag(`${new Date().toISOString()} setup start tabs=${this.app.tabs.length}`)\r\n\r\n this.buildSidebar()\r\n this.applyEnabled()\r\n this.applyOpacity()\r\n this.disableBackgroundThrottling()\r\n this.ensurePasteHotkey()\r\n this.ensureNewlineHotkey()\r\n this.releaseHomeEndHotkey()\r\n this.claimCtrlVKey()\r\n this.claimShiftEnterKey()\r\n this.claimEnterLabel()\r\n this.claimRightClick()\r\n\r\n // xterm 의 네이티브 paste 를 관측만 한다 (doPaste 의 이중 입력 방지용).\r\n // 캡처 단계라 xterm 핸들러의 stopPropagation 보다 먼저 돈다.\r\n document.addEventListener('paste', () => {\r\n this.nativePasteAt = Date.now()\r\n this.diag(`${new Date().toISOString()} native-paste`)\r\n }, true)\r\n\r\n // 탭 변화 -> 사이드바 다시 그림\r\n // 탭 복원은 ready$ 보다 늦게 끝나므로 목록이 바뀔 때마다 감시 대상을 다시 훑는다\r\n // (watched WeakSet 이 중복 구독을 막는다)\r\n this.app.tabsChanged$.subscribe(() => {\r\n for (const tab of this.app.tabs) {\r\n this.watchTab(tab)\r\n }\r\n this.scheduleRender()\r\n })\r\n // 탭을 바꾸면 그 탭은 숨어 있던 동안 폭 0 이라 refit 을 건너뛰었다 — 지금 맞춰준다\r\n this.app.activeTabChange$.subscribe(() => {\r\n this.scheduleRender()\r\n this.scheduleRefit()\r\n })\r\n this.app.tabOpened$.subscribe(tab => {\r\n this.watchTab(tab)\r\n // 새 탭은 xterm 은 맞는 폭으로 열리는데 pty 만 옛 폭으로 남는 일이 있다 (syncPtySize 주석)\r\n this.scheduleRefit()\r\n this.scheduleRender()\r\n })\r\n this.app.tabClosed$.subscribe(() => this.scheduleRender())\r\n\r\n // 세션이 이미 열린 채 복원된 탭들도 감시 대상에 넣는다\r\n for (const tab of this.app.tabs) {\r\n this.watchTab(tab)\r\n }\r\n this.status.changed$.subscribe(() => this.scheduleRender())\r\n this.config.changed$.subscribe(() => {\r\n this.applyEnabled()\r\n this.applyOpacity()\r\n this.relayout()\r\n this.scheduleRender()\r\n })\r\n\r\n // 화면 깨짐 주기 검사. 출력 구독(scheduleScreenCheck)이 더 정밀하지만, 구독이 붙지\r\n // 못한 탭에서는 아무도 보지 않게 되므로 그물을 하나 더 둔다. 활성 탭만 본다 —\r\n // 숨은 탭은 폭이 0 이라 판정할 근거가 없다.\r\n setInterval(() => this.sweepScreens(), SCREEN_SWEEP_MS)\r\n\r\n // 창 크기 변화 -> 4:3 폭 재계산\r\n this.observer = new ResizeObserver(() => this.relayout())\r\n this.observer.observe(this.windowEl)\r\n window.addEventListener('resize', () => this.relayout())\r\n\r\n // 핫키 처리는 여기서 — provider 쪽에서 하면 HotkeysService 와 순환 의존이 된다\r\n this.hotkeys.hotkey$.subscribe(hotkey => {\r\n if (hotkey === 'agentdeck-toggle') {\r\n this.config.store.agentDeck.enabled = !this.config.store.agentDeck.enabled\r\n this.config.save()\r\n }\r\n if (hotkey === 'agentdeck-newline') {\r\n this.sendNewline()\r\n }\r\n if (hotkey === 'agentdeck-paste') {\r\n this.doPaste('hotkey')\r\n }\r\n if (hotkey === 'agentdeck-repair') {\r\n this.repair('all')\r\n }\r\n })\r\n\r\n // 경과 시간 갱신 + running -> idle 자동 복귀\r\n setInterval(() => this.tick(), 1000)\r\n\r\n this.relayout()\r\n this.render()\r\n this.diag(`${new Date().toISOString()} setup done tabs=${this.app.tabs.length} enabled=${this.enabled} mainEl=${!!this.mainEl}`)\r\n\r\n // 개발/진단용 — devtools 나 CDP 에서 내부 상태를 들여다볼 수 있게 노출한다\r\n ;(window as any).__agentdeck = {\r\n app: this.app,\r\n config: this.config,\r\n status: this.status,\r\n relayout: () => this.relayout(),\r\n render: () => this.render(),\r\n repair: (scope: 'active' | 'all' = 'all') => this.repair(scope),\r\n kickLog: this.kickLog,\r\n }\r\n }\r\n\r\n // ---------- 화면 복구 ----------\r\n\r\n /**\r\n * 깨진 화면을 사람이 직접 되살린다 — 창을 복원→최대화로 흔드는 것을 코드로 대신한다.\r\n *\r\n * 자동 경로(`watchSize`)는 \"xterm 과 pty 의 크기가 어긋났다\" 를 보고 고치는데, 그 감시는\r\n * 탭이 열리고 `sizeWatchMs`(기본 6초) 동안만 돈다. 그 뒤에 깨지는 경우가 남는다 —\r\n * 두 크기는 서로 맞는데 **TUI 가 들고 있는 프레임만** 옛것인 상황이다. 크기가 이미 같으니\r\n * 커널은 SIGWINCH 를 내지 않고, 앱은 다시 그릴 이유를 영영 못 받는다. 증상은\r\n * \"statusline 이 사라지고 입력창 구분선이 중간에서 끊긴다\" (2026-09-01 실측).\r\n *\r\n * 그래서 복구는 크기를 맞추는 것으로 끝내지 않고 **항상 한 번 흔든다**(`nudgePtyRedraw`).\r\n * 어긋남이 없어도 무해하다 — 폭이 한 칸 줄었다 돌아올 뿐이고 xterm 은 건드리지 않는다.\r\n *\r\n * @param scope `active` = 지금 보고 있는 탭만, `all` = 열려 있는 모든 탭\r\n */\r\n repair (scope: 'active' | 'all' = 'all'): void {\r\n const targets = scope === 'active' && this.app.activeTab\r\n ? [this.app.activeTab]\r\n : this.app.tabs\r\n this.diag(`${new Date().toISOString()} repair scope=${scope} tabs=${targets.length}`)\r\n\r\n // 1) 사이드바 폭부터 다시 잰다 — 어긋남의 출발점이 대개 여기다\r\n this.relayout()\r\n\r\n // 2) 레이아웃이 실제로 반영된 다음에 재야 한다 (scheduleRefit 과 같은 이유로 두 프레임)\r\n requestAnimationFrame(() => requestAnimationFrame(() => {\r\n for (const tab of targets) {\r\n const anyTab = tab as any\r\n const panes: BaseTabComponent[] = typeof anyTab.getAllTabs === 'function'\r\n ? anyTab.getAllTabs()\r\n : [tab]\r\n for (const pane of panes) {\r\n this.repairPane(pane)\r\n }\r\n }\r\n }))\r\n }\r\n\r\n /**\r\n * 복구 한 pane 분 — **화면을 지우고 앱에게 처음부터 다시 그리게 한다.**\r\n *\r\n * 흔들기(`nudgePtyRedraw`)만으로는 안 고쳐지는 경우가 실제로 있다(2026-09-01 유저 확인).\r\n * 이유는 흔들기가 고치는 대상이 하나뿐이라서다 — 그건 \"앱이 폭을 잘못 알고 있다\" 를 푼다.\r\n * 그런데 깨진 화면에는 그 말고도 두 가지가 더 얹혀 있다.\r\n *\r\n * - **xterm 쪽 잔상**: 옛 폭으로 그려진 글자가 셀에 그대로 남아 있다. 앱이 다시 그려도\r\n * 앱은 자기가 쓴 자리만 덮으므로, 그 바깥(옛 프레임의 오른쪽·아래)은 영영 안 지워진다.\r\n * - **터미널 상태**: 스크롤 영역(DECSTBM)·줄바꿈 모드·속성이 옛 크기 기준으로 잡혀 있으면\r\n * 새로 그린 것까지 어긋난 자리에 들어간다.\r\n *\r\n * 그래서 순서가 있다 — ① 크기를 맞추고 ② `reset()` 으로 터미널 상태와 화면을 비우고\r\n * ③ 그래도 앱은 자기가 이미 그렸다고 믿고 있으니 흔들어 SIGWINCH 를 주고\r\n * ④ 마지막으로 `Ctrl+L`(0x0C) 을 보내 \"전부 다시 그려라\" 를 명시로 시킨다.\r\n * ③ 만으로 부족했던 이유가 ①②④ 가 빠져서였다.\r\n *\r\n * `reset()` 은 스크롤백을 함께 지운다. 지난 대화를 남기고 싶으면 `repairHard: false` —\r\n * 그때는 예전처럼 크기 정합 + 흔들기까지만 한다.\r\n */\r\n private repairPane (pane: BaseTabComponent): void {\r\n const cfg = this.config.store.agentDeck\r\n const anyPane = pane as any\r\n const frontend = anyPane.frontend\r\n const xterm = frontend?.xterm\r\n // 숨겨진 탭은 컨테이너 폭이 0 이라 fit 하면 1열로 줄어든다 — 크기는 건드리지 않고\r\n // 다시 선택될 때 Tabby 가 재측정하게 둔다\r\n const host = xterm?.element?.parentElement\r\n if (!host?.clientWidth || !host?.clientHeight) {\r\n return\r\n }\r\n\r\n const before = this.readScreen(pane)\r\n const beforeVerdict = before ? judgeScreen(before.lines, before.cols) : null\r\n this.snapshot(pane, `manual-before ${beforeVerdict\r\n ? (beforeVerdict.broken ? beforeVerdict.reasons.join(' / ') : '판정=정상')\r\n : '읽을 수 없음'}`)\r\n\r\n // ① 크기 정합 — 여기가 어긋나 있으면 뒤 단계가 전부 헛돈다\r\n try {\r\n frontend?.fitAddon?.fit?.()\r\n } catch {\r\n // 아직 붙는 중이다 — 아래 단계만이라도 태운다\r\n }\r\n this.syncPtySize(pane, frontend)\r\n\r\n // ② 잔상 지우기 — 입력창 영역만 비운다 (대화는 남는다)\r\n if (before) {\r\n this.clearInputArea(pane, before)\r\n }\r\n\r\n // ②-b 그래도 안 되면 터미널 상태까지 초기화 (스크롤백이 날아가므로 기본은 끔)\r\n if (cfg.repairHard === true) {\r\n try {\r\n xterm?.reset?.()\r\n } catch {\r\n // 프론트엔드가 막 떨어졌다\r\n }\r\n }\r\n try {\r\n xterm?.refresh?.(0, (xterm.rows ?? 1) - 1)\r\n } catch { }\r\n\r\n // ③ 크기가 이미 맞아도 무조건 흔든다 — 이 함수를 부르는 이유 자체가 \"맞는데 깨졌다\" 다\r\n this.nudgePtyRedraw(pane)\r\n\r\n // ④ 앱에게 직접 \"다시 그려라\". 흔들기가 도착해 앱이 새 폭을 받은 뒤에 보내야 하므로\r\n // nudge 의 되돌리기(60ms)보다 확실히 뒤에 둔다.\r\n if (cfg.repairSendRedrawKey !== false) {\r\n setTimeout(() => this.sendRedrawKey(pane), REPAIR_REDRAW_DELAY_MS)\r\n }\r\n\r\n // ⑤ 채증 — \"↻ 를 눌렀는데 안 고쳐진다\" 를 감이 아니라 파일로 가른다.\r\n // 누른 직후와 다시 그려진 뒤를 짝으로 남긴다.\r\n setTimeout(() => {\r\n const after = this.readScreen(pane)\r\n const still = after ? judgeScreen(after.lines, after.cols) : null\r\n this.snapshot(pane, `manual-after ${still ? (still.broken ? '아직 깨짐: ' + still.reasons.join(' / ') : '복구됨') : '읽을 수 없음'}`)\r\n }, SNAP_AFTER_MS)\r\n }\r\n\r\n /**\r\n * TUI 에 \"화면을 전부 다시 그려라\" 를 보낸다 — `Ctrl+L`(0x0C).\r\n *\r\n * Claude Code·Codex 를 포함해 거의 모든 TUI 와 셸이 이걸 전체 재렌더로 받는다.\r\n * 입력 중이던 글자는 건드리지 않는다(readline·TUI 모두 입력 버퍼는 유지하고 화면만 다시 그린다).\r\n */\r\n private sendRedrawKey (pane: BaseTabComponent): void {\r\n const anyPane = pane as any\r\n if (typeof anyPane.sendInput !== 'function' || !anyPane.session?.open) {\r\n return\r\n }\r\n this.diag(`${new Date().toISOString()} repair redraw-key ctrl-l`)\r\n try {\r\n anyPane.sendInput('\\x0c')\r\n } catch {\r\n // 세션이 막 닫혔다\r\n }\r\n }\r\n\r\n /**\r\n * 입력창 영역에 남은 **옛 프레임 잔상만** 지운다 (대화 = 스크롤백은 그대로 둔다).\r\n *\r\n * 복구가 계속 실패하던 진짜 이유가 여기 있었다 (2026-09-02 실측).\r\n * `nudge` 도 `Ctrl+L` 도 하는 일은 \"앱아 다시 그려라\" 뿐인데, **앱은 자기가 쓰는 자리만 덮는다.**\r\n * 그래서 옛 폭으로 그려진 줄이 `❯` 자리를 차지하고 있으면 아무도 그걸 못 지운다 —\r\n * 채증 원문이 그 모양이었다 (`.agentdeck-screen.log` 06:02:27):\r\n *\r\n * 72 len=275 \" \" ← 위 테두리가 있어야 할 자리, 공백\r\n * 73 len=276 \"────…\" ← ❯ 자리에 옛 프레임(276) 잔상\r\n * 74 len=277 \"────…\" ← 앱이 새로 그린 아래 테두리(277, 정상)\r\n *\r\n * 앱은 이미 277 로 제대로 그리고 있는데 73 행 잔상 때문에 계속 깨짐으로 남았다.\r\n * `auto-after 아직 깨짐` 이 두 번 연속 찍힌 게 이것이다.\r\n *\r\n * 그래서 **터미널 쪽에서 직접 지운다** — 입력창 첫 테두리 행으로 커서를 옮기고\r\n * `ESC[J`(커서부터 화면 끝까지)로 비운다. 이건 화면만 비우고 스크롤백은 건드리지 않으므로\r\n * `xterm.reset()`(스크롤백까지 날아감)과 다르다. 커서는 `ESC7`/`ESC8` 로 저장·복원해\r\n * 앱이 들고 있는 커서 위치와 어긋나지 않게 한다. 지운 뒤 `Ctrl+L` 을 보내면 앱이\r\n * 자기 UI 를 그 빈 자리에 다시 그린다.\r\n */\r\n private clearInputArea (pane: BaseTabComponent, read: { lines: ScreenLine[], cols: number }): boolean {\r\n const xterm = (pane as any).frontend?.xterm\r\n if (!xterm || typeof xterm.write !== 'function') {\r\n return false\r\n }\r\n const lines = read.lines\r\n // 하단 16행 안에서만 본다 — 대화 이력에 남아 있는 옛 입력창까지 지우면 안 된다\r\n const from = Math.max(0, lines.length - 16)\r\n let last = -1\r\n for (let i = lines.length - 1; i >= from; i--) {\r\n if (/^[─━═]{2,}$/.test(lines[i].text.trim())) {\r\n last = i\r\n break\r\n }\r\n }\r\n if (last < 0) {\r\n return false\r\n }\r\n // 마지막 테두리에서 위로 최대 4행까지만 같은 입력창 블록으로 본다\r\n let start = last\r\n for (let i = last - 1; i >= Math.max(from, last - 4); i--) {\r\n if (/^[─━═]{2,}$/.test(lines[i].text.trim())) {\r\n start = i\r\n }\r\n }\r\n const row = start + 1\r\n this.diag(`${new Date().toISOString()} clear input area row=${row}/${lines.length}`)\r\n try {\r\n xterm.write(`\u001b7\u001b[${row};1H\u001b[J\u001b8`)\r\n } catch {\r\n return false\r\n }\r\n return true\r\n }\r\n\r\n // ---------- 화면 깨짐 자동 감지 ----------\r\n\r\n /**\r\n * 출력이 잠잠해지면 화면이 온전한지 본다.\r\n *\r\n * TUI 는 한 프레임을 여러 번의 write 로 그리므로, 그리는 도중에 읽으면 멀쩡한 화면도\r\n * 깨져 보인다. 그래서 마지막 출력에서 `SCREEN_CHECK_DEBOUNCE_MS` 만큼 조용해진 뒤에만 본다.\r\n */\r\n private scheduleScreenCheck (pane: BaseTabComponent): void {\r\n // 감지·채증은 복구와 분리한다 — `autoRepairScreen` 이 꺼져 있어도 관측은 계속한다.\r\n // (2026-09-02: 이 게이트가 채증까지 막아 실사용 재현이 통째로 증거 없이 지나갔다)\r\n if (!this.screenObservingEnabled()) {\r\n return\r\n }\r\n const prev = this.screenCheckTimers.get(pane)\r\n if (prev) {\r\n clearTimeout(prev)\r\n }\r\n this.screenCheckTimers.set(pane, setTimeout(() => {\r\n this.screenCheckTimers.delete(pane)\r\n this.checkScreen(pane)\r\n }, SCREEN_CHECK_DEBOUNCE_MS))\r\n }\r\n\r\n /** 감지·채증이 켜져 있나 — 복구(`autoRepairScreen`)와는 별개다 */\r\n private screenObservingEnabled (): boolean {\r\n const cfg = this.config.store.agentDeck\r\n return cfg.screenWatch !== false || !!cfg.autoRepairScreen\r\n }\r\n\r\n /** 화면을 판정해 채증하고, 복구가 켜져 있으면 조용히 고친다 */\r\n private checkScreen (pane: BaseTabComponent): void {\r\n const cfg = this.config.store.agentDeck\r\n const read = this.readScreen(pane)\r\n if (!read) {\r\n return\r\n }\r\n const verdict = judgeScreen(read.lines, read.cols)\r\n\r\n // ---- 관측 (복구와 무관하게 항상) ----\r\n // 상태가 바뀔 때만 남긴다 — 2초마다 도는 그물이라 매번 찍으면 파일이 같은 줄로 찬다.\r\n const prevObs = this.screenObs.get(pane)\r\n const reason = verdict.reasons.join(' / ')\r\n // 같은 깨짐이 몇 번 연속으로 보였나 — TUI 가 한 프레임을 여러 write 로 그리는 도중을\r\n // 잡으면 멀쩡한 화면도 한 번은 깨져 보인다. 그 중간 프레임에 손대지 않으려고 센다.\r\n const streak = verdict.broken ? ((prevObs?.broken ? (prevObs.streak ?? 0) : 0) + 1) : 0\r\n const changed = !prevObs || prevObs.broken !== verdict.broken || prevObs.reason !== reason\r\n this.screenObs.set(pane, { broken: verdict.broken, reason, streak })\r\n if (changed) {\r\n if (verdict.broken) {\r\n this.snapshot(pane, `detect 깨짐 ${reason}`)\r\n } else if (prevObs?.broken) {\r\n // 우리가 아무것도 안 했는데 스스로 돌아왔다 — 트리거를 가르는 중요한 단서다\r\n this.snapshot(pane, 'detect 스스로 복구됨')\r\n }\r\n }\r\n\r\n if (!verdict.broken) {\r\n return\r\n }\r\n if (!cfg.autoRepairScreen) {\r\n return\r\n }\r\n // 한 번 스친 중간 프레임은 건드리지 않는다 — 2초 그물이므로 기본값 2 는 \"2초 넘게\r\n // 깨진 채로 있다\" 는 뜻이다. 예전에 자동복구가 타이핑 중에 튀어나와 체감을 망친 것이\r\n // 이 조건이 없어서였다 (2026-09-02 항목 27).\r\n if (streak < (cfg.autoRepairMinStreak ?? 2)) {\r\n return\r\n }\r\n\r\n const anyPane = pane as any\r\n const now = Date.now()\r\n const last = this.autoRepairAt.get(pane) ?? 0\r\n const count = this.autoRepairCount.get(pane) ?? 0\r\n const max = cfg.autoRepairMaxPerTab ?? 5\r\n const cooldown = cfg.autoRepairCooldownMs ?? 4000\r\n\r\n // 쿨다운/한도에 걸려 아무것도 하지 않을 때는 로그도 남기지 않는다 —\r\n // 주기 검사가 2초마다 돌므로 판정이 오탐이면 진단 파일이 같은 줄로 가득 찬다\r\n if (now - last < cooldown) {\r\n return\r\n }\r\n if (max > 0 && count >= max) {\r\n this.diagOnce(`auto-repair-cap`,\r\n `screen auto-repair 한도 도달 (${count}/${max}) — 더 고치지 않는다.`\r\n + ` 사이드바 ↻ 로 직접 복구할 것. 마지막 판정: ${verdict.reasons.join(' / ')}`)\r\n return\r\n }\r\n this.diag(`${new Date().toISOString()} screen BROKEN cols=${read.cols}`\r\n + ` sent=${anyPane.size?.columns}x${anyPane.size?.rows} ${verdict.reasons.join(' / ')}`)\r\n // 고치기 **전에** 화면 원문을 남긴다 — 복구가 덮어쓰면 증거가 사라진다\r\n this.snapshot(pane, `auto-before ${verdict.reasons.join(' / ')}`)\r\n this.autoRepairAt.set(pane, now)\r\n this.autoRepairCount.set(pane, count + 1)\r\n this.diag(`${new Date().toISOString()} screen auto-repair #${count + 1}`)\r\n\r\n // 스크롤백을 지우는 hard 복구는 하지 않는다 — 자동으로 도는 경로에서 오탐 한 번에\r\n // 지난 대화가 날아가면 손해가 크다. 크기 재동기 + pty 흔들기 + Ctrl+L 까지만 한다.\r\n // 실측(2026-09-01): 세션이 열린 직후 유실됐던 resize 도 이 흔들기로는 pty 에 도달한다.\r\n const frontend = anyPane.frontend\r\n // 크기를 건드리는 건 **실제로 어긋났을 때만.** 이번에 실사용에서 잡힌 유형은\r\n // xterm 도 pty 도 277 로 맞는데 화면만 깨져 있었다 — 거기에 흔들기를 때리면\r\n // 고치지도 못하면서 화면만 흔든다(`auto-after 아직 깨짐` 2연속이 그 결과다).\r\n const xcols = frontend?.xterm?.cols\r\n const xrows = frontend?.xterm?.rows\r\n if (xcols > 1 && (anyPane.size?.columns !== xcols || anyPane.size?.rows !== xrows)) {\r\n try {\r\n frontend?.fitAddon?.fit?.()\r\n } catch {\r\n // 붙는 중이다 — 아래 단계만이라도 태운다\r\n }\r\n this.syncPtySize(pane, frontend)\r\n this.nudgePtyRedraw(pane)\r\n }\r\n // 잔상을 **먼저** 지우고 그 다음에 앱에게 다시 그리라고 한다.\r\n // 앱은 자기가 쓰는 자리만 덮으므로, 지우지 않으면 옛 줄이 `❯` 자리를 계속 차지한다.\r\n this.clearInputArea(pane, read)\r\n if (cfg.repairSendRedrawKey !== false) {\r\n setTimeout(() => this.sendRedrawKey(pane), REPAIR_REDRAW_DELAY_MS)\r\n }\r\n // 복구가 실제로 먹혔는지 같은 파일에 이어 남긴다 — 앱이 다시 그릴 시간을 준다\r\n setTimeout(() => {\r\n const after = this.readScreen(pane)\r\n const still = after ? judgeScreen(after.lines, after.cols) : null\r\n this.snapshot(pane, `auto-after ${still ? (still.broken ? '아직 깨짐: ' + still.reasons.join(' / ') : '복구됨') : '읽을 수 없음'}`)\r\n }, SNAP_AFTER_MS)\r\n }\r\n\r\n /** 활성 탭의 pane 들을 한 번씩 본다 (주기 그물) */\r\n private sweepScreens (): void {\r\n if (!this.enabled || !this.screenObservingEnabled()) {\r\n return\r\n }\r\n const tab = this.app.activeTab\r\n if (!tab) {\r\n return\r\n }\r\n const anyTab = tab as any\r\n const panes: BaseTabComponent[] = typeof anyTab.getAllTabs === 'function'\r\n ? anyTab.getAllTabs()\r\n : [tab]\r\n for (const pane of panes) {\r\n this.checkScreen(pane)\r\n }\r\n }\r\n\r\n /** 판정에 넣을 화면 줄과 폭 — 숨겨진 탭이나 아직 안 붙은 프론트엔드는 건너뛴다 */\r\n private readScreen (pane: BaseTabComponent): { lines: ScreenLine[], cols: number } | null {\r\n const anyPane = pane as any\r\n const xterm = anyPane.frontend?.xterm\r\n const buf = xterm?.buffer?.active\r\n if (!buf || typeof buf.getLine !== 'function' || !(xterm.cols > 1)) {\r\n return null\r\n }\r\n // 숨겨진 탭은 컨테이너 폭이 0 이라 xterm 이 1열로 줄어 있다 — 판정 대상이 아니다\r\n const host = xterm.element?.parentElement\r\n if (!host?.clientWidth) {\r\n return null\r\n }\r\n const lines: ScreenLine[] = []\r\n for (let y = buf.baseY; y <= buf.baseY + xterm.rows - 1; y++) {\r\n const line = buf.getLine(y)\r\n lines.push({\r\n text: line?.translateToString(false) ?? '',\r\n wrapped: !!line?.isWrapped,\r\n })\r\n }\r\n return { lines, cols: xterm.cols }\r\n }\r\n\r\n /**\r\n * 화면 원문을 통째로 남긴다 — 깨짐 채증용.\r\n *\r\n * 판정 이유만 남기면 다음에 또 \"왜 그렇게 됐는지\" 를 추측하게 된다. 행 번호·wrap 플래그·\r\n * 길이까지 그대로 적어 두면 `❯` 가 어느 행에 있었는지, 테두리가 몇 칸이었는지가 확정된다.\r\n * before/after 를 짝으로 남기므로 복구가 실제로 먹혔는지도 이 파일에서 바로 갈린다.\r\n */\r\n private snapshot (pane: BaseTabComponent, tag: string): void {\r\n const read = this.readScreen(pane)\r\n if (!read) {\r\n return\r\n }\r\n const anyPane = pane as any\r\n const xterm = anyPane.frontend?.xterm\r\n const head = `\\n===== ${new Date().toISOString()} ${tag}`\r\n + ` cols=${read.cols} rows=${xterm?.rows} sent=${anyPane.size?.columns}x${anyPane.size?.rows}`\r\n + ` title=${JSON.stringify(pane.title ?? '')} =====`\r\n const body = read.lines\r\n .map((l, i) => ({ i, t: l.text.replace(/\\s+$/, ''), w: l.wrapped }))\r\n .filter(l => l.t)\r\n .map(l => `${String(l.i).padStart(3)} w=${l.w ? 1 : 0} len=${l.t.length} ${JSON.stringify(l.t)}`)\r\n try {\r\n fs.appendFileSync(SNAP_PATH, [head, ...body, ''].join('\\n'))\r\n } catch {\r\n // 진단일 뿐이라 실패해도 동작에는 영향이 없다\r\n }\r\n }\r\n\r\n // ---------- 세션 감시 ----------\r\n\r\n /**\r\n * 탭(그리고 그 안의 모든 pane)의 PTY 출력을 구독한다.\r\n *\r\n * TerminalDecorator 는 프론트엔드 첫 리사이즈 시점에만 붙어서 복원된 탭 등을\r\n * 놓치는 경우가 있다. 이쪽은 탭이 목록에 들어오는 즉시 붙으므로 그 빈틈을 메운다.\r\n * 같은 출력을 decorator 와 둘 다 먹어도 상태 설정이 멱등이라 결과는 같다.\r\n */\r\n private watchTab (root: BaseTabComponent): void {\r\n const anyRoot = root as any\r\n\r\n if (!this.watched.has(root)) {\r\n this.watched.add(root)\r\n\r\n // 제목은 래퍼 탭이 자식 것을 위임받으므로 여기서 받는 게 가장 확실하다\r\n if (anyRoot.titleChange$) {\r\n anyRoot.titleChange$.subscribe((title: string) => {\r\n applyTitle(this.status, root, title, this.config.store.agentDeck.autoDetect)\r\n })\r\n }\r\n if (anyRoot.title) {\r\n applyTitle(this.status, root, anyRoot.title, this.config.store.agentDeck.autoDetect)\r\n }\r\n // 나중에 분할로 추가되는 pane 도 따라간다\r\n if (anyRoot.tabAdded$) {\r\n anyRoot.tabAdded$.subscribe((pane: BaseTabComponent) => this.watchPane(root, pane))\r\n }\r\n }\r\n\r\n // pane 은 래퍼보다 늦게 붙는 경우가 있으므로 호출될 때마다 다시 훑는다\r\n // (래퍼만 보고 한 번에 끝내면 목록에 먼저 들어온 빈 SplitTab 을 잡고 끝나버린다)\r\n const panes: BaseTabComponent[] = typeof anyRoot.getAllTabs === 'function'\r\n ? anyRoot.getAllTabs()\r\n : [root]\r\n this.diag(`${new Date().toISOString()} watchTab panes=${panes.length}`)\r\n for (const pane of panes) {\r\n this.watchPane(root, pane)\r\n }\r\n\r\n // 래퍼(SplitTabComponent)가 자식보다 먼저 목록에 들어오는 경우가 있다. 그때 여기서\r\n // panes=0 을 보고 물러나면, 자식이 붙어도 다시 훑을 계기가 없어 그 탭은 영영\r\n // 감시 밖에 남는다 — 상태 감지·Enter 라벨·화면 검사가 전부 안 돈다\r\n // (2026-09-01 실측: 기동 직후 첫 탭에서 `watchTab panes=0` 만 두 번 찍히고\r\n // `session bind` 가 한 번도 없었다). 그래서 비어 있으면 잠시 뒤 다시 본다.\r\n if (!panes.length) {\r\n const tries = (this.emptyTabRetries.get(root) ?? 0) + 1\r\n this.emptyTabRetries.set(root, tries)\r\n if (tries <= EMPTY_TAB_RETRY_MAX) {\r\n setTimeout(() => {\r\n if (this.app.tabs.includes(root)) {\r\n this.watchTab(root)\r\n }\r\n }, EMPTY_TAB_RETRY_MS)\r\n }\r\n }\r\n }\r\n\r\n private watchPane (root: BaseTabComponent, pane: BaseTabComponent): void {\r\n if (this.watchedPanes.has(pane)) {\r\n return\r\n }\r\n this.watchedPanes.add(pane)\r\n this.diag(`${new Date().toISOString()} watchPane ${(pane as any).constructor?.name}`)\r\n const anyPane = pane as any\r\n const bind = (session: any) => {\r\n if (!session || !session.output$) {\r\n return\r\n }\r\n // pty 가 어떤 폭으로 태어났는지 남긴다. Tabby 는 프론트엔드의 **첫** resize$ 값으로\r\n // 세션을 스폰하므로(tabby-local: initializeSession(this.size...) -> spawn cols),\r\n // 그 스냅샷이 우리 레이아웃보다 이르면 pty 만 옛 폭으로 굳는다 — 그 순간이 여기 찍힌다.\r\n this.diag(`${new Date().toISOString()} session bind`\r\n + ` xterm=${anyPane.frontend?.xterm?.cols}x${anyPane.frontend?.xterm?.rows}`\r\n + ` paneSize=${anyPane.size?.columns}x${anyPane.size?.rows}`)\r\n session.output$.subscribe((data: string) => {\r\n applyOutput(this.status, root, pane, data, this.config.store.agentDeck.autoDetect)\r\n // 출력이 멈춘 뒤 화면이 온전한지 본다 (그리는 도중에 읽으면 멀쩡한 화면도 깨져 보인다)\r\n this.scheduleScreenCheck(pane)\r\n })\r\n }\r\n bind(anyPane.session)\r\n if (anyPane.sessionChanged$) {\r\n anyPane.sessionChanged$.subscribe((session: any) => bind(session))\r\n }\r\n\r\n // 프론트엔드가 붙는 도중에 우리가 폭을 바꿨으면 그 변경은 유실될 수 있다\r\n // (Tabby 는 attach() 맨 끝에서야 ResizeObserver 를 건다) — 준비되면 fit 한 번으로 깨워 준다.\r\n // 여기서 하는 건 `fitAddon.fit()` 뿐이다. 그 뒤는 순정 경로가 이어받는다\r\n // (fit → xterm onResize → Tabby 가 session.resize). 우리가 pty 에 직접 쏘지 않는다.\r\n if (anyPane.frontendReady$) {\r\n anyPane.frontendReady$.subscribe(() => {\r\n this.scheduleRefit()\r\n this.announceSizeOnOpen(pane)\r\n })\r\n }\r\n // frontendReady 는 replay 가 없는 맨 Subject 라, 복원된 탭의 프론트엔드가 우리보다\r\n // 먼저 붙어버리면 위 구독은 영영 못 받는다. 이벤트와 무관하게 한 번 더 예약한다 —\r\n // 같은 크기를 두 번 알려도 SIGWINCH 가 안 나므로 무해하다.\r\n this.announceSizeOnOpen(pane)\r\n }\r\n\r\n /**\r\n * 탭이 열린 뒤 몇 차례, **지금 xterm 이 쓰는 크기를 pty 에 알려준다.**\r\n *\r\n * 순정이 유일하게 못 메우는 구멍(새 탭에서 pty 만 좁게 태어남)을 메우는 최소 개입이다.\r\n * 자세한 근거와 실측은 `TAB_OPEN_ANNOUNCE_MS` 주석에 있다.\r\n *\r\n * 하지 않는 것 — xterm 은 건드리지 않고(fit 도 resize 도), 폭을 흔들지 않으며,\r\n * 감시 루프도 돌지 않는다. 그 셋이 예전에 화면을 깨뜨린 장본인이다.\r\n */\r\n private announceSizeOnOpen (pane: BaseTabComponent): void {\r\n const anyPane = pane as any\r\n for (const delay of TAB_OPEN_ANNOUNCE_MS) {\r\n setTimeout(() => {\r\n const x = anyPane.frontend?.xterm\r\n const session = anyPane.session\r\n if (!session?.open || typeof session.resize !== 'function' || !(x?.cols > 1)) {\r\n return\r\n }\r\n const prev = anyPane.size\r\n if (prev?.columns !== x.cols || prev?.rows !== x.rows) {\r\n this.diag(`${new Date().toISOString()} announce size ${prev?.columns}x${prev?.rows}`\r\n + ` -> ${x.cols}x${x.rows} (+${delay}ms)`)\r\n }\r\n try {\r\n session.resize(x.cols, x.rows)\r\n anyPane.size = { columns: x.cols, rows: x.rows }\r\n } catch {\r\n // 세션이 막 닫혔다\r\n }\r\n }, delay)\r\n }\r\n }\r\n\r\n // 흔들기 장치는 전부 폐지했다 (2026-09-02).\r\n //\r\n // 여기에 있던 것들 — `scheduleWindowKick`(기동 시 창 복원→최대화), `scheduleRedrawKick`,\r\n // `kickPtySize`(탭당 한 번 cols-1 ↔ cols) — 는 모두 \"순정이 크기를 못 맞춘다\" 는 전제에서\r\n // 나온 우회책이었다. 전제가 틀렸다: Tabby 는 xterm `ResizeObserver` → `fitAddon.fit()` →\r\n // `session.resize()` 로 스스로 맞춘다. 우리가 폭만 정해 주면 된다.\r\n // 이 흔들기들은 순정 수렴과 경쟁하며 프레임을 반쯤 그린 상태를 남겨 화면을 깨뜨렸다.\r\n // 수동 복구(`repairPane`)는 여전히 흔든다 — 거기는 사용자가 명시로 요청한 경로다.\r\n\r\n /**\r\n * Ctrl+V 를 **핫키 테이블에서 걷어낸다** (실제 처리는 claimCtrlVKey 가 한다).\r\n *\r\n * 예전에는 여기서 `agentdeck-paste` 에 Ctrl-V 를 등록했는데, 그러면 한 번 눌러 두 번 붙는\r\n * 경우가 남았다. Tabby 는 같은 keydown 을 **두 경로**로 HotkeysService 에 밀어 넣기 때문이다 —\r\n * xterm 의 커스텀 키 핸들러(`tabby-terminal/dist/index.js:40789` keyboardEventHandler →\r\n * `hotkeysService.pushKeyEvent`)와, document 에 걸린 core 리스너(`tabby-core:21425`).\r\n * `pushKeyEvent` 앞에 `timeStamp` 중복 가드가 있지만(`tabby-core:21451`) 그건 **같은**\r\n * 이벤트 객체일 때만 먹고, 두 경로가 서로 다른 이벤트(keydown/keyup 등)로 들어오면\r\n * `emitHotkeyOn` 이 두 번 나간다(실측: hotkey-paste 가 1ms 간격 2회, `.agentdeck-diag.log`).\r\n *\r\n * 그래서 핫키에 기대지 않고 캡처 단계에서 직접 한 번만 처리한다 — 우클릭을 claimRightClick\r\n * 으로 가져온 것과 같은 이유·같은 방식이다. 순정 `paste` 쪽에 Ctrl-V 가 남아 있어도 캡처가\r\n * 먼저 먹고 전파를 끊으므로 발화하지 않지만, 설정 화면이 헷갈리지 않게 양쪽 모두에서 뺀다.\r\n *\r\n * 대가: 터미널 앱에 리터럴 Ctrl+V(0x16, quoted-insert)를 보낼 수 없다.\r\n * 그게 필요하면 `agentDeck.claimCtrlV: false`.\r\n */\r\n private ensurePasteHotkey (): void {\r\n const hotkeys = this.config.store.hotkeys\r\n if (!hotkeys) {\r\n return\r\n }\r\n let changed = false\r\n\r\n // 옛 이름(workdeck-*)으로 저장된 핫키가 config.yaml 에 남아 있으면 Ctrl-V 가 그쪽에\r\n // 먼저 매칭돼 우리 핸들러가 통째로 죽는다 — HotkeysService.matchActiveHotkey 는\r\n // 길이가 같은 후보 중 config 삽입 순서로 앞선 것 하나만 고르고, 옛 항목이 먼저 저장돼 있다\r\n // (tabby-core/dist/index.js:21558 matches.sort → matches[0].id).\r\n for (const legacy of ['workdeck-paste', 'workdeck-newline', 'workdeck-toggle']) {\r\n if (legacy in hotkeys) {\r\n delete hotkeys[legacy]\r\n changed = true\r\n }\r\n }\r\n\r\n // 지난 버전이 넣어둔 Ctrl-V 를 회수한다. 남겨두면 캡처 경로와 겹쳐 다시 2중이 될 수 있다\r\n for (const id of ['agentdeck-paste', 'paste']) {\r\n const keys: string[] = Array.isArray(hotkeys[id]) ? hotkeys[id] : []\r\n if (keys.includes('Ctrl-V')) {\r\n hotkeys[id] = keys.filter(k => k !== 'Ctrl-V')\r\n changed = true\r\n }\r\n }\r\n\r\n if (changed) {\r\n this.config.save()\r\n }\r\n this.diag(`${new Date().toISOString()} hotkeys paste=${JSON.stringify(hotkeys.paste)} `\r\n + `agentdeck-paste=${JSON.stringify(hotkeys['agentdeck-paste'])} `\r\n + `legacy=${Object.keys(hotkeys).filter(k => k.startsWith('workdeck')).join(',') || 'none'}`)\r\n }\r\n\r\n /**\r\n * Ctrl+V 를 document **캡처 단계**에서 한 번만 처리한다.\r\n *\r\n * 캡처는 xterm 의 textarea 리스너보다도 먼저 돌기 때문에, 여기서 전파를 끊으면\r\n * 그 뒤에 있는 경로(xterm 커스텀 키 핸들러 → pushKeyEvent, core 의 document 리스너,\r\n * xterm 이 Ctrl+V 를 0x16 으로 바꿔 PTY 에 흘리는 기본 동작, 브라우저 네이티브 paste)가\r\n * 통째로 죽는다. 몇 개가 겹쳐 걸려 있든 붙여넣기는 정확히 한 번이 된다 —\r\n * 핫키로 받던 시절 남아 있던 2중 입력의 해법이다(ensurePasteHotkey 주석에 원인).\r\n *\r\n * 단, 설정 화면 같은 **평범한 입력 필드**에서는 손대지 않는다. 거기서는 Ctrl+V 가\r\n * 브라우저 기본 붙여넣기여야 하고, 우리가 가로채면 아예 못 붙여넣게 된다.\r\n */\r\n private claimCtrlVKey (): void {\r\n document.addEventListener('keydown', (event: KeyboardEvent) => {\r\n if (!this.config.store.agentDeck.claimCtrlV) {\r\n return\r\n }\r\n if (!event.ctrlKey || event.shiftKey || event.altKey || event.metaKey) {\r\n return\r\n }\r\n // 한글 입력 상태에서는 key 가 'ㅍ' 로 오기도 한다 — 물리 키(code)를 같이 본다\r\n if ((event.key || '').toLowerCase() !== 'v' && event.code !== 'KeyV') {\r\n return\r\n }\r\n if (this.isPlainInput(event.target)) {\r\n return\r\n }\r\n event.preventDefault()\r\n event.stopPropagation()\r\n this.zone.runOutsideAngular(() => this.doPaste('ctrl-v'))\r\n }, true)\r\n }\r\n\r\n /**\r\n * Home / End 를 Tabby 핫키 테이블에서 걷어내 xterm 순정 경로로 돌려준다.\r\n *\r\n * 증상: 한글 마지막 음절이 조합 중일 때 Home/End 를 누르면 그 음절이 **커서를 따라간다**\r\n * (2026-09-08 사용자 보고). 방향키는 멀쩡하다 — 그 차이가 곧 원인이다.\r\n *\r\n * 방향키는 핫키가 아니라서 xterm 의 키 경로를 그대로 탄다. 거기서는 조합 중에 아무 키나\r\n * 들어오면 `CompositionHelper.keydown` 이 `_finalizeComposition(false)` 로 조합을\r\n * **동기 전송**하고(`tabby-terminal/dist/index.js:44098`, `:44120` triggerDataEvent) 그다음\r\n * 방향키를 보낸다 — 글자 먼저, 이동 나중이라 순서가 맞는다.\r\n *\r\n * Home/End 는 그 경로를 못 탄다. Tabby 가 `hotkeys.home` / `hotkeys.end` 로 선점해서\r\n * `tabby-local/dist/index.js:613` 이 `sendInput('\u001b[H')` 를 **즉시** 쏘기 때문이다.\r\n * xterm 을 거치지 않으니 조합 확정은 `compositionend` 경로로 밀리는데, 그쪽\r\n * `_finalizeComposition(true)` 는 `setTimeout(..., 0)` 로 **비동기 전송**이다\r\n * (`tabby-terminal/dist/index.js:44110`). 결국 커서 이동이 먼저 나가고 음절이 한 틱 뒤에\r\n * 도착한다 — 앱은 옮겨간 자리에 글자를 찍는다.\r\n *\r\n * 그래서 고치는 방법은 핸들러를 더 얹는 게 아니라 **핫키를 놓아주는 것**이다. 비워두면\r\n * xterm 이 Home/End 를 방향키와 똑같이 처리한다(조합 확정 → 키 전송). 되돌리려면\r\n * `agentDeck.releaseHomeEnd: false` 후 설정에서 다시 지정하면 된다.\r\n */\r\n private releaseHomeEndHotkey (): void {\r\n if (!this.config.store.agentDeck.releaseHomeEnd) {\r\n return\r\n }\r\n const hotkeys = this.config.store.hotkeys\r\n if (!hotkeys) {\r\n return\r\n }\r\n let changed = false\r\n for (const id of ['home', 'end']) {\r\n const keys: string[] = Array.isArray(hotkeys[id]) ? hotkeys[id] : []\r\n const kept = keys.filter(k => k !== 'Home' && k !== 'End')\r\n if (kept.length !== keys.length) {\r\n hotkeys[id] = kept\r\n changed = true\r\n }\r\n }\r\n if (changed) {\r\n this.config.save()\r\n }\r\n this.diag(`${new Date().toISOString()} hotkeys home=${JSON.stringify(hotkeys.home)} `\r\n + `end=${JSON.stringify(hotkeys.end)}`)\r\n }\r\n\r\n /**\r\n * Shift+Enter / Ctrl+Enter 를 document **캡처 단계**에서 직접 줄바꿈으로 바꾼다.\r\n *\r\n * 핫키(`agentdeck-newline`)에만 맡겼더니 한글을 치다 누르면 절반쯤 줄바꿈이 아니라\r\n * **전송**이 됐다 (2026-09-08 사용자 보고: \"50% 정도는 그냥 enter 로 들어간다\").\r\n * 진단로그에 증거가 남아 있다 — 오발신 순간 `enter-label` 이 발화했는데\r\n * (`.agentdeck-diag.log` 00:54:59 `enter-label text=\"지금도 그랬\"`), 그 핸들러는\r\n * 수식키가 하나라도 눌려 있으면 맨 앞에서 빠져나간다. 즉 그 Enter 는 **shiftKey 가\r\n * 지워진 채** 도착했다. 한글 IME 가 조합을 확정하며 Enter 를 한 번 삼키고, 뒤이어\r\n * 내보내는 이벤트에는 Shift 상태를 싣지 않는 것이다. Shift 가 없으니 `Shift-Enter`\r\n * 핫키에 매칭될 리 없고, xterm 은 평범한 Enter 로 0x0D 를 PTY 에 흘린다 —\r\n * 쓰다 만 문장이 그대로 전송된다.\r\n *\r\n * 그래서 이벤트가 알려주는 수식키를 믿지 않고 **Shift 눌림을 우리가 따로 센다**.\r\n * Shift 자체의 keydown/keyup 은 조합과 무관하게 그대로 오므로 IME 를 타지 않는다.\r\n * 세어 둔 값이 썩는 것(키업 유실)을 막으려고 창 포커스가 나가거나, Shift 없이 평범한\r\n * 글자가 들어오거나, 오래 묵으면(STALE_MS) 스스로 잊는다.\r\n *\r\n * 조합 중(`isComposing`/keyCode 229)인 Enter 는 손대지 않는다. 그건 \"이 음절을\r\n * 확정해라\" 는 신호고 여기서 막으면 마지막 글자가 확정되지 못한 채 줄만 넘어간다.\r\n * 확정이 끝나면 Enter 가 한 번 더 오니 그때 잡으면 글자 순서도 어긋나지 않는다.\r\n *\r\n * 캡처에서 전파를 끊는 이유는 claimCtrlVKey 와 같다 — 뒤에 걸린 경로(xterm 커스텀 키\r\n * 핸들러 → pushKeyEvent, core 의 document 리스너, xterm 이 Enter 를 0x0D 로 흘리는\r\n * 기본 동작)를 통째로 죽여야 줄바꿈이 정확히 한 번이 된다.\r\n */\r\n private claimShiftEnterKey (): void {\r\n const STALE_MS = 5000\r\n const forget = (): void => {\r\n this.shiftDownAt = 0\r\n }\r\n const isShiftKey = (event: KeyboardEvent): boolean =>\r\n event.key === 'Shift' || (event.code || '').startsWith('Shift')\r\n\r\n window.addEventListener('blur', forget)\r\n document.addEventListener('keyup', (event: KeyboardEvent) => {\r\n if (isShiftKey(event)) {\r\n forget()\r\n }\r\n }, true)\r\n\r\n document.addEventListener('keydown', (event: KeyboardEvent) => {\r\n if (isShiftKey(event)) {\r\n this.shiftDownAt = Date.now()\r\n return\r\n }\r\n if (!this.config.store.agentDeck.claimShiftEnter) {\r\n return\r\n }\r\n const isEnter = event.key === 'Enter' || event.code === 'Enter' || event.code === 'NumpadEnter'\r\n // Shift 없이 평범한 글자가 들어왔다 = Shift 는 확실히 떼어져 있다 (키업 유실 자가복구)\r\n if (!isEnter && !event.shiftKey && !event.getModifierState('Shift')) {\r\n forget()\r\n return\r\n }\r\n if (!isEnter || event.altKey || event.metaKey) {\r\n return\r\n }\r\n if (event.isComposing || event.keyCode === 229) {\r\n return // 조합 확정용 Enter — 확정된 뒤에 한 번 더 온다\r\n }\r\n const tracked = this.shiftDownAt > 0 && Date.now() - this.shiftDownAt < STALE_MS\r\n const shift = event.shiftKey || event.getModifierState('Shift') || tracked\r\n if (!shift && !event.ctrlKey) {\r\n return // 맨 Enter 는 전송이다 — 건드리지 않는다\r\n }\r\n if (this.isPlainInput(event.target)) {\r\n return\r\n }\r\n event.preventDefault()\r\n event.stopPropagation()\r\n this.diag(`${new Date().toISOString()} newline (capture) shiftKey=${event.shiftKey} `\r\n + `modState=${event.getModifierState('Shift')} tracked=${tracked} ctrl=${event.ctrlKey}`)\r\n this.sendNewline()\r\n }, true)\r\n }\r\n\r\n /**\r\n * Enter 를 눌러 프롬프트를 보낼 때, 그 프롬프트 원문을 작업 라벨로 삼는다.\r\n *\r\n * 왜 이게 필요한가 — 라벨을 채우는 다른 경로(훅·콘솔 제목)는 둘 다 배포판에서 못 믿는다.\r\n * 훅은 사용자가 `~/.claude/settings.json` 을 손봐야 돌고, 플러그인이 그걸 대신 깔아줄 수도 없다.\r\n * 콘솔 제목은 Claude Code 가 세션 첫 작업을 요약해 한 번 박고 그 뒤로 갱신하지 않는다\r\n * (2026-08-28 실측: 작업이 네 번 바뀌는 동안 `◑ sendInput 한 줄 vs 두 줄 원인 파악` 그대로).\r\n * 그래서 설정이 하나도 없는 상태에서 라벨을 최신으로 유지할 수 있는 건 이 경로뿐이다.\r\n *\r\n * **Enter 만 잡는다.** Shift+Enter / Ctrl+Enter 는 줄바꿈이라(agentdeck-newline) 아직 전송이\r\n * 아니고, 그때 라벨을 바꾸면 쓰다 만 문장이 박힌다. 수식키가 하나라도 눌려 있으면 그냥 흘린다.\r\n * IME 조합 중의 Enter(한글 확정)도 전송이 아니므로 제외한다.\r\n *\r\n * 관측만 하고 이벤트는 절대 막지 않는다 — 여기서 preventDefault 하면 프롬프트가 안 보내진다.\r\n */\r\n private claimEnterLabel (): void {\r\n document.addEventListener('keydown', (event: KeyboardEvent) => {\r\n if (!this.config.store.agentDeck.enterAsLabel) {\r\n return\r\n }\r\n if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey) {\r\n return // 줄바꿈이지 전송이 아니다\r\n }\r\n if (event.key !== 'Enter' && event.code !== 'Enter' && event.code !== 'NumpadEnter') {\r\n return\r\n }\r\n if (event.isComposing || event.keyCode === 229) {\r\n return // 한글 조합 확정용 Enter\r\n }\r\n if (this.isPlainInput(event.target)) {\r\n return\r\n }\r\n const pane = this.focusedPane()\r\n if (!pane) {\r\n this.diag(`${new Date().toISOString()} enter-label skipped (no pane)`)\r\n return\r\n }\r\n // 화면은 아직 프롬프트가 지워지기 전이다 — 캡처 단계라 앱이 Enter 를 보기 전에 읽는다\r\n const text = this.readPromptLine(pane)\r\n // 상태는 루트 탭 단위로 관리한다 (watchTab 이 app.tabs 로 감시하는 것과 같은 단위)\r\n const tab = this.app.activeTab\r\n this.diag(`${new Date().toISOString()} enter-label text=\"${text}\" tab=${tab ? 'yes' : 'no'}`)\r\n if (!text || !tab) {\r\n return\r\n }\r\n this.status.setLabel(tab, text)\r\n }, true)\r\n }\r\n\r\n /**\r\n * xterm 화면 버퍼에서 지금 입력창에 쓰여 있는 프롬프트를 읽는다 (판정은 extractPrompt).\r\n *\r\n * 화면 맨 아래가 아니라 **커서 줄**을 기준점으로 잡는다. Claude Code 는 대화가 짧으면\r\n * 입력창을 화면 위쪽에 두고 그 아래를 전부 빈 줄로 남기는데(2026-08-28 실측), 아래 14줄만\r\n * 읽으면 빈 줄만 걸려 프롬프트를 영영 못 찾는다 — 라벨이 안 바뀌던 원인이 이것이다.\r\n * 커서는 항상 입력 중인 줄에 있고, 여러 줄 프롬프트면 마지막 줄에 있으니 거기서 위로 훑으면\r\n * `> ` 머리를 만난다. 커서 아래는 힌트 줄이라 애초에 읽지 않는 편이 정확하다.\r\n */\r\n private readPromptLine (pane: any): string {\r\n const xterm = pane.frontend?.xterm\r\n const buf = xterm?.buffer?.active\r\n if (!buf || typeof buf.getLine !== 'function') {\r\n this.diag(`${new Date().toISOString()} enter-label no-buffer frontend=${pane.frontend ? 'yes' : 'no'} xterm=${xterm ? 'yes' : 'no'}`)\r\n return ''\r\n }\r\n const read = (from: number, to: number): string[] => {\r\n const lines: string[] = []\r\n for (let y = Math.max(0, from); y <= to; y++) {\r\n lines.push(buf.getLine(y)?.translateToString(true) ?? '')\r\n }\r\n return lines\r\n }\r\n const cursor = buf.baseY + (buf.cursorY ?? 0)\r\n const nearCursor = read(cursor - PROMPT_SCAN_ROWS, cursor)\r\n const byCursor = extractPrompt(nearCursor)\r\n if (byCursor) {\r\n return byCursor\r\n }\r\n // 커서가 입력창 밖에 있을 때의 폴백 — 화면 전체를 아래에서 위로 훑는다\r\n const byScreen = extractPrompt(read(buf.baseY, buf.baseY + xterm.rows - 1))\r\n if (!byScreen) {\r\n // 두 경로가 다 빈손이면 화면이 어떻게 생겼는지 남긴다.\r\n // 이게 없어서 \"입력창 못 찾음\" 과 \"버퍼를 못 읽음\" 을 못 갈랐다 (2026-09-01).\r\n const dump = nearCursor.slice(-4)\r\n .map(l => JSON.stringify(l.slice(0, 60)))\r\n .join(' | ')\r\n this.diag(`${new Date().toISOString()} enter-label miss baseY=${buf.baseY} cursorY=${buf.cursorY} rows=${xterm.rows} tail=${dump}`)\r\n }\r\n return byScreen\r\n }\r\n\r\n /** 터미널이 아닌 보통 입력 필드(설정 화면 등)인지 — 거기서는 Ctrl+V 를 건드리지 않는다 */\r\n private isPlainInput (target: EventTarget | null): boolean {\r\n const el = target as HTMLElement | null\r\n if (!el || typeof el.closest !== 'function') {\r\n return false\r\n }\r\n // xterm 이 키 입력을 받는 숨은 textarea 는 터미널이지 입력 필드가 아니다\r\n if (el.classList?.contains('xterm-helper-textarea') || el.closest('.xterm')) {\r\n return false\r\n }\r\n return el.isContentEditable || ['INPUT', 'TEXTAREA'].includes(el.tagName)\r\n }\r\n\r\n /**\r\n * Ctrl+V 붙여넣기 — 클립보드가 이미지면 Alt+V 로 넘긴다.\r\n *\r\n * 터미널 붙여넣기는 \"클립보드 텍스트를 키 입력처럼 PTY 에 써넣는\" 동작이다\r\n * (`tabby-terminal/dist/index.js:41842` paste() → readClipboard() → sendInput).\r\n * PTY 는 바이트 스트림이라 이미지가 지나갈 방법 자체가 없고, 클립보드는 OS 자원이라\r\n * 터미널 안에서 도는 앱은 손댈 수 없다 — 그래서 이미지는 조용히 사라진다.\r\n *\r\n * Claude Code 는 이걸 자기가 OS 클립보드를 직접 읽어서 푼다. Alt+V(= ESC v)가 그\r\n * \"지금 클립보드를 읽어라\" 신호다. 즉 Ctrl+V 와 Alt+V 는 붙여넣는 주체가 다르다\r\n * (Ctrl+V = 터미널이 넣어줌 / Alt+V = 앱이 직접 읽음). 사용자가 그걸 구분할 이유는 없으니\r\n * 클립보드에 이미지만 있을 때 Ctrl+V 가 알아서 ESC v 를 대신 보낸다.\r\n *\r\n * 텍스트가 같이 들어 있으면(엑셀·워드 복사 등) 텍스트 붙여넣기를 유지한다 — 그쪽이 의도이므로.\r\n */\r\n private doPaste (source: string): void {\r\n // 한 번의 Ctrl+V / 우클릭이 여러 경로로 들어오는 일이 있다 (ensurePasteHotkey 주석 참고).\r\n // 어느 경로가 먼저 오든 처음 것만 살린다 — 사람 연타는 이 창보다 느리다.\r\n const now = Date.now()\r\n if (now - this.lastPasteAt < PASTE_DEDUPE_MS) {\r\n this.diag(`${new Date().toISOString()} paste ignored (dup ${now - this.lastPasteAt}ms, ${source})`)\r\n return\r\n }\r\n this.lastPasteAt = now\r\n\r\n const pane = this.focusedPane()\r\n if (!pane) {\r\n return\r\n }\r\n const imageOnly = this.clipboardHasImageOnly()\r\n this.diag(`${new Date().toISOString()} paste probe enabled=${this.config.store.agentDeck.pasteImageWithCtrlV} imageOnly=${imageOnly} sendInput=${typeof pane.sendInput}`)\r\n if (this.config.store.agentDeck.pasteImageWithCtrlV\r\n && imageOnly\r\n && typeof pane.sendInput === 'function') {\r\n // 이미지 전용 클립보드 — 텍스트 붙여넣기는 어차피 아무것도 못 넣으므로\r\n // \"네가 직접 클립보드를 읽어라\" 키를 흘려보낸다 (sendImagePasteKey 주석 참고)\r\n void this.sendImagePasteKey(pane)\r\n return\r\n }\r\n if (typeof pane.paste !== 'function') {\r\n return\r\n }\r\n // 붙여넣기 한 번이 PTY 에 몇 번 써지는지 본다 (우클릭 2중 입력 추적용).\r\n // 창을 열어둔 동안의 입력만 남긴다 — 상시 켜두면 사람이 타이핑한 것까지 다 찍힌다.\r\n this.pasteProbeUntil = Date.now() + PASTE_PROBE_MS\r\n this.probeSendInput(pane)\r\n this.probeWrite(pane)\r\n // 텍스트 붙여넣기는 xterm 이 네이티브 paste 이벤트로 이미 처리한다\r\n // (tabby-terminal/dist/index.js:5383 에서 textarea/element 에 handlePasteEvent 등록).\r\n // 그런데도 우리가 무조건 paste() 를 부르면 한 번 눌러 두 번 붙는다.\r\n // 그래서 네이티브가 오는지 잠깐 보고, 안 오면(터미널 textarea 가 포커스를 못 잡은 경우 등)\r\n // 그제야 우리가 붙인다 — 어느 쪽이든 정확히 한 번이 된다.\r\n this.diag(`${new Date().toISOString()} paste (${source})`)\r\n if (source === 'ctrl-v') {\r\n // 캡처 단계에서 이미 preventDefault 했으므로 네이티브 paste 는 오지 않는다 — 기다릴 것 없이 바로 붙인다\r\n void pane.paste()\r\n return\r\n }\r\n const startedAt = Date.now()\r\n setTimeout(() => {\r\n if (this.nativePasteAt >= startedAt) {\r\n this.diag(`${new Date().toISOString()} paste skipped (native handled)`)\r\n return\r\n }\r\n this.diag(`${new Date().toISOString()} paste fallback`)\r\n void pane.paste()\r\n }, PASTE_NATIVE_WAIT_MS)\r\n }\r\n\r\n /**\r\n * 이미지 전용 클립보드일 때 터미널 앱에 \"네가 클립보드를 직접 읽어라\" 키를 흘려보낸다.\r\n *\r\n * 어떤 키인지는 앱마다 다르다 (2026-08-28 실측):\r\n * - Claude Code: ESC v 만 받는다. 리터럴 0x16 은 5회 보내도 이미지가 들어가지 않았다\r\n * (`.agentdeck-diag.log` 09:33:47~48 `paste image (ctrl-v)` 5줄, 화면에는 아무 변화 없음).\r\n * claude.exe 안의 `ctrl+v ... paste images` 문구는 자기가 키 이벤트를 직접 볼 때의 안내였고,\r\n * PTY 로 들어온 0x16 에는 반응하지 않는다.\r\n * - Codex: 0x16 을 자기 붙여넣기로 받고, ESC v 는 모른다.\r\n * 그래서 탭에서 도는 앱을 보고 갈라 보내고, 못 알아내면 설정값(`imagePasteKey`)을 쓴다.\r\n */\r\n private async sendImagePasteKey (pane: any): Promise<void> {\r\n const app = await this.detectAgentApp(pane)\r\n const configured = this.config.store.agentDeck.imagePasteKey\r\n const mode = app === 'claude' ? 'alt-v'\r\n : app === 'codex' ? 'ctrl-v'\r\n : configured\r\n const key = mode === 'ctrl-v' ? '\u0016' : '\u001bv'\r\n this.diag(`${new Date().toISOString()} paste image app=${app} mode=${mode} `\r\n + `bytes=${[...key].map(c => c.charCodeAt(0)).join(',')}`)\r\n pane.sendInput(key)\r\n }\r\n\r\n /**\r\n * 이 탭에서 도는 에이전트 CLI 가 뭔지 — 이미지 붙여넣기 키가 앱마다 달라서 필요하다.\r\n *\r\n * 프로세스 트리를 먼저 본다 (`session.getChildProcesses()`). npm 전역 래퍼를 거치면\r\n * 커맨드가 node/pwsh 로만 보일 수 있어서, 그때는 탭 제목으로 한 번 더 본다.\r\n */\r\n private async detectAgentApp (pane: any): Promise<'claude' | 'codex' | 'unknown'> {\r\n try {\r\n const procs: any[] = await pane.session?.getChildProcesses?.() ?? []\r\n const names = procs.map(x => `${x?.command ?? ''} ${x?.name ?? ''}`).join(' ').toLowerCase()\r\n if (names.includes('codex')) {\r\n return 'codex'\r\n }\r\n if (names.includes('claude')) {\r\n return 'claude'\r\n }\r\n } catch {\r\n // 프로세스 트리를 못 읽는 세션(SSH 등) — 제목으로 떨어진다\r\n }\r\n const title = `${pane.title ?? ''} ${pane.customTitle ?? ''}`.toLowerCase()\r\n if (title.includes('codex')) {\r\n return 'codex'\r\n }\r\n if (title.includes('claude')) {\r\n return 'claude'\r\n }\r\n return 'unknown'\r\n }\r\n\r\n /**\r\n * pane.sendInput 을 한 번 감싸 PTY 로 나간 입력을 진단 로그에 남긴다.\r\n *\r\n * 붙여넣기 한 번에 텍스트가 두 번 들어가는 증상은 \"우리가 두 번 불렀는지\" 와\r\n * \"한 번 불렀는데 PTY 에 두 번 써졌는지\" 를 갈라야 원인이 잡힌다. 이 계측이 그 경계다.\r\n * `pasteProbeUntil` 창 안에서만 기록하므로 평소 타이핑은 남지 않는다.\r\n */\r\n private probeSendInput (pane: any): void {\r\n if (!pane || pane.__adSendInputProbe || typeof pane.sendInput !== 'function') {\r\n return\r\n }\r\n const orig = pane.sendInput.bind(pane)\r\n pane.__adSendInputProbe = true\r\n pane.sendInput = (data: any, ...rest: any[]) => {\r\n if (Date.now() < this.pasteProbeUntil) {\r\n const text = typeof data === 'string' ? data : String(data)\r\n this.diag(`${new Date().toISOString()} sendInput len=${text.length} `\r\n + `head=${JSON.stringify(text.slice(0, 24))} from=${this.callSite()}`)\r\n }\r\n return orig(data, ...rest)\r\n }\r\n }\r\n\r\n /**\r\n * PTY 로 나가는 최종 관문(session.write)을 랩핑한다.\r\n *\r\n * pane.sendInput 만 보면 그걸 거치지 않는 경로를 놓친다 — 실측(2026-08-28 09:44:03)에서\r\n * 우클릭 한 번에 sendInput 은 154바이트 1회뿐인데 화면에는 두 번 들어갔다. 즉 두 번째는\r\n * 우리 계측 밖의 경로다. session.write 는 어느 경로든 마지막에 지나가므로 여기서 잡힌다.\r\n */\r\n private probeWrite (pane: any): void {\r\n const session = pane?.session\r\n if (!session || session.__adWriteProbe || typeof session.write !== 'function') {\r\n return\r\n }\r\n const orig = session.write.bind(session)\r\n session.__adWriteProbe = true\r\n session.write = (data: any, ...rest: any[]) => {\r\n if (Date.now() < this.pasteProbeUntil) {\r\n const text = typeof data === 'string' ? data : String(data)\r\n this.diag(`${new Date().toISOString()} write len=${text.length} `\r\n + `head=${JSON.stringify(text.slice(0, 24))} from=${this.callSite()}`)\r\n }\r\n return orig(data, ...rest)\r\n }\r\n }\r\n\r\n /** 호출 지점 몇 프레임 — 두 번째 붙여넣기를 누가 넣는지 보려고 */\r\n private callSite (): string {\r\n return (new Error().stack ?? '').split(String.fromCharCode(10)).slice(3, 7)\r\n .map(l => l.trim().replace(/^at\\s+/, '')).join(' <- ')\r\n }\r\n\r\n /** 클립보드에 이미지가 있고 텍스트는 비어 있는지 */\r\n private clipboardHasImageOnly (): boolean {\r\n const cb = getClipboard()\r\n if (!cb) {\r\n // Electron clipboard 를 못 쓰는 환경(웹 빌드 등) — 텍스트 붙여넣기로 떨어진다\r\n this.diag(`${new Date().toISOString()} clipboard unavailable`)\r\n return false\r\n }\r\n try {\r\n const hasImage = !cb.readImage().isEmpty()\r\n const text = cb.readText()\r\n this.diag(`${new Date().toISOString()} clipboard hasImage=${hasImage} textLen=${text.length}`)\r\n return hasImage && text.trim() === ''\r\n } catch (err) {\r\n this.diag(`${new Date().toISOString()} clipboard read failed: ${err}`)\r\n return false\r\n }\r\n }\r\n\r\n /** 분할된 탭이면 래퍼가 아니라 실제 포커스된 pane 을 돌려준다 */\r\n private focusedPane (): any {\r\n const active = this.app.activeTab as any\r\n if (!active) {\r\n return null\r\n }\r\n return typeof active.getFocusedTab === 'function'\r\n ? (active.getFocusedTab() ?? active)\r\n : active\r\n }\r\n\r\n /**\r\n * 줄바꿈 핫키에 Shift+Enter 를 보정해 넣는다.\r\n *\r\n * config.yaml 에 이미 `agentdeck-newline` 이 저장돼 있으면 ConfigProvider 의 defaults 는\r\n * 무시되므로(저장값이 이긴다) 기동 시 코드로 채워 넣어야 한다 — ensurePasteHotkey 와 같은 이유.\r\n */\r\n private ensureNewlineHotkey (): void {\r\n const hotkeys = this.config.store.hotkeys\r\n if (!hotkeys || !Array.isArray(hotkeys['agentdeck-newline'])) {\r\n return\r\n }\r\n const list: string[] = hotkeys['agentdeck-newline']\r\n if (list.includes('Shift-Enter')) {\r\n return\r\n }\r\n hotkeys['agentdeck-newline'] = [...list, 'Shift-Enter']\r\n this.config.save()\r\n }\r\n\r\n // ---------- 우클릭 ----------\r\n\r\n /**\r\n * 우클릭 처리를 agentdeck 이 가져온다.\r\n *\r\n * 증상: 우클릭 한 번에 클립보드가 두 번 들어갔다.\r\n * 원인: Tabby 의 우클릭 처리는 터미널 host 엘리먼트에 건 버블 단계 mouseup 리스너인데\r\n * (`tabby-terminal/dist/index.js:40972` 에서 등록, `detach()` 는 이 리스너를 떼지 않는다)\r\n * 프론트엔드가 같은 host 에 다시 attach 되면 리스너가 겹쳐 붙어 mouseEvent$ 가 한 클릭에\r\n * 두 번 발화한다. 그러면 `handleRightMouseUp` 이 두 번 돌아 paste() 도 두 번 나간다.\r\n *\r\n * 해결: Tabby 쪽 처리를 끄고(terminal.rightClick = 'off') document 캡처 단계에서\r\n * 우리가 한 번만 처리한다. 캡처는 host 리스너보다 먼저 돌기 때문에 몇 개가 겹쳐 붙어 있든\r\n * stopPropagation 으로 전부 차단된다. 동작 자체는 Tabby 의 'clipboard' 모드와 동일하게 —\r\n * 선택이 있으면 복사, 없으면 붙여넣기, 길게 누르면 컨텍스트 메뉴 — 유지한다.\r\n */\r\n private claimRightClick (): void {\r\n if (!this.config.store.agentDeck.claimRightClick) {\r\n return\r\n }\r\n // Tabby 자체 처리를 꺼서 리스너가 겹쳐도 아무 일이 없게 만든다 (이중 안전장치)\r\n if (this.config.store.terminal && this.config.store.terminal.rightClick !== 'off') {\r\n this.config.store.terminal.rightClick = 'off'\r\n this.config.save()\r\n }\r\n\r\n document.addEventListener('mousedown', ev => {\r\n if (ev.button !== 2 || !this.inTerminalArea(ev)) {\r\n return\r\n }\r\n this.rightDownAt = Date.now()\r\n // mouseup 만 막으면 mousedown 이 xterm 까지 내려가 마우스 리포트가 PTY 로 나간다.\r\n // Claude Code 처럼 마우스 트래킹을 켠 앱은 그 우클릭 리포트(ESC [ < 2 ; x ; y M)를\r\n // 자기 붙여넣기 신호로 받아 스스로 클립보드를 읽는다 — 우리 paste 와 합쳐 두 번 붙는다\r\n // (2026-08-28 실측: .agentdeck-diag.log 09:49:08.616 에 \"\u001b[<2;172;35M\" 전송,\r\n // 플러그인 write 는 클릭당 1회뿐인데 화면에는 2회 들어감).\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n }, { capture: true })\r\n\r\n // 우클릭에 딸려오는 contextmenu 도 캡처에서 끊는다 (메뉴는 길게 누를 때 우리가 직접 띄운다)\r\n document.addEventListener('contextmenu', ev => {\r\n if (this.inTerminalArea(ev)) {\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n }\r\n }, { capture: true })\r\n\r\n document.addEventListener('mouseup', ev => {\r\n if (ev.button !== 2 || !this.inTerminalArea(ev)) {\r\n return\r\n }\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n\r\n // 같은 물리 클릭이 두 번 들어오면(리스너 중복) 뒤엣것은 버린다\r\n const now = Date.now()\r\n if (now - this.lastRightHandledAt < 150) {\r\n return\r\n }\r\n this.lastRightHandledAt = now\r\n\r\n const held = now - this.rightDownAt\r\n void this.handleRightClick(ev, held)\r\n }, { capture: true })\r\n }\r\n\r\n /** 사이드바가 아니라 터미널 뷰포트 안에서 일어난 이벤트인지 */\r\n private inTerminalArea (ev: MouseEvent): boolean {\r\n const target = ev.target as HTMLElement | null\r\n if (!target || typeof target.closest !== 'function') {\r\n return false\r\n }\r\n return !!target.closest('.content.main') && !target.closest(`#${SIDEBAR_ID}`)\r\n }\r\n\r\n private async handleRightClick (ev: MouseEvent, heldMs: number): Promise<void> {\r\n const pane = this.focusedPane()\r\n if (!pane) {\r\n return\r\n }\r\n\r\n const menuMs = this.config.store.agentDeck.rightClickMenuMs ?? 250\r\n if (heldMs >= menuMs) {\r\n if (typeof pane.buildContextMenu === 'function' && pane.platform) {\r\n pane.platform.popupContextMenu(await pane.buildContextMenu(), ev)\r\n }\r\n return\r\n }\r\n\r\n const selection = typeof pane.frontend?.getSelection === 'function'\r\n ? pane.frontend.getSelection()\r\n : ''\r\n if (selection) {\r\n pane.frontend.copySelection()\r\n pane.frontend.clearSelection()\r\n } else {\r\n // 우클릭 붙여넣기도 Ctrl+V 와 같은 경로를 타게 한다 (이미지면 Alt+V 위임)\r\n this.doPaste('rightclick')\r\n }\r\n }\r\n\r\n /**\r\n * 포커스된 pane 에 0x0A(LF) 를 보낸다 — Ctrl+J 가 보내는 것과 같은 바이트다.\r\n * Claude Code 는 이걸 줄바꿈으로 받고, Enter(0x0D) 는 전송으로 받는다.\r\n * Enter 를 눌러 줄을 넘기지 않으려는 것이므로 CR 을 섞으면 안 된다.\r\n */\r\n private sendNewline (): void {\r\n const pane = this.focusedPane()\r\n if (!pane) {\r\n return\r\n }\r\n if (typeof pane.sendInput === 'function') {\r\n pane.sendInput('\\n')\r\n }\r\n }\r\n\r\n // ---------- 레이아웃 ----------\r\n\r\n private get enabled (): boolean {\r\n return this.config.store.agentDeck.enabled\r\n }\r\n\r\n private applyEnabled (): void {\r\n document.body.classList.toggle(BODY_CLASS, this.enabled)\r\n if (this.sidebar) {\r\n this.sidebar.style.display = this.enabled ? '' : 'none'\r\n }\r\n if (!this.enabled && this.mainEl) {\r\n for (const prop of ['flex', 'width', 'max-width', 'height',\r\n 'margin-left', 'margin-right', 'margin-top', 'margin-bottom']) {\r\n this.mainEl.style.removeProperty(prop)\r\n }\r\n // 폭을 되돌렸으니 메모도 무효화하고 터미널에 새 폭을 알린다\r\n this.lastTermW = -1\r\n this.lastSidebarW = -1\r\n this.lastDock = null\r\n this.scheduleRefit()\r\n }\r\n this.syncBackgroundClip()\r\n }\r\n\r\n /**\r\n * tabby-background 의 이미지 레이어를 터미널 영역(`.content.main`)에 맞춰 자른다.\r\n *\r\n * 그 레이어는 `position: fixed` 라 viewport 좌표를 쓰므로 `getBoundingClientRect()` 값을\r\n * 그대로 CSS 변수로 내리면 된다 (styles.scss 가 `!important` 로 덮어쓴다).\r\n * relayout 직후에는 인라인 폭이 아직 레이아웃에 반영되지 않았을 수 있어 rAF 한 번 뒤에 잰다.\r\n * 꺼져 있으면(또는 agentdeck 비활성) 클래스와 변수를 걷어 순정(창 전체)으로 되돌린다.\r\n */\r\n private syncBackgroundClip (): void {\r\n const root = document.documentElement\r\n const clear = (): void => {\r\n document.body.classList.remove(BG_CLIP_CLASS)\r\n for (const v of ['--ad-bg-left', '--ad-bg-top', '--ad-bg-width', '--ad-bg-height']) {\r\n root.style.removeProperty(v)\r\n }\r\n }\r\n if (!this.enabled || !this.config.store.agentDeck.clipBackgroundToTerminal || !this.mainEl) {\r\n clear()\r\n return\r\n }\r\n requestAnimationFrame(() => {\r\n if (!this.enabled || !this.mainEl) {\r\n clear()\r\n return\r\n }\r\n const r = this.mainEl.getBoundingClientRect()\r\n if (r.width <= 0 || r.height <= 0) {\r\n return\r\n }\r\n root.style.setProperty('--ad-bg-left', Math.round(r.left) + 'px')\r\n root.style.setProperty('--ad-bg-top', Math.round(r.top) + 'px')\r\n root.style.setProperty('--ad-bg-width', Math.round(r.width) + 'px')\r\n root.style.setProperty('--ad-bg-height', Math.round(r.height) + 'px')\r\n document.body.classList.add(BG_CLIP_CLASS)\r\n })\r\n }\r\n\r\n /**\r\n * 터미널/사이드바 배경에 알파를 넣어 tabby-background 의 배경 이미지가 비치게 한다.\r\n *\r\n * 배경 이미지는 `.content-tab-active::before` 로 **모든 내용 뒤에** 깔린다. 그래서\r\n * 그 위를 덮는 두 면이 불투명하면 이미지는 어디에도 보이지 않는다 —\r\n * (1) 터미널: xterm 이 컬러스킴 background 색으로 셀을 직접 칠한다 (CSS 로는 못 뚫는다)\r\n * (2) 사이드바 / .window: 우리가 넣은 불투명 배경\r\n * (1) 은 Tabby 가 xterm 을 `allowTransparency: true` 로 만들기 때문에 색에 알파만 넣으면 된다.\r\n * config.yaml 을 손으로 고쳐도 Tabby 가 종료할 때 메모리 값으로 덮어써 되돌아가므로,\r\n * ensurePasteHotkey 와 같은 이유로 여기서 코드로 보정한다.\r\n */\r\n private applyOpacity (): void {\r\n const cfg = this.config.store.agentDeck\r\n const termPct = clampPct(cfg.terminalOpacity)\r\n const sidePct = clampPct(cfg.sidebarOpacity)\r\n\r\n // 사이드바 / 창 여백 — CSS 변수로 내려보낸다 (styles.scss 가 폴백을 들고 있다)\r\n const root = document.documentElement\r\n if (sidePct >= 100) {\r\n root.style.removeProperty('--ad-panel-bg')\r\n } else {\r\n root.style.setProperty('--ad-panel-bg', `rgba(30, 33, 39, ${sidePct / 100})`)\r\n }\r\n\r\n // 터미널 — 컬러스킴 배경색에 알파를 붙인다\r\n const scheme = this.config.store.terminal?.colorScheme\r\n if (!scheme?.background) {\r\n return\r\n }\r\n const next = withAlpha(scheme.background, termPct)\r\n // 컬러스킴 기반 배경을 쓰도록 못 박는다 — 테마 배경으로 떨어지면 알파가 무시된다\r\n const wantMode = termPct < 100 ? 'colorScheme' : this.config.store.terminal.background\r\n if (next === scheme.background && wantMode === this.config.store.terminal.background) {\r\n // 이미 적용돼 있다. 여기서 save 를 부르면 changed$ 가 다시 우리를 부른다\r\n return\r\n }\r\n scheme.background = next\r\n this.config.store.terminal.background = wantMode\r\n this.config.save()\r\n }\r\n\r\n /** 지금 사이드바가 붙어 있는 방향 (설정값이 망가져 있으면 오른쪽으로 본다) */\r\n private get dockSide (): DockSide {\r\n const v = this.config.store.agentDeck.sidebarDock\r\n return isDockSide(v) ? v : 'right'\r\n }\r\n\r\n /**\r\n * 사이드바가 차지할 크기를 px 로 정한다 — 좌/우면 폭, 상/하면 높이.\r\n *\r\n * 사용자가 경계선을 한 번이라도 끌었으면 그 값(`sidebarWidth`/`sidebarHeight`)이 진실이다.\r\n * 아직 안 끌었다면(폭이 0) 예전처럼 화면비로 터미널 폭을 역산해 남는 만큼을 사이드바가 갖는다.\r\n */\r\n private sidebarExtent (availW: number, availH: number, winH: number): number {\r\n const cfg = this.config.store.agentDeck\r\n if (isHorizontalDock(this.dockSide)) {\r\n const minSidebar = cfg.sidebarMin || 200\r\n const maxSidebar = Math.max(cfg.sidebarMax || 560, minSidebar)\r\n let want = cfg.sidebarWidth || 0\r\n if (!want) {\r\n // 화면비를 지킨다는 가정에서 터미널 폭을 높이로 역산하고 남는 폭을 사이드바에 준다\r\n const ratio = (cfg.aspectW || 4) / (cfg.aspectH || 3)\r\n let termW = Math.round(availH * ratio)\r\n termW = Math.min(termW, availW - minSidebar)\r\n termW = Math.max(termW, MIN_TERM_W)\r\n want = availW - termW\r\n }\r\n // 손으로 끈 값은 설정의 min/max 를 넘어설 수 있다 — 마우스가 우선이므로\r\n // 목록이 읽히는 최소 폭과 터미널이 남을 최대 폭까지만 막는다\r\n const hardMin = cfg.sidebarWidth ? MIN_SIDEBAR_W : minSidebar\r\n const hardMax = Math.max(availW - MIN_TERM_W, hardMin)\r\n const softMax = cfg.sidebarWidth ? Math.max(maxSidebar, cfg.sidebarWidth) : maxSidebar\r\n return Math.min(Math.max(want, hardMin), softMax, hardMax)\r\n }\r\n // 세로 도킹은 창 높이를 기준으로 잡는다 — 터미널 높이(availH)는 사이드바를 뺀 값이라\r\n // 그걸로 클램프하면 잴 때마다 값이 줄어드는 되먹임이 생긴다\r\n const want = cfg.sidebarHeight || 200\r\n return Math.min(Math.max(want, MIN_SIDEBAR_H), Math.max(winH - MIN_TERM_H, MIN_SIDEBAR_H))\r\n }\r\n\r\n /** 사이드바를 창 한쪽에 붙이고, 남는 자리를 `.content.main` 이 갖게 한다 */\r\n private relayout (): void {\r\n if (!this.enabled || !this.windowEl) {\r\n this.diagOnce('relayout-skip-enabled', `relayout skipped enabled=${this.enabled} windowEl=${!!this.windowEl}`)\r\n return\r\n }\r\n // appRoot 가 늦게 렌더되는 경우가 있어 매번 다시 찾는다\r\n if (!this.mainEl) {\r\n this.mainEl = document.querySelector('.content.main')\r\n }\r\n if (!this.mainEl) {\r\n this.diagOnce('relayout-skip-mainel', 'relayout skipped mainEl=null')\r\n return\r\n }\r\n\r\n const availW = this.windowEl.clientWidth\r\n // 화면비로 폭을 역산할 때 쓰는 높이는 터미널이 실제로 쓰는 높이여야 한다.\r\n // 창 높이를 쓰면 탭바 등을 뺀 만큼 폭이 과대 계산돼 사이드바가 좁아진다\r\n const availH = this.mainEl.clientHeight || this.windowEl.clientHeight\r\n if (!availW || !availH) {\r\n return\r\n }\r\n\r\n const side = this.dockSide\r\n const horizontal = isHorizontalDock(side)\r\n let extent = Math.round(this.sidebarExtent(availW, availH, this.windowEl.clientHeight))\r\n // 터미널이 갖는 폭 — 가로 도킹일 때만 의미가 있다 (세로 도킹이면 폭 전체를 쓴다)\r\n let termW = horizontal ? availW - extent : availW\r\n\r\n // 터미널 폭을 문자 셀의 정수배로 깎는다.\r\n //\r\n // 셀 폭으로 나누어떨어지지 않으면 오른쪽에 셀 하나가 안 되는 자투리가 남는데,\r\n // fit() 은 그 자투리를 두고 창이 몇 px 만 흔들려도 열 수가 오르내린다. 열 수가 바뀔 때마다\r\n // pty 에 새 크기가 나가고 TUI 는 전체를 다시 그린다 — 화면이 깜빡이고 어긋날 틈이 생긴다.\r\n // 정수배로 맞춰 두면 자투리가 사라져 열 수가 흔들리지 않는다. 깎아 낸 픽셀은 사이드바가 갖는다.\r\n // 한때 이 자리에서 터미널 폭을 문자 셀의 정수배로 깎았다. 자투리 픽셀을 없애려던 건데\r\n // 오히려 화면이 계속 밀리는 원인이 됐다 — 셀 폭은 폰트가 자리를 잡는 동안 조금씩 다르게\r\n // 잡히고(2026-09-01 실측: 같은 창에서 termW 가 1977 -> 1970 -> 1974 로 진동),\r\n // 폭이 바뀔 때마다 pty 를 다시 맞추고 TUI 를 다시 그리게 만들었다.\r\n // 폭은 사용자가 정한 사이드바 크기에서 곧장 나오는 값 하나로 고정하는 편이 안정적이다.\r\n // 남는 자투리는 어차피 배경색이라 눈에 띄지 않는다.\r\n extent = Math.round(extent)\r\n termW = Math.round(termW)\r\n\r\n // 값이 그대로면 DOM 을 건드리지 않는다 — relayout 은 탭/상태가 바뀔 때마다 불리므로\r\n // 매번 스타일을 다시 쓰면 xterm 이 불필요하게 재측정한다\r\n if (termW === this.lastTermW && extent === this.lastSidebarW && side === this.lastDock) {\r\n return\r\n }\r\n const prevTermW = this.lastTermW\r\n this.lastTermW = termW\r\n this.lastSidebarW = extent\r\n this.lastDock = side\r\n\r\n // 기동 직후 흔들기(rearm kick)는 폐지했다 — 아래 relayout 주석 참고.\r\n\r\n // 사이드바는 창 위에 절대 배치한다. flex 자식으로 두면 도킹 방향을 바꿀 때마다\r\n // `.window` 의 flex-direction 을 뒤집어야 하고, 그러면 같은 줄에 있는 profile-tree 까지\r\n // 따라 움직인다. 절대 배치면 우리 것만 옮기면 된다.\r\n if (this.sidebar) {\r\n const s = this.sidebar.style\r\n s.position = 'absolute'\r\n s.left = side === 'right' ? 'auto' : '0'\r\n s.right = side === 'left' ? 'auto' : '0'\r\n s.top = side === 'bottom' ? 'auto' : '0'\r\n s.bottom = side === 'top' ? 'auto' : '0'\r\n s.width = horizontal ? extent + 'px' : 'auto'\r\n s.height = horizontal ? 'auto' : extent + 'px'\r\n for (const d of DOCK_SIDES) {\r\n this.sidebar.classList.toggle('ad-dock-' + d, d === side)\r\n }\r\n }\r\n\r\n // 터미널이 차지할 자리.\r\n //\r\n // 가로 도킹에서는 폭을 px 로 못 박는다. margin 만 주고 flex 에게 남는 폭을 맡겨 봤더니\r\n // (2026-09-01) xterm 이 fit 할 때 잡는 폭과 TUI 가 아는 폭이 어긋나 입력창이 깨졌다 —\r\n // 가로선과 입력 텍스트가 한 줄에 섞여 wrap 되는 그 증상이다. 폭을 직접 주면 xterm host 가\r\n // 재는 값이 곧 우리가 정한 값이라 어긋날 여지가 없다.\r\n // 세로 도킹은 폭을 건드릴 필요가 없고, `h-100`(height:100%) 때문에 margin 만으로는\r\n // 그만큼 창 밖으로 넘치므로 높이를 대신 깎는다.\r\n const m = this.mainEl.style\r\n if (horizontal) {\r\n m.flex = '0 0 ' + termW + 'px'\r\n m.width = termW + 'px'\r\n m.maxWidth = termW + 'px'\r\n m.removeProperty('height')\r\n m.marginTop = '0'\r\n m.marginBottom = '0'\r\n // 왼쪽 도킹일 때만 앞자리를 비운다 (오른쪽 도킹은 고정폭만으로 자리가 남는다)\r\n m.marginLeft = side === 'left' ? extent + 'px' : '0'\r\n m.marginRight = '0'\r\n } else {\r\n m.removeProperty('flex')\r\n m.removeProperty('width')\r\n m.removeProperty('max-width')\r\n m.marginLeft = '0'\r\n m.marginRight = '0'\r\n m.marginTop = side === 'top' ? extent + 'px' : '0'\r\n m.marginBottom = side === 'bottom' ? extent + 'px' : '0'\r\n // **`important` 가 필요하다.** `.content.main` 에는 부트스트랩 `h-100` 클래스가 붙어\r\n // 있고 그 규칙이 `height: 100% !important` 라, 평범한 인라인 스타일은 진다.\r\n // 그래서 상하 도킹에서 터미널 높이가 전혀 줄지 않았다 — bottom 이면 아래쪽이\r\n // 사이드바에 가리고, top 이면 그만큼 창 밖으로 넘쳤다\r\n // (2026-09-02 실측, 창 1100x700 / 사이드바 200: 인라인은 `calc(100% - 200px)` 인데\r\n // computed 는 `700px`, host 는 top 에서 `1070x670@y=215` 로 하단 185px 가 잘렸다).\r\n m.setProperty('height', 'calc(100% - ' + extent + 'px)', 'important')\r\n }\r\n\r\n this.dock?.syncHandle()\r\n this.syncBackgroundClip()\r\n // 우리가 하는 일은 여기까지다 — **폭을 정해 `.content.main` 에 적고 fit 한 번.**\r\n //\r\n // 2026-09-02 방향 전환(유저 지적): \"Tabby 는 창 크기가 어떻든 알아서 줄맞춤 되잖아?\" 맞다.\r\n // 순정 경로는 xterm `ResizeObserver` → `fitAddon.fit()` → `session.resize()` 이고,\r\n // 우리가 폭만 정해 주면 그 뒤는 Tabby 가 스스로 계산한다.\r\n // 예전에는 \"순정이 우리 CSS 변경을 못 따라온다\"고 보고 보정을 4겹 쌓았다 —\r\n // relayout 시 fit / `watchSize`(250ms 마다 fit+resize, 6초) / `syncPtySize` 재전송 사슬 /\r\n // `nudgePtyRedraw`(cols-1↔cols 흔들기). 그 겹침이 순정 수렴과 경쟁하면서\r\n // 프레임을 반쯤 그린 상태를 남겼고, 그게 실사용 깨짐의 정체였다(항목 24~28 은 전부 그 부작용).\r\n // 전제도 로그로 반박됐다 — 폭은 탭이 생기기 전에 이미 확정돼 있는데도\r\n // (`rearm kick termW -1->2000 panes=0`) 새 탭 xterm 이 254 로 뜬다. 그건 레이아웃 확정 전의\r\n // 초기 측정값일 뿐이고 순정 옵저버가 어차피 수렴시킨다.\r\n // 그래서 자동 보정은 전부 걷어냈다. 남은 건 이 fit 하나(순정 경로를 깨우는 용도)다.\r\n this.scheduleRefit()\r\n // 폭이 어긋나는 사고를 다시 만나면 이 줄이 실제 값을 알려 준다 —\r\n // 우리가 정한 값(termW)과 브라우저가 실제로 준 폭(clientWidth)이 다르면 그게 원인이다\r\n this.diag(`${new Date().toISOString()} relayout dock=${side} avail=${availW}x${availH}`\r\n + ` extent=${extent} termW=${termW} mainW=${this.mainEl.clientWidth}`)\r\n }\r\n\r\n /**\r\n * 폭을 바꿨으면 터미널에 반드시 알려야 한다.\r\n *\r\n * Tabby 의 xterm 프론트엔드는 창(OS 창) 리사이즈에 맞춰 재측정하지만,\r\n * 우리처럼 CSS 로만 `.content.main` 폭을 바꾸면 그 경로를 타지 않는다.\r\n * 그러면 xterm 의 열 수는 넓어졌는데 pty 는 옛 폭 그대로라, Claude Code 같은\r\n * 전체화면 TUI 가 화면보다 좁게 그리고 오른쪽에 지워지지 않은 잔상이 남는다\r\n * (2026-08-28 실측: 입력창 구분선이 화면 중간에서 끊기고 옛 statusline 이 우측에 박혀 있었다.\r\n * 창을 복원→최대화로 흔들면 OS 리사이즈 경로를 타서 즉시 정상 복구됐다).\r\n *\r\n * fitAddon.fit() 이 xterm 의 onResize 를 발화시키고, Tabby 가 그걸 받아\r\n * session.resize() 로 pty 까지 내려보낸다. 값이 같으면 xterm 이 이벤트를 내지 않으므로\r\n * 여분 호출은 무해하다.\r\n */\r\n private scheduleRefit (): void {\r\n if (this.refitQueued) {\r\n return\r\n }\r\n this.refitQueued = true\r\n // 레이아웃이 실제로 반영된 뒤에 재야 한다 — 한 프레임으로는 아직 옛 폭이 잡힌다\r\n requestAnimationFrame(() => requestAnimationFrame(() => {\r\n this.refitQueued = false\r\n this.refitTerminals()\r\n }))\r\n // attach() 가 아직 진행 중이면 위 fit 이 무시될 수 있다. fit 은 크기가 같으면\r\n // 아무 일도 안 하므로 한 번 더 늦게 때려도 무해하다\r\n setTimeout(() => this.refitTerminals(), 500)\r\n }\r\n\r\n private refitTerminals (): void {\r\n for (const tab of this.app.tabs) {\r\n const anyTab = tab as any\r\n const panes: BaseTabComponent[] = typeof anyTab.getAllTabs === 'function'\r\n ? anyTab.getAllTabs()\r\n : [tab]\r\n for (const pane of panes) {\r\n const frontend = (pane as any).frontend\r\n const fitAddon = frontend?.fitAddon\r\n if (!fitAddon || typeof fitAddon.fit !== 'function') {\r\n continue\r\n }\r\n // 숨겨진 탭은 컨테이너 폭이 0 이라 fit 하면 1열짜리로 줄어든다 — 건너뛴다.\r\n // 그 탭은 다시 선택될 때 Tabby 가 알아서 재측정한다\r\n const host = frontend.xterm?.element?.parentElement\r\n if (!host || !host.clientWidth || !host.clientHeight) {\r\n continue\r\n }\r\n try {\r\n fitAddon.fit()\r\n } catch {\r\n // 아직 붙지 않은 프론트엔드 — 다음 relayout 때 다시 잡힌다\r\n }\r\n // 여기서 끝낸다. 예전에는 뒤이어 `syncPtySize` 로 pty 에 직접 크기를 쐈는데,\r\n // fit() 이 이미 순정 경로(onResize → session.resize)를 태우므로 중복이고,\r\n // 그 중복이 순정 수렴과 경쟁해 화면을 깨뜨렸다 (2026-09-02).\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * pty 크기를 xterm 이 실제로 그리고 있는 크기에 강제로 맞춘다.\r\n *\r\n * `fitAddon.fit()` 은 xterm 의 열/행이 이미 맞으면 onResize 를 내지 않는다. 그런데 새 탭은\r\n * xterm 은 우리가 줄여 놓은 폭으로 제대로 열리는데 **세션(pty)만** 생성 시점의 옛 폭으로 남는\r\n * 경우가 있다. 이때 fit() 은 no-op 이라 pty 가 영영 안 고쳐지고, TUI 가 처음 화면을 다시\r\n * 그리는 순간(줄바꿈 등) 오른쪽에 옛 폭 잔상이 남는다 — 창 복원→최대화로 흔들면 OS 리사이즈\r\n * 경로를 타서 그제야 맞는다(2026-08-28 실측, 새 탭에서 재현).\r\n *\r\n * 그래서 fit() 뒤에 pty 로 직접 한 번 더 내려보낸다. 같은 값이면 pty 쪽에서 무시되므로 무해하다.\r\n */\r\n private syncPtySize (pane: BaseTabComponent, frontend: any): void {\r\n const cols = frontend?.xterm?.cols\r\n const rows = frontend?.xterm?.rows\r\n if (!cols || !rows) {\r\n return\r\n }\r\n const anyPane = pane as any\r\n const session = anyPane.session\r\n if (!session || !session.open || typeof session.resize !== 'function') {\r\n return\r\n }\r\n // 이 경로는 지금까지 조용했다. 그래서 \"언제 pty 폭이 바뀌었나\" 가 로그에 안 남아\r\n // 어긋남 사고를 만나도 발생 지점을 못 짚었다 (watchSize 의 `size fix` 만 남았다).\r\n // 값이 실제로 달라질 때만 남긴다 — 같은 값 재전송은 매 refit 마다 일어나므로 시끄럽다.\r\n const prev = anyPane.size\r\n if (prev?.columns !== cols || prev?.rows !== rows) {\r\n this.diag(`${new Date().toISOString()} pty resize ${prev?.columns}x${prev?.rows}`\r\n + ` -> ${cols}x${rows}`)\r\n }\r\n try {\r\n session.resize(cols, rows)\r\n anyPane.size = { columns: cols, rows }\r\n } catch {\r\n // 세션이 막 닫혔다 — 다음 refit 때 다시 잡힌다\r\n return\r\n }\r\n\r\n // **보냈다고 도착한 것이 아니다.**\r\n //\r\n // 세션이 막 열린 직후의 `session.resize()` 는 pty 에 닿지 못하고 유실된다\r\n // (2026-09-01 실측: `size fix 254x78 -> 280x78` + `pty resize` + `redraw nudge` 가\r\n // 모두 돌고 `pane.size` 도 280 으로 남았는데, 같은 탭 셸에 물어보니 `PTYW=254`.\r\n // 같은 호출을 몇 초 뒤에 CDP 로 하면 그때는 정상 반영된다 — 초기화 경합이다).\r\n // 그런데 `pane.size` 에 낙관적으로 280 을 적어 두므로, 크기 감시(watchSize)는\r\n // \"이제 맞다\" 고 보고 손을 뗀다. 그 뒤에 뜨는 TUI 는 254 폭으로 첫 화면을 그린다.\r\n //\r\n // 그래서 값이 실제로 바뀐 경우에만 같은 크기를 몇 번 더 보낸다. pty 크기가 이미\r\n // 그 값이면 아무 일도 일어나지 않으므로(SIGWINCH 도 안 난다) 재전송은 무해하다.\r\n if (prev?.columns !== cols || prev?.rows !== rows) {\r\n for (const delay of PTY_RESIZE_RETRY_MS) {\r\n setTimeout(() => {\r\n const now = anyPane.frontend?.xterm\r\n // 그동안 폭이 또 바뀌었으면 그쪽 경로가 새 값을 보낸다 — 옛 값을 덮어쓰지 않는다\r\n if (!anyPane.session?.open || now?.cols !== cols || now?.rows !== rows) {\r\n return\r\n }\r\n try {\r\n anyPane.session.resize(cols, rows)\r\n } catch {\r\n // 세션이 닫혔다\r\n }\r\n }, delay)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * pty 크기만 한 칸 줄였다 되돌려 TUI 가 화면을 다시 그리게 한다. **수동 복구 전용.**\r\n *\r\n * 자동 경로에서는 전부 걷어냈다 — 이 흔들기가 순정 수렴과 경쟁하며 깨진 화면을\r\n * 만들어 왔다(2026-09-02). 남겨 둔 이유는 `repairPane`(사이드바 `↻` / `agentdeck-repair`)\r\n * 때문이다. 거기서는 사용자가 \"지금 깨졌으니 고쳐라\" 를 명시로 눌렀고, 크기를 맞추는\r\n * 것만으로는 앱이 다시 그리지 않는 경우가 실제로 있다 — 폭이 **실제로 바뀌어야**\r\n * SIGWINCH 가 나가므로 한 칸 흔들어 두 번 내보낸다. 뒤이어 `Ctrl+L` 이 따라간다.\r\n *\r\n * 좁힌 값을 `pane.size` 에 그대로 적는다. 되돌리기가 유실됐는데 낙관적으로 `cols` 를\r\n * 적어 두면 아무도 어긋남을 못 보고 한 열 좁은 채로 굳는다(옛 버그).\r\n */\r\n private nudgePtyRedraw (pane: BaseTabComponent): void {\r\n const anyPane = pane as any\r\n const session = anyPane.session\r\n const cols = anyPane.frontend?.xterm?.cols\r\n const rows = anyPane.frontend?.xterm?.rows\r\n if (!session?.open || typeof session.resize !== 'function' || !(cols > 1) || !(rows > 1)) {\r\n return\r\n }\r\n this.diag(`${new Date().toISOString()} redraw nudge ${cols}x${rows}`)\r\n try {\r\n session.resize(cols - 1, rows)\r\n anyPane.size = { columns: cols - 1, rows }\r\n setTimeout(() => {\r\n if (!anyPane.session?.open) {\r\n return\r\n }\r\n // 되돌릴 값은 \"지금\" 의 xterm 폭이다 — 흔드는 사이 사이드바가 움직였을 수 있다\r\n this.syncPtySize(pane, anyPane.frontend)\r\n }, 60)\r\n } catch {\r\n // 세션이 막 닫혔다\r\n }\r\n }\r\n\r\n // 크기 감시(`watchSize` / `watchAllSizes`)도 폐지했다 (2026-09-02).\r\n //\r\n // 250ms 마다 `fitAddon.fit()` + `session.resize()` 를 6초간 쏘던 장치다. 목적은\r\n // \"xterm 은 넓어졌는데 pty 는 옛 폭\" 을 잡는 것이었는데, 그 어긋남은 순정\r\n // ResizeObserver 가 이미 수렴시킨다. 우리 감시는 그 수렴 도중의 중간값을 보고\r\n // 계속 끼어들었고, 끝에 `nudgePtyRedraw` 흔들기까지 붙여 화면을 깨뜨렸다.\r\n // 순정이 정말 못 맞추는 경우가 나오면 `screenWatch` 채증에 남는다 — 그때 근거를 갖고 되켠다.\r\n\r\n // ---------- 사이드바 DOM ----------\r\n\r\n private buildSidebar (): void {\r\n const el = document.createElement('div')\r\n el.id = SIDEBAR_ID\r\n el.innerHTML = [\r\n '<div class=\"ad-head\">',\r\n ' <span class=\"ad-head-title\">AGENT DECK</span>',\r\n ' <span class=\"ad-head-count\"></span>',\r\n '</div>',\r\n '<div class=\"ad-list\"></div>',\r\n '<div class=\"ad-foot\">',\r\n ' <button class=\"ad-btn ad-new\" title=\"새 탭\">+ 새 탭</button>',\r\n ' <button class=\"ad-btn ad-settings\" title=\"설정\">설정</button>',\r\n // 화면이 깨졌을 때 누르는 자리 — 창을 복원→최대화로 흔들던 것을 대신한다.\r\n // 자주 쓰는 두 버튼(새 탭·설정) 뒤에 둔다 (2026-09-01 유저 요청)\r\n ' <button class=\"ad-btn ad-repair\" title=\"화면 복구 (모든 탭 다시 그리기)\">↻</button>',\r\n '</div>',\r\n ].join('\\n')\r\n\r\n // 순정 탭바보다 뒤(오른쪽)에 놓는다 — 왼쪽에 두면 세로로 길어 허전하다는 피드백(2026-08-28)\r\n this.windowEl.appendChild(el)\r\n this.sidebar = el\r\n this.listEl = el.querySelector('.ad-list')\r\n\r\n el.querySelector('.ad-new').addEventListener('click', () => {\r\n this.zone.run(() => { void this.openNewTab() })\r\n })\r\n el.querySelector('.ad-repair').addEventListener('click', () => {\r\n this.zone.run(() => this.repair('all'))\r\n })\r\n el.querySelector('.ad-settings').addEventListener('click', () => {\r\n this.zone.run(() => this.openSettings())\r\n })\r\n\r\n // 크기/도킹은 설정 창이 아니라 마우스로 맞춘다.\r\n // 드래그 중에는 relayout 이 초당 수십 번 불리므로 config.save() 는 손을 뗄 때만 부른다.\r\n this.dock = new DockController({\r\n sidebar: el,\r\n windowEl: this.windowEl,\r\n getDock: () => this.dockSide,\r\n setDock: side => {\r\n this.config.store.agentDeck.sidebarDock = side\r\n },\r\n getSize: side => {\r\n const cfg = this.config.store.agentDeck\r\n if (!isHorizontalDock(side)) {\r\n return cfg.sidebarHeight || 0\r\n }\r\n // 지금 좌/우로 붙어 있다면 화면에 실제로 적용된 폭이 가장 정확하다\r\n // (자동 계산 상태면 sidebarWidth 가 0 이라 물어봐야 소용이 없다)\r\n return isHorizontalDock(this.dockSide) && this.lastSidebarW > 0\r\n ? this.lastSidebarW\r\n : (cfg.sidebarWidth || 0)\r\n },\r\n setSize: px => {\r\n const cfg = this.config.store.agentDeck\r\n if (isHorizontalDock(this.dockSide)) {\r\n cfg.sidebarWidth = px\r\n } else {\r\n cfg.sidebarHeight = px\r\n }\r\n },\r\n commit: () => this.zone.run(() => this.config.save()),\r\n relayout: () => this.relayout(),\r\n })\r\n this.dock.install()\r\n }\r\n\r\n /** 설정에 지정된 기본 프로필(기본값 agentdeck:root)로 새 탭을 연다 */\r\n private async openNewTab (): Promise<void> {\r\n const wanted = this.config.store.terminal.profile\r\n const profiles = await this.profiles.getProfiles()\r\n const profile = profiles.find(p => p.id === wanted) ?? profiles[0]\r\n if (profile) {\r\n await this.profiles.openNewTabForProfile(profile)\r\n }\r\n }\r\n\r\n private openSettings (): void {\r\n this.app.openNewTabRaw({ type: SettingsTabComponent })\r\n }\r\n\r\n /**\r\n * 사이드바 다시 그리기를 한 번으로 모은다.\r\n *\r\n * rAF 만 쓰면 **창이 가려졌을 때 상태가 늦게 반영된다.** Chromium 은 창이 hidden\r\n * (최소화·완전 가려짐) 이 되면 rAF 를 아예 멈추고 타이머도 스로틀한다. 그러면\r\n * 훅이 보낸 done 은 메모리에 즉시 반영됐는데 화면만 옛 상태로 남아 있다가,\r\n * 1초 tick(그것도 스로틀되면 더 늦게)이 와야 그려진다 — \"작업중이 한참 뒤에야 완료로 바뀐다\"\r\n * 의 정체가 이것이다(2026-08-28). 시작 쪽이 빨라 보이는 건 그때는 사용자가 방금\r\n * 창에 입력해서 창이 떠 있기 때문일 뿐이다.\r\n *\r\n * 그래서 rAF 와 짧은 타이머를 같이 걸고 **먼저 오는 쪽이 그린다**. 창이 떠 있으면\r\n * 지금까지와 똑같이 다음 프레임에, 가려져 있으면 타이머가 대신 그린다.\r\n */\r\n private scheduleRender (): void {\r\n if (this.renderQueued) {\r\n return\r\n }\r\n this.renderQueued = true\r\n const run = () => {\r\n if (!this.renderQueued) {\r\n return\r\n }\r\n this.renderQueued = false\r\n if (this.renderTimer) {\r\n clearTimeout(this.renderTimer)\r\n this.renderTimer = null\r\n }\r\n this.render()\r\n this.relayout()\r\n }\r\n requestAnimationFrame(run)\r\n this.renderTimer = setTimeout(run, 50)\r\n }\r\n\r\n /**\r\n * 창이 가려져 있어도 타이머·rAF 가 계속 돌게 한다.\r\n *\r\n * 위 scheduleRender 의 타이머 폴백은 \"타이머가 제때 돈다\" 를 전제로 하는데,\r\n * Chromium 은 hidden 페이지의 타이머를 1초로 묶고 5분 넘게 가려져 있으면\r\n * **분당 1회**까지 떨어뜨린다. 그 상태에서는 폴백조차 늦다.\r\n * Electron 의 backgroundThrottling 을 꺼서 이 계층을 통째로 없앤다.\r\n */\r\n private disableBackgroundThrottling (): void {\r\n if (!this.config.store.agentDeck.keepRenderingWhenHidden) {\r\n return\r\n }\r\n try {\r\n const req = (window as any).require ?? (globalThis as any).require\r\n const win = req?.('@electron/remote')?.getCurrentWindow?.()\r\n win?.webContents?.setBackgroundThrottling?.(false)\r\n } catch {\r\n // remote 를 못 잡아도 위 타이머 폴백은 살아 있다 (조금 늦을 뿐)\r\n }\r\n }\r\n\r\n private tick (): void {\r\n if (!this.enabled) {\r\n return\r\n }\r\n let dirty = false\r\n const idleAfter = this.config.store.agentDeck.idleAfterMs || 2500\r\n for (const tab of this.app.tabs) {\r\n if (this.status.tickIdle(tab, idleAfter)) {\r\n dirty = true\r\n }\r\n }\r\n if (dirty || this.config.store.agentDeck.showElapsed) {\r\n this.render()\r\n }\r\n }\r\n\r\n private render (): void {\r\n if (!this.listEl || !this.enabled || this.editing) {\r\n return\r\n }\r\n const statusOf = (tab: BaseTabComponent): WorkStatus => this.status.get(tab).status\r\n // 정렬은 복사본에만 — app.tabs 의 순서(순정 탭바)는 그대로 둔다\r\n const tabs = this.config.store.agentDeck.sortByStatus\r\n ? sortTabsByStatus(this.app.tabs, statusOf)\r\n : this.app.tabs\r\n this.renderHeadCount(tabs, statusOf)\r\n\r\n this.listEl.innerHTML = ''\r\n for (const tab of tabs) {\r\n this.listEl.appendChild(this.renderTab(tab))\r\n }\r\n }\r\n\r\n /**\r\n * 헤더 오른쪽의 상태별 집계 — `⏸ 2 ● 3 ○ 1` 처럼 0 이 아닌 상태만 급한 순서로 놓는다.\r\n * 총 개수만 보이던 자리다. 세션을 여럿 띄우면 \"몇 개가 나를 기다리나\" 가 먼저 보여야 한다.\r\n * 동적 텍스트는 textContent 로만 넣는다 (innerHTML 금지).\r\n */\r\n private renderHeadCount (tabs: readonly BaseTabComponent[], statusOf: (tab: BaseTabComponent) => WorkStatus): void {\r\n const countEl = this.sidebar.querySelector('.ad-head-count') as HTMLElement | null\r\n if (!countEl) {\r\n return\r\n }\r\n countEl.innerHTML = ''\r\n countEl.title = `탭 ${tabs.length}개`\r\n for (const { status, count } of countByStatus(tabs, statusOf)) {\r\n const style = STATUS_STYLES[status]\r\n const chip = document.createElement('span')\r\n chip.className = 'ad-cnt'\r\n chip.style.setProperty('--ad-color', style.color)\r\n chip.title = `${style.label} ${count}`\r\n chip.textContent = `${style.icon} ${count}`\r\n countEl.appendChild(chip)\r\n }\r\n if (!tabs.length) {\r\n countEl.textContent = '0'\r\n }\r\n }\r\n\r\n private renderTab (tab: BaseTabComponent): HTMLElement {\r\n const st = this.status.get(tab)\r\n const style = STATUS_STYLES[st.status]\r\n const active = tab === this.app.activeTab\r\n\r\n const row = document.createElement('div')\r\n row.className = active ? 'ad-tab active' : 'ad-tab'\r\n row.style.setProperty('--ad-color', style.color)\r\n\r\n // [AD:...] 표식은 상태로 이미 반영했으니 제목에서는 지운다\r\n const tabTitle = stripTitleMarker(tab.customTitle || tab.title || '')\r\n // 세 줄은 서로 다른 것을 말한다 —\r\n // 1) 제목: 에이전트가 세션에 붙인 이름. 세션이 사는 동안 거의 안 바뀐다\r\n // (Claude Code 는 시작 때 붙인 콘솔 제목을 계속 들고 있다, 2026-08-28 실측)\r\n // 2) 프롬프트: 마지막으로 보낸 지시. 작업이 넘어갈 때마다 바뀐다\r\n // 3) 상태: 지금 돌고 있는지 / 얼마나 됐는지\r\n // 예전에는 1과 2를 한 줄에 겹쳐 놓느라 둘 중 하나를 못 봤다.\r\n const title = tabTitle || '(제목 없음)'\r\n const elapsed = this.config.store.agentDeck.showElapsed\r\n ? this.formatElapsed(Date.now() - st.since)\r\n : ''\r\n\r\n row.innerHTML = [\r\n '<div class=\"ad-bar\"></div>',\r\n '<div class=\"ad-body\">',\r\n ' <div class=\"ad-title\"></div>',\r\n // 라벨은 더블클릭하면 입력창으로 바뀐다(startLabelEdit) — 그때 줄이 무너지지 않게\r\n // 감싸는 줄을 따로 둔다\r\n ' <div class=\"ad-prompt\"><span class=\"ad-label\"></span></div>',\r\n ' <div class=\"ad-meta\">',\r\n ' <span class=\"ad-badge\"></span>',\r\n ' <span class=\"ad-elapsed\"></span>',\r\n ' </div>',\r\n '</div>',\r\n '<button class=\"ad-close\" title=\"탭 닫기\">&times;</button>',\r\n ].join('\\n')\r\n\r\n // textContent 로만 넣는다 — 탭 제목에 어떤 문자가 와도 마크업으로 해석되지 않게\r\n row.querySelector('.ad-title').textContent = title\r\n const labelEl = row.querySelector('.ad-label')\r\n // 아직 프롬프트가 없어도 줄은 남겨 둔다 — 줄 수가 들쭉날쭉하면 목록이 어지럽고,\r\n // 더블클릭으로 이름을 붙일 자리도 사라진다\r\n labelEl.textContent = st.label || '—'\r\n labelEl.classList.toggle('empty', !st.label)\r\n row.querySelector('.ad-elapsed').textContent = elapsed\r\n const badge = row.querySelector('.ad-badge') as HTMLElement\r\n // 승인대기 이유가 있으면 뒤에 붙인다 — \"⏸ 승인대기 · Bash 권한\". 여러 세션을 띄워 둔 사람이\r\n // 사이드바만 보고 지금 가서 승인할지 정할 수 있게. 원문은 title 로 마우스를 올리면 보인다\r\n badge.textContent = style.icon + ' ' + style.label + (st.reason ? ' · ' + st.reason : '')\r\n badge.title = st.reason\r\n if (st.pinned) {\r\n badge.classList.add('pinned')\r\n }\r\n\r\n row.addEventListener('click', ev => {\r\n if ((ev.target as HTMLElement).closest('.ad-close')) {\r\n return\r\n }\r\n this.zone.run(() => this.app.selectTab(tab))\r\n })\r\n row.addEventListener('dblclick', ev => {\r\n ev.preventDefault()\r\n this.startLabelEdit(row, tab)\r\n })\r\n row.addEventListener('contextmenu', ev => {\r\n ev.preventDefault()\r\n this.showStatusMenu(ev, tab)\r\n })\r\n row.querySelector('.ad-close').addEventListener('click', ev => {\r\n ev.stopPropagation()\r\n this.zone.run(() => { void this.app.closeTab(tab, true) })\r\n })\r\n return row\r\n }\r\n\r\n /** 더블클릭 -> 작업 이름 인라인 편집 */\r\n private startLabelEdit (row: HTMLElement, tab: BaseTabComponent): void {\r\n this.editing = tab\r\n const holder = row.querySelector('.ad-label') as HTMLElement\r\n const input = document.createElement('input')\r\n input.className = 'ad-label-input'\r\n input.value = this.status.get(tab).label\r\n input.placeholder = '작업 이름'\r\n holder.replaceWith(input)\r\n input.focus()\r\n input.select()\r\n\r\n const finish = (commit: boolean) => {\r\n if (this.editing !== tab) {\r\n return\r\n }\r\n this.editing = null\r\n if (commit) {\r\n this.status.setLabel(tab, input.value.trim())\r\n }\r\n this.render()\r\n }\r\n // 터미널로 키가 새지 않도록 이벤트를 여기서 끊는다\r\n input.addEventListener('keydown', ev => {\r\n ev.stopPropagation()\r\n if (ev.key === 'Enter') {\r\n finish(true)\r\n }\r\n if (ev.key === 'Escape') {\r\n finish(false)\r\n }\r\n })\r\n input.addEventListener('blur', () => finish(true))\r\n }\r\n\r\n /** 우클릭 -> 상태 직접 지정 */\r\n private showStatusMenu (ev: MouseEvent, tab: BaseTabComponent): void {\r\n const old = document.querySelector('.ad-menu')\r\n if (old) {\r\n old.remove()\r\n }\r\n const menu = document.createElement('div')\r\n menu.className = 'ad-menu'\r\n\r\n const statuses: WorkStatus[] = ['running', 'waiting', 'limited', 'done', 'error', 'idle']\r\n const items: Array<[string, () => void]> = statuses.map(s => {\r\n const label = STATUS_STYLES[s].icon + ' ' + STATUS_STYLES[s].label\r\n const action = () => this.status.setManual(tab, s)\r\n return [label, action] as [string, () => void]\r\n })\r\n items.push(['↺ 자동 감지로', () => this.status.unpin(tab)])\r\n // 이 탭만 다시 그리기 — 사이드바 아래 ↻ 는 모든 탭이 대상이라 무거울 때가 있다\r\n items.push(['↻ 화면 복구', () => {\r\n this.app.selectTab(tab)\r\n this.repair('active')\r\n }])\r\n\r\n for (const [label, action] of items) {\r\n const item = document.createElement('div')\r\n item.className = 'ad-menu-item'\r\n item.textContent = label\r\n item.addEventListener('click', () => {\r\n action()\r\n menu.remove()\r\n })\r\n menu.appendChild(item)\r\n }\r\n\r\n document.body.appendChild(menu)\r\n menu.style.left = ev.clientX + 'px'\r\n menu.style.top = Math.min(ev.clientY, window.innerHeight - menu.offsetHeight - 8) + 'px'\r\n\r\n const close = (e: MouseEvent) => {\r\n if (!menu.contains(e.target as Node)) {\r\n menu.remove()\r\n document.removeEventListener('mousedown', close)\r\n }\r\n }\r\n setTimeout(() => document.addEventListener('mousedown', close), 0)\r\n }\r\n\r\n private formatElapsed (ms: number): string {\r\n const s = Math.floor(ms / 1000)\r\n if (s < 60) {\r\n return s + '초'\r\n }\r\n const m = Math.floor(s / 60)\r\n if (m < 60) {\r\n return m + '분'\r\n }\r\n return Math.floor(m / 60) + '시간 ' + (m % 60) + '분'\r\n }\r\n}\r\n","import { Injectable } from '@angular/core'\nimport { AppService, BaseTabComponent, ConfigService } from 'tabby-core'\nimport { TerminalDecorator, BaseTerminalTabComponent, BaseSession } from 'tabby-terminal'\nimport { WorkStatusService } from './status.service'\nimport { applyOutput, forgetOutputBuffer } from './detect'\n\n/**\n * PTY 출력을 훔쳐보며 탭 상태를 추론한다.\n *\n * Tabby 는 프론트엔드(xterm)가 첫 리사이즈를 보고할 때 decorator 를 붙이므로\n * (tabby-terminal/src/api/baseTerminalTab.component.ts:386) 그 시점을 놓친 탭은\n * 여기로 들어오지 않는다. 그 빈틈은 AgentDeckService 의 세션 워처가 메운다.\n */\n@Injectable()\nexport class AgentDeckDecorator extends TerminalDecorator {\n constructor (\n private status: WorkStatusService,\n private config: ConfigService,\n private app: AppService,\n ) {\n super()\n }\n\n /**\n * 상태를 기록할 키를 사이드바가 보는 것과 같은 탭으로 맞춘다.\n *\n * Tabby 는 모든 탭을 SplitTabComponent 로 감싸므로 app.tabs 에 들어있는 것은\n * 그 래퍼이고, decorator 가 받는 것은 그 안의 터미널 탭이다. 정규화하지 않으면\n * 상태를 자식에 쓰고 사이드바는 부모를 읽어 영영 매칭되지 않는다.\n * 분할된 pane 여러 개는 하나의 탭 상태를 공유한다.\n */\n private rootOf (tab: BaseTerminalTabComponent<any>): BaseTabComponent {\n return this.app.getParentTab(tab) ?? tab\n }\n\n attach (tab: BaseTerminalTabComponent<any>): void {\n this.status.debug.attached++\n if (tab.session) {\n this.attachToSession(tab, tab.session)\n }\n this.subscribeUntilDetached(tab, tab.sessionChanged$.subscribe(session => {\n if (session) {\n this.attachToSession(tab, session)\n }\n }))\n }\n\n detach (tab: BaseTerminalTabComponent<any>): void {\n const root = this.rootOf(tab)\n super.detach(tab)\n forgetOutputBuffer(tab)\n // 분할 pane 중 하나만 닫힌 경우라면 탭 상태는 남겨둔다\n if (root === tab || !this.app.tabs.includes(root)) {\n this.status.forget(root)\n }\n }\n\n private attachToSession (tab: BaseTerminalTabComponent<any>, session: BaseSession): void {\n this.subscribeUntilDetached(tab, session.output$.subscribe(data => {\n applyOutput(\n this.status,\n this.rootOf(tab),\n tab,\n data,\n this.config.store.agentDeck.autoDetect,\n )\n }))\n }\n}\n","import { BaseTabComponent } from 'tabby-core'\nimport { WorkStatusService } from './status.service'\nimport { WorkStatus } from './api'\n\n/** 훅이 상태를 직접 통보하는 커스텀 OSC — ESC ] 1337 ; AgentDeck=<status>;<label> BEL */\nconst OSC_RE = /\\x1b\\]1337;AgentDeck=([a-z]+)(?:;([^\\x07\\x1b]*))?(?:\\x07|\\x1b\\\\)/gi\n\n/** Claude Code 등 TUI 가 사용자 입력을 기다릴 때 나타나는 패턴 */\nconst WAITING_RE = [\n /Do you want to\\b/i,\n /❯\\s*1\\.\\s*Yes/,\n /\\(y\\/n\\)/i,\n /\\[y\\/N\\]/i,\n /Press Enter to continue/i,\n]\n\n/**\n * 에이전트가 작업 중일 때만 화면에 내보내는 문구.\n *\n * 상태줄 갱신 같은 평시 출력과 구분하는 근거다 — 이 문구는 일을 붙잡고 있는 동안에만 뜨고\n * 끝나면 사라지므로, 사라진 시점부터 시간을 재면 진행중에서 정확히 내려올 수 있다.\n */\nconst BUSY_RE = [\n /esc to interrupt/i,\n /ctrl\\+c to (?:interrupt|cancel|stop)/i,\n /\\btokens?\\b.{0,20}\\besc\\b/i,\n]\n\nconst VALID: WorkStatus[] = ['idle', 'running', 'waiting', 'limited', 'done', 'error']\n\n/** OSC 가 청크 경계에 걸리는 것을 막기 위한 잔여 버퍼 */\nconst tails = new WeakMap<object, string>()\n\n/**\n * PTY 출력 한 조각을 보고 탭 상태를 갱신한다.\n *\n * 우선순위: OSC 통보 > 대기 패턴 > \"출력이 있다 = 진행중\".\n * idle 로의 복귀는 사이드바 타이머(tickIdle)가 담당한다.\n *\n * decorator 와 deck 의 세션 워처 양쪽에서 호출된다 — 같은 조각을 두 번 먹어도\n * 결과가 같도록 상태 설정은 모두 멱등하게 만들어 두었다.\n */\nexport function applyOutput (\n status: WorkStatusService,\n root: BaseTabComponent,\n owner: object,\n data: string,\n autoDetect: boolean,\n): void {\n status.debug.outputs++\n status.markOutput(root)\n\n const buf = (tails.get(owner) ?? '') + data\n let matched = false\n let m: RegExpExecArray | null\n // 이미 처리한 OSC 가 어디까지인지 — 그 뒤만 다음 조각으로 넘긴다\n let consumed = 0\n OSC_RE.lastIndex = 0\n while ((m = OSC_RE.exec(buf)) !== null) {\n consumed = OSC_RE.lastIndex\n const s = m[1].toLowerCase() as WorkStatus\n if (VALID.includes(s)) {\n status.setManual(root, s, m[2])\n status.debug.oscHits++\n matched = true\n }\n }\n // 미완성 OSC 가 남아있을 수 있으므로 꼬리만 보관한다.\n // 단 이미 처리한 부분은 반드시 버린다 — 완결된 OSC 가 짧으면 꼬리 안에 통째로 남고,\n // 그러면 다음 출력마다 같은 시퀀스가 또 매치돼 상태가 그 값에 박혀 버린다\n // (2026-09-01, detect 테스트에서 드러남).\n tails.set(owner, buf.slice(Math.max(consumed, buf.length - 256)))\n if (matched || !autoDetect) {\n return\n }\n\n if (WAITING_RE.some(re => re.test(data))) {\n status.setAuto(root, 'waiting')\n return\n }\n\n // 승인대기였던 탭에 작업 중 문구가 다시 보이면 사람이 승인한 것이다 — 진행중으로 올린다.\n // 훅은 이 순간을 알려주지 않는다: 승인 뒤 첫 훅(PostToolUse)은 도구가 끝난 뒤라, 2분짜리 빌드를\n // 승인하면 그동안 사이드바가 승인대기에 박혀 있다 (2026-09-07 실측 — \"승인했는데 진행중으로 안 돌아온다\").\n // 훅이 고정(pinned)한 탭에도 적용해야 하므로 setAuto 가 아니라 resume 을 쓴다.\n // 제목 스피너(BUSY_MARKS)는 근거로 삼지 않는다 — 승인 대화상자가 떠 있는 동안에도 제목에 남을 수 있다\n if (status.get(root).status === 'waiting' && BUSY_RE.some(re => re.test(data))) {\n status.markBusy(root)\n status.resume(root)\n return\n }\n\n // 에이전트가 \"지금 일하는 중\" 이라고 스스로 밝히는 표시를 찾는다\n if (BUSY_MARKS.some(mark => data.includes(mark)) || BUSY_RE.some(re => re.test(data))) {\n status.markBusy(root)\n status.setAuto(root, 'running')\n return\n }\n\n // 그 표시를 내는 탭(에이전트 TUI)이라면, 표시가 없는 출력은 진행중의 근거가 아니다.\n // Claude Code 는 놀고 있을 때도 하단 상태줄을 매초 다시 그리기 때문에, 이 갈래가 없으면\n // 사이드바가 영원히 \"진행중\" 에 박혀 있게 된다 (2026-09-01 실측 — 세 탭 모두 진행중).\n if (status.isBusyMode(root)) {\n return\n }\n // 신호를 낼 줄 모르는 보통 셸 — 예전처럼 \"출력이 있다 = 진행중\" 으로 본다\n status.setAuto(root, 'running')\n}\n\nexport function forgetOutputBuffer (owner: object): void {\n tails.delete(owner)\n}\n\n/**\n * 탭 제목에 실려 온 상태 표식 — `[AD:running] 결제 버그 수정` 형태.\n *\n * Windows 에서 이 경로를 쓰는 이유: ConPTY 는 자기가 모르는 OSC 를 삼켜서\n * 커스텀 이스케이프가 PTY 스트림까지 오지 못한다(2026-08-28 실측 — 출력에 남은 건\n * 입력 에코뿐이었다). 반면 콘솔 제목은 ConPTY 가 API 로 변환해 전달하므로 확실히 통과한다.\n */\nconst TITLE_RE = /\\[AD:([a-z]+)\\]\\s*(.*)$/i\n\n/**\n * Claude Code 가 작업 중일 때 제목에 넣는 표식.\n * 별 모양과 원형 스피너 두 계열을 모두 쓴다 (2026-08-28 실측: \"◐ WindowTitle 설정\").\n */\nconst BUSY_MARKS = ['✳', '✻', '✽', '✶', '✢', '◐', '◓', '◑', '◒']\n\nexport function stripTitleMarker (title: string): string {\n return title.replace(/\\[AD:[a-z]+\\]\\s*/i, '')\n}\n\nexport function applyTitle (\n status: WorkStatusService,\n root: BaseTabComponent,\n title: string,\n autoDetect: boolean,\n): void {\n const m = TITLE_RE.exec(title)\n if (m) {\n const s = m[1].toLowerCase() as WorkStatus\n if (VALID.includes(s)) {\n status.setManual(root, s, m[2].trim())\n status.debug.titleHits++\n return\n }\n }\n // 명시 표식이 없으면 Claude Code 의 작업중 표식이라도 읽는다\n if (autoDetect && BUSY_MARKS.some(mark => title.includes(mark))) {\n status.setAuto(root, 'running')\n }\n}\n","/**\n * 사이드바를 마우스로 조절하는 부분 — 경계선 드래그로 크기, 헤더 드래그로 붙는 방향.\n *\n * 설정 창에서 숫자를 넣게 하지 않고 Visual Studio 의 도킹처럼 직접 끌어서 맞추게 한다.\n * DOM 을 직접 만지는 코드라 deck.service 밖으로 빼 두고, 값을 읽고 쓰는 통로만\n * `DockHost` 로 받는다 (deck.service 가 config 와 relayout 을 쥐고 있으므로).\n */\n\nexport type DockSide = 'left' | 'right' | 'top' | 'bottom'\n\nexport const DOCK_SIDES: DockSide[] = ['left', 'right', 'top', 'bottom']\n\nexport function isDockSide (v: any): v is DockSide {\n return DOCK_SIDES.includes(v)\n}\n\n/** 좌/우 도킹이면 폭, 상/하 도킹이면 높이를 다룬다 */\nexport function isHorizontalDock (side: DockSide): boolean {\n return side === 'left' || side === 'right'\n}\n\nexport interface DockHost {\n /** 사이드바 엘리먼트 */\n sidebar: HTMLElement\n /** 사이드바가 얹혀 있는 `.window` */\n windowEl: HTMLElement\n getDock (): DockSide\n setDock (side: DockSide): void\n /**\n * 그 방향으로 붙였을 때의 크기 — 좌/우면 폭, 상/하면 높이.\n * 방향마다 저장된 값이 다르므로 미리보기도 물어보는 방향 기준으로 그린다.\n */\n getSize (side: DockSide): number\n setSize (px: number): void\n /** 드래그가 끝났을 때 한 번 — config.save() 를 부르라는 뜻 */\n commit (): void\n /** 값이 바뀌었으니 다시 그리라는 뜻 */\n relayout (): void\n}\n\n/** 드래그로 오해하지 않을 최소 이동 거리 (px) */\nconst DRAG_THRESHOLD = 5\n/** 존 버튼 밖에서 놓았을 때 가장자리로 인정하는 여백 비율 */\nconst EDGE_RATIO = 0.25\n\nexport class DockController {\n private handle: HTMLElement | null = null\n private overlay: HTMLElement | null = null\n private preview: HTMLElement | null = null\n private zones = new Map<DockSide, HTMLElement>()\n\n private resizing = false\n private dragging = false\n private dragArmed = false\n private dragFrom = { x: 0, y: 0 }\n private hoverSide: DockSide | null = null\n\n constructor (private host: DockHost) { }\n\n /** 사이드바가 만들어진 뒤 한 번 부른다 */\n install (): void {\n this.installResizeHandle()\n this.installDockDrag()\n }\n\n /** 도킹 방향이 바뀌면 핸들 위치도 반대편으로 옮겨야 한다 */\n syncHandle (): void {\n if (!this.handle) {\n return\n }\n const side = this.host.getDock()\n this.handle.className = 'ad-resize ad-resize-' + side\n }\n\n // ---------- 경계선 드래그 (크기) ----------\n\n private installResizeHandle (): void {\n const handle = document.createElement('div')\n handle.className = 'ad-resize'\n this.host.sidebar.appendChild(handle)\n this.handle = handle\n this.syncHandle()\n\n handle.addEventListener('pointerdown', (ev: PointerEvent) => {\n // 왼쪽 버튼만\n if (ev.button !== 0) {\n return\n }\n ev.preventDefault()\n ev.stopPropagation()\n this.resizing = true\n handle.setPointerCapture(ev.pointerId)\n document.body.classList.add('ad-resizing')\n })\n\n handle.addEventListener('pointermove', (ev: PointerEvent) => {\n if (!this.resizing) {\n return\n }\n const side = this.host.getDock()\n const rect = this.host.windowEl.getBoundingClientRect()\n // 커서와 창 가장자리 사이의 거리가 곧 사이드바 크기다\n let size: number\n if (side === 'right') {\n size = rect.right - ev.clientX\n } else if (side === 'left') {\n size = ev.clientX - rect.left\n } else if (side === 'bottom') {\n size = rect.bottom - ev.clientY\n } else {\n size = ev.clientY - rect.top\n }\n this.host.setSize(Math.round(size))\n this.host.relayout()\n })\n\n const end = (ev: PointerEvent) => {\n if (!this.resizing) {\n return\n }\n this.resizing = false\n try {\n handle.releasePointerCapture(ev.pointerId)\n } catch {\n // 이미 놓쳤다 — 무시해도 상태는 위에서 정리됐다\n }\n document.body.classList.remove('ad-resizing')\n this.host.commit()\n }\n handle.addEventListener('pointerup', end)\n handle.addEventListener('pointercancel', end)\n }\n\n // ---------- 헤더 드래그 (도킹 방향) ----------\n\n private installDockDrag (): void {\n const head = this.host.sidebar.querySelector('.ad-head') as HTMLElement | null\n if (!head) {\n return\n }\n\n head.addEventListener('pointerdown', (ev: PointerEvent) => {\n if (ev.button !== 0) {\n return\n }\n // 헤더 안의 버튼류를 누른 것이면 건드리지 않는다\n if ((ev.target as HTMLElement).closest('button, input')) {\n return\n }\n this.dragArmed = true\n this.dragFrom = { x: ev.clientX, y: ev.clientY }\n head.setPointerCapture(ev.pointerId)\n })\n\n head.addEventListener('pointermove', (ev: PointerEvent) => {\n if (!this.dragArmed) {\n return\n }\n if (!this.dragging) {\n const dx = ev.clientX - this.dragFrom.x\n const dy = ev.clientY - this.dragFrom.y\n if (Math.hypot(dx, dy) < DRAG_THRESHOLD) {\n return\n }\n // 여기서부터 도킹 드래그다 — 가이드를 띄운다\n this.dragging = true\n this.showOverlay()\n }\n this.updateHover(ev.clientX, ev.clientY)\n })\n\n const end = (ev: PointerEvent) => {\n if (!this.dragArmed) {\n return\n }\n this.dragArmed = false\n try {\n head.releasePointerCapture(ev.pointerId)\n } catch {\n // 무시\n }\n if (!this.dragging) {\n return\n }\n this.dragging = false\n const side = this.hoverSide\n this.hideOverlay()\n if (side && side !== this.host.getDock()) {\n this.host.setDock(side)\n this.host.relayout()\n this.syncHandle()\n this.host.commit()\n }\n }\n head.addEventListener('pointerup', end)\n head.addEventListener('pointercancel', end)\n }\n\n // ---------- 드롭 가이드 ----------\n\n private showOverlay (): void {\n if (this.overlay) {\n return\n }\n const overlay = document.createElement('div')\n overlay.className = 'ad-dock-overlay'\n\n const preview = document.createElement('div')\n preview.className = 'ad-dock-preview'\n overlay.appendChild(preview)\n\n for (const side of DOCK_SIDES) {\n const zone = document.createElement('div')\n zone.className = 'ad-dock-zone ad-dock-zone-' + side\n zone.innerHTML = '<span class=\"ad-dock-mark\"></span>'\n overlay.appendChild(zone)\n this.zones.set(side, zone)\n }\n\n document.body.appendChild(overlay)\n this.overlay = overlay\n this.preview = preview\n this.positionZones()\n }\n\n /** 존 버튼을 `.window` 네 가장자리 안쪽에 놓는다 (창이 전체화면이 아닐 수도 있으므로 매번 잰다) */\n private positionZones (): void {\n const rect = this.host.windowEl.getBoundingClientRect()\n const cx = rect.left + rect.width / 2\n const cy = rect.top + rect.height / 2\n const inset = 56\n const place: Record<DockSide, [number, number]> = {\n left: [rect.left + inset, cy],\n right: [rect.right - inset, cy],\n top: [cx, rect.top + inset],\n bottom: [cx, rect.bottom - inset],\n }\n for (const side of DOCK_SIDES) {\n const zone = this.zones.get(side)\n if (!zone) {\n continue\n }\n const [x, y] = place[side]\n zone.style.left = x + 'px'\n zone.style.top = y + 'px'\n }\n }\n\n /** 커서 위치로 어느 쪽에 붙일지 정하고 미리보기를 그린다 */\n private updateHover (x: number, y: number): void {\n const side = this.hitTest(x, y)\n if (side !== this.hoverSide) {\n this.hoverSide = side\n for (const [s, zone] of this.zones) {\n zone.classList.toggle('active', s === side)\n }\n }\n this.drawPreview(side)\n }\n\n /**\n * 존 버튼 위에 있으면 그쪽, 아니면 커서가 창의 어느 가장자리 띠에 들어와 있는지로 정한다.\n * 가운데에 있으면 null — 놓아도 아무 일이 없다.\n */\n private hitTest (x: number, y: number): DockSide | null {\n for (const [side, zone] of this.zones) {\n const r = zone.getBoundingClientRect()\n if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom) {\n return side\n }\n }\n const rect = this.host.windowEl.getBoundingClientRect()\n const dx = (x - rect.left) / rect.width\n const dy = (y - rect.top) / rect.height\n if (dx < EDGE_RATIO && dx <= dy && dx <= 1 - dy) {\n return 'left'\n }\n if (dx > 1 - EDGE_RATIO && 1 - dx <= dy && 1 - dx <= 1 - dy) {\n return 'right'\n }\n if (dy < EDGE_RATIO) {\n return 'top'\n }\n if (dy > 1 - EDGE_RATIO) {\n return 'bottom'\n }\n return null\n }\n\n /** 놓으면 사이드바가 어디에 얼마만큼 자리잡는지 반투명 박스로 미리 보여준다 */\n private drawPreview (side: DockSide | null): void {\n if (!this.preview) {\n return\n }\n if (!side) {\n this.preview.style.display = 'none'\n return\n }\n const rect = this.host.windowEl.getBoundingClientRect()\n const horizontal = isHorizontalDock(side)\n // 방향마다 기억된 크기가 다르다 — 지금 붙어 있는 쪽이 아니라 놓으려는 쪽 값을 물어본다\n const current = this.host.getSize(side)\n const size = horizontal\n ? Math.min(Math.max(current || 320, 180), rect.width * 0.6)\n : Math.min(Math.max(current || 200, 120), rect.height * 0.6)\n\n const s = this.preview.style\n s.display = 'block'\n s.left = (side === 'right' ? rect.right - size : rect.left) + 'px'\n s.top = (side === 'bottom' ? rect.bottom - size : rect.top) + 'px'\n s.width = (horizontal ? size : rect.width) + 'px'\n s.height = (horizontal ? rect.height : size) + 'px'\n }\n\n private hideOverlay (): void {\n this.overlay?.remove()\n this.overlay = null\n this.preview = null\n this.zones.clear()\n this.hoverSide = null\n }\n}\n","import { Injectable } from '@angular/core'\nimport { HotkeyDescription, HotkeyProvider } from 'tabby-core'\n\n/**\n * 핫키 \"선언\"만 한다.\n *\n * 여기서 HotkeysService 를 주입하면 안 된다 — HotkeysService 자신이\n * HotkeyProvider 목록을 주입받으므로(tabby-core/src/services/hotkeys.service.ts:85)\n * 순환 의존이 되어 부분 초기화된 인스턴스가 넘어온다.\n * 실제 핫키 처리는 AgentDeckService 에서 구독한다.\n */\n@Injectable()\nexport class AgentDeckHotkeyProvider extends HotkeyProvider {\n async provide (): Promise<HotkeyDescription[]> {\n return [\n {\n id: 'agentdeck-toggle',\n name: 'AgentDeck 사이드바 / 4:3 전환',\n },\n {\n id: 'agentdeck-newline',\n name: 'AgentDeck 줄바꿈 (Ctrl+Enter / Shift+Enter, 0x0A 전송)',\n },\n {\n id: 'agentdeck-paste',\n name: 'AgentDeck 붙여넣기 (텍스트는 그대로, 이미지는 Alt+V 로 위임)',\n },\n {\n id: 'agentdeck-repair',\n name: 'AgentDeck 화면 복구 (깨진 TUI 다시 그리기)',\n },\n ]\n }\n}\n","import { Injectable } from '@angular/core'\r\nimport { AppService, BaseTabComponent, ConfigService, PlatformService } from 'tabby-core'\r\nimport * as fs from 'fs'\r\nimport * as net from 'net'\r\nimport * as os from 'os'\r\nimport * as path from 'path'\r\nimport { WorkStatusService } from './status.service'\r\nimport { WorkStatus } from './api'\r\nimport { claudeSettingsPath, hooksInstalled, hooksSupported, installHooks } from './claudeHooks'\r\nimport { pickTabByPids } from './bind'\r\nimport { shortenReason } from './reason'\r\nimport { TAB_ENV, newTabId, pickTabByTabId } from './tabenv'\r\n\r\nconst DIAG_PATH = path.join(os.homedir(), '.agentdeck-diag.log')\r\n\r\n/** 훅이 남기는 파일 하나의 내용 */\r\ninterface NotifyFile {\r\n sessionId: string\r\n /** 없으면 지금 상태를 유지한다 (라벨만 바꾸는 보고) */\r\n status?: WorkStatus\r\n /** 없으면 지금 라벨을 유지한다 (상태만 바꾸는 보고) */\r\n label?: string\r\n /**\r\n * 승인대기 이유 — Notification 훅의 message 원문 (\"Claude needs your permission to use Bash\" 등).\r\n * 훅은 waiting 일 때만 넣는다. 여기서 짧은 한국어로 줄여(reason.ts) 배지에 붙인다\r\n */\r\n reason?: string\r\n /** 훅이 쓴 시각 (epoch ms) — 같은 값을 두 번 적용하지 않기 위한 판별자 */\r\n ts: number\r\n /**\r\n * 훅 프로세스의 조상 PID — claude.exe 부터 위로(탭 셸, Tabby.exe …).\r\n * 어느 탭의 보고인지 이걸로 확정한다 (bind.ts). 없으면 옛 훅이거나 셸에서 사람이 부른 것.\r\n * tabId 가 있는 보고는 이걸 보내지 않는다 (훅이 계보 조회를 건너뛴다)\r\n */\r\n pids?: number[]\r\n /**\r\n * 훅 셸의 `AGENTDECK_TAB` — 플러그인이 탭을 열 때 그 셸에 심은 값(tabenv.ts). 1순위 매칭 근거.\r\n * 없으면 이 버전 이전에 열린 탭·재시작으로 복원된 탭·옛 훅이고, pids 로 떨어진다\r\n */\r\n tabId?: string\r\n}\r\n\r\n/**\r\n * 에이전트 훅 -> 사이드바 상태 채널. **기본으로 켜져 있다** (`notifyChannel`).\r\n *\r\n * 이쪽이 상태의 정확한 원천이다 — 에이전트가 \"지시를 받았다 / 승인을 기다린다 / 끝났다\" 를\r\n * 직접 알려준다. 출력 패턴으로 추측하는 경로(detect.ts)는 훅이 없는 환경을 위한 폴백이고,\r\n * TUI 가 화면을 어떻게 그리는지에 기대는 만큼 흔들린다 (2026-09-01: Claude Code 가 놀 때도\r\n * 상태줄을 매초 갱신해 진행중이 안 풀렸다).\r\n *\r\n * 훅은 Claude Code 쪽 설정에 있어야 해서 플러그인 설치만으로는 걸리지 않는다. 그래서\r\n * 기동할 때 한 번 물어보고(promptHooksOnce), 설정 창에도 설치 버튼을 둔다(claudeHooks.ts).\r\n *\r\n * 왜 파일인가 — 콘솔 제목 방식(`hooks/agentdeck-status.ps1`)은 **훅에서는 통하지 않는다**.\r\n * Claude Code 는 훅을 파이프 stdio 로 띄우기 때문에 그 자식 프로세스는 터미널의 콘솔에\r\n * 붙어 있지 않고, 제목을 바꿔도 pty 까지 오지 않는다 (2026-08-28 실측: 훅으로\r\n * `[AD:waiting] ...` 을 걸어도 사이드바가 그대로였다). 셸 안에서 직접 실행할 때는\r\n * 제목 방식이 여전히 유효하므로 그 경로는 남겨 둔다.\r\n *\r\n * 전달 경로는 두 가닥이다.\r\n *\r\n * 1. **TCP (기본)** — 이쪽이 `127.0.0.1` 임의 포트로 듣고, 실제 포트를\r\n * `%LOCALAPPDATA%\\tabby-agentdeck\\port` 에 적어 둔다. 훅은 그 포트로 JSON 한 줄을\r\n * 보내고 끊는다. 폴링 지연이 없고 상태 파일도 남지 않는다.\r\n * 2. **파일 (폴백)** — TCP 연결이 안 되면(Tabby 미기동, 포트 파일 없음, 방화벽)\r\n * 훅이 `...\\status\\<sessionId>.json` 에 쓰고 이쪽이 400ms 마다 읽는다.\r\n *\r\n * 두 경로 모두 `apply()` 로 모이고, `applied` 의 ts 대조가 중복 적용을 막으므로\r\n * 같은 보고가 양쪽으로 들어와도 결과는 같다.\r\n *\r\n * 세션 -> 탭 매칭: 어떤 Claude 세션이 **처음** 보고할 때의 활성 탭에 묶는다.\r\n * 사용자가 프롬프트를 넣은 탭이 곧 활성 탭이므로 이 규칙이면 탭이 여러 개여도 맞다.\r\n * 한 번 묶으면 그 뒤로는 활성 탭이 바뀌어도 같은 탭을 따라간다.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class WorkNotifyService {\r\n private root = path.join(\r\n process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'),\r\n 'tabby-agentdeck',\r\n )\r\n private dir = path.join(this.root, 'status')\r\n /** 훅이 접속할 포트를 알려주는 파일 */\r\n private portFile = path.join(this.root, 'port')\r\n private server: net.Server | null = null\r\n private sessionTab = new Map<string, BaseTabComponent>()\r\n /** 역방향 — 한 탭을 두 세션이 나눠 쓰지 못하게 막는다 */\r\n private tabSession = new Map<BaseTabComponent, string>()\r\n /** 이미 적용한 (sessionId -> ts) — 같은 파일을 반복 적용하지 않는다 */\r\n private applied = new Map<string, number>()\r\n private timer: any = null\r\n /** 폴링을 시작한 시각 — 이보다 오래된 파일은 지난 실행의 잔재다 */\r\n private startedAt = 0\r\n /**\r\n * 탭(루트) -> 그 안 패널들의 셸 PID. 훅이 보낸 조상 PID 와 맞춰 어느 탭의 보고인지 확정한다.\r\n * pty 에 물어보는 비동기 작업이라 표로 들고 있고, 탭이 열릴 때와 2초마다 새로 채운다\r\n */\r\n private tabPids = new Map<BaseTabComponent, number[]>()\r\n private pidRefreshing = false\r\n /**\r\n * 탭(루트) -> 그 안 패널 셸에 심은 `AGENTDECK_TAB` 값들(tabenv.ts). 훅이 tabId 로 보내면 여기서 바로\r\n * 확정하고, 프로세스 계보(tabPids)는 이 표에 없을 때의 폴백이다. 패널의 `profile.options.env` 를 읽어\r\n * 다시 채우므로 재시작으로 복원된 탭(복원 토큰에 profile 이 통째로 들어간다, tabby-local\r\n * dist/index.js:639-648)도 지난 실행의 id 를 그대로 되찾는다 — 살아 있는 pty 에 다시 붙든, 복원이\r\n * 실패해 같은 options 로 새 셸을 띄우든 셸 환경은 그 값이다\r\n */\r\n private tabIds = new Map<BaseTabComponent, string[]>()\r\n /** tabAdded$ 를 이미 구독한 분할 루트 — 루트가 사라지면 함께 사라진다 */\r\n private watchedSplits = new WeakSet<object>()\r\n private pollCount = 0\r\n /** 같은 매칭 실패를 폴링마다 diag 에 찍지 않기 위한 마지막 메시지 */\r\n private lastBindLog = new Map<string, string>()\r\n\r\n constructor (\r\n private app: AppService,\r\n private config: ConfigService,\r\n private status: WorkStatusService,\r\n private platform: PlatformService,\r\n ) { }\r\n\r\n /**\r\n * 훅이 안 걸려 있으면 기동할 때 한 번 물어본다.\r\n *\r\n * 훅은 Claude Code 쪽 설정(`~/.claude/settings.json`)에 있어야 해서 플러그인을 설치하는 것만으로는\r\n * 걸리지 않는다. 그렇다고 말없이 남의 설정을 고칠 수는 없으니, 한 번 묻고 고른 대로 한다.\r\n * \"다시 묻지 않기\" 를 고르면 그 뒤로는 조용하고, 설정 창의 설치 버튼은 언제든 그대로 쓸 수 있다.\r\n */\r\n private async promptHooksOnce (): Promise<void> {\r\n const cfg = this.config.store.agentDeck\r\n if (cfg.hookPromptDismissed || !hooksSupported()) {\r\n return\r\n }\r\n try {\r\n if (hooksInstalled()) {\r\n return\r\n }\r\n } catch {\r\n // 설정을 못 읽었다 — 그 상태로 남의 파일을 고치자고 권할 수는 없다\r\n return\r\n }\r\n\r\n const r = await this.platform.showMessageBox({\r\n // 이 타입에는 'question' 이 없다 (tabby-core MessageBoxOptions) — 경고로 띄우면\r\n // 필요 이상으로 겁을 주므로 'warning' 대신 형만 맞추고 문구로 성격을 드러낸다\r\n type: 'warning',\r\n message: 'AgentDeck — Claude Code 상태 통보를 연결할까요?',\r\n detail: [\r\n '연결하면 에이전트가 \"지시를 받았다 / 승인을 기다린다 / 끝났다\" 를 사이드바에 직접 알려줍니다.',\r\n '연결하지 않아도 동작은 하지만, 화면에 그려진 글자를 보고 추측하는 방식이라 상태가 부정확할 수 있습니다.',\r\n '',\r\n `설치 위치: ${claudeSettingsPath()}`,\r\n '기존 훅은 건드리지 않고, 쓰기 전에 같은 폴더에 백업을 남깁니다. 설정 창에서 언제든 제거할 수 있습니다.',\r\n ].join('\\n'),\r\n buttons: ['연결한다', '나중에', '다시 묻지 않기'],\r\n defaultId: 0,\r\n cancelId: 1,\r\n })\r\n\r\n if (r.response === 0) {\r\n try {\r\n installHooks()\r\n if (!cfg.notifyChannel) {\r\n cfg.notifyChannel = true\r\n }\r\n this.config.save()\r\n } catch (e: any) {\r\n await this.platform.showMessageBox({\r\n type: 'error',\r\n message: 'AgentDeck — 훅을 설치하지 못했습니다.',\r\n detail: `${e?.message ?? e}`,\r\n buttons: ['확인'],\r\n })\r\n }\r\n return\r\n }\r\n if (r.response === 2) {\r\n cfg.hookPromptDismissed = true\r\n this.config.save()\r\n }\r\n }\r\n\r\n init (): void {\r\n this.app.ready$.subscribe(() => {\r\n // 이미 열려 있는 탭 중 셸이 아직 안 뜬 패널이 있으면 지금 심는다 (기동 직후의 첫 탭).\r\n // 셸이 이미 뜬 패널은 못 심고 계보 폴백으로 남는다\r\n for (const root of [...this.app.tabs]) {\r\n this.stampRoot(root)\r\n }\r\n // 훅이 안 걸려 있으면 기동할 때 한 번 물어본다. 통로만 열려 있고 보고자가 없으면\r\n // 아무 일도 일어나지 않는데, 사용자 눈에는 그냥 \"상태가 이상하다\" 로만 보인다.\r\n // 기동 직후는 화면이 정신없으니 조금 뒤에 띄운다\r\n setTimeout(() => { void this.promptHooksOnce() }, 3000)\r\n\r\n // 채널이 닫혀 있으면 훅이 보낸 보고가 어디에도 닿지 않는다.\r\n // 기본은 열려 있고, 비용은 유휴 포트 하나와 400ms 폴링뿐이다\r\n if (!this.config.store.agentDeck.notifyChannel) {\r\n return\r\n }\r\n this.startedAt = Date.now()\r\n this.listen()\r\n this.timer = setInterval(() => this.poll(), 400)\r\n void this.refreshPids()\r\n })\r\n this.app.tabOpened$.subscribe(tab => {\r\n // 셸은 아직 안 떴다 — `openNewTab` 은 `tabsService.create` 직후 `addTabRaw` 에서 동기로 tabOpened 를\r\n // 내고(tabby-core dist/index.js:5029), 셸은 그 뒤 프런트엔드가 준비된 다음에야 뜬다(tabby-local\r\n // dist/index.js:623-635). 여기서 profile.options.env 에 심어야 셸이 물려받는다\r\n this.stampRoot(tab)\r\n // 새 탭의 셸 PID 는 세션이 붙은 뒤에야 나온다 — 조금 뒤에 한 번 더 채운다 (2초 주기 폴링도 있다)\r\n setTimeout(() => { void this.refreshPids() }, 1500)\r\n })\r\n // 탭이 닫히면 점유를 풀어야 그 자리를 다음 세션이 쓸 수 있다\r\n this.app.tabClosed$.subscribe(tab => {\r\n this.tabPids.delete(tab)\r\n this.tabIds.delete(tab)\r\n const sid = this.tabSession.get(tab)\r\n if (sid) {\r\n this.tabSession.delete(tab)\r\n this.sessionTab.delete(sid)\r\n }\r\n })\r\n }\r\n\r\n /** 진단 한 줄 — deck.service 와 같은 파일(`~/.agentdeck-diag.log`)에 남긴다 */\r\n private diag (line: string): void {\r\n try {\r\n fs.appendFileSync(DIAG_PATH, `${new Date().toISOString()} ${line}\\n`)\r\n } catch {\r\n // 진단일 뿐이다\r\n }\r\n }\r\n\r\n private tabName (tab: BaseTabComponent): string {\r\n const anyTab = tab as any\r\n return JSON.stringify(String(anyTab.customTitle || anyTab.title || '').slice(0, 40))\r\n }\r\n\r\n /**\r\n * 탭별 셸 PID 표를 새로 채운다. 로컬 pty 는 `session.pty.getPID()` 로 셸 PID 를 준다\r\n * (tabby-local Session — gracefullyKillProcess 가 쓰는 그 경로). SSH 등 PID 가 없는 탭은 빈 목록.\r\n */\r\n private async refreshPids (): Promise<void> {\r\n if (this.pidRefreshing) {\r\n return\r\n }\r\n this.pidRefreshing = true\r\n try {\r\n for (const root of [...this.app.tabs]) {\r\n const pids: number[] = []\r\n for (const pane of this.panesOf(root)) {\r\n const pty = pane?.session?.pty\r\n if (!pty || typeof pty.getPID !== 'function') {\r\n continue\r\n }\r\n try {\r\n const pid = await pty.getPID()\r\n if (Number.isInteger(pid) && pid > 0) {\r\n pids.push(pid)\r\n }\r\n } catch {\r\n // 세션이 닫히는 중이다\r\n }\r\n }\r\n const prev = this.tabPids.get(root)\r\n if (!prev || prev.join(',') !== pids.join(',')) {\r\n this.tabPids.set(root, pids)\r\n this.diag(`pid-map tab=${this.tabName(root)} pids=[${pids.join(',')}]`)\r\n }\r\n }\r\n } finally {\r\n this.pidRefreshing = false\r\n }\r\n }\r\n\r\n /** 루트 하나의 터미널 패널들 — 분할 래퍼(`app.tabs` 의 원소는 SplitTabComponent)면 자식들, 아니면 자기 자신 */\r\n private panesOf (root: BaseTabComponent): any[] {\r\n const anyRoot = root as any\r\n return typeof anyRoot.getAllTabs === 'function' ? anyRoot.getAllTabs() : [root]\r\n }\r\n\r\n private isLocalProfile (profile: any): boolean {\r\n return !!profile && profile.type === 'local' && !!profile.options && typeof profile.options === 'object'\r\n }\r\n\r\n /**\r\n * 새 루트 탭의 셸에 `AGENTDECK_TAB` 을 심는다 — 지금 있는 패널, 복원 토큰 안의 패널, 나중에 분할로 붙는 패널.\r\n *\r\n * 심는 자리가 맞는 근거 (tabby-local/dist/index.js, 1.0.231):\r\n * - 셸은 `onFrontendReady -> initializeSession` 이 `session.start({ ...this.profile.options, width, height })`\r\n * 로 띄운다(623-635). 자식 env 는 `mergeEnv(process.env, {TERM_PROGRAM: 'Tabby', …}, substituteEnv(options.env),\r\n * config.store.terminal.environment)` 다(1158-1162). 즉 **spawn 시점의 `pane.profile.options.env`** 가 셸 환경이다.\r\n * - `ngOnInit` 의 `this.sessionOptions = this.profile.options`(604-605) 는 같은 객체를 가리키는 참조일 뿐\r\n * spawn 에 쓰이지 않는다. profile 을 새 객체로 바꾸므로 그것도 같이 맞춰 둔다.\r\n * - `tab.profile` 은 `getNewTabParameters` 가 deep clone 한 것(898)이라 저장된 프로필과 다른 객체다. 그래도\r\n * 여기서 다시 얕게 복제해 넣는다 — 다른 경로(복원·복제 토큰)로 들어온 profile 이 공유 객체일 가능성을 막고,\r\n * 탭 하나의 id 가 설정 파일의 프로필로 새는 일이 없게 한다.\r\n *\r\n * 타이밍 (tabby-core/dist/index.js): `openNewTab`(5075) 은 `wrapAndAddTab`(5086) 에서 `splitTab.addTab(tab)` 을\r\n * 부르고 — `add()` 는 첫 await(2620 `initialized$`) 앞에서 자식을 `children` 에 넣는다(2618) — 그 다음\r\n * `addTabRaw` 가 `tabOpened.next(splitTab)` 를 낸다(5029). 그래서 tabOpened 시점에 `getAllTabs()` 에 자식이\r\n * 있고 `session` 은 아직 null 이다.\r\n */\r\n private stampRoot (root: BaseTabComponent): void {\r\n this.stampPanes(root)\r\n const anyRoot = root as any\r\n // 복제 탭(duplicateTab, 5245-5249)과 재시작 복원 탭(5003-5006)은 이 시점에 자식이 없고 복원 토큰\r\n // (`_recoveredState`)만 있다 — 자식은 ngAfterViewInit 의 recoverContainer 가 비동기로 만들고(2488-2491,\r\n // 3093 `tabsService.create(recovered)`) tabAdded 도 내지 않는다. 토큰 안의 profile 을 지금 고치면 그것이\r\n // 그대로 자식의 profile 이 된다 (recoverTab -> inputs.profile)\r\n if (anyRoot._recoveredState && typeof anyRoot._recoveredState === 'object') {\r\n this.stampRecoveryState(anyRoot._recoveredState, root)\r\n }\r\n // 나중에 분할로 붙는 패널 — tabAdded 는 onAfterTabAdded 의 setImmediate 에서 나오는데(2935-2939),\r\n // 셸은 그보다 뒤인 프런트엔드 준비 후에 뜬다. 혹시 이미 떠 있으면 stampPane 이 건너뛴다.\r\n // Subject 는 루트가 destroy 될 때 complete 되므로(2510) 구독을 따로 풀 필요가 없다\r\n if (anyRoot.tabAdded$ && typeof anyRoot.tabAdded$.subscribe === 'function' && !this.watchedSplits.has(root)) {\r\n this.watchedSplits.add(root)\r\n anyRoot.tabAdded$.subscribe(() => this.stampPanes(root))\r\n }\r\n }\r\n\r\n private stampPanes (root: BaseTabComponent): void {\r\n for (const pane of this.panesOf(root)) {\r\n this.stampPane(pane, root)\r\n }\r\n this.refreshTabIds()\r\n }\r\n\r\n /**\r\n * 패널 하나에 심는다. **아직 셸이 안 뜬**(`session` 없음) 로컬 패널만 — 이미 뜬 셸의 환경은 바꿀 수 없다.\r\n * 복원 패널(`restoreFromPTYID`)은 살아 있는 pty 에 다시 붙으므로 건드리지 않는다 — 토큰의 profile 에\r\n * 지난 실행의 id 가 있으면 그게 곧 그 셸의 환경이고 refreshTabIds 가 읽어 간다.\r\n * 이미 id 가 있어도 다른 패널이 같은 값을 갖고 있으면(복제) 새로 뽑는다 — 같은 id 가 두 셸에 있으면 어느 쪽인지 알 수 없다.\r\n */\r\n private stampPane (pane: any, root: BaseTabComponent): void {\r\n if (!pane || pane.session || !this.isLocalProfile(pane.profile) || pane.profile.options.restoreFromPTYID) {\r\n return\r\n }\r\n const env = pane.profile.options.env ?? {}\r\n const cur = typeof env[TAB_ENV] === 'string' ? env[TAB_ENV] : ''\r\n if (cur && !this.idTakenElsewhere(cur, pane)) {\r\n return\r\n }\r\n const id = newTabId()\r\n pane.profile = { ...pane.profile, options: { ...pane.profile.options, env: { ...env, [TAB_ENV]: id } } }\r\n if (pane.sessionOptions !== undefined) {\r\n pane.sessionOptions = pane.profile.options\r\n }\r\n this.diag(`tabid stamp tab=${this.tabName(root)} id=${id}${cur ? ` (was ${cur}: duplicate)` : ''}`)\r\n }\r\n\r\n /**\r\n * 복원 토큰 트리(`app:split-tab` 은 children, 잎은 profile 을 가진다)의 로컬 패널에 심는다.\r\n * `restoreFromPTYID` 가 있는 잎은 재시작 복원(saveTabs 가 includeState 로 만든 토큰, tabby-core 7700) —\r\n * 살아 있는 pty 의 환경은 이미 정해져 있으니 두고, 없는 잎은 새 셸이 뜰 것이므로(복제 탭 —\r\n * `tabsService.duplicate` 는 options 없이 토큰을 만들어 restoreFromPTYID 가 비어 있다, 7819-7830) 항상 새 id 를 준다.\r\n * 복제 원본의 id 가 토큰에 그대로 실려 오는데 그걸 두면 두 탭이 같은 id 를 갖게 된다\r\n */\r\n private stampRecoveryState (state: any, root: BaseTabComponent): void {\r\n if (Array.isArray(state.children)) {\r\n for (const child of state.children) {\r\n if (child && typeof child === 'object') {\r\n this.stampRecoveryState(child, root)\r\n }\r\n }\r\n return\r\n }\r\n const profile = state.profile\r\n if (!this.isLocalProfile(profile) || profile.options.restoreFromPTYID) {\r\n return\r\n }\r\n const id = newTabId()\r\n state.profile = { ...profile, options: { ...profile.options, env: { ...(profile.options.env ?? {}), [TAB_ENV]: id } } }\r\n this.diag(`tabid stamp tab=${this.tabName(root)} id=${id} (recovery token)`)\r\n }\r\n\r\n /** 같은 id 를 다른 패널(어느 루트든)이 이미 갖고 있나 */\r\n private idTakenElsewhere (id: string, self: any): boolean {\r\n for (const root of this.app.tabs) {\r\n for (const pane of this.panesOf(root)) {\r\n if (pane !== self && pane?.profile?.options?.env?.[TAB_ENV] === id) {\r\n return true\r\n }\r\n }\r\n }\r\n return false\r\n }\r\n\r\n /**\r\n * 탭별 tabId 표를 패널의 `profile.options.env` 에서 다시 읽는다. 동기·저비용이라 폴링(400ms)마다 돈다 —\r\n * 복원 탭의 자식은 tabOpened 뒤에 비동기로 생기고(tabby-core 3093) 이벤트도 없어서 읽는 쪽이 주기적으로 봐야 한다.\r\n * 같은 id 가 두 루트에 있으면(복제 뒤 셸이 이미 뜬 경우) 어느 쪽인지 알 수 없으니 둘 다 표에서 빼고 계보 폴백에 맡긴다.\r\n */\r\n private refreshTabIds (): void {\r\n const owner = new Map<string, BaseTabComponent>()\r\n const dup = new Set<string>()\r\n const next = new Map<BaseTabComponent, string[]>()\r\n for (const root of [...this.app.tabs]) {\r\n const ids: string[] = []\r\n for (const pane of this.panesOf(root)) {\r\n const v = pane?.profile?.options?.env?.[TAB_ENV]\r\n if (typeof v !== 'string' || !v || ids.includes(v)) {\r\n continue\r\n }\r\n ids.push(v)\r\n const prevOwner = owner.get(v)\r\n if (prevOwner && prevOwner !== root) {\r\n dup.add(v)\r\n } else {\r\n owner.set(v, root)\r\n }\r\n }\r\n next.set(root, ids)\r\n }\r\n for (const root of [...this.tabIds.keys()]) {\r\n if (!next.has(root)) {\r\n this.tabIds.delete(root)\r\n }\r\n }\r\n for (const [root, ids] of next) {\r\n const clean = ids.filter(v => !dup.has(v))\r\n const prev = this.tabIds.get(root)\r\n if (!prev || prev.join(',') !== clean.join(',')) {\r\n this.tabIds.set(root, clean)\r\n const dropped = ids.filter(v => dup.has(v))\r\n this.diag(`tabid-map tab=${this.tabName(root)} ids=[${clean.join(',')}]`\r\n + (dropped.length ? ` dup-dropped=[${dropped.join(',')}]` : ''))\r\n }\r\n }\r\n }\r\n\r\n /** 진단용 */\r\n get debugDir (): string { return this.dir }\r\n /** 진단용 — 듣고 있는 포트 (0 = TCP 채널이 안 떴다) */\r\n get debugPort (): number {\r\n const addr = this.server?.address()\r\n return addr && typeof addr === 'object' ? addr.port : 0\r\n }\r\n\r\n /**\r\n * 훅이 상태를 바로 밀어 넣을 TCP 채널을 연다.\r\n *\r\n * 기본은 `agentDeck.notifyPort` 고정 포트다 — 번호가 늘 같아야 훅이나 진단 도구가\r\n * 바로 붙을 수 있다. Windows 임시 포트 범위(49152~65535) 아래로 잡아 두어야\r\n * OS 가 그 번호를 다른 프로세스에 먼저 내주는 일이 없다.\r\n *\r\n * 그 번호가 이미 물려 있으면(Tabby 두 개, 다른 프로그램) 0 으로 다시 시도한다 —\r\n * OS 가 빈 포트를 골라 준다. 어느 쪽이든 실제 번호는 port 파일에 적어 두므로\r\n * 훅은 고정/임의를 구분할 필요가 없다. 둘 다 실패해도 파일 폴백이 살아 있다.\r\n */\r\n private listen (): void {\r\n const server = net.createServer(socket => {\r\n let buf = ''\r\n socket.setEncoding('utf8')\r\n socket.on('data', chunk => {\r\n buf += chunk\r\n // 훅이 여러 건을 몰아 보낼 수도 있으니 줄 단위로 끊어 처리한다\r\n let nl: number\r\n while ((nl = buf.indexOf('\\n')) >= 0) {\r\n const line = buf.slice(0, nl)\r\n buf = buf.slice(nl + 1)\r\n this.accept(line)\r\n }\r\n })\r\n // 개행 없이 끊는 훅도 받아 준다\r\n socket.on('end', () => this.accept(buf))\r\n socket.on('error', () => { /* 훅이 먼저 끊어도 Tabby 가 죽으면 안 된다 */ })\r\n })\r\n let fellBack = false\r\n server.on('error', () => {\r\n if (!fellBack) {\r\n // 고정 포트가 물려 있다 — OS 가 골라 주는 번호로 한 번 더 시도한다\r\n fellBack = true\r\n server.listen(0, '127.0.0.1')\r\n return\r\n }\r\n this.server = null\r\n // 지난 실행의 포트 번호를 남겨 두면 훅이 그 번호로 접속을 시도한다.\r\n // 그 사이 다른 프로그램이 같은 번호를 잡았다면 엉뚱한 곳으로 JSON 을 쏘게 되므로 지운다\r\n try {\r\n fs.unlinkSync(this.portFile)\r\n } catch {\r\n // 이미 없으면 그만이다\r\n }\r\n })\r\n server.on('listening', () => {\r\n this.server = server\r\n try {\r\n fs.mkdirSync(this.root, { recursive: true })\r\n fs.writeFileSync(this.portFile, String(this.debugPort), 'utf8')\r\n } catch {\r\n // 포트를 못 알리면 훅은 파일 경로로 떨어진다\r\n }\r\n })\r\n server.listen(this.config.store.agentDeck.notifyPort || 0, '127.0.0.1')\r\n }\r\n\r\n /** TCP 로 들어온 JSON 한 줄 */\r\n private accept (line: string): void {\r\n const text = line.trim()\r\n if (!text) {\r\n return\r\n }\r\n try {\r\n this.apply(JSON.parse(text))\r\n } catch {\r\n // 깨진 줄은 버린다 — 다음 보고가 곧 온다\r\n }\r\n }\r\n\r\n private poll (): void {\r\n // tabId 표는 동기라 매번, 셸 PID 표는 pty 에 물어야 해서 2초마다 — 탭 안에서 셸을 다시 띄우거나 분할하면 바뀐다\r\n this.refreshTabIds()\r\n if (++this.pollCount % 5 === 0) {\r\n void this.refreshPids()\r\n }\r\n let names: string[]\r\n try {\r\n names = fs.readdirSync(this.dir)\r\n } catch {\r\n return // 폴더 없음 = 훅이 아직 한 번도 안 돌았다\r\n }\r\n for (const name of names) {\r\n if (!name.endsWith('.json')) {\r\n continue\r\n }\r\n const full = path.join(this.dir, name)\r\n let data: NotifyFile\r\n try {\r\n data = JSON.parse(fs.readFileSync(full, 'utf8'))\r\n } catch {\r\n continue // 훅이 쓰는 중 — 다음 폴링에서 다시 읽는다\r\n }\r\n\r\n // 지난 Tabby 실행 때 남은 파일 — 이걸 읽으면 죽은 세션들이 전부 \"지금 활성 탭\" 에\r\n // 묶여 버려서(resolveTab 규칙) 실제 세션이 엉뚱한 탭에 붙는다. 실제로 완료된 세션의\r\n // done 이 작업 중인 탭에 찍히는 증상이 이것이었다 (2026-08-28 실측). 읽지 말고 지운다\r\n if (data.ts < this.startedAt && !this.sessionTab.has(data.sessionId)) {\r\n try {\r\n fs.unlinkSync(full)\r\n } catch {\r\n // 지우기 실패해도 아래 apply 를 타지 않으므로 해는 없다\r\n }\r\n continue\r\n }\r\n\r\n this.apply(data)\r\n }\r\n }\r\n\r\n /**\r\n * 보고 한 건을 반영한다. `status` / `label` 은 **각각 선택**이고, 빠진 쪽은 지금 값을 유지한다.\r\n *\r\n * 병합 규칙을 여기(플러그인)에 둔 이유 — 예전에는 훅 스크립트가 status 파일을 읽어\r\n * 직전 값과 합친 뒤 다시 쓰는 read-modify-write 를 했다. 그러면 진짜 상태가 파일과\r\n * 플러그인 메모리 두 곳에 살고 병합 규칙이 PowerShell 안에 숨는다. 라벨만 바꾸려 해도\r\n * 직전 status 를 채워 넣어야 했고(안 채우면 여기서 통째로 버려졌다), 파일이 밀리면\r\n * 표시가 어긋났다. 보내는 쪽은 \"자기가 아는 것만\" 보내고 합치는 건 상태를 실제로\r\n * 들고 있는 이쪽이 한다 — 그래야 어느 경로로 들어오든 결과가 같다.\r\n */\r\n private apply (data: NotifyFile): void {\r\n if (!data || !data.sessionId) {\r\n return\r\n }\r\n const hasStatus = !!data.status\r\n const hasLabel = typeof data.label === 'string' && !!data.label.trim()\r\n if (!hasStatus && !hasLabel) {\r\n return\r\n }\r\n if (this.applied.get(data.sessionId) === data.ts) {\r\n return\r\n }\r\n\r\n const tab = this.resolveTab(data.sessionId, data.tabId, data.pids)\r\n if (!tab) {\r\n // tabId 도 pids 도 없는 보고(옛 훅·수동 호출)는 다시 봐도 결과가 같다. 그런데 폴링이 400ms 마다\r\n // 되풀이하면 \"활성 탭에 묶는다\" 규칙이 다음에 열리는 빈 탭을 붙잡는다 — 끝난 세션의\r\n // done 이 새 탭에 박히고, 그 탭의 진짜 세션은 주인이 있다며 거절됐다 (2026-09-02 실측).\r\n // 적용한 것으로 쳐서 멈춘다. 다음 보고(새 ts)가 오면 그때 다시 시도한다.\r\n // tabId / pids 가 있는 보고는 표가 채워지면 맞을 수 있으니 다음 폴링에 다시 본다.\r\n if (!data.pids?.length && !data.tabId) {\r\n this.applied.set(data.sessionId, data.ts)\r\n }\r\n return\r\n }\r\n this.applied.set(data.sessionId, data.ts)\r\n\r\n const label = (data.label || '').trim()\r\n if (hasStatus) {\r\n // 라벨이 안 왔으면 undefined 를 넘겨 기존 라벨을 지키게 한다 (setManual 규약)\r\n // 이유는 waiting 에서만 의미가 있고 setManual 이 다른 상태에서는 비운다\r\n const reason = shortenReason(typeof data.reason === 'string' ? data.reason : '')\r\n this.status.setManual(tab, data.status!, hasLabel ? label : undefined, reason)\r\n } else {\r\n // 라벨만 온 보고 — 상태도 고정 여부도 건드리지 않는다\r\n this.status.setLabel(tab, label)\r\n }\r\n\r\n // 탭 제목(customTitle)은 건드리지 않는다.\r\n // 제목을 라벨 원천으로 쓸 수 있는지 보려고 한동안 비워 뒀고, 판정은 났다 —\r\n // Claude Code 는 세션 첫 작업을 요약해 제목에 한 번 박고 그 뒤로 갱신하지 않는다.\r\n // 그래서 라벨은 Enter 시점 입력창에서 직접 읽고(claimEnterLabel), 사이드바는\r\n // 제목과 그 라벨을 각자 줄에 나눠 그린다(renderTab). 여기서 제목을 덮어쓸 이유가 없다.\r\n }\r\n\r\n /**\r\n * 세션에 묶인 탭을 찾는다.\r\n *\r\n * 1순위는 **셸에 심어 둔 `AGENTDECK_TAB`**(tabId, tabenv.ts) — 플러그인이 탭을 열 때 심은 값을 훅이 그대로\r\n * 돌려보낸 것이라 표에 있으면 곧 그 탭이다. 2순위는 **프로세스 계보**(pids) — 훅이 보낸 조상 PID(claude.exe →\r\n * 탭 셸 → Tabby) 에 어떤 탭의 셸 PID 가 들어 있으면 그 탭이다(bind.ts). 이 버전 이전에 열린 탭·복원된 탭이\r\n * 여기로 온다. 둘 다 이미 다른 세션이 그 탭을 갖고 있어도 넘겨받는다: 같은 탭에서 claude 를 다시 띄우면\r\n * 세션 id 가 바뀌는 게 정상이고, 이전 주인은 이미 죽은 세션이다. 알던 탭과 다른 탭이 맞으면 옮긴다\r\n * (`claude --resume` 을 다른 탭에서 띄운 경우).\r\n *\r\n * tabId 나 pids 가 왔는데 맞는 탭이 없으면 **추측하지 않고** null 이다 — 표가 아직 안 채워진 것일 수\r\n * 있고(복원 탭의 자식은 늦게 생긴다), 그 경우 다음 폴링(400ms)에 다시 온다. 활성 탭으로 떨어지던 예전 규칙이\r\n * 낸 사고가 \"끝난 세션의 done 이 새 탭에 박힘\" 이었다 (2026-09-02 실측).\r\n *\r\n * 둘 다 없는 보고(옛 훅·셸에서 사람이 부른 것)만 예전 규칙을 탄다 — 처음 보는 세션이면 지금 활성 탭.\r\n * 단 그 탭을 이미 다른 세션이 점유했으면 묶지 않는다 (여러 세션이 한 탭에 겹쳐 붙어 서로의\r\n * 상태를 덮어쓰던 2026-08-28 사고의 방지책).\r\n */\r\n private resolveTab (sessionId: string, tabId: string | undefined, pids?: number[]): BaseTabComponent | null {\r\n const known = this.sessionTab.get(sessionId)\r\n const alive = known && this.app.tabs.includes(known) ? known : null\r\n\r\n const byId = pickTabByTabId(tabId, this.tabIds)\r\n if (byId) {\r\n if (byId !== alive) {\r\n this.bind(sessionId, byId, alive ? 'tabid-move' : 'tabid')\r\n }\r\n return byId\r\n }\r\n const pick = pickTabByPids(pids, this.tabPids)\r\n if (pick.mode === 'pid' && pick.tab) {\r\n if (pick.tab !== alive) {\r\n this.bind(sessionId, pick.tab, alive ? 'pid-move' : 'pid')\r\n }\r\n return pick.tab\r\n }\r\n if (alive) {\r\n return alive\r\n }\r\n if (tabId) {\r\n // 훅은 tabId 가 있으면 pids 를 보내지 않으므로 여기서 멈춘다 — 계보처럼 추측 없이 다음 폴링을 기다린다\r\n const table = [...this.tabIds.entries()]\r\n .map(([tab, list]) => `${this.tabName(tab)}:[${list.join(',')}]`)\r\n .join(' ')\r\n this.bindLog(sessionId, `unbound (tabid-miss) tabId=${tabId} tabs=${table}`)\r\n return null\r\n }\r\n if (pick.mode === 'pid-miss') {\r\n const table = [...this.tabPids.entries()]\r\n .map(([tab, list]) => `${this.tabName(tab)}:[${list.join(',')}]`)\r\n .join(' ')\r\n this.bindLog(sessionId, `unbound (pid-miss) pids=[${(pids ?? []).join(',')}] tabs=${table}`)\r\n return null\r\n }\r\n\r\n const active = this.app.activeTab\r\n if (!active) {\r\n return null\r\n }\r\n const owner = this.tabSession.get(active)\r\n if (owner && owner !== sessionId) {\r\n this.bindLog(sessionId, `unbound (legacy: active tab owned by ${owner.slice(0, 8)})`)\r\n return null\r\n }\r\n this.bind(sessionId, active, 'legacy')\r\n return active\r\n }\r\n\r\n /** 세션 <-> 탭 을 묶고, 그 탭의 이전 주인과 이 세션의 이전 탭은 풀어 준다 */\r\n private bind (sessionId: string, tab: BaseTabComponent, how: string): void {\r\n const prevOwner = this.tabSession.get(tab)\r\n if (prevOwner && prevOwner !== sessionId) {\r\n this.sessionTab.delete(prevOwner)\r\n }\r\n const prevTab = this.sessionTab.get(sessionId)\r\n if (prevTab && prevTab !== tab && this.tabSession.get(prevTab) === sessionId) {\r\n this.tabSession.delete(prevTab)\r\n }\r\n this.sessionTab.set(sessionId, tab)\r\n this.tabSession.set(tab, sessionId)\r\n this.lastBindLog.delete(sessionId)\r\n this.diag(`bind sid=${sessionId.slice(0, 8)} via=${how} tab=${this.tabName(tab)}`\r\n + (prevOwner && prevOwner !== sessionId ? ` (took over from ${prevOwner.slice(0, 8)})` : ''))\r\n }\r\n\r\n /** 매칭 실패는 폴링마다 반복되므로 같은 내용은 한 번만 남긴다 */\r\n private bindLog (sessionId: string, msg: string): void {\r\n if (this.lastBindLog.get(sessionId) === msg) {\r\n return\r\n }\r\n this.lastBindLog.set(sessionId, msg)\r\n this.diag(`bind sid=${sessionId.slice(0, 8)} ${msg}`)\r\n }\r\n}\r\n","/**\r\n * 사이드바 정렬·집계의 순수 규칙 — Angular/Tabby 에 기대지 않아 단위 테스트가 된다.\r\n *\r\n * 헤더 집계와 `sortByStatus` 정렬이 같은 우선순위를 써야 하므로 한 곳에 둔다.\r\n * 순서는 \"사람이 지금 손대야 하는 것\" 부터다 —\r\n * waiting(승인대기) → error(오류) → limited(한도 도달) → running(진행중) → done(완료) → idle(대기)\r\n * 한도 도달은 사람이 풀 수 있는 일은 아니지만 \"이 세션은 멈춰 있다\" 를 알아야 하므로 진행중보다 앞에 둔다.\r\n * 세션을 여섯 개쯤 띄워 두면 어느 탭이 나를 기다리는지 한눈에 봐야 한다 (2026-09-02 요청).\r\n */\r\nimport { WorkStatus } from './api'\r\n\r\n/** 표시·정렬 우선순위. 앞이 더 급하다 */\r\nexport const STATUS_ORDER: readonly WorkStatus[] = ['waiting', 'error', 'limited', 'running', 'done', 'idle']\r\n\r\n/** 우선순위 숫자 — 작을수록 앞. 모르는 값은 맨 뒤로 보낸다 */\r\nexport function statusRank (status: WorkStatus | string): number {\r\n const i = STATUS_ORDER.indexOf(status as WorkStatus)\r\n return i < 0 ? STATUS_ORDER.length : i\r\n}\r\n\r\n/**\r\n * 상태별 개수. `STATUS_ORDER` 순서로, 0 인 상태는 빼고 돌려준다 — 헤더에 그대로 그리면 된다.\r\n */\r\nexport function countByStatus<T> (tabs: readonly T[], statusOf: (tab: T) => WorkStatus): Array<{ status: WorkStatus, count: number }> {\r\n const counts = new Map<WorkStatus, number>()\r\n for (const tab of tabs) {\r\n const s = statusOf(tab)\r\n counts.set(s, (counts.get(s) ?? 0) + 1)\r\n }\r\n const out: Array<{ status: WorkStatus, count: number }> = []\r\n for (const s of STATUS_ORDER) {\r\n const n = counts.get(s) ?? 0\r\n if (n > 0) {\r\n out.push({ status: s, count: n })\r\n }\r\n }\r\n return out\r\n}\r\n\r\n/**\r\n * 상태 우선순위로 정렬한 **복사본**. 같은 상태끼리는 원래 탭 순서를 지킨다(안정 정렬).\r\n * 원본 배열(`app.tabs`)은 건드리지 않는다 — Tabby 의 탭 순서는 사용자의 것이다.\r\n */\r\nexport function sortTabsByStatus<T> (tabs: readonly T[], statusOf: (tab: T) => WorkStatus): T[] {\r\n return tabs\r\n .map((tab, index) => ({ tab, index, rank: statusRank(statusOf(tab)) }))\r\n .sort((a, b) => a.rank - b.rank || a.index - b.index)\r\n .map(x => x.tab)\r\n}\r\n","import { Injectable } from '@angular/core'\nimport { AppService, ConfigService } from 'tabby-core'\n\nexport const ROOT_PROFILE_ID = 'agentdeck:root'\n\n/**\n * 새 탭이 항상 작업 루트에서 열리게 한다.\n *\n * Tabby 프로필을 하나 만들어 config 에 심고, 사용자가 아직 기본 프로필을\n * 직접 고른 적이 없으면 이것을 기본으로 지정한다.\n * 한 번 심은 뒤에는 사용자가 설정에서 바꾼 값을 존중한다 (매 기동 덮어쓰지 않음).\n */\n@Injectable({ providedIn: 'root' })\nexport class AgentDeckProfileService {\n constructor (\n private app: AppService,\n private config: ConfigService,\n ) { }\n\n init (): void {\n this.app.ready$.subscribe(() => this.ensureProfile())\n }\n\n private ensureProfile (): void {\n const cfg = this.config.store.agentDeck\n // 경로를 안 정했으면 만들지 않는다 — 남의 홈 디렉토리에 엉뚱한 프로필을 심지 않기 위해\n if (!cfg.rootProfile || !cfg.rootProfileCwd) {\n return\n }\n\n const profiles = this.config.store.profiles || []\n const existing = profiles.find((p: any) => p.id === ROOT_PROFILE_ID)\n\n const profile = {\n id: ROOT_PROFILE_ID,\n type: 'local',\n name: cfg.rootProfileName || 'Agent Root',\n options: {\n command: cfg.rootProfileCommand || 'powershell.exe',\n args: [...(cfg.rootProfileArgs || [])],\n cwd: cfg.rootProfileCwd,\n env: { ...(cfg.rootProfileEnv || {}) },\n // 권한 승격은 이 플러그인이 다루지 않는다 — Tabby 를 어떤 권한으로 띄울지는 사용자의 몫이다.\n },\n }\n\n if (existing) {\n // 사용자가 설정 UI 에서 손댔을 수 있으므로 비어 있는 값만 보정한다\n if (!existing.options) {\n existing.options = profile.options\n this.config.save()\n } else {\n let dirty = false\n if (!existing.options.cwd) {\n existing.options.cwd = profile.options.cwd\n dirty = true\n }\n // npm 전역 .ps1 래퍼(claude 등)가 기본 실행 정책에 막히지 않도록 인자를 보정한다.\n // 사용자가 직접 인자를 넣어 뒀다면 건드리지 않는다.\n if (!existing.options.args || existing.options.args.length === 0) {\n existing.options.args = [...profile.options.args]\n dirty = true\n }\n // 색 지원 환경변수는 사용자가 지정한 값을 덮지 않고 빠진 것만 채운다\n existing.options.env = existing.options.env || {}\n for (const [k, v] of Object.entries(profile.options.env)) {\n if (existing.options.env[k] === undefined) {\n existing.options.env[k] = v\n dirty = true\n }\n }\n if (dirty) {\n this.config.save()\n }\n }\n } else {\n profiles.push(profile)\n this.config.store.profiles = profiles\n // 최초 1회만 기본 프로필로 지정\n if (!cfg.rootProfileClaimed) {\n this.config.store.terminal.profile = ROOT_PROFILE_ID\n cfg.rootProfileClaimed = true\n }\n this.config.save()\n }\n }\n}\n","/**\n * 터미널 화면에 그려진 입력창에서 지금 쓰여 있는 프롬프트를 뽑아낸다.\n *\n * 타이핑을 따로 세지 않고 화면을 읽는 이유 — 붙여넣기·↑ 히스토리·자동완성·IME 로 들어온 글자는\n * 키 이벤트로 안 오거나 원문과 다르다. 화면에 실제로 그려진 것이 곧 보낼 내용이다.\n *\n * 입력창 모양은 앱·버전마다 다르다. 옛 Claude Code / Codex 는 테두리 상자였고\n * ╭────────────────────╮\n * │ > 프롬프트 내용 │\n * ╰────────────────────╯\n * Claude Code 2.1.x 는 상자를 버리고 위아래 가로선 사이에 한 줄만 그린다.\n * ────────────────────────\n * ❯ 프롬프트 내용\n * ────────────────────────\n * ? for shortcuts\n * 머리글자도 ASCII `>` 가 아니라 `❯`(U+276F) 다 — 2026-09-01 화면 캡처로 확인.\n * `>` 만 찾던 정규식이 이걸 못 잡아 라벨이 한 번도 안 바뀌었다.\n *\n * 머리를 못 찾으면 빈 문자열을 준다 — 일반 셸이나 y/n 확인 같은 데서 엉뚱한 라벨이 박히느니\n * 라벨을 그대로 두는 편이 낫다.\n *\n * 화면 버퍼를 직접 받지 않고 줄 배열만 받는 순수 함수로 둔다 (xterm 없이 검증할 수 있게).\n */\n\n/** 입력창의 첫 줄 표식 — ASCII `>` 와 꺾쇠 계열(❯ › ➜ ❭) 을 모두 받는다 */\nconst PROMPT_HEAD_RE = /^[>❯›❭➜]\\s*/\n/**\n * 같은 꺾쇠를 선택지 커서로도 쓴다 (`❯ 1. Yes`). 그건 프롬프트가 아니다.\n * 번호 목록뿐 아니라 Yes/No 같은 무번호 선택지도 배제한다.\n */\nconst CHOICE_RE = /^[>❯›❭➜]\\s*(\\d+[.)]\\s|(?:Yes|No)\\b)/i\n/** 입력창 아래 테두리 — 상자 모서리(╰└) 또는 가로선만으로 된 줄 */\nconst BOX_BOTTOM_RE = /^[\\s│┃|]*[─━═-]{3,}[\\s│┃|]*$|[╰└]/\n/** 이보다 짧으면 라벨로 쓰지 않는다 (y/n 응답 등) */\nconst MIN_PROMPT_LEN = 2\n/** 사이드바에 들어가는 라벨 길이 */\nexport const MAX_LABEL_LEN = 40\n\n/** 입력창 테두리(│ ┃ 등)와 좌우 여백을 떼어낸 알맹이 */\nfunction stripBox (line: string): string {\n return line.replace(/^[\\s│┃|╭╰┌└─╮╯┐┘]+/, '').replace(/[\\s│┃|╮╯┐┘─]+$/, '').trim()\n}\n\nexport function extractPrompt (lines: string[]): string {\n // 아래에서 위로 머리 줄을 찾는다 (마지막 입력창이 곧 지금 입력창)\n let head = -1\n for (let i = lines.length - 1; i >= 0; i--) {\n const body = stripBox(lines[i])\n if (!PROMPT_HEAD_RE.test(body)) {\n continue\n }\n if (CHOICE_RE.test(body)) {\n return '' // 선택지 커서 — 여기서 위로 더 올라가면 옛 프롬프트를 주워온다\n }\n head = i\n break\n }\n if (head < 0) {\n return ''\n }\n const parts = [stripBox(lines[head]).replace(PROMPT_HEAD_RE, '')]\n for (let i = head + 1; i < lines.length; i++) {\n if (BOX_BOTTOM_RE.test(lines[i])) {\n break // 입력창 끝 — 그 아래는 힌트 줄이라 프롬프트가 아니다\n }\n const body = stripBox(lines[i])\n if (body) {\n parts.push(body)\n }\n }\n const text = parts.join(' ').replace(/\\s+/g, ' ').trim()\n if (text.length < MIN_PROMPT_LEN) {\n return '' // y/n 같은 한 글자 응답 — 라벨로 쓸 것이 못 된다\n }\n return text.length > MAX_LABEL_LEN ? text.slice(0, MAX_LABEL_LEN).trimEnd() + '...' : text\n}\n","/**\n * 승인대기 이유 줄이기 — Notification 훅의 message 원문을 배지에 붙일 짧은 한국어로 바꾼다.\n *\n * 훅(hooks/agentdeck-notify.ps1)은 원문을 그대로 보내고, 줄이는 규칙은 여기 한 곳에만 둔다.\n * Claude Code 가 문구를 바꾸면 이 파일만 고치면 되고, 훅을 다시 설치할 필요가 없다.\n *\n * 알려진 문구 (2026-09 기준):\n * \"Claude needs your permission to use Bash\" -> \"Bash 권한\"\n * \"Claude is waiting for your input\" -> \"입력 대기\"\n * 플랜 승인 / 질문 응답도 같은 요령으로 잡는다.\n * 한도 도달(StopFailure error=rate_limit 의 last_assistant_message):\n * \"You've hit your session limit · resets 12pm (Asia/Seoul)\" -> \"12pm 리셋\"\n * 리셋 시각이 없으면 빈 값 — 배지가 이미 `⛔ 한도 도달` 이라 같은 말을 되풀이하지 않는다.\n * 모르는 문구는 앞 24자만 남긴다 — 배지 한 줄을 넘기지 않기 위해서다.\n */\n\n/** 모르는 문구를 잘라 낼 길이 */\nconst UNKNOWN_MAX = 24\n\nexport function shortenReason (msg: string): string {\n const m = (msg || '').replace(/\\s+/g, ' ').trim()\n if (!m) {\n return ''\n }\n // 도구 승인 — 도구 이름만 남긴다 (Bash, Edit, Write, mcp__vs-mcp__Xxx …). MCP 이름의 '-' 도 포함\n const tool = /permission to use ([\\w-]+)/i.exec(m)\n if (tool) {\n return tool[1] + ' 권한'\n }\n if (/waiting for your input/i.test(m)) {\n return '입력 대기'\n }\n // 한도 도달 — 리셋 시각만 남긴다. 실측 문구 3형:\n // \"You've hit your session limit · resets 12pm (Asia/Seoul)\"\n // \"You've reached your weekly limit · resets Monday 9am\"\n // \"Claude usage limit reached. Your limit will reset at 7pm (Asia/Seoul).\"\n if (/\\b(?:hit|reached|exceeded)\\b.*\\blimit\\b|usage limit|limit reached|limit will reset/i.test(m)) {\n const reset = /\\breset(?:s)?\\s+(?:at\\s+)?(.+?)\\s*(?:\\(|\\.\\s*$|$)/i.exec(m)\n return reset ? reset[1].trim() + ' 리셋' : ''\n }\n if (/plan/i.test(m)) {\n return '플랜 승인'\n }\n if (/question|answer/i.test(m)) {\n return '질문 응답'\n }\n return m.slice(0, UNKNOWN_MAX).trimEnd()\n}\n","import { Injectable } from '@angular/core'\nimport { AppService, ConfigService } from 'tabby-core'\n\n/**\n * \"기동 시 탭 복원 끄기\" — Tabby 의 `recoverTabs` 를 강제로 false 에 묶는다.\n *\n * 왜 따로 있나: Tabby 는 종료 때 열려 있던 탭을 `localStorage.tabsRecovery` 에 저장하고\n * 다음 기동에서 `config.store.recoverTabs` 가 참이면 되살린다(tabby-core/dist/index.js:5003).\n * 그런데 복원되는 것은 **셸만**이다 — 그 안에서 돌던 Claude Code 세션은 이미 죽어 있어\n * 되살아난 탭은 빈 프롬프트일 뿐이고, 사이드바에는 주인 없는 탭이 줄줄이 남는다.\n * 그래서 사용자가 고르면 \"무조건 빈 상태로 시작\" 을 보장한다.\n *\n * 두 상태만 있다:\n * - `agentDeck.noTabRecovery = false` : 순정. Tabby 의 `recoverTabs` 값을 건드리지 않는다.\n * - `agentDeck.noTabRecovery = true` : 무조건 끔. Tabby 설정 창에서 `recoverTabs` 를 다시 켜도\n * 기동 때와 설정이 바뀔 때마다 false 로 되돌린다(`enforce`).\n *\n * 기동 분기(5003)는 `config.ready$` 직후라 플러그인보다 먼저 지나간다 — 그래서 값은 토글 순간에\n * config.yaml 에 써 두고, 여기서는 그 뒤로 누가 뒤집어 놓는 경우만 막는다.\n */\n@Injectable({ providedIn: 'root' })\nexport class AgentDeckRecoveryService {\n constructor (\n private app: AppService,\n private config: ConfigService,\n ) { }\n\n init (): void {\n this.app.ready$.subscribe(() => this.enforce())\n this.config.changed$.subscribe(() => this.enforce())\n }\n\n /**\n * 토글 진입점. 켜면 `recoverTabs=false` + 이미 저장된 복원 목록도 지운다 —\n * 남겨 두면 나중에 순정으로 되돌렸을 때 그때의 낡은 탭들이 되살아난다.\n * 끄면 Tabby 기본값(true)으로 되돌린다.\n */\n setNoTabRecovery (on: boolean): void {\n this.config.store.agentDeck.noTabRecovery = on\n this.config.store.recoverTabs = !on\n if (on) {\n try {\n delete window.localStorage.tabsRecovery\n } catch { /* 격리/비브라우저 환경 — 없으면 지울 것도 없다 */ }\n }\n this.config.save()\n }\n\n /** noTabRecovery 가 켜져 있는데 recoverTabs 가 참으로 돌아와 있으면 다시 끈다. 필요할 때만 저장한다 */\n private enforce (): void {\n if (!this.config.store.agentDeck?.noTabRecovery || this.config.store.recoverTabs === false) {\n return\n }\n this.config.store.recoverTabs = false\n this.config.save()\n }\n}\n","/**\n * 터미널 화면이 깨졌는지 판정한다.\n *\n * \"깨졌다\" 의 정체는 하나다 — **TUI 가 아는 폭과 xterm 이 가진 폭이 다르다.**\n * 그러면 TUI 가 그린 한 행이 xterm 에서 두 행으로 접히거나(폭이 더 크다),\n * 행 오른쪽에 옛 프레임이 남는다(폭이 더 작다). 눈으로는 \"입력창 구분선이 중간에서 끊긴다\",\n * \"가로선과 입력 텍스트가 한 줄에 섞인다\" 로 보인다.\n *\n * 정상 화면의 모양은 실측해서 확정했다 (2026-09-01, Claude Code 2.1.x, CDP 로 xterm 버퍼 원문).\n * 사이드바를 켠 창(cols=280)과 순정 창(cols=360) 양쪽에서 완전히 같은 구조가 나왔다.\n *\n * 71 wrapped=0 len=278 \" … ● high · /effort\" ← 오른쪽 정렬 힌트\n * 72 wrapped=0 len=280 \"──────────────────────────────────────────────────\" ← len == cols\n * 73 wrapped=1 len= 1 \"❯\" ← wrapped=1 이 정상\n * 74 wrapped=0 len=280 \"──────────────────────────────────────────────────\" ← len == cols\n * 75 wrapped=0 len=155 \" ⚠ Transcript saving is off — …\"\n * 76 wrapped=0 len= 58 \" ⏱ 1s 컨텍스트 사용량: …\"\n * 77 wrapped=0 len= 38 \" ⏵⏵ auto mode on (shift+tab to cycle)\"\n *\n * 여기서 놓치기 쉬운 세 가지 —\n * - 가로선은 **cols 를 정확히 꽉 채운다**. 그래서 그 다음 줄에 `wrapped=1` 이 붙는 것은\n * xterm 의 pending-wrap 이고 **정상이다**. `wrapped` 만 보고 깨졌다고 판정하면 안 된다.\n * - 프롬프트 오른쪽에 오는 힌트(`● high · /effort`, `Try \"how does …\"`)는 **별도 줄**이다.\n * 프롬프트 줄과 같은 줄에 두 개의 머리(`❯`/`>`)가 보이면 그것이 깨진 화면이다.\n * - **폭이 다 맞아도 깨진 화면이 있다.** 테두리 두 줄이 맞붙어 `❯` 가 들어갈 행이\n * 사라지는 모양인데, 두 테두리 모두 cols 를 꽉 채우므로 폭 기준 판정은 전부 통과한다\n * (2026-09-02: 사람 눈으로도 이 도구로도 \"정상\" 이라고 오판했다). 그래서 폭만이 아니라\n * **입력할 자리가 있는가**(테두리 사이 간격 ≥ 2)를 같이 본다.\n *\n * xterm 없이 검증할 수 있도록 줄 배열만 받는 순수 함수로 둔다.\n */\n\n/** 판정에 필요한 한 줄 — 오른쪽 공백을 떼어낸 본문과 xterm 의 wrap 플래그 */\nexport interface ScreenLine {\n text: string\n wrapped: boolean\n}\n\nexport interface ScreenVerdict {\n broken: boolean\n /** 왜 깨졌다고 보는지 — 진단 로그에 그대로 남긴다 */\n reasons: string[]\n}\n\n/**\n * 가로선만으로 된 줄 (입력창 위/아래 테두리).\n * 두 글자까지 내려 잡는 이유 — 테두리가 화면 폭을 넘치면 다음 줄에 한두 칸짜리\n * 자투리로 떨어진다 (실측: cols=280 화면에 280칸 + `──` 2칸).\n */\nconst RULE_RE = /^[─━═]{2,}$/\n/** 입력창 머리글자 — prompt.ts 와 같은 집합. 뒤가 줄 끝이어도(빈 입력창) 머리다 */\nconst HEAD_RE = /^[>❯›❭➜](\\s|$)/\n/** 줄 어딘가에 있는 머리글자 — 가로선과 섞였는지 볼 때 쓴다 */\nconst HEAD_ANYWHERE_RE = /[>❯›❭➜](\\s|$)/\n/** 선택지 커서(`❯ 1. Yes`)는 입력창 머리가 아니다 */\nconst CHOICE_RE = /^[>❯›❭➜]\\s*(\\d+[.)]\\s|(?:Yes|No)\\b)/i\n/** 가로선 문자 */\nconst RULE_CHAR_RE = /[─━═]/\n\nexport function judgeScreen (lines: ScreenLine[], cols: number): ScreenVerdict {\n const reasons: string[] = []\n if (!(cols > 1) || !lines.length) {\n return { broken: false, reasons: [] }\n }\n\n const rules: number[] = []\n const heads: number[] = []\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]\n const body = line.text.replace(/\\s+$/, '')\n if (!body) {\n continue\n }\n\n if (RULE_RE.test(body)) {\n rules.push(i)\n // 테두리는 화면 폭을 꽉 채운다. 짧으면 TUI 가 더 좁은 폭으로 그린 것이고,\n // 그보다 짧은 자투리 줄이면 넘쳐 접힌 꼬리다 — 어느 쪽이든 폭이 어긋났다.\n //\n // 2026-09-02: `cols - 1` 도 정상으로 봐주도록 한 번 완화했다가 되돌렸다.\n // 근거로 삼은 `len=279` 스냅샷이 **전부 깨짐으로 판정된 화면**이었고,\n // 같은 로그의 정상 표본(`auto-after 복구됨`)은 `len == cols == 280` 이었다.\n // 병상 표본을 정상 기준으로 삼으면 안 된다.\n if (body.length !== cols) {\n reasons.push(`rule@${i} len=${body.length} != cols=${cols}`)\n }\n continue\n }\n\n // 가로선과 다른 글자가 한 줄에 섞였다.\n // 상자형 입력창(`╭──╮` / `│ > … │`)을 쓰는 앱도 있으므로, 머리글자가 같은 줄에\n // 함께 있을 때만 깨진 것으로 본다 — 그것이 \"가로선과 입력 텍스트가 섞인\" 그 증상이다.\n if (RULE_CHAR_RE.test(body) && HEAD_ANYWHERE_RE.test(body)) {\n reasons.push(`mixed@${i} ${JSON.stringify(body.slice(0, 40))}`)\n }\n\n if (HEAD_RE.test(body) && !CHOICE_RE.test(body)) {\n heads.push(i)\n }\n }\n\n // 입력창 **안에** 머리가 두 개 이상 보인다 = 옛 프레임이 지워지지 않았다.\n //\n // 화면 전체의 머리 수를 세면 안 된다 — Claude Code 는 지난 사용자 프롬프트를\n // `❯ 내가 보낸 말` 로 대화 이력에 남기고, 큐에 쌓인 메시지도 같은 모양으로 나열한다.\n // 그래서 정상 화면에도 머리가 예사로 일곱 개 보인다 (2026-09-01 실측: `heads=7` 오탐으로\n // 자동 복구가 2초마다 헛돌았다). 판정은 입력창 테두리(가로선) 사이 구간에서만 한다.\n //\n // 판정은 **맨 아래 두 테두리** 사이에서만 한다. 위쪽 테두리를 `rules[0]` 으로 잡으면\n // 대화 이력에 스크롤되어 남은 옛 입력창의 테두리를 물어, 그 사이의 지난 프롬프트가\n // 전부 머리로 세어진다. 입력창은 언제나 화면 맨 아래에 있다.\n // 자투리 테두리(폭이 안 맞는 줄)는 위치 기준이 못 되므로 **화면 폭을 꽉 채운 것**만 쓴다.\n const fullRules = rules.filter(i => lines[i].text.replace(/\\s+$/, '').length === cols)\n if (fullRules.length >= 2) {\n const bottom = fullRules[fullRules.length - 1]\n const top = fullRules[fullRules.length - 2]\n\n // **입력할 자리가 없다** — 테두리 두 줄이 맞붙어 `❯` 가 들어갈 행이 사라졌다.\n //\n // 이것이 2026-09-02 에 사람 눈으로도 도구로도 놓친 그 증상이다. 폭은 멀쩡해서\n // (테두리 둘 다 cols 를 꽉 채운다) 폭 기준 판정은 전부 통과해 버린다. 실측 픽셀:\n // 가로선 y=59 와 y=76 이 행높이(17px) 1행 간격, 그 사이 커서 글리프가 아래 선을 관통.\n // 정상이라면 두 테두리는 최소 한 행(입력줄)을 사이에 두므로 간격이 2 이상이다.\n if (bottom - top < 2) {\n reasons.push(`입력창에 자리가 없다 (테두리 ${top}·${bottom} 이 맞붙었다)`)\n } else {\n const inside = heads.filter(i => i > top && i < bottom).length\n // 머리가 0 개인 것은 깨짐으로 보지 않는다 — 선택지 커서(`❯ 1. Yes`)만 있는\n // 정상 화면이 그렇게 보인다 (CHOICE_RE 로 빼고 나면 머리가 0 이 된다).\n if (inside > 1) {\n reasons.push(`입력창 안 머리=${inside} (기대 1)`)\n }\n }\n }\n // **아래 테두리가 통째로 사라졌다.**\n //\n // 2026-09-02 실사용 실측(창 캡처 픽셀 스캔, 행높이 17px): 가로선이 `y=1295` 하나뿐이고\n // 프롬프트 글리프(y≈1304~1320) 아래 `y≈1329` 에 있어야 할 두 번째 가로선이 없었다.\n // 이 모양은 위 규칙들이 전부 통과한다 — 남은 테두리 하나는 폭을 꽉 채우고(폭 규칙 통과),\n // 테두리가 하나뿐이라 `fullRules.length >= 2` 가 거짓이라 자리 규칙도 건너뛰고,\n // `rules.length > 1` 도 거짓이라 섞임 규칙도 안 본다. 판정의 구멍이었다.\n //\n // 머리 **바로 위** 가 폭을 꽉 채운 테두리일 때만 본다. 그래야 3줄 입력창(`──/❯/──`)을\n // 쓰는 화면에만 적용되고, 테두리가 없는 일반 셸이나 상자형 입력창은 건드리지 않는다.\n // 대화 이력에 남은 옛 `❯ 내가 보낸 말` 도 안전하다 — 그 아래에는 현재 입력창의\n // 테두리가 있으므로 \"아래에 테두리가 없다\" 조건에 걸리지 않는다.\n if (heads.length && fullRules.length) {\n const head = heads[heads.length - 1]\n const topAttached = fullRules.includes(head - 1)\n const belowHead = fullRules.some(i => i > head)\n if (topAttached && !belowHead) {\n reasons.push(`입력창 아래 테두리가 없다 (머리@${head}, 위 테두리@${head - 1})`)\n }\n }\n\n // 테두리 길이가 서로 다르면 두 폭이 화면에 공존한다\n if (rules.length > 1) {\n const lens = new Set(rules.map(i => lines[i].text.replace(/\\s+$/, '').length))\n if (lens.size > 1) {\n reasons.push(`rule lens=${[...lens].join(',')} (섞임)`)\n }\n }\n\n return { broken: reasons.length > 0, reasons }\n}\n","import { Component } from '@angular/core'\nimport { ConfigService, PlatformService } from 'tabby-core'\n\nimport { LAYOUT_DEFAULTS } from './config'\nimport { hooksInstalled, hooksSupported, installHooks, uninstallHooks } from './claudeHooks'\nimport { AgentDeckRecoveryService } from './recovery.service'\n\nconst DOCK_LABELS: Record<string, string> = {\n left: '왼쪽',\n right: '오른쪽',\n top: '위쪽',\n bottom: '아래쪽',\n}\n\n/**\n * 설정 > AgentDeck 탭.\n *\n * 사용자가 실제로 바꿀 일이 있는 것만 노출한다 — 레이아웃 on/off, 기동 시 탭 복원 끄기, 작업 루트 프로필.\n * 나머지(화면비, 사이드바 폭, 투명도, 상태 감지, 입력 가로채기, 렌더 보정, 통보 채널)는\n * 손댈 이유가 거의 없고 잘못 만지면 화면이 깨지는 값이라 `config.ts` 의 기본값으로 고정하고\n * 설정 창에서는 뺐다. 정말 필요하면 설정 파일의 `agentDeck.*` 를 직접 고친다.\n *\n * `enabled` 는 deck.service 가 `config.changed$` 를 구독해 즉시 반영한다(deck.service.ts:256).\n * 루트 프로필은 기동 시 한 번만 읽으므로 재시작이 필요하다고 적어 둔다.\n */\n@Component({\n selector: 'agentdeck-settings-tab',\n template: `\n<h3 class=\"mb-3\">AgentDeck</h3>\n\n<div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">레이아웃 사용</div>\n <div class=\"description\">끄면 사이드바와 고정폭 레이아웃이 사라지고 Tabby 순정 화면으로 돌아간다.</div>\n </div>\n <toggle [(ngModel)]=\"config.store.agentDeck.enabled\" (ngModelChange)=\"config.save()\"></toggle>\n</div>\n\n<div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">UI 배치 초기화</div>\n <div class=\"description\">\n 마우스로 바꾼 사이드바 위치와 크기를 처음 상태로 되돌린다 —\n 오른쪽 도킹 + 화면비로 자동 계산한 폭.\n <span *ngIf=\"layoutChanged()\">지금: {{dockLabel()}} 도킹, {{sizeLabel()}}.</span>\n <span *ngIf=\"!layoutChanged()\">지금은 기본 상태다.</span>\n </div>\n </div>\n <button class=\"btn btn-secondary\" type=\"button\" [disabled]=\"!layoutChanged()\" (click)=\"resetLayout()\">\n <i class=\"fas fa-undo me-2\"></i>초기화\n </button>\n</div>\n\n<div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">기동 시 탭 복원 끄기</div>\n <div class=\"description\">\n 켜면 Tabby 를 다시 열 때 지난 탭을 되살리지 않고 빈 상태로 시작한다 —\n 복원되는 건 셸뿐이고 그 안의 Claude 세션은 이미 끝나 있어 의미가 없다.\n 끄면 Tabby 순정 동작(<code>recoverTabs</code>)으로 돌아간다. 다음 기동부터 적용.\n </div>\n </div>\n <toggle [ngModel]=\"config.store.agentDeck.noTabRecovery\" (ngModelChange)=\"recovery.setNoTabRecovery($event)\"></toggle>\n</div>\n\n<h3 class=\"mt-4 mb-3\">Claude Code 연동</h3>\n<div class=\"text-muted mb-3\">\n 에이전트가 \"지시를 받았다 / 승인을 기다린다 / 끝났다\" 를 직접 알려주게 한다.\n 이게 사이드바 상태의 가장 정확한 원천이다 — 걸지 않으면 화면에 그려진 글자를 보고\n 추측하는 방식으로 동작하고, 그만큼 판정이 흔들린다.\n</div>\n\n<div class=\"form-line\" *ngIf=\"!hooksSupported\">\n <div class=\"header\">\n <div class=\"title\">이 환경에서는 걸 수 없다</div>\n <div class=\"description\">통보 스크립트가 PowerShell 이라 Windows 에서만 동작한다. 상태는 출력 패턴으로 추측한다.</div>\n </div>\n</div>\n\n<div class=\"form-line\" *ngIf=\"hooksSupported\">\n <div class=\"header\">\n <div class=\"title\">상태 통보 훅</div>\n <div class=\"description\">\n {{hooksOn ? '설치됨' : '설치 안 됨'}} — <code>~/.claude/settings.json</code> 의\n UserPromptSubmit / Notification / PostToolUse / PostToolUseFailure / PermissionDenied / Stop / StopFailure 에 걸린다.\n 다른 훅은 건드리지 않고, 쓰기 전에 같은 폴더에 백업을 남긴다.\n <span *ngIf=\"hookError\" class=\"text-danger d-block mt-1\">{{hookError}}</span>\n </div>\n </div>\n <button class=\"btn\" type=\"button\"\n [class.btn-secondary]=\"!hooksOn\" [class.btn-outline-danger]=\"hooksOn\"\n (click)=\"toggleHooks()\">\n <i class=\"fas me-2\" [class.fa-plug]=\"!hooksOn\" [class.fa-trash]=\"hooksOn\"></i>\n {{hooksOn ? '제거' : '설치'}}\n </button>\n</div>\n\n<div class=\"form-line\" *ngIf=\"hooksSupported && hooksOn\">\n <div class=\"header\">\n <div class=\"title\">통보 채널</div>\n <div class=\"description\">훅이 보낸 상태를 받는 통로. 꺼져 있으면 훅을 걸어도 전달되지 않는다. 변경은 Tabby 재시작 후 적용된다.</div>\n </div>\n <toggle [(ngModel)]=\"config.store.agentDeck.notifyChannel\" (ngModelChange)=\"config.save()\"></toggle>\n</div>\n\n<h3 class=\"mt-4 mb-3\">작업 루트 프로필</h3>\n<div class=\"text-muted mb-3\">새 탭이 항상 같은 작업 폴더에서 뜨도록 전용 프로필을 만든다. 변경은 Tabby 재시작 후 적용된다.</div>\n\n<div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">루트 프로필 사용</div>\n <div class=\"description\">켜고 작업 폴더를 채우면 해당 프로필을 만들어 기본 프로필로 삼는다.</div>\n </div>\n <toggle [(ngModel)]=\"config.store.agentDeck.rootProfile\" (ngModelChange)=\"config.save()\"></toggle>\n</div>\n\n<ng-container *ngIf=\"config.store.agentDeck.rootProfile\">\n <div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">프로필 이름</div>\n </div>\n <input class=\"form-control w-50\" type=\"text\"\n [(ngModel)]=\"config.store.agentDeck.rootProfileName\" (change)=\"config.save()\">\n </div>\n\n <div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">작업 폴더</div>\n <div class=\"description\">비우면 프로필을 만들지 않는다. 직접 적을 때는 백슬래시 이스케이프 함정을 피하려고 슬래시로 적는다 (예: D:/Project).</div>\n </div>\n <div class=\"input-group w-50\">\n <input class=\"form-control\" type=\"text\" placeholder=\"D:/Project\"\n [(ngModel)]=\"config.store.agentDeck.rootProfileCwd\" (change)=\"config.save()\">\n <button class=\"btn btn-secondary\" type=\"button\" (click)=\"pickCwd()\">\n <i class=\"fas fa-folder-open me-2\"></i>찾아보기\n </button>\n </div>\n </div>\n\n <div class=\"form-line\">\n <div class=\"header\">\n <div class=\"title\">실행 명령</div>\n </div>\n <input class=\"form-control w-50\" type=\"text\"\n [(ngModel)]=\"config.store.agentDeck.rootProfileCommand\" (change)=\"config.save()\">\n </div>\n\n</ng-container>\n\n<div class=\"text-muted mt-4\">\n 화면비·사이드바 폭·투명도·상태 감지·입력 처리 등 나머지 값은 기본값으로 고정돼 있다.\n 바꿔야 한다면 설정 파일의 <code>agentDeck.*</code> 를 직접 고친다.\n 단축키는 <b>단축키</b> 탭의 <code>agentdeck-*</code> 항목에서 바꾼다.\n</div>\n`,\n})\nexport class AgentDeckSettingsTabComponent {\n /** 이 환경에서 훅을 걸 수 있나 (통보 스크립트가 PowerShell 이라 Windows 전용) */\n hooksSupported = hooksSupported()\n /** 지금 걸려 있나 — 파일을 매번 읽지 않도록 화면용으로 들고 있는다 */\n hooksOn = false\n /** 훅을 쓰다 실패한 이유 — 조용히 삼키면 사용자는 버튼이 먹통인 줄 안다 */\n hookError = ''\n\n constructor (\n public config: ConfigService,\n public recovery: AgentDeckRecoveryService,\n private platform: PlatformService,\n ) {\n this.refreshHooks()\n }\n\n private refreshHooks (): void {\n try {\n this.hooksOn = this.hooksSupported && hooksInstalled()\n } catch (e: any) {\n this.hooksOn = false\n this.hookError = `설정을 읽지 못했다: ${e?.message ?? e}`\n }\n }\n\n /**\n * 훅을 걸거나 뗀다.\n *\n * 걸 때는 통보 채널도 같이 켠다 — 훅만 걸고 채널이 닫혀 있으면 보고가 어디에도 닿지 않는데,\n * 사용자 입장에서는 \"설치했는데 아무 일도 안 일어난다\" 로만 보인다.\n */\n toggleHooks (): void {\n this.hookError = ''\n try {\n if (this.hooksOn) {\n uninstallHooks()\n } else {\n installHooks()\n if (!this.config.store.agentDeck.notifyChannel) {\n this.config.store.agentDeck.notifyChannel = true\n this.config.save()\n }\n }\n } catch (e: any) {\n this.hookError = `${e?.message ?? e}`\n }\n this.refreshHooks()\n }\n\n /**\n * OS 폴더 선택 창을 띄워 작업 폴더를 고른다.\n *\n * `pickDirectory` 는 취소하면 null/undefined 를 주므로 그때는 기존 값을 건드리지 않는다.\n * 다이얼로그 제목은 Tabby 버전에 따라 인자를 받기도 하고 안 받기도 해서 any 로 넘긴다 —\n * 안 받는 쪽은 그냥 무시하므로 어느 쪽에서도 깨지지 않는다.\n * 돌려받은 경로는 백슬래시를 슬래시로 바꿔 저장한다. 설정 파일에 그대로 적히는 값이라\n * 손으로 고칠 때 이스케이프 사고가 나지 않게 하려는 것이고, Windows 도 슬래시 경로를 받는다.\n */\n /** 배치가 기본값에서 벗어나 있나 — 벗어나 있을 때만 초기화 버튼이 살아 있다 */\n layoutChanged (): boolean {\n const cfg = this.config.store.agentDeck\n return Object.keys(LAYOUT_DEFAULTS).some(k => cfg[k] !== LAYOUT_DEFAULTS[k])\n }\n\n dockLabel (): string {\n return DOCK_LABELS[this.config.store.agentDeck.sidebarDock] ?? '오른쪽'\n }\n\n sizeLabel (): string {\n const cfg = this.config.store.agentDeck\n if (cfg.sidebarDock === 'top' || cfg.sidebarDock === 'bottom') {\n return '높이 ' + cfg.sidebarHeight + 'px'\n }\n return cfg.sidebarWidth ? '폭 ' + cfg.sidebarWidth + 'px' : '폭 자동'\n }\n\n /**\n * 도킹 방향과 크기만 기본값으로 되돌린다.\n *\n * 되돌리기 쉬운 조작이라 확인 창은 두지 않는다. `config.save()` 가 `changed$` 를 발화시키고\n * deck.service 가 그걸 받아 곧바로 다시 배치하므로(deck.service.ts:256) 재시작도 필요 없다.\n */\n resetLayout (): void {\n Object.assign(this.config.store.agentDeck, LAYOUT_DEFAULTS)\n this.config.save()\n }\n\n async pickCwd (): Promise<void> {\n const picked = await (this.platform as any).pickDirectory('작업 폴더 선택')\n if (!picked) {\n return\n }\n this.config.store.agentDeck.rootProfileCwd = String(picked).replace(/\\\\/g, '/')\n this.config.save()\n }\n}\n","import { Injectable } from '@angular/core'\nimport { SettingsTabProvider } from 'tabby-settings'\n\nimport { AgentDeckSettingsTabComponent } from './settings.component'\n\n/**\n * 설정 창 왼쪽 목록에 AgentDeck 탭을 끼워 넣는다.\n * `weight` 를 주지 않으면 등록 순서 뒤쪽에 붙는다 — 순정 탭들 아래로 가도록 그대로 둔다.\n */\n@Injectable()\nexport class AgentDeckSettingsTabProvider extends SettingsTabProvider {\n id = 'agentdeck'\n icon = 'layer-group'\n title = 'AgentDeck'\n\n getComponentType (): any {\n return AgentDeckSettingsTabComponent\n }\n}\n","import { Injectable } from '@angular/core'\r\nimport { Subject, Observable } from 'rxjs'\r\nimport { BaseTabComponent } from 'tabby-core'\r\nimport { TabState, WorkStatus } from './api'\r\n\r\n/**\r\n * 부연(reason)을 들고 있을 수 있는 상태. 나머지 상태로 바뀌면 무조건 비운다 —\r\n * 끝난 뒤에도 \"Bash 권한\" 이 남아 있으면 지금 승인을 기다리는 것처럼 읽히기 때문이다\r\n */\r\nconst REASON_STATUSES: readonly WorkStatus[] = ['waiting', 'limited', 'error']\r\n\r\n/**\r\n * 탭별 작업 상태 보관소.\r\n * 상태의 출처는 3가지 — 자동 감지(decorator), OSC 시퀀스(Claude Code 훅), 사이드바에서의 수동 지정.\r\n * pinned 가 true 면 자동 감지가 값을 덮어쓰지 않는다.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class WorkStatusService {\r\n private states = new Map<BaseTabComponent, TabState>()\r\n private changed = new Subject<void>()\r\n\r\n /** 진단용 카운터 — decorator 가 실제로 붙었는지, 출력이 흘러오는지 확인한다 */\r\n debug = {\r\n attached: 0,\r\n outputs: 0,\r\n oscHits: 0,\r\n titleHits: 0,\r\n }\r\n\r\n get changed$ (): Observable<void> { return this.changed }\r\n\r\n get (tab: BaseTabComponent): TabState {\r\n let s = this.states.get(tab)\r\n if (!s) {\r\n s = {\r\n status: 'idle', label: '', reason: '', since: Date.now(), pinned: false,\r\n lastOutput: 0, busyMode: false, lastBusy: 0,\r\n }\r\n this.states.set(tab, s)\r\n }\r\n return s\r\n }\r\n\r\n /** 자동 감지용 — pinned 상태는 건드리지 않는다 */\r\n setAuto (tab: BaseTabComponent, status: WorkStatus): void {\r\n const s = this.get(tab)\r\n if (s.pinned || s.status === status) {\r\n return\r\n }\r\n s.status = status\r\n s.since = Date.now()\r\n this.clearReasonUnlessWaiting(s)\r\n this.changed.next()\r\n }\r\n\r\n /**\r\n * 수동/훅 지정 — 이후 자동 감지보다 우선한다.\r\n * `reason` 은 상태의 부연(승인 이유 / 한도 리셋 시각 / 오류 코드) — REASON_STATUSES 일 때만 담는다\r\n */\r\n setManual (tab: BaseTabComponent, status: WorkStatus, label?: string, reason?: string): void {\r\n const s = this.get(tab)\r\n s.status = status\r\n s.since = Date.now()\r\n s.pinned = true\r\n if (label !== undefined) {\r\n s.label = label\r\n }\r\n s.reason = REASON_STATUSES.includes(status) ? (reason ?? '') : ''\r\n this.changed.next()\r\n }\r\n\r\n /**\r\n * 승인대기 → 진행중. 사람이 승인한 순간을 훅은 알려주지 않는다 — 다음 훅(PostToolUse)은\r\n * 도구가 **끝난 뒤**라 긴 빌드 동안 사이드바가 승인대기에 박혀 있다. 그래서 화면에 \"esc to interrupt\"\r\n * 같은 작업 중 표시가 다시 보이면 여기로 올린다 (detect.ts). pinned·label 은 그대로 둔다 —\r\n * 훅이 고정한 탭도 이 전이만은 허용해야 하기 때문이다. waiting 이 아니면 아무것도 하지 않는다\r\n */\r\n resume (tab: BaseTabComponent): void {\r\n const s = this.get(tab)\r\n if (s.status !== 'waiting') {\r\n return\r\n }\r\n s.status = 'running'\r\n s.since = Date.now()\r\n s.reason = ''\r\n this.changed.next()\r\n }\r\n\r\n setLabel (tab: BaseTabComponent, label: string): void {\r\n this.get(tab).label = label\r\n this.changed.next()\r\n }\r\n\r\n /** 수동 고정을 풀고 자동 감지로 되돌린다 */\r\n unpin (tab: BaseTabComponent): void {\r\n const s = this.get(tab)\r\n s.pinned = false\r\n s.status = 'idle'\r\n s.since = Date.now()\r\n this.clearReasonUnlessWaiting(s)\r\n this.changed.next()\r\n }\r\n\r\n /** 부연을 가질 수 없는 상태에는 이유가 남아 있을 수 없다 */\r\n private clearReasonUnlessWaiting (s: TabState): void {\r\n if (!REASON_STATUSES.includes(s.status)) {\r\n s.reason = ''\r\n }\r\n }\r\n\r\n markOutput (tab: BaseTabComponent): void {\r\n this.get(tab).lastOutput = Date.now()\r\n }\r\n\r\n /**\r\n * 에이전트가 \"작업 중\" 이라고 스스로 밝힌 순간 — 스피너나 \"esc to interrupt\" 같은 표시.\r\n *\r\n * 이 신호를 한 번이라도 본 탭은 그 뒤로 신호만 보고 판단한다(busyMode).\r\n * 상태줄을 매초 다시 그리는 TUI 를 \"계속 일하는 중\" 으로 오해하지 않기 위해서다.\r\n */\r\n markBusy (tab: BaseTabComponent): void {\r\n const s = this.get(tab)\r\n s.busyMode = true\r\n s.lastBusy = Date.now()\r\n }\r\n\r\n /** 이 탭을 에이전트 TUI 로 볼지 — 아니면 예전처럼 출력 유무로 판단한다 */\r\n isBusyMode (tab: BaseTabComponent): boolean {\r\n return this.get(tab).busyMode\r\n }\r\n\r\n forget (tab: BaseTabComponent): void {\r\n this.states.delete(tab)\r\n this.changed.next()\r\n }\r\n\r\n /** 사이드바가 매 틱 호출 — idle 전환만 담당하고 화면 갱신 필요 여부를 돌려준다 */\r\n tickIdle (tab: BaseTabComponent, idleAfterMs: number): boolean {\r\n const s = this.get(tab)\r\n if (s.pinned || s.status !== 'running') {\r\n return false\r\n }\r\n // 에이전트 탭은 \"작업 중\" 신호가 끊긴 시점부터 잰다.\r\n // 일반 셸은 예전대로 출력이 끊긴 시점부터 잰다 (신호를 낼 줄 모르므로)\r\n const from = s.busyMode ? s.lastBusy : s.lastOutput\r\n if (from && Date.now() - from > idleAfterMs) {\r\n s.status = 'idle'\r\n s.since = Date.now()\r\n this.clearReasonUnlessWaiting(s)\r\n return true\r\n }\r\n return false\r\n }\r\n}\r\n","/**\r\n * 훅 보고를 탭에 직결하는 열쇠 — 탭 셸에 심는 환경변수와 그것으로 탭을 고르는 순수 규칙.\r\n * Angular/Tabby 에 기대지 않아 단위 테스트가 된다 (test/tabenv.test.js).\r\n *\r\n * 왜 환경변수인가 — 0.2.1 의 프로세스 계보(bind.ts)는 훅이 매 세션 `Win32_Process` 전체를\r\n * 훑어(~450ms) 조상 PID 를 보내고 플러그인이 탭별 셸 PID 와 맞추는 방식이다. 맞기는 하지만\r\n * 훅이 느리고, 셸 PID 를 pty 에 비동기로 물어야 해서 표가 늦게 채워지는 창이 있다.\r\n * 플러그인이 탭을 열 때 셸 환경에 `AGENTDECK_TAB=<id>` 를 심어 두면 그 셸에서 뜬 claude 와\r\n * 그 훅은 환경을 그대로 물려받으므로, 훅은 `$env:AGENTDECK_TAB` 을 읽어 보내기만 하면 되고\r\n * 플러그인은 표에서 바로 찾는다. 계보 조회가 통째로 빠진다.\r\n *\r\n * 계보는 폴백으로 남는다 — 이 버전 이전에 열린 탭, 재시작으로 복원된 탭(셸이 이미 떠 있어\r\n * 새 값을 심을 수 없다), 사람이 셸 밖에서 부른 훅은 환경변수가 없다.\r\n */\r\nexport const TAB_ENV = 'AGENTDECK_TAB'\r\n\r\n/**\r\n * 탭 하나를 가리키는 짧은 무작위 id — 12 hex 자리(48비트). 같은 Tabby 안에서만 유일하면 되므로\r\n * 이 길이로 충분하고, 셸 프롬프트나 진단 로그에 찍혀도 거슬리지 않는다.\r\n * Electron 렌더러와 Node 20 은 `globalThis.crypto.getRandomValues` 를 둘 다 갖고 있다.\r\n */\r\nexport function newTabId (): string {\r\n const bytes = new Uint8Array(6)\r\n const c: any = (globalThis as any).crypto\r\n if (c && typeof c.getRandomValues === 'function') {\r\n c.getRandomValues(bytes)\r\n } else {\r\n for (let i = 0; i < bytes.length; i++) {\r\n bytes[i] = Math.floor(Math.random() * 256)\r\n }\r\n }\r\n return Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('')\r\n}\r\n\r\n/**\r\n * 훅이 보낸 tabId 를 가진 탭(루트)을 찾는다. 분할 탭은 패널마다 id 가 다르므로 루트 하나에\r\n * 여러 id 가 달린다. 없으면 null — 추측하지 않는다 (호출자가 계보/폴백으로 넘어간다).\r\n */\r\nexport function pickTabByTabId<T> (tabId: string | undefined, tabIds: Map<T, string[]>): T | null {\r\n const want = typeof tabId === 'string' ? tabId.trim() : ''\r\n if (!want) {\r\n return null\r\n }\r\n for (const [tab, ids] of tabIds) {\r\n if (ids.includes(want)) {\r\n return tab\r\n }\r\n }\r\n return null\r\n}\r\n","module.exports = require(\"net\");","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_common__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_forms__;","if(typeof __WEBPACK_EXTERNAL_MODULE_electron__ === 'undefined') { const e = new Error(\"Cannot find module 'electron'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }\n\nmodule.exports = __WEBPACK_EXTERNAL_MODULE_electron__;","module.exports = __WEBPACK_EXTERNAL_MODULE_fs__;","module.exports = __WEBPACK_EXTERNAL_MODULE_os__;","module.exports = __WEBPACK_EXTERNAL_MODULE_path__;","module.exports = __WEBPACK_EXTERNAL_MODULE_rxjs__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_settings__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_terminal__;","// The module cache\nconst __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tconst 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\tconst module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\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\tconst 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\tconst 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/value 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\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nc = undefined;","import { NgModule } from '@angular/core'\nimport { CommonModule } from '@angular/common'\nimport { FormsModule } from '@angular/forms'\nimport TabbyCoreModule, { ConfigProvider, HotkeyProvider } from 'tabby-core'\nimport { SettingsTabProvider } from 'tabby-settings'\nimport { TerminalDecorator } from 'tabby-terminal'\n\nimport { AgentDeckConfigProvider } from './config'\nimport { AgentDeckHotkeyProvider } from './hotkeys'\nimport { AgentDeckDecorator } from './decorator'\nimport { AgentDeckService } from './deck.service'\nimport { AgentDeckProfileService } from './profile.service'\nimport { WorkNotifyService } from './notify.service'\nimport { AgentDeckAlertService } from './alert.service'\nimport { AgentDeckRecoveryService } from './recovery.service'\nimport { AgentDeckSettingsTabProvider } from './settings'\nimport { AgentDeckSettingsTabComponent } from './settings.component'\n\nimport './styles.scss'\n\nexport * from './api'\n\n@NgModule({\n imports: [\n CommonModule,\n // 설정 탭이 [(ngModel)] 로 config.store 를 직접 물고 있어서 필요하다\n FormsModule,\n TabbyCoreModule,\n ],\n providers: [\n { provide: ConfigProvider, useClass: AgentDeckConfigProvider, multi: true },\n { provide: HotkeyProvider, useClass: AgentDeckHotkeyProvider, multi: true },\n { provide: TerminalDecorator, useClass: AgentDeckDecorator, multi: true },\n { provide: SettingsTabProvider, useClass: AgentDeckSettingsTabProvider, multi: true },\n ],\n declarations: [\n AgentDeckSettingsTabComponent,\n ],\n})\nexport default class AgentDeckModule {\n constructor (\n deck: AgentDeckService,\n profiles: AgentDeckProfileService,\n notify: WorkNotifyService,\n alert: AgentDeckAlertService,\n recovery: AgentDeckRecoveryService,\n ) {\n // 다섯 서비스 모두 app.ready$ 를 기다렸다가 스스로 붙는다.\n // alert 는 deck 이 만드는 `__agentdeck` 에 붙으므로 deck 뒤에 둔다\n deck.init()\n profiles.init()\n notify.init()\n alert.init()\n recovery.init()\n }\n}\n"],"names":[],"sourceRoot":""}