@midscene/web 0.26.0 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/agent.js +1 -1
- package/dist/es/agent.js.map +1 -1
- package/dist/es/bridge-mode-browser.js +3 -3
- package/dist/es/bridge-mode.js +3 -3
- package/dist/es/bridge-mode.js.map +1 -1
- package/dist/es/chrome-extension.js +2 -2
- package/dist/es/chrome-extension.js.map +1 -1
- package/dist/es/index.js +49 -1
- package/dist/es/index.js.map +1 -1
- package/dist/es/midscene-playground.js +1 -1
- package/dist/es/midscene-playground.js.map +1 -1
- package/dist/es/playground.js +1 -1
- package/dist/es/playground.js.map +1 -1
- package/dist/es/playwright.js +49 -1
- package/dist/es/playwright.js.map +1 -1
- package/dist/es/puppeteer-agent-launcher.js +1 -1
- package/dist/es/puppeteer-agent-launcher.js.map +1 -1
- package/dist/es/puppeteer.js +1 -1
- package/dist/es/puppeteer.js.map +1 -1
- package/dist/lib/agent.js +1 -1
- package/dist/lib/agent.js.map +1 -1
- package/dist/lib/bridge-mode-browser.js +3 -3
- package/dist/lib/bridge-mode.js +3 -3
- package/dist/lib/bridge-mode.js.map +1 -1
- package/dist/lib/chrome-extension.js +2 -2
- package/dist/lib/chrome-extension.js.map +1 -1
- package/dist/lib/index.js +49 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/midscene-playground.js +1 -1
- package/dist/lib/midscene-playground.js.map +1 -1
- package/dist/lib/playground.js +1 -1
- package/dist/lib/playground.js.map +1 -1
- package/dist/lib/playwright.js +49 -1
- package/dist/lib/playwright.js.map +1 -1
- package/dist/lib/puppeteer-agent-launcher.js +1 -1
- package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
- package/dist/lib/puppeteer.js +1 -1
- package/dist/lib/puppeteer.js.map +1 -1
- package/dist/types/playwright.d.ts +24 -0
- package/package.json +3 -3
package/dist/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,IAAAA,eAwBO;AAEP,IAAAC,kBAAiB;;;AC3BjB,qBAAqD;AACrD,uBAAiD;AACjD,mBAAgD;AA4BhD,oBAAqC;AAE9B,IAAM,eAAN,MAAoD;AAAA,EAczD,YACU,QACA,YAID,oBACP,YACA;AAPQ;AACA;AAID;AAlBT,SAAO,iBAA2C,CAAC;AACnD,SAAO,SAAkC;AAGzC,SAAQ,qBAAqB;AAI7B,SAAQ,YAA8B;AAapC,SAAK,aAAa;AAClB,SAAK,SAAS,CAAC;AAEf,SAAK,SAAS,OAAO,UAAU,OAAO,OAAO,OAAO;AAEpD,QAAI,4BAAe,yBAAY;AAC7B,WAAK,SAAS;AAAA,IAChB,WAAW,KAAK,QAAQ,QAAQ;AAC9B,WAAK,aAAS,0BAAQ,QAAQ,IAAI,GAAG,KAAK,OAAO,MAAM;AAAA,IACzD,OAAO;AACL,YAAM,aAAa,KAAK,iBACpB,2BAAS,KAAK,YAAY,OAAO,EAAE,QAAQ,eAAe,EAAE,IAC5D;AACJ,WAAK,aAAS;AAAA,YACZ,oCAAqB,QAAQ;AAAA,QAC7B,GAAG,UAAU,IAAI,KAAK,IAAI,CAAC;AAAA,MAC7B;AAAA,IACF;AAEA,QAAI,4BAAe,yBAAY;AAC7B,WAAK,qBAAqB;AAAA,IAC5B,WAAW,OAAO,KAAK,QAAQ,uBAAuB,UAAU;AAC9D,WAAK,yBAAqB;AAAA,QACxB,QAAQ,IAAI;AAAA,QACZ,KAAK,OAAO;AAAA,MACd;AAAA,IACF,WAAW,KAAK,QAAQ,uBAAuB,MAAM;AACnD,WAAK,yBAAqB;AAAA,YACxB,oCAAqB,QAAQ;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAEA,SAAK,kBAAkB,OAAO,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,eAAe;AAAA,MACnE,GAAG;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY,KAAK,MAAM,UAAU;AAAA,IACnC,EAAE;AAAA,EACJ;AAAA,EAEQ,UAAU,KAAyB,OAAY;AACrD,UAAM,WAAW,OAAO,KAAK;AAC7B,QAAI,KAAK,OAAO,QAAQ,GAAG;AACzB,cAAQ,KAAK,cAAc,QAAQ,iCAAiC;AAAA,IACtE;AACA,SAAK,OAAO,QAAQ,IAAI;AAExB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEQ,gBAAgB,QAAiC,OAAe;AACtE,SAAK,SAAS;AACd,SAAK,eAAe;AAAA,EACtB;AAAA,EAEQ,8BAA8B,WAAoB;AACxD,UAAM,oBACJ,OAAO,cAAc,WAAW,YAAY,KAAK;AAEnD,QAAI,OAAO,sBAAsB,UAAU;AACzC;AAAA,IACF;AAEA,UAAM,aAAa,KAAK,eAAe,iBAAiB;AACxD,QAAI,KAAK,oBAAoB;AAC3B,WAAK,mBAAmB,UAAU;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,MAAc,cACZ,OACA,aACA,OACA;AACA,SAAK,eAAe,KAAK,EAAE,SAAS;AACpC,QAAI,OAAO;AACT,WAAK,eAAe,KAAK,EAAE,QAAQ;AAAA,IACrC;AAEA,SAAK,8BAA8B,KAAK;AAAA,EAC1C;AAAA,EAEQ,aAAa,WAAmB;AACtC,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEQ,cAAc;AACpB,QAAI,KAAK,QAAQ;AACf,YAAM,aAAS,0BAAQ,QAAQ,IAAI,GAAG,KAAK,MAAM;AACjD,YAAM,gBAAY,0BAAQ,MAAM;AAChC,UAAI,KAAC,2BAAW,SAAS,GAAG;AAC1B,sCAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,MAC1C;AACA,wCAAc,QAAQ,KAAK,UAAU,KAAK,UAAU,CAAC,GAAG,QAAW,CAAC,CAAC;AAAA,IACvE;AAAA,EACF;AAAA,EAEQ,0BAA0B;AAChC,QAAI,KAAK,oBAAoB;AAC3B,YAAM,UAAU,KAAK,WAAW,oBAAoB;AACpD,YAAM,eAAW,0BAAQ,QAAQ,IAAI,GAAG,KAAK,kBAAkB;AAC/D,YAAM,gBAAY,0BAAQ,QAAQ;AAClC,UAAI,KAAC,2BAAW,SAAS,GAAG;AAC1B,sCAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,MAC1C;AACA,wCAAc,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,IAC1D;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,YAAoC,OAAkB;AACnE,UAAM,EAAE,KAAK,IAAI;AACjB,6BAAO,MAAM,sBAAsB;AAEnC,eAAW,iBAAiB,MAAM;AAChC,YAAM,cAAc,OAAO,SAAS,eAAe,EAAE;AACrD,iBAAW,cAAc;AACzB,YAAM,WAAW,KAAK,aAAa;AACnC,UACE,cAAe,YACf,QAAS,UACT;AACA,cAAM,aAAa;AACnB,cAAM,SAAS,WAAW,YAAY,WAAW;AACjD,iCAAO,QAAQ,kCAAkC;AACjD;AAAA,UACE,OAAO,WAAW;AAAA,UAClB;AAAA,QACF;AACA,cAAM,MAAM,SAAS,QAAQ;AAAA,UAC3B,WAAW,WAAW;AAAA,QACxB,CAAC;AAAA,MACH,WAAW,cAAe,UAA2C;AACnE,cAAM,aAAa;AACnB,cAAM,SAAS,WAAW;AAC1B,cAAM,MAAM,WAAW;AACvB,iCAAO,QAAQ,6BAA6B;AAC5C;AAAA,UACE,OAAO,WAAW;AAAA,UAClB;AAAA,QACF;AACA,cAAM,MAAM,SAAS,QAAQ,GAAG;AAAA,MAClC,WAAW,aAAc,UAA0C;AACjE,cAAM,YAAY;AAClB,cAAM,SAAS,UAAU;AACzB,cAAM,UAAU;AAAA,UACd,aAAa,UAAU;AAAA,UACvB,oBAAoB,UAAU;AAAA,QAChC;AACA,iCAAO,QAAQ,4BAA4B;AAC3C;AAAA,UACE,OAAO,WAAW;AAAA,UAClB;AAAA,QACF;AACA,cAAM,cAAc,MAAM,MAAM,QAAQ,QAAQ,OAAO;AACvD,aAAK,UAAU,UAAU,MAAM,WAAW;AAAA,MAC5C,WAAW,cAAe,UAA2C;AACnE,cAAM,aAAa;AACnB,cAAM,SAAS,WAAW;AAC1B,cAAM,UAAU;AAAA,UACd,aAAa,WAAW;AAAA,UACxB,oBAAoB,WAAW;AAAA,QACjC;AACA,iCAAO,QAAQ,6BAA6B;AAC5C;AAAA,UACE,OAAO,WAAW;AAAA,UAClB;AAAA,QACF;AACA,cAAM,eAAe,MAAM,MAAM,SAAS,QAAQ,OAAO;AACzD,aAAK,UAAU,WAAW,MAAM,YAAY;AAAA,MAC9C,WAAW,cAAe,UAA2C;AACnE,cAAM,aAAa;AACnB,cAAM,SAAS,WAAW;AAC1B,cAAM,UAAU;AAAA,UACd,aAAa,WAAW;AAAA,UACxB,oBAAoB,WAAW;AAAA,QACjC;AACA,iCAAO,QAAQ,6BAA6B;AAC5C;AAAA,UACE,OAAO,WAAW;AAAA,UAClB;AAAA,QACF;AACA,cAAM,eAAe,MAAM,MAAM,SAAS,QAAQ,OAAO;AACzD,aAAK,UAAU,WAAW,MAAM,YAAY;AAAA,MAC9C,WAAW,eAAgB,UAA4C;AACrE,cAAM,cAAc;AACpB,cAAM,SAAS,YAAY;AAC3B,cAAM,UAAU;AAAA,UACd,aAAa,YAAY;AAAA,UACzB,oBAAoB,YAAY;AAAA,QAClC;AACA,iCAAO,QAAQ,8BAA8B;AAC7C;AAAA,UACE,OAAO,WAAW;AAAA,UAClB;AAAA,QACF;AACA,cAAM,gBAAgB,MAAM,MAAM,UAAU,QAAQ,OAAO;AAC3D,aAAK,UAAU,YAAY,MAAM,aAAa;AAAA,MAChD,WAAW,WAAY,UAAwC;AAC7D,cAAM,UAAU;AAChB,cAAM,SAAS,QAAQ;AACvB,iCAAO,QAAQ,0BAA0B;AACzC,iCAAO,OAAO,WAAW,UAAU,mCAAmC;AACtE,cAAM,YAAY,MAAM,MAAM,MAAM,MAAM;AAC1C,aAAK,UAAU,QAAQ,MAAM,SAAS;AAAA,MACxC,WAAW,cAAe,UAA2C;AACnE,cAAM,aAAa;AACnB,cAAM,SAAS,WAAW;AAC1B,iCAAO,QAAQ,6BAA6B;AAC5C;AAAA,UACE,OAAO,WAAW;AAAA,UAClB;AAAA,QACF;AACA,cAAM,eAAe,MAAM,MAAM,SAAS,QAAQ,UAAU;AAC5D,aAAK,UAAU,WAAW,MAAM,YAAY;AAAA,MAC9C,WAAW,eAAgB,UAA4C;AACrE,cAAM,cAAc;AACpB,cAAM,SAAS,YAAY;AAC3B,iCAAO,QAAQ,8BAA8B;AAC7C;AAAA,UACE,OAAO,WAAW;AAAA,UAClB;AAAA,QACF;AACA,cAAM,UAAU,YAAY;AAC5B,cAAM,MAAM,UAAU,QAAQ,EAAE,WAAW,QAAQ,CAAC;AAAA,MACtD,WAAW,WAAY,UAAwC;AAC7D,cAAM,YAAY;AAClB,cAAM,KAAK,UAAU;AACrB,YAAI,WAAW;AACf,YAAI,OAAO,OAAO,UAAU;AAC1B,qBAAW,OAAO,SAAS,IAAI,EAAE;AAAA,QACnC;AACA;AAAA,UACE,YAAY,WAAW;AAAA,UACvB,gDAAgD,EAAE;AAAA,QACpD;AACA,cAAM,IAAI,QAAQ,CAACC,aAAY,WAAWA,UAAS,QAAQ,CAAC;AAAA,MAC9D,WAAW,WAAY,UAAwC;AAC7D,cAAM,UAAU;AAChB,cAAM,MAAM,MAAM,QAAQ,OAAO,OAAO;AAAA,MAC1C,WACE,kBAAmB,UACnB;AACA,cAAM,iBAAiB;AACvB,cAAM,MAAM,aAAa,eAAe,cAAc,cAAc;AAAA,MACtE,WAAW,aAAc,UAA0C;AACjE,cAAM,YAAY;AAClB,cAAM,MAAM,QAAQ,UAAU,SAAS,SAAS;AAAA,MAClD,WAAW,aAAc,UAA0C;AAEjE,cAAM,YAAY;AAClB,cAAM,MAAM,QAAQ,UAAU,SAAS,UAAU,QAAQ,SAAS;AAAA,MACpE,WACE,qBAAsB,UACtB;AACA,cAAM,oBACJ;AACF,cAAM,MAAM;AAAA,UACV,kBAAkB;AAAA,UAClB,kBAAkB;AAAA,UAClB;AAAA,QACF;AAAA,MACF,WAAW,cAAe,UAA2C;AACnE,cAAM,aAAa;AACnB,cAAM,MAAM,SAAS,YAAY,WAAW,QAAQ,UAAU;AAAA,MAChE,WACE,gBAAiB,UACjB;AACA,cAAM,yBACJ;AAEF,cAAM,SAAS,MAAM,MAAM;AAAA,UACzB,uBAAuB;AAAA,QACzB;AACA,aAAK,UAAU,uBAAuB,MAAM,MAAM;AAAA,MACpD,WACE,mBAAoB,UACpB;AACA,cAAM,oBAAoB;AAC1B,cAAM,MAAM,cAAc,kBAAkB,eAAe;AAAA,UACzD,SAAS,kBAAkB,WAAW;AAAA,QACxC,CAAC;AAAA,MACH,OAAO;AACL,cAAM,IAAI,MAAM,qBAAqB,KAAK,UAAU,QAAQ,CAAC,EAAE;AAAA,MACjE;AAAA,IACF;AACA,SAAK,aAAa,MAAM;AACxB,UAAM,KAAK,wBAAwB;AAAA,EACrC;AAAA,EAEA,MAAM,MAAM;AACV,UAAM,EAAE,QAAQ,KAAK,SAAS,MAAM,IAAI,KAAK;AAC7C,UAAM,SAAS,OAAO;AACtB,UAAM,aAAa;AACnB,UAAM,WAAW,UAAU;AAE3B,SAAK,gBAAgB,SAAS;AAE9B,QAAI,QAA0B;AAC9B,QAAI,SAAmB,CAAC;AACxB,QAAI;AACF,YAAM,EAAE,OAAO,UAAU,QAAQ,UAAU,IAAI,MAAM,KAAK;AAAA,QACxD;AAAA,MACF;AACA,cAAQ;AACR,YAAM,yBAAyB,MAAM;AACrC,YAAM,iBAAiB,CAAC,QAAQ;AAC9B,YAAI,KAAK,WAAW,WAAW;AAC7B,eAAK,iBAAiB;AAAA,QACxB;AACA,iCAAyB,GAAG;AAAA,MAC9B;AACA,eAAS;AAAA,QACP,GAAI,aAAa,CAAC;AAAA,QAClB;AAAA,UACE,MAAM;AAAA,UACN,IAAI,MAAM;AACR,gBAAI,OAAO;AACT,oBAAM,iBAAiB;AAAA,YACzB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,GAAG;AACV,WAAK,gBAAgB,SAAS,CAAU;AACxC;AAAA,IACF;AACA,SAAK,YAAY;AAEjB,QAAI,YAAY;AAChB,SAAK,gBAAgB,SAAS;AAC9B,QAAI,YAAY;AAChB,WAAO,YAAY,MAAM,QAAQ;AAC/B,YAAM,aAAa,KAAK,eAAe,SAAS;AAChD,WAAK,cAAc,WAAW,SAAgB;AAC9C,WAAK,aAAa,SAAS;AAE3B,UAAI;AACF,cAAM,KAAK,SAAS,YAAY,KAAK,SAAS;AAC9C,aAAK,cAAc,WAAW,MAAa;AAAA,MAC7C,SAAS,GAAG;AACV,aAAK,cAAc,WAAW,SAAgB,CAAU;AAExD,YAAI,WAAW,iBAAiB;AAAA,QAEhC,OAAO;AACL,eAAK,aAAa,MAAM;AACxB,sBAAY;AACZ;AAAA,QACF;AAAA,MACF;AACA,WAAK,aAAa,OAAO;AACzB;AAAA,IACF;AAEA,QAAI,WAAW;AACb,WAAK,gBAAgB,OAAO;AAAA,IAC9B,OAAO;AACL,WAAK,gBAAgB,MAAM;AAAA,IAC7B;AACA,SAAK,iBAAiB;AAGtB,eAAW,MAAM,QAAQ;AACvB,UAAI;AAEF,cAAM,GAAG,GAAG;AAAA,MAEd,SAAS,GAAG;AAAA,MAEZ;AAAA,IACF;AAAA,EACF;AACF;;;ACvaA,qBAAiB;;;ACLjB,IAAAC,gBAAuB;AACvB,IAAAF,kBAAiB;AAIV,SAAS,mBAAmB,SAAyB;AAC1D,SAAO,QAAQ,QAAQ,kBAAkB,CAAC,GAAG,WAAW;AACtD,UAAM,QAAQ,QAAQ,IAAI,OAAO,KAAK,CAAC;AACvC,QAAI,UAAU,QAAW;AACvB,YAAM,IAAI,MAAM,yBAAyB,OAAO,KAAK,CAAC,kBAAkB;AAAA,IAC1E;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAEO,SAAS,gBACd,SACA,UACA,sBACoB;AACpB,MAAI,mBAAmB;AACvB,MAAI,QAAQ,QAAQ,SAAS,MAAM,MAAM,QAAQ,MAAM,mBAAmB,GAAG;AAC3E,QAAI;AACJ,uBAAmB,QAAQ;AAAA,MACzB;AAAA,MACA,CAAC,OAAO,aAAa;AACnB,0BAAkB;AAClB,eAAO,cAAc,QAAQ;AAAA,MAC/B;AAAA,IACF;AACA,YAAQ;AAAA,MACN,4EAA4E,eAAe;AAAA,IAC7F;AAAA,EACF;AACA,QAAM,sBAAsB,mBAAmB,gBAAgB;AAC/D,QAAM,MAAM,gBAAAG,QAAK,KAAK,qBAAqB;AAAA,IACzC,QAAQ,gBAAAA,QAAK;AAAA,EACf,CAAC;AAED,QAAM,UAAU,WAAW,oBAAoB,QAAQ,KAAK;AAC5D,QAAM,UACJ,OAAO,IAAI,YAAY,cACnB,OAAO,OAAO,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,IACnC;AACN,QAAM,YAAY,IAAI,OAAO,IAAI;AACjC,QAAM,MACJ,OAAO,cAAc,cACjB,OAAO,OAAO,CAAC,GAAG,aAAa,CAAC,CAAC,IACjC;AAEN,MAAI,CAAC,sBAAsB;AAEzB;AAAA,MACE,OAAO;AAAA,MACP,sFAAsF,OAAO;AAAA,IAC/F;AAGA;AAAA,MACG,OAAO,CAAC,WAAa,CAAC,OAAO;AAAA,MAC9B,iFAAiF,OAAO;AAAA,IAC1F;AAGA,QAAI,OAAO,SAAS;AAClB;AAAA,QACE,OAAO,QAAQ,YAAY,OAAO,YAAY;AAAA,QAC9C,kDAAkD,OAAO;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AAEA,4BAAO,IAAI,OAAO,+CAA+C,OAAO,EAAE;AAC1E;AAAA,IACE,MAAM,QAAQ,IAAI,KAAK;AAAA,IACvB,6DAA6D,IAAI,KAAK;AAAA,EACxE;AACA,SAAO;AACT;;;AHhDA,IAAAD,iBAKO;AACP,IAAAE,oBAGO;AACP,IAAAC,cAAmD;AACnD,IAAAC,iBAAyB;AACzB,IAAAJ,iBAAuB;;;AIxCvB,kBAuCO;AACP,IAAAK,mBAKO;AACP,IAAAL,gBAAsB;AACtB,uBAAyB;AACzB,IAAAG,cAGO;AAEP,IAAAC,iBAAyB;AACzB,IAAAJ,gBAAuB;;;AC5ChB,SAAS,QAAQ,MAAqB;AAC3C,SAAO,KAAK,WAAW,KAAK,YAAY,SACpC,GAAG,KAAK,IAAI,MAAM,KAAK,WAAW,EAAE,KACpC,KAAK;AACX;AAEO,SAAS,eACd,OAC0C;AAE1C,QAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAIlD,SAAO,KAAK,OAAO,CAAC,KAA+C,MAAM;AACvE,UAAM,cAAc,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,SAAS;AACpE,QAAI,gBAAgB,MAAM,OAAO,MAAM,MAAM;AAC3C,aAAO,IAAI,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,YAAY,CAAC,CAAC;AAAA,IACtD;AACA,QAAI,gBAAgB,MAAM,OAAO,MAAM,MAAM;AAC3C,aAAO,IAAI,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,OAAO,CAAC,CAAC;AAAA,IACjD;AACA,QAAI,gBAAgB,MAAM,OAAO,MAAM,MAAM;AAC3C,aAAO,IAAI,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,QAAQ,CAAC,CAAC;AAAA,IAClD;AACA,WAAO,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAAA,EAChC,GAAG,CAAC,CAAC;AACP;AAEO,SAAS,eAAe,QAA8B;AAC3D,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,OAAO,WAAW,WAC5B,OAAO,SACP,OAAO,OAAO;AACpB;AAEO,SAAS,eAAe,aAAyC;AACtE,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AACA,SAAO,GAAG,YAAY,aAAa,MAAM,KAAK,YAAY,cAAc,MAAM,KAAK,YAAY,YAAY,kBAAkB;AAC/H;AAEO,SAAS,aAAa,WAA4C;AACvE,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AACA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,cAAc,UAAU,aAAa,MAAM,EAAE;AACxD,MAAI,UAAU,YAAY;AACxB,UAAM,KAAK,WAAW,UAAU,WAAW,CAAC,KAAK,UAAU,WAAW,CAAC,GAAG;AAAA,EAC5E;AACA,MAAI,UAAU,UAAU;AACtB,UAAM,KAAK,aAAa,UAAU,QAAQ,EAAE;AAAA,EAC9C;AACA,MAAI,UAAU,UAAU;AACtB,UAAM,KAAK,aAAa,UAAU,QAAQ,IAAI;AAAA,EAChD;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,aACd,MAeA,QACA;AACA,MAAI,QAAQ;AACV,WAAO,GAAG,IAAI,MAAM,MAAM;AAAA,EAC5B;AACA,SAAO;AACT;AAEO,SAAS,SAAS,MAAqB;AAC5C,MAAI;AACJ,MAAI,KAAK,SAAS,YAAY;AAC5B,YAAS,MAAgC,OAAO;AAAA,EAClD;AAEA,MAAI,KAAK,SAAS,WAAW;AAC3B,YACG,MAAqC,OAAO,UAC5C,MAAqC,OAAO,MAC5C,MAAoC,OAAO,cAC3C,MAAwC,OAAO;AAAA,EACpD;AAEA,MAAI,KAAK,SAAS,UAAU;AAC1B,UAAM,SAAU,MAA8B;AAC9C,UAAM,YAAY,SAAS,eAAe,MAAM,IAAI;AAEpD,YAAQ,KAAK,WAAW;AACxB,QAAI,OAAQ,MAA8B,OAAO,WAAW,UAAU;AACpE,cAAQ,GAAI,MAA8B,OAAO,MAAM;AAAA,IACzD,WACE,OAAQ,MAA8B,OAAO,eAAe,UAC5D;AACA,cAAQ,eAAgB,MAA8B,KAAK;AAAA,IAC7D,WACE,OAAQ,MAA8B,OAAO,cAAc,YAC1D,MAA8B,YAAY,eAC3C;AACA,cAAQ,aAAc,MAA8B,KAAK;AAAA,IAC3D,WACE,OAAQ,MAA8B,OAAO,UAAU,aACvD;AACA,cAAS,MAA8B,OAAO;AAAA,IAChD;AAEA,QAAI,WAAW;AACb,UAAI,OAAO;AACT,gBAAQ,GAAG,SAAS,MAAM,KAAK;AAAA,MACjC,OAAO;AACL,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,UAAU;AAAa,WAAO;AACzC,SAAO,OAAO,UAAU,WACpB,QACA,KAAK,UAAU,OAAO,QAAW,CAAC;AACxC;;;AC7IA,sBAAiD;AACjD,IAAAA,gBAAuC;AACvC,IAAAG,cAAsD;AAEtD,uBAIO;AACP,iBAAgC;AAChC,IAAAC,iBAA6C;AAC7C,IAAAJ,gBAAqC;AACrC,mBAAkB;;;ACdX,IAAM,iBAAN,MAA4C;AAAA,EAoBjD,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAWG;AACD,SAAK,UAAU;AACf,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,MACZ,KAAK,MAAM,KAAK,OAAO,KAAK,QAAQ,CAAC;AAAA,MACrC,KAAK,MAAM,KAAK,MAAM,KAAK,SAAS,CAAC;AAAA,IACvC;AACA,SAAK,KAAK;AACV,SAAK,aAAa;AAClB,SAAK,UAAU;AACf,SAAK,SAAS;AACd,SAAK,YAAY;AAAA,EACnB;AACF;;;AC9DA,yBAAmB;AACnB,IAAAM,kBAAmE;AACnE,IAAAC,oBAA8B;AAC9B,uBAAkC;AAElC,IAAAC,iBAAqC;AACrC,iBAGO;AACP,oBAAyB;AACzB,IAAAR,gBAAwC;AACxC,IAAAA,gBAA+B;AAC/B,IAAAF,kBAAiB;AACjB,oBAAmB;;;ACJjB,cAAW;;;ADQb,IAAM,oCAAoC;AAEnC,IAAM,YAAQ,wBAAS,OAAO;AAyBrC,IAAM,iCAAiC;AAChC,IAAM,eAAe;AAErB,IAAM,YAAN,MAAgB;AAAA;AAAA,EAYrB,YACE,SACA,mBACA,eACA;AANF,SAAQ,sBAAmC,oBAAI,IAAI;AAOjD,2BAAAW,SAAO,SAAS,qBAAqB;AACrC,QAAI,cAAc,gCAAgC,OAAO;AACzD,UAAM,6BACJ,gCAAoB,6CAAkC,KACtD;AACF,QAAI,OAAO,WAAW,aAAa,MAAM,IAAI,wBAAwB;AACnE,YAAM,SAAS,YAAY,MAAM,GAAG,EAAE;AACtC,YAAM,WAAO,8BAAe,QAAW,WAAW;AAClD,oBAAc,GAAG,MAAM,IAAI,IAAI;AAAA,IACjC;AACA,SAAK,UAAU;AAEf,SAAK,gBACH,6BAAe,2BACX,SACA,qBACA,4BAAK,qCAAqB,OAAO,GAAG,GAAG,KAAK,OAAO,GAAG,YAAY,EAAE;AAC1E,SAAK,oBAAoB;AAEzB,QAAI;AACJ,QAAI,KAAK,eAAe;AACtB,qBAAe,KAAK,kBAAkB;AAAA,IACxC;AACA,QAAI,CAAC,cAAc;AACjB,qBAAe;AAAA,QACb,iBAAiB;AAAA,QACjB,SAAS,KAAK;AAAA,QACd,QAAQ,CAAC;AAAA,MACX;AAAA,IACF;AACA,SAAK,QAAQ;AACb,SAAK,sBAAsB,KAAK,MAAM,OAAO;AAAA,EAC/C;AAAA,EAEA,WACE,QACA,MAC2D;AAE3D,aAAS,IAAI,GAAG,IAAI,KAAK,qBAAqB,KAAK;AACjD,YAAM,OAAO,KAAK,MAAM,OAAO,CAAC;AAChC,YAAM,YACJ,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,MAAM;AAC7D,YAAM,MAAM,GAAG,IAAI,IAAI,SAAS,IAAI,CAAC;AACrC,UACE,KAAK,SAAS,YACd,oCAAkB,KAAK,QAAQ,MAAM,KACrC,CAAC,KAAK,oBAAoB,IAAI,GAAG,GACjC;AACA,aAAK,oBAAoB,IAAI,GAAG;AAChC;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,eAAO;AAAA,UACL,cAAc;AAAA,UACd,UAAU,CAAC,OAAqD;AAC9D;AAAA,cACE;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AACA,eAAG,IAAI;AACP;AAAA,cACE;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AACA,iBAAK,iBAAiB;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,+CAA+C,MAAM,MAAM;AACjE,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,QAA6D;AAC1E,WAAO,KAAK,WAAW,QAAQ,MAAM;AAAA,EAGvC;AAAA,EAEA,iBACE,QAC2C;AAC3C,WAAO,KAAK,WAAW,QAAQ,QAAQ;AAAA,EAGzC;AAAA,EAEA,YAAY,OAAoC;AAC9C,UAAM,qBAAqB,KAAK;AAChC,SAAK,MAAM,OAAO,KAAK,KAAK;AAC5B,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,oBAAoB;AAClB,UAAM,YAAY,KAAK;AACvB,2BAAAA,SAAO,WAAW,6BAA6B;AAE/C,QAAI,KAAC,4BAAW,SAAS,GAAG;AAC1B,YAAM,iCAAiC,SAAS;AAChD,aAAO;AAAA,IACT;AAGA,UAAM,oBAAoB,UAAU,QAAQ,cAAc,OAAO;AACjE,YAAI,4BAAW,iBAAiB,KAAK,KAAK,mBAAmB;AAC3D,cAAQ;AAAA,QACN,8LAA8L,iBAAiB;AAAA,MACjN;AACA,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,WAAO,8BAAa,WAAW,MAAM;AAC3C,YAAM,WAAW,gBAAAR,QAAK,KAAK,IAAI;AAE/B,UAAI,CAAC,SAAS;AACZ,cAAM,yDAAyD;AAC/D,eAAO;AAAA,MACT;AAEA,UACE,cAAAS,QAAO,GAAG,SAAS,iBAAiB,8BAA8B,KAClE,CAAC,SAAS,gBAAgB,SAAS,MAAM,GACzC;AACA,gBAAQ;AAAA,UACN;AAAA;AAAA,cAA2S,SAAS;AAAA,QACtT;AACA,eAAO;AAAA,MACT;AAEA;AAAA,QACE;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT,SAAS,OAAO;AAAA,MAClB;AACA,eAAS,kBAAkB;AAC3B,aAAO;AAAA,IACT,SAAS,KAAK;AACZ;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,mBAAmB;AACjB,QAAI,CAAC,SAAS;AACZ,YAAM,wDAAwD;AAC9D;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,eAAe;AACvB,YAAM,kDAAkD;AACxD;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAM,2BAAQ,KAAK,aAAa;AACtC,UAAI,KAAC,4BAAW,GAAG,GAAG;AACpB,uCAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAClC,cAAM,+BAA+B,GAAG;AAAA,MAC1C;AAGA,YAAM,eAAe,CAAC,GAAG,KAAK,MAAM,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM;AACzD,YAAI,EAAE,SAAS,UAAU,EAAE,SAAS;AAAU,iBAAO;AACrD,YAAI,EAAE,SAAS,YAAY,EAAE,SAAS;AAAQ,iBAAO;AACrD,eAAO;AAAA,MACT,CAAC;AAED,YAAM,eAAe;AAAA,QACnB,GAAG,KAAK;AAAA,QACR,QAAQ;AAAA,MACV;AAEA,YAAM,WAAW,gBAAAT,QAAK,KAAK,YAAY;AACvC,yCAAc,KAAK,eAAe,QAAQ;AAC1C,YAAM,6BAA6B,KAAK,aAAa;AAAA,IACvD,SAAS,KAAK;AACZ;AAAA,QACE;AAAA,QACA,KAAK;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,0BACE,WACA,cACA;AACA,QAAI,cAAc;AAEhB,UAAI,UAAU,SAAS,QAAQ;AAC7B,qBAAa,SAAS,CAAC,UAAU;AAC/B,UAAC,MAAwB,eAAe,UAAU;AAAA,QACpD,CAAC;AAAA,MACH,OAAO;AACL,qBAAa,SAAS,CAAC,UAAU;AAC/B,UAAC,MAAsB,SAAS,UAAU;AAAA,QAC5C,CAAC;AAAA,MACH;AAAA,IACF,OAAO;AACL,WAAK,YAAY,SAAS;AAAA,IAC5B;AAAA,EACF;AACF;;;AF1PA,IAAMU,aAAQ,yBAAS,cAAc;AAErC,eAAsB,wBACpB,MACA,MACuB;AACvB,4BAAO,MAAM,kBAAkB;AAC/B,MAAK,KAAoB,sBAAsB;AAC7C,WAAO,MAAO,KAAa,qBAAqB;AAAA,EAClD;AAEA,EAAAA,OAAM,kBAAkB;AACxB,QAAM,MAAM,MAAM,KAAK,IAAI;AAC3B,EAAAA,OAAM,SAAS;AAEf,EAAAA,OAAM,+BAA+B;AACrC,4CAAuB,EAAE,SAAS,IAAI,CAAC;AACvC,EAAAA,OAAM,4BAA4B;AAElC,MAAI;AACJ,MAAI;AAEJ,EAAAA,OAAM,2DAA2D;AACjE,QAAM,QAAQ,IAAI;AAAA,IAChB,KAAK,iBAAiB,EAAE,KAAK,CAAC,WAAW;AACvC,yBAAmB;AACnB,MAAAA,OAAM,sBAAsB;AAAA,IAC9B,CAAC;AAAA,IACD,KAAK,oBAAoB,EAAE,KAAK,OAAO,aAAa;AAClD,aAAO;AACP,MAAAA,OAAM,yBAAyB;AAAA,IACjC,CAAC;AAAA,EACH,CAAC;AACD,EAAAA,OAAM,6BAA6B;AACnC,EAAAA,OAAM,yBAAyB;AAC/B,QAAM,cAAU,+BAAa,MAAO,CAAC,gBAAgB;AACnD,UAAM,EAAE,MAAM,IAAI,SAAS,YAAY,SAAS,UAAU,IAAI;AAC9D,WAAO,IAAI,eAAe;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACD,EAAAA,OAAM,kBAAkB;AACxB,4BAAO,kBAAmB,8BAA8B;AAExD,QAAM,OAAO,MAAM,KAAK,KAAK;AAE7B,EAAAA,OAAM,SAAS,KAAK,KAAK,IAAI,KAAK,MAAM,SAAS,KAAK,GAAG,EAAE;AAE3D,MAAI,KAAK,OAAO,KAAK,MAAM,GAAG;AAC5B,IAAAA,OAAM,0CAA0C;AAChD,uBAAmB,UAAM,4BAAgB,kBAAkB;AAAA,MACzD,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,IACf,CAAC;AACD,IAAAA,OAAM,qBAAqB;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,kBAAkB,MAAM,OAAO;AAC7C,QAAM,oBAAgB,yBAAY,oCAAwB;AAC1D,QAAM,yBAAqB,aAAAC,SAAM,EAAE,OAAO,qBAAqB;AAE/D,QAAM,eAAW,oBAAK,EAAE,UAAU,GAAG,CAAC;AACtC,SAAO,GAAG,iBAAiB,GAAG,IAAI,kBAAkB,IAAI,QAAQ;AAClE;AAEO,SAAS,eAAe,UAAkB;AAC/C,4BAAO,mCAAmC,QAAQ,EAAE;AACtD;AA0DO,SAAS,gCAAgC,KAAa;AAE3D,SAAO,IAAI,QAAQ,eAAe,GAAG;AACvC;AAEO,SAAS,gBACd,MACAD,QACA;AACA,OAAK,GAAG,SAAS,OAAO,UAAU;AAChC,QAAI,CAAC,OAAO;AACV,cAAQ,KAAK,yDAAyD;AACtE;AAAA,IACF;AACA,UAAM,MAAM,MAAO,MAAwB,IAAI;AAC/C,YAAQ,IAAI,iBAAiB,GAAG,EAAE;AAClC,QAAI,CAAE,MAAwB,SAAS,GAAG;AACxC,UAAI;AACF,cAAO,MAAwB,MAAM;AAAA,MACvC,SAAS,OAAO;AACd,QAAAA,OAAM,yBAAyB,GAAG,YAAY,KAAK,EAAE;AAAA,MACvD;AAAA,IACF,OAAO;AACL,MAAAA,OAAM,uCAAuC,GAAG,EAAE;AAAA,IACpD;AAEA,QAAI,CAAC,KAAK,SAAS,GAAG;AACpB,UAAI;AACF,cAAM,KAAK,KAAK,GAAG;AAAA,MACrB,SAAS,OAAO;AACd,QAAAA,OAAM,kBAAkB,GAAG,YAAY,KAAK,EAAE;AAAA,MAChD;AAAA,IACF,OAAO;AACL,MAAAA,OAAM,qCAAqC,GAAG,EAAE;AAAA,IAClD;AAAA,EACF,CAAC;AACH;AAEO,SAAS,qBACd,iBACA,MACA;AACA,MAAI,CAAC,iBAAiB;AACpB,WAAO;AAAA,EACT;AACA,MAAI,gBAAgB,IAAI;AACtB,eAAO,uCAAqB,gBAAgB,EAAE;AAAA,EAChD;AAEA,MAAI,gBAAgB,MAAM;AACxB,UAAM,iBAAiB;AAAA,MACrB,GAAG,KAAK,OAAO,gBAAgB,KAAK,CAAC,IAAI,gBAAgB,KAAK,CAAC,KAAK,CAAC;AAAA,MACrE,GAAG,KAAK,OAAO,gBAAgB,KAAK,CAAC,IAAI,gBAAgB,KAAK,CAAC,KAAK,CAAC;AAAA,IACvE;AACA,QAAI,cAAU,kDAAiC,MAAM,cAAc;AAEnE,QAAI,CAAC,SAAS;AACZ,oBAAU,4CAA0B,cAAc;AAAA,IACpD;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAsB,sBACpB,cACA,QACA,aACA,WACA;AACA,MAAI;AACF,QACE,QAAQ,UACR,aAAa,WAAW,qBACxB,cAAc,OACd;AAEA,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,cAAM,UAAU,MAAM,aAAa,KAAK;AAAA,UACtC,OAAO,CAAC;AAAA,QACV;AAEA,YAAI,SAAS,IAAI;AACf,gBAAW,yBAAyB,WAAW;AAC/C;AAAA,YACE;AAAA,YACA,OAAO,CAAC;AAAA,YACR,SAAS;AAAA,UACX;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAW,qCAAqC,KAAK;AAAA,EACvD;AACF;AAEO,SAAS,sBAAsB,WAA0B;AAC9D,WAAS,kBACP,MACqC;AACrC,QAAI,CAAC;AAAM,aAAO;AAGlB,UAAM,mBAAmB,MAAM,QAAQ,KAAK,QAAQ,IAC/C,KAAK,SACH,IAAI,iBAAiB,EACrB,OAAO,CAAC,UAAU,UAAU,IAAI,IACnC,CAAC;AAGL,QAAI,KAAK,QAAQ,KAAK,KAAK,cAAc,MAAM;AAC7C,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,MACZ;AAAA,IACF;AAGA,QAAI,iBAAiB,SAAS,GAAG;AAC/B,aAAO;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,IACF;AAGA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO,MAAM,QAAQ,UAAU,KAAK,IAChC,UAAU,MAAM,IAAI,CAAC,SAAwB;AAC3C,YAAM,UAAU,EAAE,GAAG,KAAK;AAC1B,UAAI,KAAK,aAAa,MAAM;AAC1B,gBAAQ,cAAc;AAAA,UACpB,GAAG,KAAK;AAAA,UACR,MAAM,kBAAkB,KAAK,YAAY,IAAI,KAAK;AAAA,YAChD,MAAM;AAAA,YACN,UAAU,CAAC;AAAA,UACb;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT,CAAC,IACD,UAAU;AAAA,EAChB;AACF;AAEO,IAAM,cAAc,CACzB,WAIG;AACH,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,kBAAkB;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AAAA,IACL,YAAY,OAAO;AAAA,IACnB,kBAAkB,OAAO,SACrB;AAAA,MACE,QAAQ,OAAO;AAAA,MACf,yBAAyB,CAAC,CAAC,OAAO;AAAA,IACpC,IACA;AAAA,EACN;AACF;;;AFhRA,IAAMA,aAAQ,yBAAS,oBAAoB;AAC3C,IAAM,8BAA8B;AAEpC,IAAM,gBAAgB,CAAC,SAA6C;AAClE,SAAO,KAAK,aAAa;AAC3B;AAEO,IAAM,mBAAN,MAAuB;AAAA,EAW5B,YACE,MACA,SACA,MAIA;AAXF,+BAAoD,CAAC;AAYnD,SAAK,OAAO;AACZ,SAAK,UAAU;AAEf,SAAK,YAAY,KAAK;AAEtB,SAAK,sBAAsB,MAAM;AAAA,EACnC;AAAA,EAEA,MAAc,iBAAiB,QAAyC;AACtE,UAAM,SAAS,MAAM,KAAK,KAAK,iBAAiB;AAChD,UAAM,OAA8B;AAAA,MAClC,MAAM;AAAA,MACN,IAAI,KAAK,IAAI;AAAA,MACb,YAAY;AAAA,MACZ;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,gBACZ,aACA,SAC+B;AAC/B,QAAI,YAAY,SAAS;AACzB,QAAI,SAAS,qBAAqB,QAAW;AAC3C,YAAM,SAAS,MAAM,KAAK,KAAK;AAAA,QAC7B;AAAA,UACE,MAAM,QAAQ,OAAO,CAAC;AAAA,UACtB,KAAK,QAAQ,OAAO,CAAC;AAAA,QACvB;AAAA,QACA,SAAS;AAAA,MACX;AAEA,aAAO;AAAA,IACT;AAGA,QAAI,SAAS,YAAY,aAAa,0BAAS,UAAU;AACvD,YAAM,KAAK,QAAQ,mBAAmB,QAAQ;AAC9C,YAAM,WAAO;AAAA,QACX,YAAY;AAAA,QACZ;AAAA,UACE,GAAG,QAAQ,OAAO,CAAC;AAAA,UACnB,GAAG,QAAQ,OAAO,CAAC;AAAA,QACrB;AAAA,QACA;AAAA,UACE,uBAAuB;AAAA,UACvB,wBAAwB;AAAA,QAC1B;AAAA,MACF;AACA,UAAI,MAAM,IAAI;AACZ,oBAAY,KAAK;AAAA,MACnB,OAAO;AACL,QAAAA;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AACA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,KAAK,cAAc,SAAS;AACtD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,OAAM,yBAAyB,KAAK;AAAA,IACtC;AAAA,EACF;AAAA,EAEQ,8BACN,WACA,uBAAuB,OACH;AACpB,UAAM,qBAAyC;AAAA,MAC7C,GAAG;AAAA,MACH,UAAU,OAAO,OAAO,YAAY,SAAS;AAC3C,cAAM,WAAoC,CAAC;AAC3C,cAAM,EAAE,KAAK,IAAI;AAEjB,aAAK,WAAW;AAChB,cAAM,OAAO,MAAM,KAAK,iBAAiB,UAAU,KAAK,IAAI,EAAE;AAC9D,iBAAS,KAAK,IAAI;AAClB,cAAM,SAAS,MAAM,UAAU,SAAS,OAAO,SAAS,GAAG,IAAI;AAC/D,YAAI,UAAU,SAAS,UAAU;AAC/B,gBAAM,QAAQ,IAAI;AAAA,aACf,YAAY;AACX,wBAAM,qBAAM,GAAG;AACf,kBAAK,KAAK,KAA0B,sBAAsB;AACxD,oBAAI;AACF,wBAAO,KAAK,KAA0B,qBAAqB;AAAA,gBAC7D,SAAS,OAAO;AAAA,gBAEhB;AAAA,cACF;AAAA,YACF,GAAG;AAAA,gBACH,qBAAM,GAAG;AAAA,UACX,CAAC;AAAA,QACH;AACA,YAAI,sBAAsB;AACxB,gBAAM,QAAQ,MAAM,KAAK,iBAAiB,cAAc;AACxD,mBAAS,KAAK,KAAK;AAAA,QACrB;AACA,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAa,wBACX,OACA,MAGA;AACA,UAAM,QAA8B,CAAC;AACrC,UAAM,QAAQ,CAACE,UAAS;AACtB,UAAIA,MAAK,SAAS,UAAU;AAC1B,YACEA,MAAK,WAAW,QAChBA,MAAK,QAAQ,OAAO,QACpBA,MAAK,QAAQ,OAAO,QACpB;AAEA;AAAA,QACF;AACA,cAAM,WAA4C;AAAA,UAChD,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAOA,MAAK,SACR;AAAA,YACE,GAAGA,MAAK;AAAA,YACR,WAAW,MAAM;AAAA,UACnB,IACA;AAAA,UACJ,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,OAAO,gBAAgB;AACtC,kBAAM,EAAE,KAAK,IAAI;AACjB;AAAA,cACE,OAAO,UAAU,OAAO,MAAM,OAAO;AAAA,cACrC;AAAA,YACF;AACA,gBAAI;AACJ,gBAAI;AACJ,kBAAM,gBAAgC,CAAC,SAAS;AAC9C,4BAAc;AACd,sBAAQ,MAAM,UAAU;AAExB,mBAAK,MAAM;AAAA,gBACT,MAAM;AAAA,cACR;AAEA,mBAAK,QAAQ;AAAA,YACf;AACA,iBAAK,QAAQ,oBAAoB;AACjC,kBAAM,WAAW,KAAK,IAAI;AAG1B,kBAAM,cAAc,MAAM,KAAK,QAAQ,mBAAmB,QAAQ;AAClE,iBAAK,cAAc;AAEnB,kBAAM,aAAoC;AAAA,cACxC,MAAM;AAAA,cACN,IAAI;AAAA,cACJ,YAAY,YAAY;AAAA,cACxB,QAAQ;AAAA,YACV;AACA,iBAAK,WAAW,CAAC,UAAU;AAG3B,kBAAM,mBAAmB,MAAM,QAC3B,MAAM,KAAK,KAAK,sBAAsB,MAAM,KAAK,IACjD;AACJ,kBAAM,0BAA0B,CAAC,CAAC;AAGlC,kBAAM,cAAc,MAAM;AAC1B,kBAAM,oBACJ,KAAK,WAAW,iBAAiB,WAAW;AAC9C,kBAAM,SAAS,mBAAmB,cAAc;AAChD,kBAAM,mBAAmB,0BACrB,OACA,MAAM;AAAA,cACJ;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM;AAAA,YACR;AACJ,kBAAM,eAAe,CAAC,CAAC;AAGvB,kBAAM,kBACJ,CAAC,2BAA2B,CAAC,eACzB,qBAAqB,OAAO,YAAY,IAAI,IAC5C;AACN,kBAAM,cAAc,CAAC,CAAC;AAGtB,kBAAM,sBACJ,CAAC,2BAA2B,CAAC,gBAAgB,CAAC,eAExC,MAAM,KAAK,QAAQ,OAAO,OAAO;AAAA;AAAA,cAE/B,SAAS;AAAA,YACX,CAAC,GACD,UACF;AACN,kBAAM,kBAAkB,CAAC,CAAC;AAE1B,kBAAM,UACJ;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAGF,gBAAI;AACJ,gBACE,WACA,KAAK,aACL,CAAC,gBACD,OAAO,cAAc,OACrB;AACA,oBAAM,gBAAgB,MAAM,KAAK;AAAA,gBAC/B;AAAA,gBACA;AAAA,cACF;AACA,kBAAI,eAAe,QAAQ;AACzB,gCAAgB;AAChB,qBAAK,UAAU;AAAA,kBACb;AAAA,oBACE,MAAM;AAAA,oBACN,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACV;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,OAAO;AACL,gBAAAF;AAAA,kBACE;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AACA,gBAAI,CAAC,SAAS;AACZ,oBAAM,IAAI,MAAM,sBAAsB,MAAM,MAAM,EAAE;AAAA,YACtD;AAEA,gBAAI;AAEJ,gBAAI,yBAAyB;AAC3B,sBAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,SAAS;AAAA,kBACP,OAAO,MAAM;AAAA,gBACf;AAAA,cACF;AAAA,YACF,WAAW,cAAc;AACvB,sBAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,SAAS;AAAA,kBACP,iBAAiB;AAAA,kBACjB,cAAc;AAAA,gBAChB;AAAA,cACF;AAAA,YACF,WAAW,aAAa;AACtB,sBAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,SAAS;AAAA,kBACP,IAAI,iBAAiB;AAAA,kBACrB,MAAM,iBAAiB;AAAA,gBACzB;AAAA,cACF;AAAA,YACF,WAAW,iBAAiB;AAC1B,sBAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,SAAS;AAAA,kBACP,QAAQ,MAAM;AAAA,gBAChB;AAAA,cACF;AAAA,YACF;AAEA,mBAAO;AAAA,cACL,QAAQ;AAAA,gBACN;AAAA,cACF;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,cAAM,KAAK,QAAQ;AAAA,MACrB,WAAWE,MAAK,SAAS,YAAYA,MAAK,SAAS,sBAAsB;AACvE,cAAM,aAAaA;AACnB,cAAM,aAAiC;AAAA,UACrC,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAO,WAAW;AAAA,UAClB,SAAS,WAAW;AAAA,UACpB,QAAQ,WAAW;AAAA,UACnB,UAAU,OAAO,OAAO,gBAAgB;AACtC,kBAAM,EAAE,KAAK,IAAI;AACjB,gBAAI;AACJ,kBAAM,gBAAgC,CAAC,SAAS;AAC9C,4BAAc;AAAA,YAChB;AACA,iBAAK,QAAQ,oBAAoB;AACjC,kBAAM,WAAW,KAAK,IAAI;AAC1B,kBAAM,cAAc,MAAM,KAAK,QAAQ,mBAAmB,QAAQ;AAClE,iBAAK,cAAc;AAEnB,kBAAM,aAAoC;AAAA,cACxC,MAAM;AAAA,cACN,IAAI;AAAA,cACJ,YAAY,YAAY;AAAA,cACxB,QAAQ;AAAA,YACV;AACA,iBAAK,WAAW,CAAC,UAAU;AAE3B,kBAAM,YAAY,MAAM,KAAK,QAAQ;AAAA,cACnC,WAAW,MAAM;AAAA,YACnB;AAEA,gBAAI,CAAC,UAAU,MAAM;AACnB,kBAAIA,MAAK,SAAS,UAAU;AAC1B,qBAAK,SAAS;AACd,qBAAK,MAAM;AAAA,kBACT,MAAM;AAAA,gBACR;AACA,sBAAM,IAAI;AAAA,kBACR,UAAU,WAAW;AAAA,gBACvB;AAAA,cACF;AAEA,mBAAK,QAAQ,IAAI,MAAM,UAAU,OAAO;AAAA,YAC1C;AAEA,mBAAO;AAAA,cACL,QAAQ;AAAA,cACR;AAAA,cACA,KAAK;AAAA,gBACH,MAAM;AAAA,cACR;AAAA,cACA,OAAO,UAAU;AAAA,YACnB;AAAA,UACF;AAAA,QACF;AACA,cAAM,KAAK,UAAU;AAAA,MACvB,WAAWA,MAAK,SAAS,SAAS;AAChC,cAAM,kBACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAOA,MAAK;AAAA,UACZ,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,WAAW,EAAE,QAAQ,MAAM;AAC1C,gBAAI,SAAS;AACX,oBAAM,KAAK,KAAK,WAAW,OAAiC;AAE5D,kBAAI,CAAC,aAAa,CAAC,UAAU,OAAO;AAClC;AAAA,cACF;AAAA,YACF;AAEA,kBAAM,KAAK,KAAK,SAAS,KAAK,UAAU,OAAO;AAAA,cAC7C,qBAAqB,UAAU;AAAA,YACjC,CAAC;AAAA,UACH;AAAA,QACF;AACF,cAAM,KAAK,eAAe;AAAA,MAC5B,WAAWA,MAAK,SAAS,iBAAiB;AACxC,cAAM,0BACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAOA,MAAK;AAAA,UACZ,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,cAAc;AAC7B,kBAAM,OAAO,eAAe,UAAU,KAAK;AAE3C,kBAAM,KAAK,KAAK,SAAS,MAAM,IAAI;AAAA,UACrC;AAAA,QACF;AACF,cAAM,KAAK,uBAAuB;AAAA,MACpC,WAAWA,MAAK,SAAS,OAAO;AAC9B,cAAM,gBACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,OAAO,EAAE,QAAQ,MAAM;AACtC,sCAAO,SAAS,+BAA+B;AAC/C,kBAAM,KAAK,KAAK,MAAM,MAAM,QAAQ,OAAO,CAAC,GAAG,QAAQ,OAAO,CAAC,CAAC;AAAA,UAClE;AAAA,QACF;AACF,cAAM,KAAK,aAAa;AAAA,MAC1B,WAAWA,MAAK,SAAS,cAAc;AACrC,cAAM,uBACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,OAAO,EAAE,QAAQ,MAAM;AACtC,sCAAO,SAAS,uCAAuC;AACvD,kBAAM,KAAK,KAAK,MAAM;AAAA,cACpB,QAAQ,OAAO,CAAC;AAAA,cAChB,QAAQ,OAAO,CAAC;AAAA,cAChB,EAAE,QAAQ,QAAQ;AAAA,YACpB;AAAA,UACF;AAAA,QACF;AACF,cAAM,KAAK,oBAAoB;AAAA,MACjC,WAAWA,MAAK,SAAS,QAAQ;AAC/B,cAAM,iBAGD;AAAA,UACH,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAOA,MAAK;AAAA,UACZ,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,cAAc;AAC7B;AAAA,cACE,WAAW,aAAa,WAAW;AAAA,cACnC;AAAA,YACF;AACA,kBAAM,KAAK,KAAK,MAAM,KAAK,UAAU,WAAW,UAAU,OAAO;AAAA,UACnE;AAAA,QACF;AACA,cAAM,KAAK,cAAc;AAAA,MAC3B,WAAWA,MAAK,SAAS,SAAS;AAChC,cAAM,kBACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,OAAO,EAAE,QAAQ,MAAM;AACtC,sCAAO,SAAS,iCAAiC;AACjD,kBAAM,KAAK,KAAK,MAAM,KAAK,QAAQ,OAAO,CAAC,GAAG,QAAQ,OAAO,CAAC,CAAC;AAAA,UACjE;AAAA,QACF;AACF,cAAM,KAAK,eAAe;AAAA,MAC5B,WAAWA,MAAK,SAAS,UAAU;AACjC,cAAM,mBACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAOA,MAAK;AAAA,UACZ,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,WAAW,EAAE,QAAQ,MAAM;AAC1C,kBAAM,gBAAgB,UAClB;AAAA,cACE,MAAM,QAAQ,OAAO,CAAC;AAAA,cACtB,KAAK,QAAQ,OAAO,CAAC;AAAA,YACvB,IACA;AACJ,kBAAM,oBAAoB,WAAW;AACrC,gBAAI,sBAAsB,YAAY;AACpC,oBAAM,KAAK,KAAK,eAAe,aAAa;AAAA,YAC9C,WAAW,sBAAsB,eAAe;AAC9C,oBAAM,KAAK,KAAK,kBAAkB,aAAa;AAAA,YACjD,WAAW,sBAAsB,cAAc;AAC7C,oBAAM,KAAK,KAAK,iBAAiB,aAAa;AAAA,YAChD,WAAW,sBAAsB,aAAa;AAC5C,oBAAM,KAAK,KAAK,gBAAgB,aAAa;AAAA,YAC/C,WAAW,sBAAsB,UAAU,CAAC,mBAAmB;AAC7D,kBACE,WAAW,cAAc,UACzB,CAAC,aACD,CAAC,UAAU,WACX;AACA,sBAAM,KAAK,KAAK;AAAA,kBACd,WAAW,YAAY;AAAA,kBACvB;AAAA,gBACF;AAAA,cACF,WAAW,UAAU,cAAc,MAAM;AACvC,sBAAM,KAAK,KAAK;AAAA,kBACd,UAAU,YAAY;AAAA,kBACtB;AAAA,gBACF;AAAA,cACF,WAAW,UAAU,cAAc,QAAQ;AACzC,sBAAM,KAAK,KAAK;AAAA,kBACd,UAAU,YAAY;AAAA,kBACtB;AAAA,gBACF;AAAA,cACF,WAAW,UAAU,cAAc,SAAS;AAC1C,sBAAM,KAAK,KAAK;AAAA,kBACd,UAAU,YAAY;AAAA,kBACtB;AAAA,gBACF;AAAA,cACF,OAAO;AACL,sBAAM,IAAI;AAAA,kBACR,6BAA6B,UAAU,SAAS;AAAA,gBAClD;AAAA,cACF;AAEA,wBAAM,qBAAM,GAAG;AAAA,YACjB,OAAO;AACL,oBAAM,IAAI;AAAA,gBACR,8BAA8B,iBAAiB,gBAAgB,KAAK;AAAA,kBAClE;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACF,cAAM,KAAK,gBAAgB;AAAA,MAC7B,WAAWA,MAAK,SAAS,SAAS;AAChC,cAAM,kBACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAOA,MAAK;AAAA,UACZ,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,cAAc;AAC7B,sBAAM,qBAAM,WAAW,UAAU,GAAI;AAAA,UACvC;AAAA,QACF;AACF,cAAM,KAAK,eAAe;AAAA,MAC5B,WAAWA,MAAK,SAAS,SAAS;AAChC,cAAM,kBACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAOA,MAAK;AAAA,UACZ,SAASA,MAAK,WAAWA,MAAK,OAAO;AAAA,UACrC,QAAQA,MAAK;AAAA,UACb,UAAU,YAAY;AACpB,kBAAM,IAAI;AAAA,cACRA,OAAM,WAAWA,MAAK,OAAO,WAAW;AAAA,YAC1C;AAAA,UACF;AAAA,QACF;AACF,cAAM,KAAK,eAAe;AAAA,MAC5B,WAAWA,MAAK,SAAS,0BAA0B;AACjD,cAAM,oCACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAASA,MAAK,OAAO;AAAA,UACrB,QAAQA,MAAK;AAAA,UACb,UAAU,YAAY;AAAA,UAEtB;AAAA,QACF;AACF,cAAM,KAAK,iCAAiC;AAAA,MAC9C,WAAWA,MAAK,SAAS,YAAY;AACnC,cAAM,qBAAqD;AAAA,UACzD,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,UAAU;AAAA,UAAC;AAAA,QAC9B;AACA,cAAM,KAAK,kBAAkB;AAAA,MAC/B,WAAWA,MAAK,SAAS,qBAAqB;AAC5C,cAAM,8BAA8D;AAAA,UAClE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,UAAU;AAEzB;AAAA,cACE,cAAc,KAAK,IAAI;AAAA,cACvB;AAAA,YACF;AACA,kBAAM,KAAK,KAAK,KAAK;AAAA,UACvB;AAAA,QACF;AACA,cAAM,KAAK,2BAA2B;AAAA,MACxC,WAAWA,MAAK,SAAS,qBAAqB;AAC5C,cAAM,8BAA8D;AAAA,UAClE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,UAAU;AACzB;AAAA,cACE,cAAc,KAAK,IAAI;AAAA,cACvB;AAAA,YACF;AACA,kBAAM,KAAK,KAAK,KAAK;AAAA,UACvB;AAAA,QACF;AACA,cAAM,KAAK,2BAA2B;AAAA,MACxC,WAAWA,MAAK,SAAS,2BAA2B;AAClD,cAAM,oCACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,UAAU;AACzB;AAAA,cACE,cAAc,KAAK,IAAI;AAAA,cACvB;AAAA,YACF;AACA,kBAAM,KAAK,KAAK,WAAW;AAAA,UAC7B;AAAA,QACF;AACF,cAAM,KAAK,iCAAiC;AAAA,MAC9C,WAAWA,MAAK,SAAS,oBAAoB;AAC3C,cAAM,6BACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAOA,MAAK;AAAA,UACZ,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,UAAU;AACzB;AAAA,cACE,cAAc,KAAK,IAAI;AAAA,cACvB;AAAA,YACF;AACA,kBAAM,EAAE,GAAG,GAAG,SAAS,IAAI;AAC3B,kBAAM,KAAK,KAAK,UAAU,GAAG,GAAG,QAAQ;AAAA,UAC1C;AAAA,QACF;AACF,cAAM,KAAK,0BAA0B;AAAA,MACvC,WAAWA,MAAK,SAAS,eAAe;AACtC,cAAM,wBACJ;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAOA,MAAK;AAAA,UACZ,SAASA,MAAK;AAAA,UACd,QAAQA,MAAK;AAAA,UACb,UAAU,OAAO,UAAU;AACzB;AAAA,cACE,cAAc,KAAK,IAAI;AAAA,cACvB;AAAA,YACF;AACA,kBAAM,EAAE,WAAW,YAAY,UAAU,SAAS,IAAI;AAEtD,kBAAM,sBAAsB,aACxB,EAAE,MAAM,WAAW,GAAG,KAAK,WAAW,EAAE,IACxC;AAEJ,gBAAI,cAAc,QAAQ;AACxB,oBAAM,KAAK,KAAK;AAAA,gBACd;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF,WAAW,cAAc,MAAM;AAC7B,oBAAM,KAAK,KAAK,OAAO,qBAAqB,UAAU,QAAQ;AAAA,YAChE,OAAO;AACL,oBAAM,IAAI,MAAM,2BAA2B,SAAS,EAAE;AAAA,YACxD;AAAA,UACF;AAAA,QACF;AACF,cAAM,KAAK,qBAAqB;AAAA,MAClC,OAAO;AACL,cAAM,IAAI,MAAM,qCAAqCA,MAAK,IAAI,EAAE;AAAA,MAClE;AAAA,IACF,CAAC;AAED,UAAM,eAAe,MAAM;AAAA,MACzB,CAAC,MAA0B,UAAkB;AAC3C,YAAI,KAAK,SAAS,UAAU;AAC1B,iBAAO,KAAK;AAAA,YACV;AAAA,YACA,UAAU,MAAM,SAAS;AAAA,UAC3B;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,qBAAqB,iBAAkC;AACnE,UAAM,WAAW,KAAK,IAAI;AAC1B,UAAM,cAAc,MAAM,KAAK,QAAQ,mBAAmB,QAAQ;AAClE,UAAM,aAAoC;AAAA,MACxC,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,YAAY,YAAY;AAAA,MACxB,QAAQ;AAAA,IACV;AAEA,oBAAgB,KAAK,WAAW,CAAC,UAAU;AAC3C,IAAC,gBAAgB,KAA+B,cAAc;AAE9D,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,iBAAyB,YAAoB;AACxE,UAAM,eAAe,IAAI,qBAAS,aAAa,UAAU,eAAe,GAAG;AAAA,MACzE,aAAa,KAAK;AAAA,IACpB,CAAC;AAED,UAAM,OAAmC;AAAA,MACvC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA,QACL;AAAA,MACF;AAAA,MACA,UAAU,OAAO,OAAO,oBAAoB;AAC1C,cAAM,KAAK,qBAAqB,eAAe;AAC/C,eAAO;AAAA,UACL,QAAQ;AAAA,YACN,SAAS,CAAC;AAAA,YACV,oCAAoC;AAAA,YACpC,KAAK;AAAA,YACL;AAAA,UACF;AAAA,UACA,OAAO;AAAA,YACL,KAAK;AAAA,UACP;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAa,OAAO,IAAI;AAC9B,UAAM,aAAa,MAAM;AAEzB,WAAO;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EAEQ,uBACN,iBACA,KACA,eACA;AACA,UAAM,OAAmC;AAAA,MACvC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA,QACL;AAAA,QACA;AAAA,MACF;AAAA,MACA,UAAU,OAAO,OAAO,oBAAoB;AAC1C,cAAM,YAAY,KAAK,IAAI;AAC3B,cAAM,EAAE,YAAY,IAClB,MAAM,KAAK,qBAAqB,eAAe;AAEjD,cAAM,aAAa,UAAM,kBAAK,MAAM,iBAAiB;AAAA,UACnD,SAAS;AAAA,UACT,KAAK,MAAM;AAAA,UACX;AAAA,UACA,UAAU,KAAK,KAAK;AAAA,QACtB,CAAC;AAED,cAAM;AAAA,UACJ;AAAA,UACA,KAAAC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,OAAAC;AAAA,QACF,IAAI;AAEJ,wBAAgB,KAAK,MAAM;AAAA,UACzB,GAAI,gBAAgB,KAAK,OAAO,CAAC;AAAA,UACjC;AAAA,QACF;AACA,wBAAgB,KAAK,QAAQ;AAE7B,YAAI,iBAAiB;AACrB,YAAI,gBAAgB;AACpB,YAAI,mBAAmB;AACvB,cAAM,gBAAgB,WAAW,CAAC,GAAG;AAAA,UACnC,CAAC,KAAK,mBAAmB;AACvB,gBAAI,gBAAgB;AAClB,qBAAO;AAAA,YACT;AAEA,gBAAI,eAAe,QAAQ;AAEzB,kBAAI,iBAAiB,eAAe,OAAO,MAAM;AAE/C,uBAAO,eAAe,OAAO;AAAA,cAC/B;AAEA,kBAAI,eAAe,OAAO,MAAM;AAC9B,gCAAgB;AAAA,cAClB;AAEA,kBAAI,KAAK;AAAA,gBACP,MAAM;AAAA,gBACN,QAAQ,eAAe;AAAA,gBACvB,OAAO;AAAA;AAAA,gBAEP,SAAS,eAAe,OAAO;AAAA,cACjC,CAAC;AAAA,YACH,WACE,CAAC,OAAO,SAAS,OAAO,EAAE,SAAS,eAAe,IAAI,GACtD;AACA,iCAAmB,8BAA8B,KAAK,UAAU,cAAc,CAAC;AAE/E,+BAAiB;AACjB,qBAAO;AAAA,YACT;AACA,gBAAI,KAAK,cAAc;AACvB,mBAAO;AAAA,UACT;AAAA,UACA,CAAC;AAAA,QACH;AAEA,YAAIA,QAAO;AACT,gBAAM,UAAU,KAAK,IAAI;AACzB,gBAAM,gBAAgBA,UAAS,UAAU;AACzC,cAAI,gBAAgB,GAAG;AACrB,yBAAa,KAAK;AAAA,cAChB,MAAM;AAAA,cACN,OAAO;AAAA,gBACL,QAAQ;AAAA,cACV;AAAA,cACA,QAAQ;AAAA,YACV,CAA6C;AAAA,UAC/C;AAAA,QACF;AAEA,YAAI,aAAa,WAAW,GAAG;AAC7B;AAAA,YACE,CAAC,sCAAsCA;AAAA,YACvC,QACI,mBAAmB,KAAK,KACxB,oBAAoB;AAAA,UAC1B;AAAA,QACF;AAEA,eAAO;AAAA,UACL,QAAQ;AAAA,YACN,SAAS;AAAA,YACT;AAAA,YACA,KAAAD;AAAA,YACA,UAAU,WAAW;AAAA,UACvB;AAAA,UACA,OAAO;AAAA,YACL,KAAK;AAAA,UACP;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,mBAAmB,iBAAyB;AAClD,UAAM,OAAmC;AAAA,MACvC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA,QACL;AAAA,MACF;AAAA,MACA,UAAU,OAAO,OAAO,oBAAoB;AAC1C,cAAM,EAAE,YAAY,IAClB,MAAM,KAAK,qBAAqB,eAAe;AAEjD,cAAM,eAAe,UAAM;AAAA,UACzB,YAAY;AAAA,UACZ,YAAY;AAAA,QACd;AAEA,aAAK,0BAA0B;AAAA,UAC7B,MAAM;AAAA,UACN,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,WAAW;AAAA,gBACT,KAAK;AAAA,cACP;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAC;AACD,cAAM,aAMF,UAAM,8BAAY;AAAA,UACpB,iBAAiB,MAAM;AAAA,UACvB,qBAAqB,KAAK;AAAA,UAC1B,MAAM,YAAY;AAAA,QACpB,CAAC;AAED,cAAM,EAAE,SAAS,gBAAgB,MAAM,IAAI;AAC3C,wBAAgB,KAAK,MAAM;AAAA,UACzB,GAAI,gBAAgB,KAAK,OAAO,CAAC;AAAA,UACjC,aAAa,WAAW;AAAA,QAC1B;AACA,wBAAgB,KAAK,QAAQ;AAC7B,aAAK,0BAA0B;AAAA,UAC7B,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD,eAAO;AAAA,UACL,QAAQ;AAAA,YACN;AAAA,YACA,SAAS,QAAQ,CAAC,GAAG;AAAA,YACrB,YAAY,QAAQ,CAAC,EAAE;AAAA,YACvB,oCAAoC;AAAA,YACpC,KAAK;AAAA,YACL,UAAU,WAAW;AAAA,UACvB;AAAA,UACA,OAAO;AAAA,YACL,KAAK;AAAA,UACP;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SACJ,OACA,OACA,MAG0B;AAC1B,UAAM,eAAe,IAAI,qBAAS,OAAO;AAAA,MACvC,aAAa,KAAK;AAAA,IACpB,CAAC;AACD,UAAM,EAAE,MAAM,IAAI,MAAM,KAAK,wBAAwB,OAAO,IAAI;AAChE,UAAM,aAAa,OAAO,KAAK;AAC/B,UAAM,SAAS,MAAM,aAAa,MAAM;AACxC,UAAM,EAAE,OAAO,IAAI;AACnB,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,YACA,eACA,MAUA;AACA,UAAM,eAAe,IAAI,qBAAS,aAAa,UAAU,UAAU,GAAG;AAAA,MACpE,aAAa,KAAK;AAAA,IACpB,CAAC;AAED,QAAI,eACF,KAAK,uBAAuB,YAAY,QAAW,aAAa;AAClE,QAAI,cAAc;AAClB,UAAM,UAAoB,CAAC;AAE3B,UAAM,WAAmC,CAAC;AAC1C,UAAM,2BACJ,iCAAoB,2CAA+B,KACnD;AACF,WAAO,cAAc;AACnB,UAAI,cAAc,sBAAsB;AACtC,cAAM,WACJ;AAEF,eAAO,KAAK,gBAAgB,cAAc,QAAQ;AAAA,MACpD;AAGA,YAAM,aAAa,OAAO,YAAY;AACtC,YAAM,SAAS,MAAM,aAAa,MAAM;AACxC,YAAM,aAAiC,QAAQ;AAC/C,UAAI,aAAa,eAAe,GAAG;AACjC,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ;AAAA,MACF;AAEA,YAAM,QAAQ,WAAW,WAAW,CAAC;AACrC,eAAS,KAAK,GAAI,WAAW,YAAY,CAAC,CAAE;AAE5C,UAAI;AACJ,UAAI;AACF,sBAAc,MAAM,KAAK,wBAAwB,OAAO,IAAI;AAC5D,qBAAa,OAAO,YAAY,KAAK;AAAA,MACvC,SAAS,OAAO;AACd,eAAO,KAAK;AAAA,UACV;AAAA,UACA,+CAA+C,KAAK,YAAY,KAAK;AAAA,YACnE;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,aAAa,MAAM;AACzB,UAAI,aAAa,eAAe,GAAG;AACjC,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ;AAAA,MACF;AACA,UAAI,YAAY,KAAK;AACnB,gBAAQ,KAAK,WAAW,GAAG;AAAA,MAC7B;AAEA,UAAI,CAAC,WAAW,oCAAoC;AAClD,uBAAe;AACf;AAAA,MACF;AACA,qBAAe,KAAK;AAAA,QAClB;AAAA,QACA,QAAQ,SAAS,IAAI,KAAK,QAAQ,KAAK,MAAM,CAAC,KAAK;AAAA,QACnD;AAAA,MACF;AACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,QACN;AAAA,MACF;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,MAAM,aACJ,YACA,MAUA;AACA,UAAM,eAAe,IAAI,qBAAS,aAAa,UAAU,UAAU,GAAG;AAAA,MACpE,aAAa,KAAK;AAAA,IACpB,CAAC;AACD,SAAK,sBAAsB,CAAC;AAC5B,UAAM,cAAc;AACpB,QAAI,sBAAsB;AAC1B,UAAM,kBAAkB;AAExB,UAAM,WAAmC,CAAC;AAC1C,WAAO,CAAC,eAAe,sBAAsB,iBAAiB;AAC5D;AACA,YAAM,eACJ,KAAK,mBAAmB,UAAU;AACpC,YAAM,aAAa,OAAO,YAAY;AACtC,YAAM,SAAS,MAAM,aAAa,MAAM;AACxC,UAAI,aAAa,eAAe,GAAG;AACjC,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ;AAAA,MACF;AACA,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,YAAM,EAAE,OAAO,IAAI;AACnB,YAAM,QAAQ,OAAO;AACrB,eAAS,KAAK,GAAI,OAAO,YAAY,CAAC,CAAE;AACxC,UAAI;AACJ,UAAI;AACF,sBAAc,MAAM,KAAK,wBAAwB,OAAO,IAAI;AAC5D,qBAAa,OAAO,YAAY,KAAK;AAAA,MACvC,SAAS,OAAO;AACd,eAAO,KAAK;AAAA,UACV;AAAA,UACA,+CAA+C,KAAK,YAAY,KAAK;AAAA,YACnE;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,aAAa,MAAM;AAEzB,UAAI,aAAa,eAAe,GAAG;AACjC,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ;AAAA,MACF;AAEA,UAAI,MAAM,CAAC,EAAE,SAAS,YAAY;AAChC;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,QACN;AAAA,MACF;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,MAAc,oBACZ,MACA,QACA,KACA,kBAC6B;AAC7B,UAAM,eAAe,IAAI;AAAA,MACvB;AAAA,QACE;AAAA,QACA,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,MAAM;AAAA,MAC7D;AAAA,MACA;AAAA,QACE,aAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAEA,UAAM,YAA4C;AAAA,MAChD,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA;AAAA,QAEL,YAAY,mBACP;AAAA,UACC;AAAA,UACA;AAAA,QACF,IACA;AAAA;AAAA,MACN;AAAA,MACA,UAAU,OAAO,OAAO,gBAAgB;AACtC,cAAM,EAAE,KAAK,IAAI;AACjB,YAAI;AACJ,cAAM,gBAAgC,CAAC,SAAS;AAC9C,wBAAc;AAAA,QAChB;AACA,aAAK,QAAQ,oBAAoB;AAGjC,cAAM,WAAW,KAAK,IAAI;AAC1B,cAAM,cAAc,MAAM,KAAK,QAAQ,mBAAmB,SAAS;AACnE,aAAK,cAAc;AAEnB,cAAM,aAAoC;AAAA,UACxC,MAAM;AAAA,UACN,IAAI;AAAA,UACJ,YAAY,YAAY;AAAA,UACxB,QAAQ;AAAA,QACV;AACA,aAAK,WAAW,CAAC,UAAU;AAE3B,cAAM,mBAAmB,SAAS;AAClC,YAAI,cAAc;AAClB,YAAI,kBAAkB;AACpB,wBAAc;AAAA,YACZ,QAAQ,GAAG,IAAI,KAAK,MAAM;AAAA,UAC5B;AAAA,QACF;AAEA,cAAM,EAAE,MAAM,OAAO,SAAAE,SAAQ,IAAI,MAAM,KAAK,QAAQ;AAAA,UAClD;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,YAAI,eAAe;AACnB,YAAI,kBAAkB;AACpB,oCAAO,MAAM,WAAW,QAAW,yBAAyB;AAC5D,yBAAgB,KAAa;AAAA,QAC/B;AAEA,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,KAAK,EAAE,MAAM,YAAY;AAAA,UACzB;AAAA,UACA,SAAAA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAa,OAAO,KAAK,8BAA8B,SAAS,CAAC;AACvE,UAAM,SAAS,MAAM,aAAa,MAAM;AAExC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,EAAE,QAAQ,QAAQ,IAAI;AAE5B,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,MAAM,MACJ,QACA,KAC0B;AAC1B,WAAO,KAAK,oBAAoB,SAAS,QAAQ,GAAG;AAAA,EACtD;AAAA,EAEA,MAAM,QACJ,QACA,KACmC;AACnC,UAAM,EAAE,YAAY,iBAAiB,IAAI,YAAY,MAAM;AAC3D,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,QACA,KACkC;AAClC,UAAM,EAAE,YAAY,iBAAiB,IAAI,YAAY,MAAM;AAC3D,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,QACA,KACkC;AAClC,UAAM,EAAE,YAAY,iBAAiB,IAAI,YAAY,MAAM;AAC3D,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,WACA,KACmC;AACnC,UAAM,EAAE,YAAY,iBAAiB,IAAI,YAAY,SAAS;AAC9D,WAAO,MAAM,KAAK;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,0BACN,qBACA;AACA,QAAI,oBAAoB,SAAS,QAAQ;AAEvC,YAAM,eAAe,KAAK,oBAAoB;AAAA,QAC5C,CAAC,SAAS,KAAK,SAAS;AAAA,MAC1B;AAGA,UAAI,aAAa,UAAU,KAAK,oBAAoB,SAAS,QAAQ;AAEnE,cAAM,oBAAoB,KAAK,oBAAoB;AAAA,UACjD,CAAC,SAAS,KAAK,SAAS;AAAA,QAC1B;AACA,YAAI,qBAAqB,GAAG;AAC1B,eAAK,oBAAoB,OAAO,mBAAmB,CAAC;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAEA,SAAK,oBAAoB,KAAK,mBAAmB;AAAA,EACnD;AAAA,EAEA,MAAc,gBAAgB,cAAwB,UAAkB;AACtE,UAAM,YAAsD;AAAA,MAC1D,MAAM;AAAA,MACN,OAAO;AAAA,QACL,SAAS;AAAA,MACX;AAAA,MACA,QAAQ;AAAA,IACV;AACA,UAAM,EAAE,MAAM,IAAI,MAAM,KAAK,wBAAwB,CAAC,SAAS,CAAC;AAChE,UAAM,aAAa,OAAO,KAAK,8BAA8B,MAAM,CAAC,CAAC,CAAC;AACtE,UAAM,aAAa,MAAM;AAEzB,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,MAAM,QACJ,WACA,KACgC;AAChC,UAAM,cAAc,YAAY,SAAS;AACzC,UAAM,eAAe,IAAI,qBAAS,aAAa,WAAW,WAAW,GAAG;AAAA,MACtE,aAAa,KAAK;AAAA,IACpB,CAAC;AACD,UAAM,EAAE,WAAW,gBAAgB,IAAI;AAEvC,8BAAO,WAAW,0BAA0B;AAC5C,8BAAO,WAAW,0BAA0B;AAC5C,8BAAO,iBAAiB,gCAAgC;AAExD,UAAM,mBAAmB,KAAK,IAAI;AAClC,QAAI,YAAY,KAAK,IAAI;AACzB,QAAI,eAAe;AACnB,WAAO,KAAK,IAAI,IAAI,mBAAmB,WAAW;AAChD,kBAAY,KAAK,IAAI;AACrB,YAAM,aAAwD;AAAA,QAC5D,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,QACF;AAAA,QACA,QAAQ;AAAA,MACV;AACA,YAAM,EAAE,OAAO,YAAY,IAAI,MAAM,KAAK,wBAAwB;AAAA,QAChE;AAAA,MACF,CAAC;AACD,YAAM,aAAa;AAAA,QACjB,KAAK,8BAA8B,YAAY,CAAC,CAAC;AAAA,MACnD;AACA,YAAM,SAAS,MAAM,aAAa,MAAM;AAExC,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,YAAM,EAAE,OAAO,IAAI;AAEnB,UAAI,QAAQ,MAAM;AAChB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ;AAAA,MACF;AAEA,qBACE,QAAQ,WACR,6CAA6C,SAAS;AACxD,YAAM,MAAM,KAAK,IAAI;AACrB,UAAI,MAAM,YAAY,iBAAiB;AACrC,cAAM,gBAAgB,mBAAmB,MAAM;AAC/C,cAAM,YAAsD;AAAA,UAC1D,MAAM;AAAA,UACN,OAAO;AAAA,YACL,QAAQ;AAAA,UACV;AAAA,UACA,QAAQ;AAAA,QACV;AACA,cAAM,EAAE,OAAO,WAAW,IAAI,MAAM,KAAK,wBAAwB;AAAA,UAC/D;AAAA,QACF,CAAC;AACD,cAAM,aAAa;AAAA,UACjB,KAAK,8BAA8B,WAAW,CAAC,CAAC;AAAA,QAClD;AACA,cAAM,aAAa,MAAM;AAAA,MAC3B;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,MACV;AAAA,MACA,oBAAoB,YAAY;AAAA,IAClC;AAAA,EACF;AACF;;;AM19CA,IAAAZ,iBAAyB;AACzB,IAAAJ,iBAAuB;AAEvB,IAAMW,aAAQ,yBAAS,cAAc;AAE9B,SAAS,WACd,MACA,aACA,OAIkB;AAClB,MAAI,cAAgC,CAAC;AACrC,QAAM,aAAyD,cAC3D;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,EACX,IACA;AACJ,MAAI,SAAS,SAAS,SAAS,WAAW,SAAS,cAAc;AAC/D,+BAAO,aAAa,mCAAmC,IAAI,GAAG;AAC9D,+BAAO,YAAY,mCAAmC,IAAI,GAAG;AAC7D,UAAM,UAAkD;AAAA,MACtD;AAAA,MACA,OAAO;AAAA,MACP,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAEA,kBAAc,CAAC,YAAY,OAAO;AAAA,EACpC;AACA,MAAI,SAAS,WAAW,SAAS,iBAAiB;AAChD,QAAI,SAAS,SAAS;AACpB,iCAAO,aAAa,mCAAmC,IAAI,GAAG;AAAA,IAChE;AACA,+BAAO,OAAO,6BAA6B,IAAI,GAAG;AAElD,UAAM,YAAgE;AAAA,MACpE;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAEA,QAAI,YAAY;AACd,oBAAc,CAAC,YAAY,SAAS;AAAA,IACtC,OAAO;AACL,oBAAc,CAAC,SAAS;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,SAAS,UAAU;AACrB,+BAAO,OAAO,6BAA6B,IAAI,GAAG;AAElD,UAAM,aAAwD;AAAA,MAC5D;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAEA,QAAI,YAAY;AACd,oBAAc,CAAC,YAAY,UAAU;AAAA,IACvC,OAAO;AACL,oBAAc,CAAC,UAAU;AAAA,IAC3B;AAAA,EACF;AAEA,MAAI,SAAS,SAAS;AACpB,+BAAO,OAAO,6BAA6B,IAAI,GAAG;AAElD,UAAM,YAAsD;AAAA,MAC1D;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAEA,kBAAc,CAAC,SAAS;AAAA,EAC1B;AAEA,MAAI,SAAS,UAAU;AACrB,+BAAO,aAAa,mCAAmC,IAAI,GAAG;AAC9D,UAAMM,cAAkD;AAAA,MACtD;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AACA,kBAAc,CAACA,WAAU;AAAA,EAC3B;AAEA,MAAI,aAAa;AACf,IAAAN,OAAM,cAAc,WAAW;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,uBAAuB,IAAI,EAAE;AAC/C;;;AVlDA,IAAMA,aAAQ,yBAAS,iBAAiB;AAExC,IAAM,sBAAsB,CAAC,IAAsB,OAAyB;AAC1E,QAAM,CAAC,IAAI,EAAE,IAAI;AACjB,QAAM,CAAC,IAAI,EAAE,IAAI;AACjB,SAAO,KAAK,MAAM,KAAK,MAAM,KAAK,OAAO,KAAK,KAAK,OAAO,CAAC,CAAC;AAC9D;AAEA,IAAM,iBAAiB,CAAC,OAAyB,SAAe;AAC9D,QAAM,CAAC,GAAG,CAAC,IAAI;AACf,QAAM,EAAE,MAAM,KAAK,OAAO,OAAO,IAAI;AACrC,SAAO,KAAK,QAAQ,KAAK,OAAO,SAAS,KAAK,OAAO,KAAK,MAAM;AAClE;AAEA,IAAM,8BAAoD;AAAA,EACxD,aAAa;AAAA,EACb,oBAAoB;AACtB;AAwBO,IAAM,YAAN,MAAoD;AAAA,EAiCzD,YAAY,MAAgB,MAAqB;AAfjD;AAAA;AAAA;AAAA,mBAAU;AAQV,qBAAY;AAQV,SAAK,OAAO;AACZ,SAAK,OAAO,OAAO;AAAA,MACjB;AAAA,QACE,gBAAgB;AAAA,QAChB,oBAAoB;AAAA,QACpB,WAAW;AAAA,QACX,kBAAkB;AAAA,MACpB;AAAA,MACA,QAAQ,CAAC;AAAA,IACX;AAEA,QACE,KAAK,KAAK,aAAa,eACvB,KAAK,KAAK,aAAa,cACvB;AACA,MACE,KAAK,KACL,2BACC,KAAK,KAAyB,4BAC/B;AACF,MACE,KAAK,KACL,4BACC,KAAK,KAAyB,6BAC/B;AAAA,IACJ;AAEA,SAAK,iBAAiB,KAAK,KAAK;AAIhC,SAAK,UAAU,IAAI;AAAA,MACjB,OAAO,WAA0B;AAC/B,eAAO,KAAK,aAAa,MAAM;AAAA,MACjC;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,KAAK,KAAK,aAAa,WAAW;AACrD,WAAK,YAAY,IAAI;AAAA,QACnB,KAAK;AAAA,YACL,kCAAqB,gBAAgB;AAAA;AAAA,MACvC;AAAA,IACF;AAEA,SAAK,eAAe,IAAI,iBAAiB,KAAK,MAAM,KAAK,SAAS;AAAA,MAChE,WAAW,KAAK;AAAA,MAChB,aAAa,KAAK,uBAAuB,KAAK,IAAI;AAAA,IACpD,CAAC;AACD,SAAK,OAAO,KAAK,UAAU;AAC3B,SAAK,iBACH,MAAM,kBACN,kBAAkB,MAAM,UAAU,KAAK,KAAK,YAAY,KAAK;AAAA,EACjE;AAAA,EAEA,MAAM,aAAa,QAA+C;AAEhE,QAAI,KAAK,mBAAmB;AAC1B,MAAAA,OAAM,yCAAyC,MAAM;AACrD,aAAO,KAAK;AAAA,IACd;AAGA,QAAI,WAAW,WAAW,aAAa,WAAW,WAAW;AAC3D,aAAO,MAAM,wBAAwB,KAAK,MAAM;AAAA,QAC9C,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AACA,WAAO,MAAM,wBAAwB,KAAK,MAAM;AAAA,MAC9C,cAAc,CAAC,KAAC,0BAAa;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBAA0C;AAC9C,WAAO,MAAM,KAAK,aAAa,QAAQ;AAAA,EACzC;AAAA,EAEA,MAAM,mBAAmB,QAAgB;AACvC,SAAK,KAAK,kBAAkB;AAAA,EAC9B;AAAA,EAEA,YAAY;AACV,SAAK,OAAO;AAAA,MACV,WAAW,KAAK,KAAK;AAAA,MACrB,kBAAkB,KAAK,KAAK;AAAA,MAC5B,YAAY,CAAC;AAAA,IACf;AAEA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,oBAAoB,WAA0B;AAE5C,UAAM,mBAAmB,sBAAsB,SAAS;AACxD,UAAM,cAAc,KAAK;AACzB,gBAAY,WAAW,KAAK,gBAAgB;AAAA,EAC9C;AAAA,EAEA,iBAAiB;AAEf,SAAK,KAAK,YAAY,KAAK,KAAK;AAChC,SAAK,KAAK,mBAAmB,KAAK,KAAK;AACvC,eAAO,kCAAkB,KAAK,IAAI;AAAA,EACpC;AAAA,EAEA,mBAAmB;AACjB,eAAO,kCAAkB,KAAK,eAAe,CAAC;AAAA,EAChD;AAAA,EAEA,sBAAsB;AACpB,QAAI,KAAK,WAAW;AAClB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,UAAM,EAAE,gBAAgB,mBAAmB,IAAI,KAAK;AACpD,SAAK,iBAAa,6BAAa;AAAA,MAC7B,UAAU,KAAK;AAAA,MACf,SAAS;AAAA,MACT,aAAa,KAAK,eAAe;AAAA,MACjC,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AACD,IAAAA,OAAM,uBAAuB,KAAK,UAAU;AAC5C,QAAI,kBAAkB,sBAAsB,KAAK,YAAY;AAC3D,qBAAe,KAAK,UAAU;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,MAAc,uBAAuB,MAAqB;AACxD,UAAM,QAAQ,SAAS,IAAI;AAC3B,UAAM,MAAM,QAAQ,GAAG,QAAQ,IAAI,CAAC,MAAM,KAAK,KAAK,QAAQ,IAAI;AAEhE,QAAI,KAAK,gBAAgB;AACvB,YAAM,KAAK,eAAe,GAAG;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,MAAc,iBAAiB,UAAoB,kBAAkB,OAAO;AAC1E,SAAK,oBAAoB,SAAS,KAAK,CAAC;AAExC,QAAI;AACF,YAAM,KAAK,eAAe,KAAK,eAAe,CAAC;AAAA,IACjD,SAAS,OAAO;AACd,cAAQ,MAAM,yBAAyB,KAAK;AAAA,IAC9C;AAEA,SAAK,oBAAoB;AAEzB,QAAI,SAAS,eAAe,KAAK,CAAC,iBAAiB;AACjD,YAAM,YAAY,SAAS,gBAAgB;AAC3C,YAAM,IAAI,MAAM,GAAG,WAAW,YAAY;AAAA,EAAK,WAAW,UAAU,IAAI;AAAA,QACtE,OAAO,WAAW;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,yBACN,cACA,KACqB;AACrB,+BAAO,cAAc,uBAAuB;AAE5C,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,YAAM,SAAS;AACf,YAAM,YAAY,IAAI,aAAa;AACnC,YAAM,YAAY,IAAI,aAAa;AACnC,YAAM,QAAQ,IAAI;AAElB,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,cAA2B,KAAoB;AACzD,UAAM,sBAAsB,KAAK;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AACA,UAAM,QAAQ,WAAW,OAAO,mBAAmB;AACnD,UAAM,EAAE,UAAU,OAAO,IAAI,MAAM,KAAK,aAAa;AAAA,MACnD,aAAa,OAAO,eAAe,mBAAmB,CAAC;AAAA,MACvD;AAAA,MACA,EAAE,WAAW,KAAK,UAAU;AAAA,IAC9B;AACA,UAAM,KAAK,iBAAiB,QAAQ;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aAAa,cAA2B,KAAoB;AAChE,UAAM,sBAAsB,KAAK;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AACA,UAAM,QAAQ,WAAW,cAAc,mBAAmB;AAC1D,UAAM,EAAE,UAAU,OAAO,IAAI,MAAM,KAAK,aAAa;AAAA,MACnD,aAAa,cAAc,eAAe,mBAAmB,CAAC;AAAA,MAC9D;AAAA,MACA,EAAE,WAAW,KAAK,UAAU;AAAA,IAC9B;AACA,UAAM,KAAK,iBAAiB,QAAQ;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,cAA2B,KAAoB;AAC3D,UAAM,sBAAsB,KAAK;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AACA,UAAM,QAAQ,WAAW,SAAS,mBAAmB;AACrD,UAAM,EAAE,UAAU,OAAO,IAAI,MAAM,KAAK,aAAa;AAAA,MACnD,aAAa,SAAS,eAAe,mBAAmB,CAAC;AAAA,MACzD;AAAA,MACA,EAAE,WAAW,KAAK,UAAU;AAAA,IAC9B;AACA,UAAM,KAAK,iBAAiB,QAAQ;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QACJ,OACA,cACA,KACA;AACA;AAAA,MACE,OAAO,UAAU;AAAA,MACjB;AAAA,IACF;AACA,+BAAO,cAAc,iCAAiC;AACtD,UAAM,sBAAsB,KAAK;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AACA,UAAM,QAAQ,WAAW,SAAS,qBAAqB;AAAA,MACrD;AAAA,MACA,qBAAqB,KAAK;AAAA,IAC5B,CAAC;AACD,UAAM,EAAE,UAAU,OAAO,IAAI,MAAM,KAAK,aAAa;AAAA,MACnD,aAAa,SAAS,eAAe,mBAAmB,CAAC;AAAA,MACzD;AAAA,MACA;AAAA,QACE,WAAW,KAAK;AAAA,MAClB;AAAA,IACF;AACA,UAAM,KAAK,iBAAiB,QAAQ;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBACJ,SACA,cACA,KACA;AACA,+BAAO,SAAS,oCAAoC;AACpD,UAAM,sBAAsB,eACxB,KAAK,yBAAyB,cAAc,GAAG,IAC/C;AACJ,UAAM,QAAQ,WAAW,iBAAiB,qBAAqB;AAAA,MAC7D,OAAO;AAAA,IACT,CAAC;AACD,UAAM,EAAE,UAAU,OAAO,IAAI,MAAM,KAAK,aAAa;AAAA,MACnD,aAAa,iBAAiB,eAAe,mBAAmB,CAAC;AAAA,MACjE;AAAA,MACA,EAAE,WAAW,KAAK,UAAU;AAAA,IAC9B;AACA,UAAM,KAAK,iBAAiB,QAAQ;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SACJ,aACA,cACA,KACA;AACA,UAAM,sBAAsB,eACxB,KAAK,yBAAyB,cAAc,GAAG,IAC/C;AACJ,UAAM,QAAQ,WAAW,UAAU,qBAAqB,WAAW;AACnE,UAAM,eAAe,eACjB,GAAG,eAAe,mBAAmB,CAAC,MAAM,eAAe,WAAW,CAAC,KACvE,eAAe,WAAW;AAC9B,UAAM,EAAE,UAAU,OAAO,IAAI,MAAM,KAAK,aAAa;AAAA,MACnD,aAAa,UAAU,YAAY;AAAA,MACnC;AAAA,MACA,EAAE,WAAW,KAAK,UAAU;AAAA,IAC9B;AACA,UAAM,KAAK,iBAAiB,QAAQ;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SACJ,YACA,KAGA;AACA,UAAM,YAAY,KAAK;AAEvB,UAAM,kBAAc,0BAAa,MAAM;AACvC,UAAM,eACJ,eAAe,cAAc,QACzB,SACA,KAAK,WAAW,eAAe,UAAU;AAC/C,QAAI,gBAAgB,KAAK,WAAW,mBAAmB;AAErD,YAAM,EAAE,UAAAO,UAAS,IAAI,MAAM,KAAK,aAAa;AAAA,QAC3C;AAAA,QACA,aAAa,cAAc;AAAA,MAC7B;AAEA,YAAM,MAAM,KAAK,iBAAiBA,SAAQ;AAE1C,MAAAP,OAAM,qDAAqD;AAC3D,YAAMV,QAAO,aAAa,cAAc;AACxC,aAAO,KAAK,QAAQA,KAAI;AAAA,IAC1B;AAEA,UAAM,EAAE,QAAQ,SAAS,IAAI,OAAO,cAChC,KAAK,aAAa,aAAa,YAAY,EAAE,UAAU,CAAC,IACxD,KAAK,aAAa,OAAO,YAAY,KAAK,KAAK,iBAAiB;AAAA,MAC9D;AAAA,IACF,CAAC;AAGL,QAAI,KAAK,aAAa,QAAQ,YAAY,cAAc,OAAO;AAC7D,YAAM,cAAkC;AAAA,QACtC,OAAO;AAAA,UACL;AAAA,YACE,MAAM;AAAA,YACN,MAAM,OAAO;AAAA,UACf;AAAA,QACF;AAAA,MACF;AACA,YAAM,cAAc,gBAAAA,QAAK,KAAK,WAAW;AACzC,WAAK,UAAU;AAAA,QACb;AAAA,UACE,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,cAAc;AAAA,QAChB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,KAAK,iBAAiB,QAAQ;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QACJ,QACA,MAA4B,6BAC5B;AACA,UAAM,EAAE,QAAQ,SAAS,IAAI,MAAM,KAAK,aAAa,MAAM,QAAQ,GAAG;AACtE,UAAM,KAAK,iBAAiB,QAAQ;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UACJ,QACA,MAA4B,6BAC5B;AACA,UAAM,EAAE,QAAQ,SAAS,IAAI,MAAM,KAAK,aAAa,QAAQ,QAAQ,GAAG;AACxE,UAAM,KAAK,iBAAiB,QAAQ;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SACJ,QACA,MAA4B,6BAC5B;AACA,UAAM,EAAE,QAAQ,SAAS,IAAI,MAAM,KAAK,aAAa,OAAO,QAAQ,GAAG;AACvE,UAAM,KAAK,iBAAiB,QAAQ;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SACJ,QACA,MAA4B,6BAC5B;AACA,UAAM,EAAE,QAAQ,SAAS,IAAI,MAAM,KAAK,aAAa,OAAO,QAAQ,GAAG;AACvE,UAAM,KAAK,iBAAiB,QAAQ;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MACJ,QACA,MAA4B,6BAC5B;AACA,WAAO,KAAK,SAAS,QAAQ,GAAG;AAAA,EAClC;AAAA,EAEA,MAAM,uBACJ,QACA,KAK4C;AAC5C,UAAM,EAAE,eAAe,MAAM,aAAa,EAAE,IAAI,OAAO,CAAC;AAExD,QAAI,UAAU;AACd,QAAI,aAAa;AACjB,QAAI,eAAe;AACnB,QAAI,YAAY,KAAK,aAAa;AAClC,QAAI;AAEJ,WAAO,CAAC,WAAW,aAAa,YAAY;AAC1C,UAAI,cAAc,GAAG;AACnB,oBAAY;AAAA,MACd;AACA,MAAAU;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,OAAO,MAAM,KAAK,QAAQ,SAAS,QAAQ,EAAE,UAAU,CAAC;AAC9D,MAAAA,OAAM,mBAAmB,IAAI;AAC7B,iCAAO,KAAK,aAAa,kCAAkC,MAAM,GAAG;AACpE,qBAAe,KAAK;AAEpB,qBAAe,MAAM,KAAK;AAAA,QACxB;AAAA,QACA,YAAY,EAAE,WAAW,KAAK,IAAI;AAAA,QAClC;AAAA,QACA;AAAA,MACF;AACA,UAAI,aAAa,MAAM;AACrB,kBAAU;AAAA,MACZ,OAAO;AACL;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,cACJ,QACA,WACA,cACA,oBACgC;AAChC,IAAAA,OAAM,iBAAiB,QAAQ,WAAW,cAAc,kBAAkB;AAE1E,UAAM,EAAE,QAAQ,cAAc,MAAM,WAAW,IAAI,MAAM,KAAK;AAAA,MAC5D;AAAA,MACA;AAAA,IACF;AACA,UAAM,WAAW,oBAAoB,cAAc,YAAY;AAC/D,UAAM,WAAW,eAAe,cAAc,UAAU;AACxD,UAAM,OACJ,aAAa,oBAAoB,2BAA2B,OAC5D;AACF,UAAM,eAAe;AAAA,MACnB;AAAA,MACA,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,gBAAgB;AAAA,IAClB;AACA,IAAAA,OAAM,2BAA2B,YAAY;AAC7C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,QAAqB,KAAoB;AACtD,UAAM,sBAAsB,KAAK,yBAAyB,QAAQ,GAAG;AACrE,UAAM,QAAQ,WAAW,UAAU,mBAAmB;AACtD,UAAM,EAAE,UAAU,OAAO,IAAI,MAAM,KAAK,aAAa;AAAA,MACnD,aAAa,UAAU,eAAe,mBAAmB,CAAC;AAAA,MAC1D;AAAA,MACA,EAAE,WAAW,KAAK,UAAU;AAAA,IAC9B;AACA,UAAM,KAAK,iBAAiB,QAAQ;AAEpC,UAAM,EAAE,QAAQ,IAAI;AAEpB,WAAO;AAAA,MACL,MAAM,SAAS;AAAA,MACf,QAAQ,SAAS;AAAA,MACjB,QAAQ,MAAM,KAAK,KAAK,KAAK,GAAG;AAAA,IAClC;AAAA,EAGF;AAAA,EAEA,MAAM,SAAS,WAAwB,KAAc,KAAsB;AACzE,UAAM,EAAE,QAAQ,UAAU,QAAQ,IAAI,MAAM,KAAK,aAAa;AAAA,MAC5D;AAAA,MACA;AAAA,QACE,eAAe;AAAA,MACjB;AAAA,IACF;AACA,UAAM,KAAK,iBAAiB,UAAU,IAAI;AAE1C,QAAI,KAAK,iBAAiB;AACxB,aAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ;AACX,YAAM,SAAS,OAAO,qBAAqB,SAAS;AACpD,YAAM,YAAY,WAChB,WAAW,SAAS,gBAAgB,GAAG,SAAS,aAClD;AACA,YAAM,IAAI,MAAM,GAAG,MAAM;AAAA,EAAK,SAAS,EAAE;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,MAAM,UAAU,WAAmB,KAAuB;AACxD,UAAM,EAAE,SAAS,IAAI,MAAM,KAAK,aAAa,QAAQ,WAAW;AAAA,MAC9D,WAAW,KAAK,aAAa,KAAK;AAAA,MAClC,iBAAiB,KAAK,mBAAmB,IAAI;AAAA,MAC7C;AAAA,IACF,CAAC;AACD,UAAM,KAAK,iBAAiB,UAAU,IAAI;AAE1C,QAAI,SAAS,eAAe,GAAG;AAC7B,YAAM,YAAY,SAAS,gBAAgB;AAC3C,YAAM,IAAI,MAAM,GAAG,WAAW,KAAK;AAAA,EAAK,WAAW,UAAU,EAAE;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,GAAG,YAAoB,OAAO,UAAU;AAC5C,QAAI,SAAS,UAAU;AACrB,aAAO,KAAK,SAAS,UAAU;AAAA,IACjC;AACA,QAAI,SAAS,SAAS;AACpB,aAAO,KAAK,QAAQ,UAAU;AAAA,IAChC;AAEA,QAAI,SAAS,UAAU;AACrB,aAAO,KAAK,SAAS,UAAU;AAAA,IACjC;AAEA,QAAI,SAAS,OAAO;AAClB,aAAO,KAAK,MAAM,UAAU;AAAA,IAC9B;AAEA,QAAI,SAAS,cAAc;AACzB,aAAO,KAAK,aAAa,UAAU;AAAA,IACrC;AAEA,UAAM,IAAI;AAAA,MACR,iBAAiB,IAAI;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,mBAEX;AACD,UAAM,SAAS,gBAAgB,mBAAmB,QAAQ,IAAI;AAC9D,UAAM,SAAS,IAAI,aAAa,QAAQ,OAAO,WAAW;AACxD,aAAO,EAAE,OAAO,MAAM,QAAQ,CAAC,EAAE;AAAA,IACnC,CAAC;AACD,UAAM,OAAO,IAAI;AAEjB,QAAI,OAAO,WAAW,SAAS;AAC7B,YAAM,SAAS,OAAO,eACnB,OAAO,CAAC,SAAS,KAAK,WAAW,OAAO,EACxC,IAAI,CAAC,SAAS;AACb,eAAO,UAAU,KAAK,IAAI,KAAK,KAAK,OAAO,OAAO;AAAA,MACpD,CAAC,EACA,KAAK,IAAI;AACZ,YAAM,IAAI,MAAM;AAAA,EAA8C,MAAM,EAAE;AAAA,IACxE;AAEA,WAAO;AAAA,MACL,QAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,QAAgB;AACvC;AAAA,MACE,KAAK,KAAK;AAAA,MACV;AAAA,IACF;AACA,WAAO,KAAK,KAAK,mBAAmB,MAAM;AAAA,EAC5C;AAAA,EAEA,MAAM,UAAU;AACd,UAAM,KAAK,KAAK,QAAQ;AACxB,SAAK,UAAU;AACf,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAM,cACJ,OACA,KAGA;AAEA,UAAM,SAAS,MAAM,KAAK,KAAK,iBAAiB;AAChD,UAAM,MAAM,KAAK,IAAI;AAErB,UAAM,WAAoC;AAAA,MACxC;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,YAAY;AAAA,MACd;AAAA,IACF;AAEA,UAAM,OAAyB;AAAA,MAC7B,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,KAAK;AAAA,QACL,MAAM;AAAA,MACR;AAAA,MACA,OAAO;AAAA,QACL,SAAS,KAAK,WAAW;AAAA,MAC3B;AAAA,MACA,UAAU,YAAY;AAAA,MAAC;AAAA,IACzB;AAEA,UAAM,gBAA+B;AAAA,MACnC,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,mBAAmB;AAAA,MACnB,MAAM,SAAS,SAAS,UAAU;AAAA,MAClC,aAAa,KAAK,WAAW;AAAA,MAC7B,OAAO,CAAC,IAAI;AAAA,IACd;AAEA,SAAK,oBAAoB,aAAa;AAEtC,QAAI;AACF,WAAK,eAAe,KAAK,eAAe,CAAC;AAAA,IAC3C,SAAS,OAAO;AACd,cAAQ,MAAM,yBAAyB,KAAK;AAAA,IAC9C;AAEA,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEA,sBAAsB;AACpB,UAAM,EAAE,WAAW,kBAAkB,WAAW,IAAI,KAAK;AACzD,UAAM,gBAAgB,MAAM,QAAQ,UAAU,IAC1C,WAAW,IAAI,CAAC,cAAmB;AACjC,YAAM,EAAE,OAAO,GAAG,cAAc,IAAI;AACpC,UAAI,WAAW;AACf,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,mBAAW,MAAM,IAAI,CAAC,SAAc;AAElC,gBAAM,EAAE,aAAa,KAAK,GAAG,SAAS,IAAI;AAC1C,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AACA,aAAO,EAAE,GAAG,eAAe,GAAI,WAAW,EAAE,OAAO,SAAS,IAAI,CAAC,EAAG;AAAA,IACtE,CAAC,IACD,CAAC;AACL,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,YAAY;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBAAmC;AACvC,IAAAA,OAAM,uBAAuB;AAC7B,UAAM,UAAU,MAAM,KAAK,iBAAiB;AAE5C,YAAQ,YAAY;AACpB,SAAK,oBAAoB;AACzB,IAAAA,OAAM,kCAAkC;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,sBAAqC;AACzC,IAAAA,OAAM,yBAAyB;AAC/B,SAAK,oBAAoB;AACzB,IAAAA,OAAM,oCAAoC;AAAA,EAC5C;AACF;;;AWt0BA,IAAAT,oBAGO;;;ACFP,IAAAF,iBAAsB;AACtB,IAAAE,oBAAoD;AAEpD,IAAAiB,oBAA2B;AAC3B,gBAGO;AACP,IAAAf,iBAAyB;AACzB,IAAAJ,iBAAuB;AAOhB,IAAM,gBAAY,yBAAS,UAAU;AAErC,IAAM,OAAN,MAIP;AAAA,EA4BE,YACE,gBACA,UACA,MAGA;AAwQF,SAAQ,YAAY;AAvQlB,SAAK,iBAAiB;AACtB,SAAK,WAAW;AAChB,SAAK,2BACH,MAAM,4BAA4B;AAAA,EACtC;AAAA,EAhCA,MAAc,SACZ,cACA,KACY;AACZ,QAAI;AACJ,cAAU,yBAAyB;AACnC,QAAI,KAAK,aAAa,aAAa;AACjC,eAAS,MAAO,KAAK,eAAiC;AAAA,QACpD;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,eAAS,MAAO,KAAK,eAAkC;AAAA,QACrD;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,cAAU,uBAAuB;AACjC,WAAO;AAAA,EACT;AAAA,EAeA,MAAM,mBAA4B,QAA4B;AAC5D,WAAO,KAAK,SAAS,MAAM;AAAA,EAC7B;AAAA,EAEA,MAAM,oBAAoB;AACxB,QAAI,KAAK,6BAA6B,GAAG;AACvC,gBAAU,8CAA8C;AACxD;AAAA,IACF;AAGA,QAAI,KAAK,aAAa,eAAe,KAAK,aAAa,cAAc;AACnE,gBAAU,yBAAyB;AACnC,gBAAU,8BAA8B,KAAK,wBAAwB,EAAE;AACvE,UAAI;AACF,cAAO,KAAK,eAAiC,gBAAgB,QAAQ;AAAA,UACnE,SAAS,KAAK;AAAA,QAChB,CAAC;AAAA,MACH,SAAS,OAAO;AAEd,gBAAQ;AAAA,UACN;AAAA,QACF;AAAA,MACF;AACA,gBAAU,uBAAuB;AAAA,IACnC;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,kBAAkB;AAItB,UAAM,KAAK,kBAAkB;AAC7B,cAAU,uBAAuB;AACjC,UAAM,OAAO,MAAM,KAAK,oBAAoB;AAC5C,cAAU,qBAAqB;AAC/B,eAAO,8BAAW,IAAI;AAAA,EACxB;AAAA,EAEA,MAAM,cAAc,IAAY;AAC9B,UAAM,gCAA4B,wCAA6B;AAE/D,WAAO,KAAK;AAAA,MACV,GAAG,yBAAyB,6CAA6C,EAAE;AAAA,IAC7E;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,OAAc,kBAA2B;AAC9D,UAAM,gCAA4B,wCAA6B;AAE/D,WAAO,KAAK;AAAA,MACV,GAAG,yBAAyB,sDAAsD,MAAM,IAAI,UAAU,MAAM,GAAG,MAAM,gBAAgB;AAAA,IACvI;AAAA,EACF;AAAA,EAEA,MAAM,sBAAsB,OAAe;AACzC,UAAM,gCAA4B,wCAA6B;AAE/D,WAAO,KAAK;AAAA,MACV,GAAG,yBAAyB,qDAAqD,KAAK;AAAA,IACxF;AAAA,EACF;AAAA,EAEA,MAAM,sBAAsB;AAI1B,UAAM,KAAK,kBAAkB;AAC7B,UAAM,UAAU,UAAM,+BAAoB,IAAI;AAC9C,+BAAO,SAAS,wDAAwD;AACxE,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,yBAAyB,MAAM,KAAK,SAAS,OAAO;AAC1D,UAAM,UAAU,KAAK,IAAI;AACzB,cAAU,kCAAkC,UAAU,SAAS,IAAI;AACnE,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI,KAAK;AAAc,aAAO,KAAK;AACnC,UAAM,WAAiB,MAAM,KAAK,SAAS,MAAM;AAC/C,aAAO;AAAA,QACL,OAAO,SAAS,gBAAgB;AAAA,QAChC,QAAQ,SAAS,gBAAgB;AAAA,QACjC,KAAK,OAAO;AAAA,MACd;AAAA,IACF,CAAC;AACD,SAAK,eAAe;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,mBAAoC;AACxC,UAAM,UAAU;AAChB,UAAM,UAAU;AAChB,UAAM,KAAK,kBAAkB;AAC7B,UAAM,YAAY,KAAK,IAAI;AAC3B,cAAU,wBAAwB;AAElC,QAAI;AACJ,QAAI,KAAK,aAAa,aAAa;AACjC,YAAM,SAAS,MAAO,KAAK,eAAiC,WAAW;AAAA,QACrE,MAAM;AAAA,QACN;AAAA,QACA,UAAU;AAAA,MACZ,CAAC;AACD,eAAS,0BAA0B,MAAM;AAAA,IAC3C,WAAW,KAAK,aAAa,cAAc;AACzC,YAAM,SAAS,MAAO,KAAK,eAAkC,WAAW;AAAA,QACtE,MAAM;AAAA,QACN;AAAA,QACA,SAAS,KAAK;AAAA,MAChB,CAAC;AACD,eAAS,0BAA0B,OAAO,SAAS,QAAQ,CAAC;AAAA,IAC9D,OAAO;AACL,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,UAAM,UAAU,KAAK,IAAI;AACzB,cAAU,+BAA+B,UAAU,SAAS,IAAI;AAChE,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAuB;AAC3B,WAAO,KAAK,eAAe,IAAI;AAAA,EACjC;AAAA,EAEA,IAAI,QAAQ;AACV,WAAO;AAAA,MACL,OAAO,OACL,GACA,GACA,YACG;AACH,cAAM,KAAK,MAAM,KAAK,GAAG,CAAC;AAC1B,kBAAU,eAAe,CAAC,KAAK,CAAC,EAAE;AAClC,aAAK,eAAe,MAAM,MAAM,GAAG,GAAG;AAAA,UACpC,QAAQ,SAAS,UAAU;AAAA,UAC3B,OAAO,SAAS,SAAS;AAAA,QAC3B,CAAC;AAAA,MACH;AAAA,MACA,OAAO,OAAO,QAAgB,WAAmB;AAC/C,kBAAU,eAAe,MAAM,KAAK,MAAM,EAAE;AAC5C,YAAI,KAAK,aAAa,aAAa;AACjC,gBAAO,KAAK,eAAiC,MAAM,MAAM;AAAA,YACvD;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH,WAAW,KAAK,aAAa,cAAc;AACzC,gBAAO,KAAK,eAAkC,MAAM;AAAA,YAClD;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,OAAO,GAAW,MAAc;AACpC,aAAK,YAAY;AACjB,kBAAU,iBAAiB,CAAC,KAAK,CAAC,EAAE;AACpC,eAAO,KAAK,eAAe,MAAM,KAAK,GAAG,CAAC;AAAA,MAC5C;AAAA,MACA,MAAM,OACJ,MACA,OACG;AACH,kBAAU,mBAAmB,KAAK,CAAC,KAAK,KAAK,CAAC,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE;AACpE,YAAI,KAAK,aAAa,aAAa;AACjC,gBAAO,KAAK,eAAiC,MAAM;AAAA,YACjD;AAAA,cACE,GAAG,KAAK;AAAA,cACR,GAAG,KAAK;AAAA,YACV;AAAA,YACA;AAAA,cACE,GAAG,GAAG;AAAA,cACN,GAAG,GAAG;AAAA,YACR;AAAA,UACF;AAAA,QACF,WAAW,KAAK,aAAa,cAAc;AAEzC,gBAAO,KAAK,eAAkC,MAAM;AAAA,YAClD,KAAK;AAAA,YACL,KAAK;AAAA,UACP;AACA,gBAAO,KAAK,eAAkC,MAAM,KAAK;AACzD,gBAAO,KAAK,eAAkC,MAAM,KAAK,GAAG,GAAG,GAAG,CAAC;AACnE,gBAAO,KAAK,eAAkC,MAAM,GAAG;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,IAAI,WAAW;AACb,WAAO;AAAA,MACL,MAAM,OAAO,SAAiB;AAC5B,kBAAU,iBAAiB,IAAI,EAAE;AACjC,eAAO,KAAK,eAAe,SAAS,KAAK,MAAM,EAAE,OAAO,GAAG,CAAC;AAAA,MAC9D;AAAA,MACA,OAAO,OACL,WAGG;AACH,cAAM,OAAO,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AACrD,kBAAU,kBAAkB,IAAI;AAChC,mBAAW,KAAK,MAAM;AACpB,gBAAM,WAAW,EAAE,UAAU,CAAC,EAAE,OAAO,IAAI,CAAC;AAC5C,gBAAM,KAAK,eAAe,SAAS,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC;AAAA,QAC7D;AACA,mBAAW,KAAK,CAAC,GAAG,IAAI,EAAE,QAAQ,GAAG;AACnC,gBAAM,KAAK,eAAe,SAAS,GAAG,EAAE,GAAG;AAAA,QAC7C;AAAA,MACF;AAAA,MACA,MAAM,OAAO,QAAqB;AAChC,kBAAU,iBAAiB,GAAG,EAAE;AAChC,aAAK,eAAe,SAAS,KAAK,GAAG;AAAA,MACvC;AAAA,MACA,IAAI,OAAO,QAAqB;AAC9B,kBAAU,eAAe,GAAG,EAAE;AAC9B,aAAK,eAAe,SAAS,GAAG,GAAG;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,SAAqC;AACpD,QAAI,CAAC,SAAS;AACZ,cAAQ,KAAK,2BAA2B;AACxC;AAAA,IACF;AAEA,UAAM,YAAY,YAAY;AAC5B,gBAAM,sBAAM,GAAG;AACf,YAAM,KAAK,SAAS,MAAM,CAAC,EAAE,KAAK,YAAY,CAAC,CAAC;AAAA,IAClD;AAEA,UAAM,QAAQ,QAAQ,aAAa;AACnC,cAAU,kBAAkB;AAC5B,QAAI,OAAO;AACT,UAAI,KAAK,aAAa,aAAa;AAEjC,cAAM,KAAK,MAAM,MAAM,QAAQ,OAAO,CAAC,GAAG,QAAQ,OAAO,CAAC,GAAG;AAAA,UAC3D,OAAO;AAAA,QACT,CAAC;AACD,cAAM,UAAU;AAAA,MAClB;AAEA,YAAM,KAAK,MAAM,MAAM,QAAQ,OAAO,CAAC,GAAG,QAAQ,OAAO,CAAC,CAAC;AAC3D,YAAM,KAAK,eAAe,SAAS,KAAK,MAAM;AAC9C,YAAM,KAAK,eAAe,SAAS,MAAM,GAAG;AAC5C,YAAM,KAAK,eAAe,SAAS,GAAG,MAAM;AAC5C,YAAM,UAAU;AAAA,IAClB,OAAO;AACL,YAAM,KAAK,MAAM,MAAM,QAAQ,OAAO,CAAC,GAAG,QAAQ,OAAO,CAAC,CAAC;AAC3D,YAAM,KAAK,eAAe,SAAS,KAAK,SAAS;AACjD,YAAM,KAAK,eAAe,SAAS,MAAM,GAAG;AAC5C,YAAM,KAAK,eAAe,SAAS,GAAG,SAAS;AAC/C,YAAM,UAAU;AAAA,IAClB;AACA,cAAU,gBAAgB;AAAA,EAC5B;AAAA,EAGA,MAAc,wBAAwB,OAA8B;AAClE,QAAI,OAAO;AACT,YAAM,KAAK,MAAM,KAAK,MAAM,MAAM,MAAM,GAAG;AAAA,IAC7C,WAAW,CAAC,KAAK,WAAW;AAE1B,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,YAAM,UAAU,KAAK,MAAM,KAAK,QAAQ,CAAC;AACzC,YAAM,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC;AAC1C,YAAM,KAAK,MAAM,KAAK,SAAS,OAAO;AAAA,IACxC;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,eAAsC;AACzD,UAAM,KAAK,wBAAwB,aAAa;AAChD,WAAO,KAAK,MAAM,MAAM,GAAG,QAAQ;AAAA,EACrC;AAAA,EAEA,MAAM,kBAAkB,eAAsC;AAC5D,UAAM,KAAK,wBAAwB,aAAa;AAChD,WAAO,KAAK,MAAM,MAAM,GAAG,OAAO;AAAA,EACpC;AAAA,EAEA,MAAM,gBAAgB,eAAsC;AAC1D,UAAM,KAAK,wBAAwB,aAAa;AAChD,WAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAAA,EACrC;AAAA,EAEA,MAAM,iBAAiB,eAAsC;AAC3D,UAAM,KAAK,wBAAwB,aAAa;AAChD,WAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAAA,EACpC;AAAA,EAEA,MAAM,SAAS,UAAmB,eAAsC;AACtE,UAAM,cAAc,MAAM,KAAK,SAAS,MAAM,OAAO,WAAW;AAChE,UAAM,iBAAiB,YAAY,cAAc;AACjD,UAAM,KAAK,wBAAwB,aAAa;AAChD,WAAO,KAAK,MAAM,MAAM,GAAG,CAAC,cAAc;AAAA,EAC5C;AAAA,EAEA,MAAM,WAAW,UAAmB,eAAsC;AACxE,UAAM,cAAc,MAAM,KAAK,SAAS,MAAM,OAAO,WAAW;AAChE,UAAM,iBAAiB,YAAY,cAAc;AACjD,UAAM,KAAK,wBAAwB,aAAa;AAChD,WAAO,KAAK,MAAM,MAAM,GAAG,cAAc;AAAA,EAC3C;AAAA,EAEA,MAAM,WAAW,UAAmB,eAAsC;AACxE,UAAM,aAAa,MAAM,KAAK,SAAS,MAAM,OAAO,UAAU;AAC9D,UAAM,iBAAiB,YAAY,aAAa;AAChD,UAAM,KAAK,wBAAwB,aAAa;AAChD,WAAO,KAAK,MAAM,MAAM,CAAC,gBAAgB,CAAC;AAAA,EAC5C;AAAA,EAEA,MAAM,YAAY,UAAmB,eAAsC;AACzE,UAAM,aAAa,MAAM,KAAK,SAAS,MAAM,OAAO,UAAU;AAC9D,UAAM,iBAAiB,YAAY,aAAa;AAChD,UAAM,KAAK,wBAAwB,aAAa;AAChD,WAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAAA,EAC3C;AAAA,EAEA,MAAM,SAAS,KAA4B;AACzC,cAAU,eAAe,GAAG,EAAE;AAC9B,QAAI,KAAK,aAAa,aAAa;AACjC,YAAO,KAAK,eAAiC,KAAK,GAAG;AAAA,IACvD,WAAW,KAAK,aAAa,cAAc;AACzC,YAAO,KAAK,eAAkC,KAAK,GAAG;AAAA,IACxD,OAAO;AACL,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAAA,EAAC;AAClC;;;ADlYO,IAAM,UAAN,cAAsB,KAA2C;AAAA,EAItE,YAAY,MAA0B,MAAmB;AACvD,UAAM,MAAM,cAAc,IAAI;AAC9B,UAAM;AAAA,MACJ,2BAA2B;AAAA,MAC3B,4BAA4B;AAAA,IAC9B,IAAI,QAAQ,CAAC;AACb,SAAK,2BAA2B;AAChC,SAAK,4BAA4B;AAAA,EACnC;AACF;;;AErBA,yBAA2B;AAK3B,IAAAE,oBAGO;AACP,IAAAE,iBAAyB;AACzB,kBAAmD;AAInD,IAAMgB,iBAAY,yBAAS,2BAA2B;AAEtD,IAAM,sBAAsB,CAAC,aAAuB;AAClD,MAAI;AACJ,MAAI;AACJ,QAAM,YAAY,CAAC,GAAG,SAAS,SAAS;AAExC,MAAI,UAAU,SAAS,GAAG;AACxB,eAAW,UAAU,MAAM,KAAK;AAChC,gBAAY,UAAU,KAAK,IAAI;AAAA,EACjC,WAAW,UAAU,WAAW,GAAG;AACjC,gBAAY,UAAU,CAAC;AACvB,eAAW,GAAG,SAAS;AAAA,EACzB,OAAO;AACL,gBAAY;AACZ,eAAW;AAAA,EACb;AAEA,QAAM,qBAAqB,GAAG,SAAS,GAAG,SAAS,QAAQ,WAAW,SAAS,KAAK,MAAM,EAAE;AAE5F,SAAO;AAAA,IACL,MAAM;AAAA,IACN,IAAI,gCAAgC,GAAG,QAAQ,IAAI,SAAS,GAAG;AAAA,IAC/D,OAAO,gCAAgC,kBAAkB;AAAA,EAC3D;AACF;AAEA,IAAM,qBAAqB;AACpB,IAAM,2BAA2B;AAEjC,IAAM,sBAAsB,CAAC,YAI9B;AACJ,QAAM;AAAA,IACJ,yBAAyB;AAAA,IACzB,4BAA4B;AAAA,IAC5B,2BAA2B;AAAA,EAC7B,IAAI,WAAW,CAAC;AAChB,QAAM,eAA0C,CAAC;AACjD,QAAM,4BAA4B,CAChC,MACA,UACA,SACG;AACH,QAAI,YAAa,KAAa,kBAAkB;AAChD,QAAI,CAAC,WAAW;AACd,sBAAY,+BAAW;AACvB,MAAC,KAAa,kBAAkB,IAAI;AACpC,YAAM,EAAE,OAAO,IAAI;AACnB,YAAM,EAAE,MAAM,IAAI,MAAM,IAAI,oBAAoB,QAAQ;AACxD,mBAAa,SAAS,IAAI,IAAI,gBAAgB,MAAM;AAAA,QAClD,QAAQ,cAAc,MAAM,IAAI,SAAS;AAAA,QACzC;AAAA,QACA,SAAS;AAAA,QACT,WAAW;AAAA,QACX,kBAAkB;AAAA,QAClB,gBAAgB;AAAA;AAAA,QAChB,GAAG;AAAA,MACL,CAAC;AAED,mBAAa,SAAS,EAAE,eAAe,CAAC,SAAiB;AACvD,6BAAqB,UAAU,IAAI;AAAA,MACrC;AAEA,WAAK,GAAG,SAAS,MAAM;AACrB,QAAAA,WAAU,aAAa;AACvB,qBAAa,SAAS,EAAE,QAAQ;AAChC,eAAO,aAAa,SAAS;AAAA,MAC/B,CAAC;AAAA,IACH;AAEA,WAAO,aAAa,SAAS;AAAA,EAC/B;AAEA,iBAAe,mBAAmBC,UAqB/B;AACD,UAAM,EAAE,MAAM,UAAU,KAAK,aAAa,IAAIA;AAC9C,UAAM,QAAQ,0BAA0B,MAAM,UAAU;AAAA,MACtD;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,IAAI,OAAO,eAAuB,SAAgB;AACtD,aAAO,IAAI,QAAQ,CAACtB,UAAS,WAAW;AACtC,yBAAK,KAAK,MAAM,YAAY,MAAM,KAAK,UAAU,UAAU,CAAC,IAAI,YAAY;AAC1E,cAAI;AACF,YAAAqB;AAAA,cACE,+BAA+B,yBAAyB;AAAA,YAC1D;AACA,kBAAM,MAAM,mBAAmB,yBAAyB;AAAA,UAC1D,SAAS,OAAO;AACd,oBAAQ;AAAA,cACN;AAAA,YACF;AAAA,UACF;AACA,cAAI;AAKF,kBAAM,SAAS,MAAO,MAAM,YAAY;AAAA,cACtC;AAAA,cACA,GAAI,QAAQ,CAAC;AAAA,YACf;AACA,YAAArB,SAAQ,MAAM;AAAA,UAChB,SAAS,OAAO;AACd,mBAAO,KAAK;AAAA,UACd;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,QAAM,uBAAuB,CAACuB,OAAgB,SAAiB;AAC7D,UAAM,oBAAoBA,MAAK,YAAY,KAAK,CAAC,SAAS;AACxD,aAAO,KAAK,SAAS;AAAA,IACvB,CAAC;AACD,QAAI,mBAAmB;AACrB,wBAAkB,cAAc;AAAA,IAClC,OAAO;AACL,MAAAA,MAAK,YAAY,KAAK;AAAA,QACpB,MAAM;AAAA,QACN,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,cAAc,OACZ,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM;AAAA,QACJ,OACE,WACA,SACG;AACH,gBAAM,QAAQ,0BAA0B,aAAa,MAAM,UAAU;AAAA,YACnE;AAAA,YACA;AAAA,YACA,GAAG;AAAA,UACL,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,IACA,IAAI,OACF,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,UAAU,OACR,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,OAAO,OACL,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,cAAc,OACZ,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,SAAS,OACP,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,SAAS,OACP,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,iBAAiB,OACf,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,UAAU,OACR,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,SAAS,OACP,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,UAAU,OACR,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,WAAW,OACT,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,UAAU,OACR,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,UAAU,OACR,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,UAAU,OACR,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,WAAW,OACT,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA,OAAO,OACL,EAAE,KAAK,GACP,KACA,aACG;AACH,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AClXA,IAAAnB,cAAiC;AAGjC,IAAAC,iBAAyB;AAEzB,IAAMO,aAAQ,yBAAS,kBAAkB;AAElC,IAAM,kBAAN,cAA8B,UAA6B;AAAA,EAChE,YAAY,MAAsB,MAAwB;AACxD,UAAM,UAAU,IAAI,QAAkB,MAAM,IAAI;AAChD,UAAM,SAAS,IAAI;AAEnB,UAAM,EAAE,yBAAyB,KAAK,IAAI,QAAQ,CAAC;AAEnD,QAAI,wBAAwB;AAC1B,sBAAgB,MAAMA,MAAK;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,UAAU,KAAM;AACvC,UAAM,KAAK,KAAK,eAAe,iBAAiB,eAAe,EAAE,QAAQ,CAAC;AAAA,EAC5E;AACF;;;AC1BA,IAAAP,iBAAyB;;;ACFzB,IAAAF,oBAIO;AAKA,IAAMqB,WAAN,cAAsB,KAAyC;AAAA,EAIpE,YAAY,MAAyB,MAAmB;AACtD,UAAM,MAAM,aAAa,IAAI;AAC7B,UAAM;AAAA,MACJ,2BAA2B;AAAA,MAC3B,4BAA4B;AAAA,IAC9B,IAAI,QAAQ,CAAC;AACb,SAAK,2BAA2B;AAChC,SAAK,4BAA4B;AAAA,EACnC;AAAA,EAEA,MAAM,qBAAqB,SAIT;AAChB,QAAI,KAAK,8BAA8B,GAAG;AACxC,gBAAU,iDAAiD;AAC3D;AAAA,IACF;AACA,UAAM,KAAK,eAAe,mBAAmB;AAAA,MAC3C,UAAU,SAAS,YAAY,KAAK;AAAA,MACpC,aACE,SAAS,eAAe;AAAA,MAC1B,SAAS,SAAS,WAAW,KAAK;AAAA,IACpC,CAAC;AAAA,EACH;AACF;;;ADdA,IAAApB,cAAiC;AAlBjC,IAAMQ,aAAQ,yBAAS,iBAAiB;AAKjC,IAAM,iBAAN,cAA6B,UAA4B;AAAA,EAC9D,YAAY,MAAqB,MAAwB;AACvD,UAAM,UAAU,IAAIY,SAAiB,MAAM,IAAI;AAC/C,UAAM,SAAS,IAAI;AAEnB,UAAM,EAAE,yBAAyB,KAAK,IAAI,QAAQ,CAAC;AAEnD,QAAI,wBAAwB;AAC1B,sBAAgB,MAAMZ,MAAK;AAAA,IAC7B;AAAA,EACF;AACF;;;AEpBO,IAAM,kBAAN,cAA8B,UAAU;AAAA,EAC7C,YAAY,MAAkB;AAC5B,UAAM,MAAM,CAAC,CAAC;AACd,SAAK,UAAU;AAAA,EACjB;AACF","names":["import_core","import_js_yaml","resolve","import_utils","yaml","import_constants","import_env","import_logger","import_ai_model","import_node_fs","import_node_path","import_common","assert","semver","debug","dayjs","plan","log","sleep","thought","locatePlan","executor","import_extractor","debugPage","options","test","WebPage"],"ignoreList":[],"sources":["../../src/index.ts","../../src/common/agent.ts","../../src/yaml/player.ts","../../src/yaml/builder.ts","../../src/yaml/utils.ts","../../src/common/tasks.ts","../../src/common/ui-utils.ts","../../src/common/utils.ts","../../src/web-element.ts","../../src/common/task-cache.ts","../../package.json","../../src/common/plan-builder.ts","../../src/playwright/page.ts","../../src/puppeteer/base-page.ts","../../src/playwright/ai-fixture.ts","../../src/playwright/index.ts","../../src/puppeteer/index.ts","../../src/puppeteer/page.ts","../../src/playground/agent.ts"],"sourcesContent":["export { PlaywrightAiFixture } from './playwright';\nexport type { PlayWrightAiFixtureType } from './playwright';\nexport type {\n WebPage,\n AndroidDevicePage,\n AndroidDeviceInputOpt,\n} from './common/page';\nexport type { AbstractPage } from './page';\nexport type { WebUIContext } from './web-element';\n\nexport { PageAgent, type PageAgentOpt } from './common/agent';\nexport { PuppeteerAgent } from './puppeteer';\nexport { PlaywrightAgent } from './playwright';\nexport { StaticPageAgent } from './playground/agent';\n\nexport { ScriptPlayer, parseYamlScript } from './yaml';\nexport { parseContextFromWebPage } from './common/utils';\n","import type { WebPage } from '@/common/page';\nimport {\n type AgentAssertOpt,\n type AgentDescribeElementAtPointResult,\n type AgentWaitForOpt,\n type DetailedLocateParam,\n type ExecutionDump,\n type ExecutionRecorderItem,\n type ExecutionTask,\n type ExecutionTaskLog,\n type Executor,\n type GroupedActionDump,\n Insight,\n type InsightAction,\n type InsightExtractOption,\n type InsightExtractParam,\n type LocateOption,\n type LocateResultElement,\n type LocateValidatorResult,\n type LocatorValidatorOption,\n type MidsceneYamlScript,\n type OnTaskStartTip,\n type PlanningActionParamScroll,\n type Rect,\n type TUserPrompt,\n} from '@midscene/core';\n\nimport yaml from 'js-yaml';\n\nimport { ScriptPlayer, parseYamlScript } from '@/yaml/index';\nimport {\n groupedActionDumpFileExt,\n reportHTMLContent,\n stringifyDumpData,\n writeLogFile,\n} from '@midscene/core/utils';\nimport {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@midscene/shared/constants';\nimport { getAIConfigInBoolean, vlLocateMode } from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport { PageTaskExecutor } from '../common/tasks';\nimport type { PlaywrightWebPage } from '../playwright';\nimport type { PuppeteerWebPage } from '../puppeteer';\nimport type { WebElementInfo, WebUIContext } from '../web-element';\nimport type { AndroidDeviceInputOpt } from './page';\nimport { buildPlans } from './plan-builder';\nimport { TaskCache } from './task-cache';\nimport {\n locateParamStr,\n paramStr,\n scrollParamStr,\n taskTitleStr,\n typeStr,\n} from './ui-utils';\nimport { getReportFileName, printReportMsg } from './utils';\nimport { parseContextFromWebPage } from './utils';\nimport { trimContextByViewport } from './utils';\n\nconst debug = getDebug('web-integration');\n\nconst distanceOfTwoPoints = (p1: [number, number], p2: [number, number]) => {\n const [x1, y1] = p1;\n const [x2, y2] = p2;\n return Math.round(Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2));\n};\n\nconst includedInRect = (point: [number, number], rect: Rect) => {\n const [x, y] = point;\n const { left, top, width, height } = rect;\n return x >= left && x <= left + width && y >= top && y <= top + height;\n};\n\nconst defaultInsightExtractOption: InsightExtractOption = {\n domIncluded: false,\n screenshotIncluded: true,\n};\n\nexport interface PageAgentOpt {\n forceSameTabNavigation?: boolean /* if limit the new tab to the current page, default true */;\n testId?: string;\n cacheId?: string;\n groupName?: string;\n groupDescription?: string;\n /* if auto generate report, default true */\n generateReport?: boolean;\n /* if auto print report msg, default true */\n autoPrintReportMsg?: boolean;\n onTaskStartTip?: OnTaskStartTip;\n aiActionContext?: string;\n /* custom report file name */\n reportFileName?: string;\n}\n\nexport type WebPageAgentOpt = PageAgentOpt & WebPageOpt;\nexport type WebPageOpt = {\n waitForNavigationTimeout?: number;\n waitForNetworkIdleTimeout?: number;\n};\n\nexport class PageAgent<PageType extends WebPage = WebPage> {\n page: PageType;\n\n insight: Insight<WebElementInfo, WebUIContext>;\n\n dump: GroupedActionDump;\n\n reportFile?: string | null;\n\n reportFileName?: string;\n\n taskExecutor: PageTaskExecutor;\n\n opts: PageAgentOpt;\n\n /**\n * If true, the agent will not perform any actions\n */\n dryMode = false;\n\n onTaskStartTip?: OnTaskStartTip;\n\n taskCache?: TaskCache;\n\n onDumpUpdate?: (dump: string) => void;\n\n destroyed = false;\n\n /**\n * Frozen page context for consistent AI operations\n */\n private frozenPageContext?: WebUIContext;\n\n constructor(page: PageType, opts?: PageAgentOpt) {\n this.page = page;\n this.opts = Object.assign(\n {\n generateReport: true,\n autoPrintReportMsg: true,\n groupName: 'Midscene Report',\n groupDescription: '',\n },\n opts || {},\n );\n\n if (\n this.page.pageType === 'puppeteer' ||\n this.page.pageType === 'playwright'\n ) {\n (\n this.page as PuppeteerWebPage | PlaywrightWebPage\n ).waitForNavigationTimeout =\n (this.opts as WebPageAgentOpt).waitForNavigationTimeout ??\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;\n (\n this.page as PuppeteerWebPage | PlaywrightWebPage\n ).waitForNetworkIdleTimeout =\n (this.opts as WebPageAgentOpt).waitForNetworkIdleTimeout ??\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n }\n\n this.onTaskStartTip = this.opts.onTaskStartTip;\n // get the parent browser of the puppeteer page\n // const browser = (this.page as PuppeteerWebPage).browser();\n\n this.insight = new Insight<WebElementInfo, WebUIContext>(\n async (action: InsightAction) => {\n return this.getUIContext(action);\n },\n );\n\n if (opts?.cacheId && this.page.pageType !== 'android') {\n this.taskCache = new TaskCache(\n opts.cacheId,\n getAIConfigInBoolean('MIDSCENE_CACHE'), // if we should use cache to match the element\n );\n }\n\n this.taskExecutor = new PageTaskExecutor(this.page, this.insight, {\n taskCache: this.taskCache,\n onTaskStart: this.callbackOnTaskStartTip.bind(this),\n });\n this.dump = this.resetDump();\n this.reportFileName =\n opts?.reportFileName ||\n getReportFileName(opts?.testId || this.page.pageType || 'web');\n }\n\n async getUIContext(action?: InsightAction): Promise<WebUIContext> {\n // If page context is frozen, return the frozen context for all actions\n if (this.frozenPageContext) {\n debug('Using frozen page context for action:', action);\n return this.frozenPageContext;\n }\n\n // Otherwise, get fresh context based on the action type\n if (action && (action === 'extract' || action === 'assert')) {\n return await parseContextFromWebPage(this.page, {\n ignoreMarker: true,\n });\n }\n return await parseContextFromWebPage(this.page, {\n ignoreMarker: !!vlLocateMode(),\n });\n }\n\n async _snapshotContext(): Promise<WebUIContext> {\n return await this.getUIContext('locate');\n }\n\n async setAIActionContext(prompt: string) {\n this.opts.aiActionContext = prompt;\n }\n\n resetDump() {\n this.dump = {\n groupName: this.opts.groupName!,\n groupDescription: this.opts.groupDescription,\n executions: [],\n };\n\n return this.dump;\n }\n\n appendExecutionDump(execution: ExecutionDump) {\n // use trimContextByViewport to process execution\n const trimmedExecution = trimContextByViewport(execution);\n const currentDump = this.dump;\n currentDump.executions.push(trimmedExecution);\n }\n\n dumpDataString() {\n // update dump info\n this.dump.groupName = this.opts.groupName!;\n this.dump.groupDescription = this.opts.groupDescription;\n return stringifyDumpData(this.dump);\n }\n\n reportHTMLString() {\n return reportHTMLContent(this.dumpDataString());\n }\n\n writeOutActionDumps() {\n if (this.destroyed) {\n throw new Error(\n 'PageAgent has been destroyed. Cannot update report file.',\n );\n }\n const { generateReport, autoPrintReportMsg } = this.opts;\n this.reportFile = writeLogFile({\n fileName: this.reportFileName!,\n fileExt: groupedActionDumpFileExt,\n fileContent: this.dumpDataString(),\n type: 'dump',\n generateReport,\n });\n debug('writeOutActionDumps', this.reportFile);\n if (generateReport && autoPrintReportMsg && this.reportFile) {\n printReportMsg(this.reportFile);\n }\n }\n\n private async callbackOnTaskStartTip(task: ExecutionTask) {\n const param = paramStr(task);\n const tip = param ? `${typeStr(task)} - ${param}` : typeStr(task);\n\n if (this.onTaskStartTip) {\n await this.onTaskStartTip(tip);\n }\n }\n\n private async afterTaskRunning(executor: Executor, doNotThrowError = false) {\n this.appendExecutionDump(executor.dump());\n\n try {\n await this.onDumpUpdate?.(this.dumpDataString());\n } catch (error) {\n console.error('Error in onDumpUpdate', error);\n }\n\n this.writeOutActionDumps();\n\n if (executor.isInErrorState() && !doNotThrowError) {\n const errorTask = executor.latestErrorTask();\n throw new Error(`${errorTask?.errorMessage}\\n${errorTask?.errorStack}`, {\n cause: errorTask?.error,\n });\n }\n }\n\n private buildDetailedLocateParam(\n locatePrompt: TUserPrompt,\n opt?: LocateOption,\n ): DetailedLocateParam {\n assert(locatePrompt, 'missing locate prompt');\n\n if (typeof opt === 'object' && opt !== null) {\n const prompt = locatePrompt;\n const deepThink = opt.deepThink ?? false;\n const cacheable = opt.cacheable ?? true;\n const xpath = opt.xpath;\n\n return {\n prompt,\n deepThink,\n cacheable,\n xpath,\n };\n }\n\n return {\n prompt: locatePrompt,\n };\n }\n\n async aiTap(locatePrompt: TUserPrompt, opt?: LocateOption) {\n const detailedLocateParam = this.buildDetailedLocateParam(\n locatePrompt,\n opt,\n );\n const plans = buildPlans('Tap', detailedLocateParam);\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Tap', locateParamStr(detailedLocateParam)),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiRightClick(locatePrompt: TUserPrompt, opt?: LocateOption) {\n const detailedLocateParam = this.buildDetailedLocateParam(\n locatePrompt,\n opt,\n );\n const plans = buildPlans('RightClick', detailedLocateParam);\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('RightClick', locateParamStr(detailedLocateParam)),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiHover(locatePrompt: TUserPrompt, opt?: LocateOption) {\n const detailedLocateParam = this.buildDetailedLocateParam(\n locatePrompt,\n opt,\n );\n const plans = buildPlans('Hover', detailedLocateParam);\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Hover', locateParamStr(detailedLocateParam)),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiInput(\n value: string,\n locatePrompt: TUserPrompt,\n opt?: AndroidDeviceInputOpt & LocateOption,\n ) {\n assert(\n typeof value === 'string',\n 'input value must be a string, use empty string if you want to clear the input',\n );\n assert(locatePrompt, 'missing locate prompt for input');\n const detailedLocateParam = this.buildDetailedLocateParam(\n locatePrompt,\n opt,\n );\n const plans = buildPlans('Input', detailedLocateParam, {\n value,\n autoDismissKeyboard: opt?.autoDismissKeyboard,\n });\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Input', locateParamStr(detailedLocateParam)),\n plans,\n {\n cacheable: opt?.cacheable,\n },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiKeyboardPress(\n keyName: string,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ) {\n assert(keyName, 'missing keyName for keyboard press');\n const detailedLocateParam = locatePrompt\n ? this.buildDetailedLocateParam(locatePrompt, opt)\n : undefined;\n const plans = buildPlans('KeyboardPress', detailedLocateParam, {\n value: keyName,\n });\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('KeyboardPress', locateParamStr(detailedLocateParam)),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiScroll(\n scrollParam: PlanningActionParamScroll,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ) {\n const detailedLocateParam = locatePrompt\n ? this.buildDetailedLocateParam(locatePrompt, opt)\n : undefined;\n const plans = buildPlans('Scroll', detailedLocateParam, scrollParam);\n const paramInTitle = locatePrompt\n ? `${locateParamStr(detailedLocateParam)} - ${scrollParamStr(scrollParam)}`\n : scrollParamStr(scrollParam);\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Scroll', paramInTitle),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiAction(\n taskPrompt: string,\n opt?: {\n cacheable?: boolean;\n },\n ) {\n const cacheable = opt?.cacheable;\n // if vlm-ui-tars, plan cache is not used\n const isVlmUiTars = vlLocateMode() === 'vlm-ui-tars';\n const matchedCache =\n isVlmUiTars || cacheable === false\n ? undefined\n : this.taskCache?.matchPlanCache(taskPrompt);\n if (matchedCache && this.taskCache?.isCacheResultUsed) {\n // log into report file\n const { executor } = await this.taskExecutor.loadYamlFlowAsPlanning(\n taskPrompt,\n matchedCache.cacheContent?.yamlWorkflow,\n );\n\n await await this.afterTaskRunning(executor);\n\n debug('matched cache, will call .runYaml to run the action');\n const yaml = matchedCache.cacheContent?.yamlWorkflow;\n return this.runYaml(yaml);\n }\n\n const { output, executor } = await (isVlmUiTars\n ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable })\n : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext, {\n cacheable,\n }));\n\n // update cache\n if (this.taskCache && output?.yamlFlow && cacheable !== false) {\n const yamlContent: MidsceneYamlScript = {\n tasks: [\n {\n name: taskPrompt,\n flow: output.yamlFlow,\n },\n ],\n };\n const yamlFlowStr = yaml.dump(yamlContent);\n this.taskCache.updateOrAppendCacheRecord(\n {\n type: 'plan',\n prompt: taskPrompt,\n yamlWorkflow: yamlFlowStr,\n },\n matchedCache,\n );\n }\n\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiQuery(\n demand: InsightExtractParam,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ) {\n const { output, executor } = await this.taskExecutor.query(demand, opt);\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiBoolean(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ) {\n const { output, executor } = await this.taskExecutor.boolean(prompt, opt);\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiNumber(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ) {\n const { output, executor } = await this.taskExecutor.number(prompt, opt);\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiString(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ) {\n const { output, executor } = await this.taskExecutor.string(prompt, opt);\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiAsk(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ) {\n return this.aiString(prompt, opt);\n }\n\n async describeElementAtPoint(\n center: [number, number],\n opt?: {\n verifyPrompt?: boolean;\n retryLimit?: number;\n deepThink?: boolean;\n } & LocatorValidatorOption,\n ): Promise<AgentDescribeElementAtPointResult> {\n const { verifyPrompt = true, retryLimit = 3 } = opt || {};\n\n let success = false;\n let retryCount = 0;\n let resultPrompt = '';\n let deepThink = opt?.deepThink || false;\n let verifyResult: LocateValidatorResult | undefined;\n\n while (!success && retryCount < retryLimit) {\n if (retryCount >= 2) {\n deepThink = true;\n }\n debug(\n 'aiDescribe',\n center,\n 'verifyPrompt',\n verifyPrompt,\n 'retryCount',\n retryCount,\n 'deepThink',\n deepThink,\n );\n const text = await this.insight.describe(center, { deepThink });\n debug('aiDescribe text', text);\n assert(text.description, `failed to describe element at [${center}]`);\n resultPrompt = text.description;\n\n verifyResult = await this.verifyLocator(\n resultPrompt,\n deepThink ? { deepThink: true } : undefined,\n center,\n opt,\n );\n if (verifyResult.pass) {\n success = true;\n } else {\n retryCount++;\n }\n }\n\n return {\n prompt: resultPrompt,\n deepThink,\n verifyResult,\n };\n }\n\n async verifyLocator(\n prompt: string,\n locateOpt: LocateOption | undefined,\n expectCenter: [number, number],\n verifyLocateOption?: LocatorValidatorOption,\n ): Promise<LocateValidatorResult> {\n debug('verifyLocator', prompt, locateOpt, expectCenter, verifyLocateOption);\n\n const { center: verifyCenter, rect: verifyRect } = await this.aiLocate(\n prompt,\n locateOpt,\n );\n const distance = distanceOfTwoPoints(expectCenter, verifyCenter);\n const included = includedInRect(expectCenter, verifyRect);\n const pass =\n distance <= (verifyLocateOption?.centerDistanceThreshold || 20) ||\n included;\n const verifyResult = {\n pass,\n rect: verifyRect,\n center: verifyCenter,\n centerDistance: distance,\n };\n debug('aiDescribe verifyResult', verifyResult);\n return verifyResult;\n }\n\n async aiLocate(prompt: TUserPrompt, opt?: LocateOption) {\n const detailedLocateParam = this.buildDetailedLocateParam(prompt, opt);\n const plans = buildPlans('Locate', detailedLocateParam);\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Locate', locateParamStr(detailedLocateParam)),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n\n const { element } = output;\n\n return {\n rect: element?.rect,\n center: element?.center,\n scale: (await this.page.size()).dpr,\n } as Pick<LocateResultElement, 'rect' | 'center'> & {\n scale: number;\n };\n }\n\n async aiAssert(assertion: TUserPrompt, msg?: string, opt?: AgentAssertOpt) {\n const { output, executor, thought } = await this.taskExecutor.assert(\n assertion,\n {\n returnThought: true,\n },\n );\n await this.afterTaskRunning(executor, true);\n\n if (opt?.keepRawResponse) {\n return {\n pass: output,\n thought,\n };\n }\n\n if (!output) {\n const errMsg = msg || `Assertion failed: ${assertion}`;\n const reasonMsg = `Reason: ${\n thought || executor.latestErrorTask()?.error || '(no_reason)'\n }`;\n throw new Error(`${errMsg}\\n${reasonMsg}`);\n }\n }\n\n async aiWaitFor(assertion: string, opt?: AgentWaitForOpt) {\n const { executor } = await this.taskExecutor.waitFor(assertion, {\n timeoutMs: opt?.timeoutMs || 15 * 1000,\n checkIntervalMs: opt?.checkIntervalMs || 3 * 1000,\n assertion,\n });\n await this.afterTaskRunning(executor, true);\n\n if (executor.isInErrorState()) {\n const errorTask = executor.latestErrorTask();\n throw new Error(`${errorTask?.error}\\n${errorTask?.errorStack}`);\n }\n }\n\n async ai(taskPrompt: string, type = 'action') {\n if (type === 'action') {\n return this.aiAction(taskPrompt);\n }\n if (type === 'query') {\n return this.aiQuery(taskPrompt);\n }\n\n if (type === 'assert') {\n return this.aiAssert(taskPrompt);\n }\n\n if (type === 'tap') {\n return this.aiTap(taskPrompt);\n }\n\n if (type === 'rightClick') {\n return this.aiRightClick(taskPrompt);\n }\n\n throw new Error(\n `Unknown type: ${type}, only support 'action', 'query', 'assert', 'tap', 'rightClick'`,\n );\n }\n\n async runYaml(yamlScriptContent: string): Promise<{\n result: Record<string, any>;\n }> {\n const script = parseYamlScript(yamlScriptContent, 'yaml', true);\n const player = new ScriptPlayer(script, async (target) => {\n return { agent: this, freeFn: [] };\n });\n await player.run();\n\n if (player.status === 'error') {\n const errors = player.taskStatusList\n .filter((task) => task.status === 'error')\n .map((task) => {\n return `task - ${task.name}: ${task.error?.message}`;\n })\n .join('\\n');\n throw new Error(`Error(s) occurred in running yaml script:\\n${errors}`);\n }\n\n return {\n result: player.result,\n };\n }\n\n async evaluateJavaScript(script: string) {\n assert(\n this.page.evaluateJavaScript,\n 'evaluateJavaScript is not supported in current agent',\n );\n return this.page.evaluateJavaScript(script);\n }\n\n async destroy() {\n await this.page.destroy();\n this.resetDump(); // reset dump to release memory\n this.destroyed = true;\n }\n\n async logScreenshot(\n title?: string,\n opt?: {\n content: string;\n },\n ) {\n // 1. screenshot\n const base64 = await this.page.screenshotBase64();\n const now = Date.now();\n // 2. build recorder\n const recorder: ExecutionRecorderItem[] = [\n {\n type: 'screenshot',\n ts: now,\n screenshot: base64,\n },\n ];\n // 3. build ExecutionTaskLog\n const task: ExecutionTaskLog = {\n type: 'Log',\n subType: 'Screenshot',\n status: 'finished',\n recorder,\n timing: {\n start: now,\n end: now,\n cost: 0,\n },\n param: {\n content: opt?.content || '',\n },\n executor: async () => {},\n };\n // 4. build ExecutionDump\n const executionDump: ExecutionDump = {\n sdkVersion: '',\n logTime: now,\n model_name: '',\n model_description: '',\n name: `Log - ${title || 'untitled'}`,\n description: opt?.content || '',\n tasks: [task],\n };\n // 5. append to execution dump\n this.appendExecutionDump(executionDump);\n\n try {\n this.onDumpUpdate?.(this.dumpDataString());\n } catch (error) {\n console.error('Failed to update dump', error);\n }\n\n this.writeOutActionDumps();\n }\n\n _unstableLogContent() {\n const { groupName, groupDescription, executions } = this.dump;\n const newExecutions = Array.isArray(executions)\n ? executions.map((execution: any) => {\n const { tasks, ...restExecution } = execution;\n let newTasks = tasks;\n if (Array.isArray(tasks)) {\n newTasks = tasks.map((task: any) => {\n // only remove pageContext and log from task\n const { pageContext, log, ...restTask } = task;\n return restTask;\n });\n }\n return { ...restExecution, ...(newTasks ? { tasks: newTasks } : {}) };\n })\n : [];\n return {\n groupName,\n groupDescription,\n executions: newExecutions,\n };\n }\n\n /**\n * Freezes the current page context to be reused in subsequent AI operations\n * This avoids recalculating page context for each operation\n */\n async freezePageContext(): Promise<void> {\n debug('Freezing page context');\n const context = await this._snapshotContext();\n // Mark the context as frozen\n context._isFrozen = true;\n this.frozenPageContext = context;\n debug('Page context frozen successfully');\n }\n\n /**\n * Unfreezes the page context, allowing AI operations to calculate context dynamically\n */\n async unfreezePageContext(): Promise<void> {\n debug('Unfreezing page context');\n this.frozenPageContext = undefined;\n debug('Page context unfrozen successfully');\n }\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { assert, ifInBrowser, ifInWorker } from '@midscene/shared/utils';\n\nimport type { PageAgent } from '@/common/agent';\nimport type {\n FreeFn,\n MidsceneYamlFlowItemAIAction,\n MidsceneYamlFlowItemAIAsk,\n MidsceneYamlFlowItemAIAssert,\n MidsceneYamlFlowItemAIBoolean,\n MidsceneYamlFlowItemAIHover,\n MidsceneYamlFlowItemAIInput,\n MidsceneYamlFlowItemAIKeyboardPress,\n MidsceneYamlFlowItemAILocate,\n MidsceneYamlFlowItemAINumber,\n MidsceneYamlFlowItemAIQuery,\n MidsceneYamlFlowItemAIRightClick,\n MidsceneYamlFlowItemAIScroll,\n MidsceneYamlFlowItemAIString,\n MidsceneYamlFlowItemAITap,\n MidsceneYamlFlowItemAIWaitFor,\n MidsceneYamlFlowItemEvaluateJavaScript,\n MidsceneYamlFlowItemLogScreenshot,\n MidsceneYamlFlowItemSleep,\n MidsceneYamlScript,\n MidsceneYamlScriptEnv,\n ScriptPlayerStatusValue,\n ScriptPlayerTaskStatus,\n} from '@midscene/core';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\n\nexport class ScriptPlayer<T extends MidsceneYamlScriptEnv> {\n public currentTaskIndex?: number;\n public taskStatusList: ScriptPlayerTaskStatus[] = [];\n public status: ScriptPlayerStatusValue = 'init';\n public reportFile?: string | null;\n public result: Record<string, any>;\n private unnamedResultIndex = 0;\n public output?: string | null;\n public unstableLogContent?: string | null;\n public errorInSetup?: Error;\n private pageAgent: PageAgent | null = null;\n public agentStatusTip?: string;\n public target?: MidsceneYamlScriptEnv;\n private scriptPath?: string;\n constructor(\n private script: MidsceneYamlScript,\n private setupAgent: (platform: T) => Promise<{\n agent: PageAgent;\n freeFn: FreeFn[];\n }>,\n public onTaskStatusChange?: (taskStatus: ScriptPlayerTaskStatus) => void,\n scriptPath?: string,\n ) {\n this.scriptPath = scriptPath;\n this.result = {};\n\n this.target = script.target || script.web || script.android;\n\n if (ifInBrowser || ifInWorker) {\n this.output = undefined;\n } else if (this.target?.output) {\n this.output = resolve(process.cwd(), this.target.output);\n } else {\n const scriptName = this.scriptPath\n ? basename(this.scriptPath, '.yaml').replace(/\\.(ya?ml)$/i, '')\n : 'script';\n this.output = join(\n getMidsceneRunSubDir('output'),\n `${scriptName}-${Date.now()}.json`,\n );\n }\n\n if (ifInBrowser || ifInWorker) {\n this.unstableLogContent = undefined;\n } else if (typeof this.target?.unstableLogContent === 'string') {\n this.unstableLogContent = resolve(\n process.cwd(),\n this.target.unstableLogContent,\n );\n } else if (this.target?.unstableLogContent === true) {\n this.unstableLogContent = join(\n getMidsceneRunSubDir('output'),\n 'unstableLogContent.json',\n );\n }\n\n this.taskStatusList = (script.tasks || []).map((task, taskIndex) => ({\n ...task,\n index: taskIndex,\n status: 'init',\n totalSteps: task.flow?.length || 0,\n }));\n }\n\n private setResult(key: string | undefined, value: any) {\n const keyToUse = key || this.unnamedResultIndex++;\n if (this.result[keyToUse]) {\n console.warn(`result key ${keyToUse} already exists, will overwrite`);\n }\n this.result[keyToUse] = value;\n\n return this.flushResult();\n }\n\n private setPlayerStatus(status: ScriptPlayerStatusValue, error?: Error) {\n this.status = status;\n this.errorInSetup = error;\n }\n\n private notifyCurrentTaskStatusChange(taskIndex?: number) {\n const taskIndexToNotify =\n typeof taskIndex === 'number' ? taskIndex : this.currentTaskIndex;\n\n if (typeof taskIndexToNotify !== 'number') {\n return;\n }\n\n const taskStatus = this.taskStatusList[taskIndexToNotify];\n if (this.onTaskStatusChange) {\n this.onTaskStatusChange(taskStatus);\n }\n }\n\n private async setTaskStatus(\n index: number,\n statusValue: ScriptPlayerStatusValue,\n error?: Error,\n ) {\n this.taskStatusList[index].status = statusValue;\n if (error) {\n this.taskStatusList[index].error = error;\n }\n\n this.notifyCurrentTaskStatusChange(index);\n }\n\n private setTaskIndex(taskIndex: number) {\n this.currentTaskIndex = taskIndex;\n }\n\n private flushResult() {\n if (this.output) {\n const output = resolve(process.cwd(), this.output);\n const outputDir = dirname(output);\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(output, JSON.stringify(this.result || {}, undefined, 2));\n }\n }\n\n private flushUnstableLogContent() {\n if (this.unstableLogContent) {\n const content = this.pageAgent?._unstableLogContent();\n const filePath = resolve(process.cwd(), this.unstableLogContent);\n const outputDir = dirname(filePath);\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(filePath, JSON.stringify(content, null, 2));\n }\n }\n\n async playTask(taskStatus: ScriptPlayerTaskStatus, agent: PageAgent) {\n const { flow } = taskStatus;\n assert(flow, 'missing flow in task');\n\n for (const flowItemIndex in flow) {\n const currentStep = Number.parseInt(flowItemIndex, 10);\n taskStatus.currentStep = currentStep;\n const flowItem = flow[flowItemIndex];\n if (\n 'aiAction' in (flowItem as MidsceneYamlFlowItemAIAction) ||\n 'ai' in (flowItem as MidsceneYamlFlowItemAIAction)\n ) {\n const actionTask = flowItem as MidsceneYamlFlowItemAIAction;\n const prompt = actionTask.aiAction || actionTask.ai;\n assert(prompt, 'missing prompt for ai (aiAction)');\n assert(\n typeof prompt === 'string',\n 'prompt for aiAction must be a string',\n );\n await agent.aiAction(prompt, {\n cacheable: actionTask.cacheable,\n });\n } else if ('aiAssert' in (flowItem as MidsceneYamlFlowItemAIAssert)) {\n const assertTask = flowItem as MidsceneYamlFlowItemAIAssert;\n const prompt = assertTask.aiAssert;\n const msg = assertTask.errorMessage;\n assert(prompt, 'missing prompt for aiAssert');\n assert(\n typeof prompt === 'string',\n 'prompt for aiAssert must be a string',\n );\n await agent.aiAssert(prompt, msg);\n } else if ('aiQuery' in (flowItem as MidsceneYamlFlowItemAIQuery)) {\n const queryTask = flowItem as MidsceneYamlFlowItemAIQuery;\n const prompt = queryTask.aiQuery;\n const options = {\n domIncluded: queryTask.domIncluded,\n screenshotIncluded: queryTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiQuery');\n assert(\n typeof prompt === 'string',\n 'prompt for aiQuery must be a string',\n );\n const queryResult = await agent.aiQuery(prompt, options);\n this.setResult(queryTask.name, queryResult);\n } else if ('aiNumber' in (flowItem as MidsceneYamlFlowItemAINumber)) {\n const numberTask = flowItem as MidsceneYamlFlowItemAINumber;\n const prompt = numberTask.aiNumber;\n const options = {\n domIncluded: numberTask.domIncluded,\n screenshotIncluded: numberTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiNumber');\n assert(\n typeof prompt === 'string',\n 'prompt for number must be a string',\n );\n const numberResult = await agent.aiNumber(prompt, options);\n this.setResult(numberTask.name, numberResult);\n } else if ('aiString' in (flowItem as MidsceneYamlFlowItemAIString)) {\n const stringTask = flowItem as MidsceneYamlFlowItemAIString;\n const prompt = stringTask.aiString;\n const options = {\n domIncluded: stringTask.domIncluded,\n screenshotIncluded: stringTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiString');\n assert(\n typeof prompt === 'string',\n 'prompt for string must be a string',\n );\n const stringResult = await agent.aiString(prompt, options);\n this.setResult(stringTask.name, stringResult);\n } else if ('aiBoolean' in (flowItem as MidsceneYamlFlowItemAIBoolean)) {\n const booleanTask = flowItem as MidsceneYamlFlowItemAIBoolean;\n const prompt = booleanTask.aiBoolean;\n const options = {\n domIncluded: booleanTask.domIncluded,\n screenshotIncluded: booleanTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiBoolean');\n assert(\n typeof prompt === 'string',\n 'prompt for boolean must be a string',\n );\n const booleanResult = await agent.aiBoolean(prompt, options);\n this.setResult(booleanTask.name, booleanResult);\n } else if ('aiAsk' in (flowItem as MidsceneYamlFlowItemAIAsk)) {\n const askTask = flowItem as MidsceneYamlFlowItemAIAsk;\n const prompt = askTask.aiAsk;\n assert(prompt, 'missing prompt for aiAsk');\n assert(typeof prompt === 'string', 'prompt for aiAsk must be a string');\n const askResult = await agent.aiAsk(prompt);\n this.setResult(askTask.name, askResult);\n } else if ('aiLocate' in (flowItem as MidsceneYamlFlowItemAILocate)) {\n const locateTask = flowItem as MidsceneYamlFlowItemAILocate;\n const prompt = locateTask.aiLocate;\n assert(prompt, 'missing prompt for aiLocate');\n assert(\n typeof prompt === 'string',\n 'prompt for aiLocate must be a string',\n );\n const locateResult = await agent.aiLocate(prompt, locateTask);\n this.setResult(locateTask.name, locateResult);\n } else if ('aiWaitFor' in (flowItem as MidsceneYamlFlowItemAIWaitFor)) {\n const waitForTask = flowItem as MidsceneYamlFlowItemAIWaitFor;\n const prompt = waitForTask.aiWaitFor;\n assert(prompt, 'missing prompt for aiWaitFor');\n assert(\n typeof prompt === 'string',\n 'prompt for aiWaitFor must be a string',\n );\n const timeout = waitForTask.timeout;\n await agent.aiWaitFor(prompt, { timeoutMs: timeout });\n } else if ('sleep' in (flowItem as MidsceneYamlFlowItemSleep)) {\n const sleepTask = flowItem as MidsceneYamlFlowItemSleep;\n const ms = sleepTask.sleep;\n let msNumber = ms;\n if (typeof ms === 'string') {\n msNumber = Number.parseInt(ms, 10);\n }\n assert(\n msNumber && msNumber > 0,\n `ms for sleep must be greater than 0, but got ${ms}`,\n );\n await new Promise((resolve) => setTimeout(resolve, msNumber));\n } else if ('aiTap' in (flowItem as MidsceneYamlFlowItemAITap)) {\n const tapTask = flowItem as MidsceneYamlFlowItemAITap;\n await agent.aiTap(tapTask.aiTap, tapTask);\n } else if (\n 'aiRightClick' in (flowItem as MidsceneYamlFlowItemAIRightClick)\n ) {\n const rightClickTask = flowItem as MidsceneYamlFlowItemAIRightClick;\n await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);\n } else if ('aiHover' in (flowItem as MidsceneYamlFlowItemAIHover)) {\n const hoverTask = flowItem as MidsceneYamlFlowItemAIHover;\n await agent.aiHover(hoverTask.aiHover, hoverTask);\n } else if ('aiInput' in (flowItem as MidsceneYamlFlowItemAIInput)) {\n // may be input empty string ''\n const inputTask = flowItem as MidsceneYamlFlowItemAIInput;\n await agent.aiInput(inputTask.aiInput, inputTask.locate, inputTask);\n } else if (\n 'aiKeyboardPress' in (flowItem as MidsceneYamlFlowItemAIKeyboardPress)\n ) {\n const keyboardPressTask =\n flowItem as MidsceneYamlFlowItemAIKeyboardPress;\n await agent.aiKeyboardPress(\n keyboardPressTask.aiKeyboardPress,\n keyboardPressTask.locate,\n keyboardPressTask,\n );\n } else if ('aiScroll' in (flowItem as MidsceneYamlFlowItemAIScroll)) {\n const scrollTask = flowItem as MidsceneYamlFlowItemAIScroll;\n await agent.aiScroll(scrollTask, scrollTask.locate, scrollTask);\n } else if (\n 'javascript' in (flowItem as MidsceneYamlFlowItemEvaluateJavaScript)\n ) {\n const evaluateJavaScriptTask =\n flowItem as MidsceneYamlFlowItemEvaluateJavaScript;\n\n const result = await agent.evaluateJavaScript(\n evaluateJavaScriptTask.javascript,\n );\n this.setResult(evaluateJavaScriptTask.name, result);\n } else if (\n 'logScreenshot' in (flowItem as MidsceneYamlFlowItemLogScreenshot)\n ) {\n const logScreenshotTask = flowItem as MidsceneYamlFlowItemLogScreenshot;\n await agent.logScreenshot(logScreenshotTask.logScreenshot, {\n content: logScreenshotTask.content || '',\n });\n } else {\n throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);\n }\n }\n this.reportFile = agent.reportFile;\n await this.flushUnstableLogContent();\n }\n\n async run() {\n const { target, web, android, tasks } = this.script;\n const webEnv = web || target;\n const androidEnv = android;\n const platform = webEnv || androidEnv;\n\n this.setPlayerStatus('running');\n\n let agent: PageAgent | null = null;\n let freeFn: FreeFn[] = [];\n try {\n const { agent: newAgent, freeFn: newFreeFn } = await this.setupAgent(\n platform as T,\n );\n agent = newAgent;\n const originalOnTaskStartTip = agent.onTaskStartTip;\n agent.onTaskStartTip = (tip) => {\n if (this.status === 'running') {\n this.agentStatusTip = tip;\n }\n originalOnTaskStartTip?.(tip);\n };\n freeFn = [\n ...(newFreeFn || []),\n {\n name: 'restore-agent-onTaskStartTip',\n fn: () => {\n if (agent) {\n agent.onTaskStartTip = originalOnTaskStartTip;\n }\n },\n },\n ];\n } catch (e) {\n this.setPlayerStatus('error', e as Error);\n return;\n }\n this.pageAgent = agent;\n\n let taskIndex = 0;\n this.setPlayerStatus('running');\n let errorFlag = false;\n while (taskIndex < tasks.length) {\n const taskStatus = this.taskStatusList[taskIndex];\n this.setTaskStatus(taskIndex, 'running' as any);\n this.setTaskIndex(taskIndex);\n\n try {\n await this.playTask(taskStatus, this.pageAgent);\n this.setTaskStatus(taskIndex, 'done' as any);\n } catch (e) {\n this.setTaskStatus(taskIndex, 'error' as any, e as Error);\n\n if (taskStatus.continueOnError) {\n // nothing more to do\n } else {\n this.reportFile = agent.reportFile;\n errorFlag = true;\n break;\n }\n }\n this.reportFile = agent?.reportFile;\n taskIndex++;\n }\n\n if (errorFlag) {\n this.setPlayerStatus('error');\n } else {\n this.setPlayerStatus('done');\n }\n this.agentStatusTip = '';\n\n // free the resources\n for (const fn of freeFn) {\n try {\n // console.log('freeing', fn.name);\n await fn.fn();\n // console.log('freed', fn.name);\n } catch (e) {\n // console.error('error freeing', fn.name, e);\n }\n }\n }\n}\n","import type {\n MidsceneYamlScript,\n MidsceneYamlScriptWebEnv,\n MidsceneYamlTask,\n} from '@midscene/core';\nimport yaml from 'js-yaml';\n\nexport function buildYaml(\n env: MidsceneYamlScriptWebEnv,\n tasks: MidsceneYamlTask[],\n) {\n const result: MidsceneYamlScript = {\n target: env,\n tasks,\n };\n\n return yaml.dump(result, {\n indent: 2,\n });\n}\n","import { assert } from '@midscene/shared/utils';\nimport yaml from 'js-yaml';\n\nimport type { MidsceneYamlScript } from '@midscene/core';\n\nexport function interpolateEnvVars(content: string): string {\n return content.replace(/\\$\\{([^}]+)\\}/g, (_, envVar) => {\n const value = process.env[envVar.trim()];\n if (value === undefined) {\n throw new Error(`Environment variable \"${envVar.trim()}\" is not defined`);\n }\n return value;\n });\n}\n\nexport function parseYamlScript(\n content: string,\n filePath?: string,\n ignoreCheckingTarget?: boolean,\n): MidsceneYamlScript {\n let processedContent = content;\n if (content.indexOf('android') !== -1 && content.match(/deviceId:\\s*(\\d+)/)) {\n let matchedDeviceId;\n processedContent = content.replace(\n /deviceId:\\s*(\\d+)/g,\n (match, deviceId) => {\n matchedDeviceId = deviceId;\n return `deviceId: '${deviceId}'`;\n },\n );\n console.warn(\n `please use string-style deviceId in yaml script, for example: deviceId: \"${matchedDeviceId}\"`,\n );\n }\n const interpolatedContent = interpolateEnvVars(processedContent);\n const obj = yaml.load(interpolatedContent, {\n schema: yaml.JSON_SCHEMA,\n }) as MidsceneYamlScript;\n\n const pathTip = filePath ? `, failed to load ${filePath}` : '';\n const android =\n typeof obj.android !== 'undefined'\n ? Object.assign({}, obj.android || {})\n : undefined;\n const webConfig = obj.web || obj.target; // no need to handle null case, because web has required parameters url\n const web =\n typeof webConfig !== 'undefined'\n ? Object.assign({}, webConfig || {})\n : undefined;\n\n if (!ignoreCheckingTarget) {\n // make sure at least one of target/web/android is provided\n assert(\n web || android,\n `at least one of \"target\", \"web\", or \"android\" properties is required in yaml script${pathTip}`,\n );\n\n // make sure only one of target/web/android is provided\n assert(\n (web && !android) || (!web && android),\n `only one of \"target\", \"web\", or \"android\" properties is allowed in yaml script${pathTip}`,\n );\n\n // make sure the config is valid\n if (web || android) {\n assert(\n typeof web === 'object' || typeof android === 'object',\n `property \"target/web/android\" must be an object${pathTip}`,\n );\n }\n }\n\n assert(obj.tasks, `property \"tasks\" is required in yaml script ${pathTip}`);\n assert(\n Array.isArray(obj.tasks),\n `property \"tasks\" must be an array in yaml script, but got ${obj.tasks}`,\n );\n return obj;\n}\n","import type { AndroidDevicePage, WebPage } from '@/common/page';\nimport type { PuppeteerWebPage } from '@/puppeteer';\nimport {\n type AIUsageInfo,\n type BaseElement,\n type DumpSubscriber,\n type ExecutionRecorderItem,\n type ExecutionTaskActionApply,\n type ExecutionTaskApply,\n type ExecutionTaskHitBy,\n type ExecutionTaskInsightLocateApply,\n type ExecutionTaskInsightQueryApply,\n type ExecutionTaskPlanning,\n type ExecutionTaskPlanningApply,\n type ExecutionTaskProgressOptions,\n Executor,\n type ExecutorContext,\n type Insight,\n type InsightAssertionResponse,\n type InsightDump,\n type InsightExtractOption,\n type InsightExtractParam,\n type LocateResultElement,\n type MidsceneYamlFlowItem,\n type PageType,\n type PlanningAIResponse,\n type PlanningAction,\n type PlanningActionParamAndroidLongPress,\n type PlanningActionParamAndroidPull,\n type PlanningActionParamAssert,\n type PlanningActionParamError,\n type PlanningActionParamHover,\n type PlanningActionParamInputOrKeyPress,\n type PlanningActionParamScroll,\n type PlanningActionParamSleep,\n type PlanningActionParamTap,\n type PlanningActionParamWaitFor,\n type TMultimodalPrompt,\n type TUserPrompt,\n type UIContext,\n plan,\n} from '@midscene/core';\nimport {\n type ChatCompletionMessageParam,\n elementByPositionWithElementInfo,\n resizeImageForUiTars,\n vlmPlanning,\n} from '@midscene/core/ai-model';\nimport { sleep } from '@midscene/core/utils';\nimport { NodeType } from '@midscene/shared/constants';\nimport {\n MIDSCENE_REPLANNING_CYCLE_LIMIT,\n getAIConfigInNumber,\n} from '@midscene/shared/env';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport type { WebElementInfo, WebUIContext } from '../web-element';\nimport type { TaskCache } from './task-cache';\nimport { getKeyCommands, taskTitleStr } from './ui-utils';\nimport {\n matchElementFromCache,\n matchElementFromPlan,\n parsePrompt,\n} from './utils';\n\ninterface ExecutionResult<OutputType = any> {\n output: OutputType;\n thought?: string;\n executor: Executor;\n}\n\nconst debug = getDebug('page-task-executor');\nconst defaultReplanningCycleLimit = 10;\n\nconst isAndroidPage = (page: WebPage): page is AndroidDevicePage => {\n return page.pageType === 'android';\n};\n\nexport class PageTaskExecutor {\n page: WebPage;\n\n insight: Insight<WebElementInfo, WebUIContext>;\n\n taskCache?: TaskCache;\n\n conversationHistory: ChatCompletionMessageParam[] = [];\n\n onTaskStartCallback?: ExecutionTaskProgressOptions['onTaskStart'];\n\n constructor(\n page: WebPage,\n insight: Insight<WebElementInfo, WebUIContext>,\n opts: {\n taskCache?: TaskCache;\n onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];\n },\n ) {\n this.page = page;\n this.insight = insight;\n\n this.taskCache = opts.taskCache;\n\n this.onTaskStartCallback = opts?.onTaskStart;\n }\n\n private async recordScreenshot(timing: ExecutionRecorderItem['timing']) {\n const base64 = await this.page.screenshotBase64();\n const item: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: Date.now(),\n screenshot: base64,\n timing,\n };\n return item;\n }\n\n private async getElementXpath(\n pageContext: UIContext<BaseElement>,\n element: LocateResultElement,\n ): Promise<string[] | undefined> {\n let elementId = element?.id;\n if (element?.isOrderSensitive !== undefined) {\n const xpaths = await this.page.getXpathsByPoint(\n {\n left: element.center[0],\n top: element.center[1],\n },\n element?.isOrderSensitive,\n );\n\n return xpaths;\n }\n\n // find the nearest xpath for the element\n if (element?.attributes?.nodeType === NodeType.POSITION) {\n await this.insight.contextRetrieverFn('locate');\n const info = elementByPositionWithElementInfo(\n pageContext.tree,\n {\n x: element.center[0],\n y: element.center[1],\n },\n {\n requireStrictDistance: false,\n filterPositionElements: true,\n },\n );\n if (info?.id) {\n elementId = info.id;\n } else {\n debug(\n 'no element id found for position node, will not update cache',\n element,\n );\n }\n }\n\n if (!elementId) {\n return undefined;\n }\n try {\n const result = await this.page.getXpathsById(elementId);\n return result;\n } catch (error) {\n debug('getXpathsById error: ', error);\n }\n }\n\n private prependExecutorWithScreenshot(\n taskApply: ExecutionTaskApply,\n appendAfterExecution = false,\n ): ExecutionTaskApply {\n const taskWithScreenshot: ExecutionTaskApply = {\n ...taskApply,\n executor: async (param, context, ...args) => {\n const recorder: ExecutionRecorderItem[] = [];\n const { task } = context;\n // set the recorder before executor in case of error\n task.recorder = recorder;\n const shot = await this.recordScreenshot(`before ${task.type}`);\n recorder.push(shot);\n const result = await taskApply.executor(param, context, ...args);\n if (taskApply.type === 'Action') {\n await Promise.all([\n (async () => {\n await sleep(100);\n if ((this.page as PuppeteerWebPage).waitUntilNetworkIdle) {\n try {\n await (this.page as PuppeteerWebPage).waitUntilNetworkIdle();\n } catch (error) {\n // console.error('waitUntilNetworkIdle error', error);\n }\n }\n })(),\n sleep(200),\n ]);\n }\n if (appendAfterExecution) {\n const shot2 = await this.recordScreenshot('after Action');\n recorder.push(shot2);\n }\n return result;\n },\n };\n return taskWithScreenshot;\n }\n\n public async convertPlanToExecutable(\n plans: PlanningAction[],\n opts?: {\n cacheable?: boolean;\n },\n ) {\n const tasks: ExecutionTaskApply[] = [];\n plans.forEach((plan) => {\n if (plan.type === 'Locate') {\n if (\n plan.locate === null ||\n plan.locate?.id === null ||\n plan.locate?.id === 'null'\n ) {\n // console.warn('Locate action with id is null, will be ignored');\n return;\n }\n const taskFind: ExecutionTaskInsightLocateApply = {\n type: 'Insight',\n subType: 'Locate',\n param: plan.locate\n ? {\n ...plan.locate,\n cacheable: opts?.cacheable,\n }\n : undefined,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param, taskContext) => {\n const { task } = taskContext;\n assert(\n param?.prompt || param?.id || param?.bbox,\n 'No prompt or id or position or bbox to locate',\n );\n let insightDump: InsightDump | undefined;\n let usage: AIUsageInfo | undefined;\n const dumpCollector: DumpSubscriber = (dump) => {\n insightDump = dump;\n usage = dump?.taskInfo?.usage;\n\n task.log = {\n dump: insightDump,\n };\n\n task.usage = usage;\n };\n this.insight.onceDumpUpdatedFn = dumpCollector;\n const shotTime = Date.now();\n\n // Get context through contextRetrieverFn which handles frozen context\n const pageContext = await this.insight.contextRetrieverFn('locate');\n task.pageContext = pageContext;\n\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: pageContext.screenshotBase64,\n timing: 'before Insight',\n };\n task.recorder = [recordItem];\n\n // try matching xpath\n const elementFromXpath = param.xpath\n ? await this.page.getElementInfoByXpath(param.xpath)\n : undefined;\n const userExpectedPathHitFlag = !!elementFromXpath;\n\n // try matching cache\n const cachePrompt = param.prompt;\n const locateCacheRecord =\n this.taskCache?.matchLocateCache(cachePrompt);\n const xpaths = locateCacheRecord?.cacheContent?.xpaths;\n const elementFromCache = userExpectedPathHitFlag\n ? null\n : await matchElementFromCache(\n this,\n xpaths,\n cachePrompt,\n param.cacheable,\n );\n const cacheHitFlag = !!elementFromCache;\n\n // try matching plan\n const elementFromPlan =\n !userExpectedPathHitFlag && !cacheHitFlag\n ? matchElementFromPlan(param, pageContext.tree)\n : undefined;\n const planHitFlag = !!elementFromPlan;\n\n // try ai locate\n const elementFromAiLocate =\n !userExpectedPathHitFlag && !cacheHitFlag && !planHitFlag\n ? (\n await this.insight.locate(param, {\n // fallback to ai locate\n context: pageContext,\n })\n ).element\n : undefined;\n const aiLocateHitFlag = !!elementFromAiLocate;\n\n const element =\n elementFromXpath || // highest priority\n elementFromCache || // second priority\n elementFromPlan || // third priority\n elementFromAiLocate;\n\n // update cache\n let currentXpaths: string[] | undefined;\n if (\n element &&\n this.taskCache &&\n !cacheHitFlag &&\n param?.cacheable !== false\n ) {\n const elementXpaths = await this.getElementXpath(\n pageContext,\n element,\n );\n if (elementXpaths?.length) {\n currentXpaths = elementXpaths;\n this.taskCache.updateOrAppendCacheRecord(\n {\n type: 'locate',\n prompt: cachePrompt,\n xpaths: elementXpaths,\n },\n locateCacheRecord,\n );\n } else {\n debug(\n 'no xpaths found, will not update cache',\n cachePrompt,\n elementXpaths,\n );\n }\n }\n if (!element) {\n throw new Error(`Element not found: ${param.prompt}`);\n }\n\n let hitBy: ExecutionTaskHitBy | undefined;\n\n if (userExpectedPathHitFlag) {\n hitBy = {\n from: 'User expected path',\n context: {\n xpath: param.xpath,\n },\n };\n } else if (cacheHitFlag) {\n hitBy = {\n from: 'Cache',\n context: {\n xpathsFromCache: xpaths,\n xpathsToSave: currentXpaths,\n },\n };\n } else if (planHitFlag) {\n hitBy = {\n from: 'Planning',\n context: {\n id: elementFromPlan?.id,\n bbox: elementFromPlan?.bbox,\n },\n };\n } else if (aiLocateHitFlag) {\n hitBy = {\n from: 'AI model',\n context: {\n prompt: param.prompt,\n },\n };\n }\n\n return {\n output: {\n element,\n },\n pageContext,\n hitBy,\n };\n },\n };\n tasks.push(taskFind);\n } else if (plan.type === 'Assert' || plan.type === 'AssertWithoutThrow') {\n const assertPlan = plan as PlanningAction<PlanningActionParamAssert>;\n const taskAssert: ExecutionTaskApply = {\n type: 'Insight',\n subType: 'Assert',\n param: assertPlan.param,\n thought: assertPlan.thought,\n locate: assertPlan.locate,\n executor: async (param, taskContext) => {\n const { task } = taskContext;\n let insightDump: InsightDump | undefined;\n const dumpCollector: DumpSubscriber = (dump) => {\n insightDump = dump;\n };\n this.insight.onceDumpUpdatedFn = dumpCollector;\n const shotTime = Date.now();\n const pageContext = await this.insight.contextRetrieverFn('assert');\n task.pageContext = pageContext;\n\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: pageContext.screenshotBase64,\n timing: 'before Insight',\n };\n task.recorder = [recordItem];\n\n const assertion = await this.insight.assert(\n assertPlan.param.assertion,\n );\n\n if (!assertion.pass) {\n if (plan.type === 'Assert') {\n task.output = assertion;\n task.log = {\n dump: insightDump,\n };\n throw new Error(\n assertion.thought || 'Assertion failed without reason',\n );\n }\n\n task.error = new Error(assertion.thought);\n }\n\n return {\n output: assertion,\n pageContext,\n log: {\n dump: insightDump,\n },\n usage: assertion.usage,\n };\n },\n };\n tasks.push(taskAssert);\n } else if (plan.type === 'Input') {\n const taskActionInput: ExecutionTaskActionApply<PlanningActionParamInputOrKeyPress> =\n {\n type: 'Action',\n subType: 'Input',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam, { element }) => {\n if (element) {\n await this.page.clearInput(element as unknown as ElementInfo);\n\n if (!taskParam || !taskParam.value) {\n return;\n }\n }\n\n await this.page.keyboard.type(taskParam.value, {\n autoDismissKeyboard: taskParam.autoDismissKeyboard,\n });\n },\n };\n tasks.push(taskActionInput);\n } else if (plan.type === 'KeyboardPress') {\n const taskActionKeyboardPress: ExecutionTaskActionApply<PlanningActionParamInputOrKeyPress> =\n {\n type: 'Action',\n subType: 'KeyboardPress',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam) => {\n const keys = getKeyCommands(taskParam.value);\n\n await this.page.keyboard.press(keys);\n },\n };\n tasks.push(taskActionKeyboardPress);\n } else if (plan.type === 'Tap') {\n const taskActionTap: ExecutionTaskActionApply<PlanningActionParamTap> =\n {\n type: 'Action',\n subType: 'Tap',\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param, { element }) => {\n assert(element, 'Element not found, cannot tap');\n await this.page.mouse.click(element.center[0], element.center[1]);\n },\n };\n tasks.push(taskActionTap);\n } else if (plan.type === 'RightClick') {\n const taskActionRightClick: ExecutionTaskActionApply<PlanningActionParamTap> =\n {\n type: 'Action',\n subType: 'RightClick',\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param, { element }) => {\n assert(element, 'Element not found, cannot right click');\n await this.page.mouse.click(\n element.center[0],\n element.center[1],\n { button: 'right' },\n );\n },\n };\n tasks.push(taskActionRightClick);\n } else if (plan.type === 'Drag') {\n const taskActionDrag: ExecutionTaskActionApply<{\n start_box: { x: number; y: number };\n end_box: { x: number; y: number };\n }> = {\n type: 'Action',\n subType: 'Drag',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam) => {\n assert(\n taskParam?.start_box && taskParam?.end_box,\n 'No start_box or end_box to drag',\n );\n await this.page.mouse.drag(taskParam.start_box, taskParam.end_box);\n },\n };\n tasks.push(taskActionDrag);\n } else if (plan.type === 'Hover') {\n const taskActionHover: ExecutionTaskActionApply<PlanningActionParamHover> =\n {\n type: 'Action',\n subType: 'Hover',\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param, { element }) => {\n assert(element, 'Element not found, cannot hover');\n await this.page.mouse.move(element.center[0], element.center[1]);\n },\n };\n tasks.push(taskActionHover);\n } else if (plan.type === 'Scroll') {\n const taskActionScroll: ExecutionTaskActionApply<PlanningActionParamScroll> =\n {\n type: 'Action',\n subType: 'Scroll',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam, { element }) => {\n const startingPoint = element\n ? {\n left: element.center[0],\n top: element.center[1],\n }\n : undefined;\n const scrollToEventName = taskParam?.scrollType;\n if (scrollToEventName === 'untilTop') {\n await this.page.scrollUntilTop(startingPoint);\n } else if (scrollToEventName === 'untilBottom') {\n await this.page.scrollUntilBottom(startingPoint);\n } else if (scrollToEventName === 'untilRight') {\n await this.page.scrollUntilRight(startingPoint);\n } else if (scrollToEventName === 'untilLeft') {\n await this.page.scrollUntilLeft(startingPoint);\n } else if (scrollToEventName === 'once' || !scrollToEventName) {\n if (\n taskParam?.direction === 'down' ||\n !taskParam ||\n !taskParam.direction\n ) {\n await this.page.scrollDown(\n taskParam?.distance || undefined,\n startingPoint,\n );\n } else if (taskParam.direction === 'up') {\n await this.page.scrollUp(\n taskParam.distance || undefined,\n startingPoint,\n );\n } else if (taskParam.direction === 'left') {\n await this.page.scrollLeft(\n taskParam.distance || undefined,\n startingPoint,\n );\n } else if (taskParam.direction === 'right') {\n await this.page.scrollRight(\n taskParam.distance || undefined,\n startingPoint,\n );\n } else {\n throw new Error(\n `Unknown scroll direction: ${taskParam.direction}`,\n );\n }\n // until mouse event is done\n await sleep(500);\n } else {\n throw new Error(\n `Unknown scroll event type: ${scrollToEventName}, taskParam: ${JSON.stringify(\n taskParam,\n )}`,\n );\n }\n },\n };\n tasks.push(taskActionScroll);\n } else if (plan.type === 'Sleep') {\n const taskActionSleep: ExecutionTaskActionApply<PlanningActionParamSleep> =\n {\n type: 'Action',\n subType: 'Sleep',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam) => {\n await sleep(taskParam?.timeMs || 3000);\n },\n };\n tasks.push(taskActionSleep);\n } else if (plan.type === 'Error') {\n const taskActionError: ExecutionTaskActionApply<PlanningActionParamError> =\n {\n type: 'Action',\n subType: 'Error',\n param: plan.param,\n thought: plan.thought || plan.param?.thought,\n locate: plan.locate,\n executor: async () => {\n throw new Error(\n plan?.thought || plan.param?.thought || 'error without thought',\n );\n },\n };\n tasks.push(taskActionError);\n } else if (plan.type === 'ExpectedFalsyCondition') {\n const taskActionFalsyConditionStatement: ExecutionTaskActionApply<null> =\n {\n type: 'Action',\n subType: 'ExpectedFalsyCondition',\n param: null,\n thought: plan.param?.reason,\n locate: plan.locate,\n executor: async () => {\n // console.warn(`[warn]falsy condition: ${plan.thought}`);\n },\n };\n tasks.push(taskActionFalsyConditionStatement);\n } else if (plan.type === 'Finished') {\n const taskActionFinished: ExecutionTaskActionApply<null> = {\n type: 'Action',\n subType: 'Finished',\n param: null,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {},\n };\n tasks.push(taskActionFinished);\n } else if (plan.type === 'AndroidHomeButton') {\n const taskActionAndroidHomeButton: ExecutionTaskActionApply<null> = {\n type: 'Action',\n subType: 'AndroidHomeButton',\n param: null,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {\n // Check if the page has back method (Android devices)\n assert(\n isAndroidPage(this.page),\n 'Cannot use home button on non-Android devices',\n );\n await this.page.home();\n },\n };\n tasks.push(taskActionAndroidHomeButton);\n } else if (plan.type === 'AndroidBackButton') {\n const taskActionAndroidBackButton: ExecutionTaskActionApply<null> = {\n type: 'Action',\n subType: 'AndroidBackButton',\n param: null,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {\n assert(\n isAndroidPage(this.page),\n 'Cannot use back button on non-Android devices',\n );\n await this.page.back();\n },\n };\n tasks.push(taskActionAndroidBackButton);\n } else if (plan.type === 'AndroidRecentAppsButton') {\n const taskActionAndroidRecentAppsButton: ExecutionTaskActionApply<null> =\n {\n type: 'Action',\n subType: 'AndroidRecentAppsButton',\n param: null,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {\n assert(\n isAndroidPage(this.page),\n 'Cannot use recent apps button on non-Android devices',\n );\n await this.page.recentApps();\n },\n };\n tasks.push(taskActionAndroidRecentAppsButton);\n } else if (plan.type === 'AndroidLongPress') {\n const taskActionAndroidLongPress: ExecutionTaskActionApply<PlanningActionParamAndroidLongPress> =\n {\n type: 'Action',\n subType: 'AndroidLongPress',\n param: plan.param as PlanningActionParamAndroidLongPress,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {\n assert(\n isAndroidPage(this.page),\n 'Cannot use long press on non-Android devices',\n );\n const { x, y, duration } = param;\n await this.page.longPress(x, y, duration);\n },\n };\n tasks.push(taskActionAndroidLongPress);\n } else if (plan.type === 'AndroidPull') {\n const taskActionAndroidPull: ExecutionTaskActionApply<PlanningActionParamAndroidPull> =\n {\n type: 'Action',\n subType: 'AndroidPull',\n param: plan.param as PlanningActionParamAndroidPull,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {\n assert(\n isAndroidPage(this.page),\n 'Cannot use pull action on non-Android devices',\n );\n const { direction, startPoint, distance, duration } = param;\n\n const convertedStartPoint = startPoint\n ? { left: startPoint.x, top: startPoint.y }\n : undefined;\n\n if (direction === 'down') {\n await this.page.pullDown(\n convertedStartPoint,\n distance,\n duration,\n );\n } else if (direction === 'up') {\n await this.page.pullUp(convertedStartPoint, distance, duration);\n } else {\n throw new Error(`Unknown pull direction: ${direction}`);\n }\n },\n };\n tasks.push(taskActionAndroidPull);\n } else {\n throw new Error(`Unknown or unsupported task type: ${plan.type}`);\n }\n });\n\n const wrappedTasks = tasks.map(\n (task: ExecutionTaskApply, index: number) => {\n if (task.type === 'Action') {\n return this.prependExecutorWithScreenshot(\n task,\n index === tasks.length - 1,\n );\n }\n return task;\n },\n );\n\n return {\n tasks: wrappedTasks,\n };\n }\n\n private async setupPlanningContext(executorContext: ExecutorContext) {\n const shotTime = Date.now();\n const pageContext = await this.insight.contextRetrieverFn('locate');\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: pageContext.screenshotBase64,\n timing: 'before Planning',\n };\n\n executorContext.task.recorder = [recordItem];\n (executorContext.task as ExecutionTaskPlanning).pageContext = pageContext;\n\n return {\n pageContext,\n };\n }\n\n async loadYamlFlowAsPlanning(userInstruction: string, yamlString: string) {\n const taskExecutor = new Executor(taskTitleStr('Action', userInstruction), {\n onTaskStart: this.onTaskStartCallback,\n });\n\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'LoadYaml',\n locate: null,\n param: {\n userInstruction,\n },\n executor: async (param, executorContext) => {\n await this.setupPlanningContext(executorContext);\n return {\n output: {\n actions: [],\n more_actions_needed_by_instruction: false,\n log: '',\n yamlString,\n },\n cache: {\n hit: true,\n },\n };\n },\n };\n\n await taskExecutor.append(task);\n await taskExecutor.flush();\n\n return {\n executor: taskExecutor,\n };\n }\n\n private planningTaskFromPrompt(\n userInstruction: string,\n log?: string,\n actionContext?: string,\n ) {\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'Plan',\n locate: null,\n param: {\n userInstruction,\n log,\n },\n executor: async (param, executorContext) => {\n const startTime = Date.now();\n const { pageContext } =\n await this.setupPlanningContext(executorContext);\n\n const planResult = await plan(param.userInstruction, {\n context: pageContext,\n log: param.log,\n actionContext,\n pageType: this.page.pageType as PageType,\n });\n\n const {\n actions,\n log,\n more_actions_needed_by_instruction,\n error,\n usage,\n rawResponse,\n sleep,\n } = planResult;\n\n executorContext.task.log = {\n ...(executorContext.task.log || {}),\n rawResponse,\n };\n executorContext.task.usage = usage;\n\n let stopCollecting = false;\n let bboxCollected = false;\n let planParsingError = '';\n const finalActions = (actions || []).reduce<PlanningAction[]>(\n (acc, planningAction) => {\n if (stopCollecting) {\n return acc;\n }\n\n if (planningAction.locate) {\n // we only collect bbox once, let qwen re-locate in the following steps\n if (bboxCollected && planningAction.locate.bbox) {\n // biome-ignore lint/performance/noDelete: <explanation>\n delete planningAction.locate.bbox;\n }\n\n if (planningAction.locate.bbox) {\n bboxCollected = true;\n }\n\n acc.push({\n type: 'Locate',\n locate: planningAction.locate,\n param: null,\n // thought is prompt created by ai, always a string\n thought: planningAction.locate.prompt as string,\n });\n } else if (\n ['Tap', 'Hover', 'Input'].includes(planningAction.type)\n ) {\n planParsingError = `invalid planning response: ${JSON.stringify(planningAction)}`;\n // should include locate but get null\n stopCollecting = true;\n return acc;\n }\n acc.push(planningAction);\n return acc;\n },\n [],\n );\n\n if (sleep) {\n const timeNow = Date.now();\n const timeRemaining = sleep - (timeNow - startTime);\n if (timeRemaining > 0) {\n finalActions.push({\n type: 'Sleep',\n param: {\n timeMs: timeRemaining,\n },\n locate: null,\n } as PlanningAction<PlanningActionParamSleep>);\n }\n }\n\n if (finalActions.length === 0) {\n assert(\n !more_actions_needed_by_instruction || sleep,\n error\n ? `Failed to plan: ${error}`\n : planParsingError || 'No plan found',\n );\n }\n\n return {\n output: {\n actions: finalActions,\n more_actions_needed_by_instruction,\n log,\n yamlFlow: planResult.yamlFlow,\n },\n cache: {\n hit: false,\n },\n pageContext,\n };\n },\n };\n\n return task;\n }\n\n private planningTaskToGoal(userInstruction: string) {\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'Plan',\n locate: null,\n param: {\n userInstruction,\n },\n executor: async (param, executorContext) => {\n const { pageContext } =\n await this.setupPlanningContext(executorContext);\n\n const imagePayload = await resizeImageForUiTars(\n pageContext.screenshotBase64,\n pageContext.size,\n );\n\n this.appendConversationHistory({\n role: 'user',\n content: [\n {\n type: 'image_url',\n image_url: {\n url: imagePayload,\n },\n },\n ],\n });\n const planResult: {\n actions: PlanningAction<any>[];\n action_summary: string;\n usage?: AIUsageInfo;\n yamlFlow?: MidsceneYamlFlowItem[];\n rawResponse?: string;\n } = await vlmPlanning({\n userInstruction: param.userInstruction,\n conversationHistory: this.conversationHistory,\n size: pageContext.size,\n });\n\n const { actions, action_summary, usage } = planResult;\n executorContext.task.log = {\n ...(executorContext.task.log || {}),\n rawResponse: planResult.rawResponse,\n };\n executorContext.task.usage = usage;\n this.appendConversationHistory({\n role: 'assistant',\n content: action_summary,\n });\n return {\n output: {\n actions,\n thought: actions[0]?.thought,\n actionType: actions[0].type,\n more_actions_needed_by_instruction: true,\n log: '',\n yamlFlow: planResult.yamlFlow,\n },\n cache: {\n hit: false,\n },\n };\n },\n };\n\n return task;\n }\n\n async runPlans(\n title: string,\n plans: PlanningAction[],\n opts?: {\n cacheable?: boolean;\n },\n ): Promise<ExecutionResult> {\n const taskExecutor = new Executor(title, {\n onTaskStart: this.onTaskStartCallback,\n });\n const { tasks } = await this.convertPlanToExecutable(plans, opts);\n await taskExecutor.append(tasks);\n const result = await taskExecutor.flush();\n const { output } = result!;\n return {\n output,\n executor: taskExecutor,\n };\n }\n\n async action(\n userPrompt: string,\n actionContext?: string,\n opts?: {\n cacheable?: boolean;\n },\n ): Promise<\n ExecutionResult<\n | {\n yamlFlow?: MidsceneYamlFlowItem[]; // for cache use\n }\n | undefined\n >\n > {\n const taskExecutor = new Executor(taskTitleStr('Action', userPrompt), {\n onTaskStart: this.onTaskStartCallback,\n });\n\n let planningTask: ExecutionTaskPlanningApply | null =\n this.planningTaskFromPrompt(userPrompt, undefined, actionContext);\n let replanCount = 0;\n const logList: string[] = [];\n\n const yamlFlow: MidsceneYamlFlowItem[] = [];\n const replanningCycleLimit =\n getAIConfigInNumber(MIDSCENE_REPLANNING_CYCLE_LIMIT) ||\n defaultReplanningCycleLimit;\n while (planningTask) {\n if (replanCount > replanningCycleLimit) {\n const errorMsg =\n 'Replanning too many times, please split the task into multiple steps';\n\n return this.appendErrorPlan(taskExecutor, errorMsg);\n }\n\n // plan\n await taskExecutor.append(planningTask);\n const result = await taskExecutor.flush();\n const planResult: PlanningAIResponse = result?.output;\n if (taskExecutor.isInErrorState()) {\n return {\n output: planResult,\n executor: taskExecutor,\n };\n }\n\n const plans = planResult.actions || [];\n yamlFlow.push(...(planResult.yamlFlow || []));\n\n let executables: Awaited<ReturnType<typeof this.convertPlanToExecutable>>;\n try {\n executables = await this.convertPlanToExecutable(plans, opts);\n taskExecutor.append(executables.tasks);\n } catch (error) {\n return this.appendErrorPlan(\n taskExecutor,\n `Error converting plans to executable tasks: ${error}, plans: ${JSON.stringify(\n plans,\n )}`,\n );\n }\n\n await taskExecutor.flush();\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n if (planResult?.log) {\n logList.push(planResult.log);\n }\n\n if (!planResult.more_actions_needed_by_instruction) {\n planningTask = null;\n break;\n }\n planningTask = this.planningTaskFromPrompt(\n userPrompt,\n logList.length > 0 ? `- ${logList.join('\\n- ')}` : undefined,\n actionContext,\n );\n replanCount++;\n }\n\n return {\n output: {\n yamlFlow,\n },\n executor: taskExecutor,\n };\n }\n\n async actionToGoal(\n userPrompt: string,\n opts?: {\n cacheable?: boolean;\n },\n ): Promise<\n ExecutionResult<\n | {\n yamlFlow?: MidsceneYamlFlowItem[]; // for cache use\n }\n | undefined\n >\n > {\n const taskExecutor = new Executor(taskTitleStr('Action', userPrompt), {\n onTaskStart: this.onTaskStartCallback,\n });\n this.conversationHistory = [];\n const isCompleted = false;\n let currentActionNumber = 0;\n const maxActionNumber = 40;\n\n const yamlFlow: MidsceneYamlFlowItem[] = [];\n while (!isCompleted && currentActionNumber < maxActionNumber) {\n currentActionNumber++;\n const planningTask: ExecutionTaskPlanningApply =\n this.planningTaskToGoal(userPrompt);\n await taskExecutor.append(planningTask);\n const result = await taskExecutor.flush();\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function actionToGoal',\n );\n }\n const { output } = result;\n const plans = output.actions;\n yamlFlow.push(...(output.yamlFlow || []));\n let executables: Awaited<ReturnType<typeof this.convertPlanToExecutable>>;\n try {\n executables = await this.convertPlanToExecutable(plans, opts);\n taskExecutor.append(executables.tasks);\n } catch (error) {\n return this.appendErrorPlan(\n taskExecutor,\n `Error converting plans to executable tasks: ${error}, plans: ${JSON.stringify(\n plans,\n )}`,\n );\n }\n\n await taskExecutor.flush();\n\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n if (plans[0].type === 'Finished') {\n break;\n }\n }\n return {\n output: {\n yamlFlow,\n },\n executor: taskExecutor,\n };\n }\n\n private async createTypeQueryTask<T>(\n type: 'Query' | 'Boolean' | 'Number' | 'String' | 'Assert',\n demand: InsightExtractParam,\n opt?: InsightExtractOption,\n multimodalPrompt?: TMultimodalPrompt,\n ): Promise<ExecutionResult<T>> {\n const taskExecutor = new Executor(\n taskTitleStr(\n type,\n typeof demand === 'string' ? demand : JSON.stringify(demand),\n ),\n {\n onTaskStart: this.onTaskStartCallback,\n },\n );\n\n const queryTask: ExecutionTaskInsightQueryApply = {\n type: 'Insight',\n subType: type,\n locate: null,\n param: {\n // TODO: display image thumbnail in report\n dataDemand: multimodalPrompt\n ? ({\n demand,\n multimodalPrompt,\n } as never)\n : demand, // for user param presentation in report right sidebar\n },\n executor: async (param, taskContext) => {\n const { task } = taskContext;\n let insightDump: InsightDump | undefined;\n const dumpCollector: DumpSubscriber = (dump) => {\n insightDump = dump;\n };\n this.insight.onceDumpUpdatedFn = dumpCollector;\n\n // Get page context for query operations\n const shotTime = Date.now();\n const pageContext = await this.insight.contextRetrieverFn('extract');\n task.pageContext = pageContext;\n\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: pageContext.screenshotBase64,\n timing: 'before Extract',\n };\n task.recorder = [recordItem];\n\n const ifTypeRestricted = type !== 'Query';\n let demandInput = demand;\n if (ifTypeRestricted) {\n demandInput = {\n result: `${type}, ${demand}`,\n };\n }\n\n const { data, usage, thought } = await this.insight.extract<any>(\n demandInput,\n opt,\n multimodalPrompt,\n );\n\n let outputResult = data;\n if (ifTypeRestricted) {\n assert(data?.result !== undefined, 'No result in query data');\n outputResult = (data as any).result;\n }\n\n return {\n output: outputResult,\n log: { dump: insightDump },\n usage,\n thought,\n };\n },\n };\n\n await taskExecutor.append(this.prependExecutorWithScreenshot(queryTask));\n const result = await taskExecutor.flush();\n\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function createTypeQueryTask',\n );\n }\n\n const { output, thought } = result;\n\n return {\n output,\n thought,\n executor: taskExecutor,\n };\n }\n\n async query(\n demand: InsightExtractParam,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult> {\n return this.createTypeQueryTask('Query', demand, opt);\n }\n\n async boolean(\n prompt: TUserPrompt,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult<boolean>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n return this.createTypeQueryTask<boolean>(\n 'Boolean',\n textPrompt,\n opt,\n multimodalPrompt,\n );\n }\n\n async number(\n prompt: TUserPrompt,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult<number>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n return this.createTypeQueryTask<number>(\n 'Number',\n textPrompt,\n opt,\n multimodalPrompt,\n );\n }\n\n async string(\n prompt: TUserPrompt,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult<string>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n return this.createTypeQueryTask<string>(\n 'String',\n textPrompt,\n opt,\n multimodalPrompt,\n );\n }\n\n async assert(\n assertion: TUserPrompt,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult<boolean>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(assertion);\n return await this.createTypeQueryTask<boolean>(\n 'Assert',\n textPrompt,\n opt,\n multimodalPrompt,\n );\n }\n\n /**\n * Append a message to the conversation history\n * For user messages with images:\n * - Keep max 4 user image messages in history\n * - Remove oldest user image message when limit reached\n * For assistant messages:\n * - Simply append to history\n * @param conversationHistory Message to append\n */\n private appendConversationHistory(\n conversationHistory: ChatCompletionMessageParam,\n ) {\n if (conversationHistory.role === 'user') {\n // Get all existing user messages with images\n const userImgItems = this.conversationHistory.filter(\n (item) => item.role === 'user',\n );\n\n // If we already have 4 user image messages\n if (userImgItems.length >= 4 && conversationHistory.role === 'user') {\n // Remove first user image message when we already have 4, before adding new one\n const firstUserImgIndex = this.conversationHistory.findIndex(\n (item) => item.role === 'user',\n );\n if (firstUserImgIndex >= 0) {\n this.conversationHistory.splice(firstUserImgIndex, 1);\n }\n }\n }\n // For non-user messages, simply append to history\n this.conversationHistory.push(conversationHistory);\n }\n\n private async appendErrorPlan(taskExecutor: Executor, errorMsg: string) {\n const errorPlan: PlanningAction<PlanningActionParamError> = {\n type: 'Error',\n param: {\n thought: errorMsg,\n },\n locate: null,\n };\n const { tasks } = await this.convertPlanToExecutable([errorPlan]);\n await taskExecutor.append(this.prependExecutorWithScreenshot(tasks[0]));\n await taskExecutor.flush();\n\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n async waitFor(\n assertion: string,\n opt: PlanningActionParamWaitFor,\n ): Promise<ExecutionResult<void>> {\n const description = `waitFor: ${assertion}`;\n const taskExecutor = new Executor(taskTitleStr('WaitFor', description), {\n onTaskStart: this.onTaskStartCallback,\n });\n const { timeoutMs, checkIntervalMs } = opt;\n\n assert(assertion, 'No assertion for waitFor');\n assert(timeoutMs, 'No timeoutMs for waitFor');\n assert(checkIntervalMs, 'No checkIntervalMs for waitFor');\n\n const overallStartTime = Date.now();\n let startTime = Date.now();\n let errorThought = '';\n while (Date.now() - overallStartTime < timeoutMs) {\n startTime = Date.now();\n const assertPlan: PlanningAction<PlanningActionParamAssert> = {\n type: 'AssertWithoutThrow',\n param: {\n assertion,\n },\n locate: null,\n };\n const { tasks: assertTasks } = await this.convertPlanToExecutable([\n assertPlan,\n ]);\n await taskExecutor.append(\n this.prependExecutorWithScreenshot(assertTasks[0]),\n );\n const result = await taskExecutor.flush();\n\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function waitFor',\n );\n }\n\n const { output } = result as { output: InsightAssertionResponse };\n\n if (output?.pass) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n errorThought =\n output?.thought ||\n `unknown error when waiting for assertion: ${assertion}`;\n const now = Date.now();\n if (now - startTime < checkIntervalMs) {\n const timeRemaining = checkIntervalMs - (now - startTime);\n const sleepPlan: PlanningAction<PlanningActionParamSleep> = {\n type: 'Sleep',\n param: {\n timeMs: timeRemaining,\n },\n locate: null,\n };\n const { tasks: sleepTasks } = await this.convertPlanToExecutable([\n sleepPlan,\n ]);\n await taskExecutor.append(\n this.prependExecutorWithScreenshot(sleepTasks[0]),\n );\n await taskExecutor.flush();\n }\n }\n\n return this.appendErrorPlan(\n taskExecutor,\n `waitFor timeout: ${errorThought}`,\n );\n }\n}\n","import type {\n DetailedLocateParam,\n ExecutionTask,\n ExecutionTaskAction,\n ExecutionTaskInsightAssertion,\n ExecutionTaskInsightLocate,\n ExecutionTaskInsightQuery,\n ExecutionTaskPlanning,\n PlanningActionParamAndroidPull,\n PlanningActionParamScroll,\n} from '@midscene/core';\n\nexport function typeStr(task: ExecutionTask) {\n return task.subType && task.subType !== 'Plan'\n ? `${task.type} / ${task.subType || ''}`\n : task.type;\n}\n\nexport function getKeyCommands(\n value: string | string[],\n): Array<{ key: string; command?: string }> {\n // Ensure value is an array of keys\n const keys = Array.isArray(value) ? value : [value];\n\n // Process each key to attach a corresponding command if needed, based on the presence of 'Meta' or 'Control' in the keys array.\n // ref: https://github.com/puppeteer/puppeteer/pull/9357/files#diff-32cf475237b000f980eb214a0a823e45a902bddb7d2426d677cae96397aa0ae4R94\n return keys.reduce((acc: Array<{ key: string; command?: string }>, k) => {\n const includeMeta = keys.includes('Meta') || keys.includes('Control');\n if (includeMeta && (k === 'a' || k === 'A')) {\n return acc.concat([{ key: k, command: 'SelectAll' }]);\n }\n if (includeMeta && (k === 'c' || k === 'C')) {\n return acc.concat([{ key: k, command: 'Copy' }]);\n }\n if (includeMeta && (k === 'v' || k === 'V')) {\n return acc.concat([{ key: k, command: 'Paste' }]);\n }\n return acc.concat([{ key: k }]);\n }, []);\n}\n\nexport function locateParamStr(locate?: DetailedLocateParam) {\n if (!locate) {\n return '';\n }\n\n if (typeof locate === 'string') {\n return locate;\n }\n\n return typeof locate.prompt === 'string'\n ? locate.prompt\n : locate.prompt.prompt;\n}\n\nexport function scrollParamStr(scrollParam?: PlanningActionParamScroll) {\n if (!scrollParam) {\n return '';\n }\n return `${scrollParam.direction || 'down'}, ${scrollParam.scrollType || 'once'}, ${scrollParam.distance || 'distance-not-set'}`;\n}\n\nexport function pullParamStr(pullParam?: PlanningActionParamAndroidPull) {\n if (!pullParam) {\n return '';\n }\n const parts: string[] = [];\n parts.push(`direction: ${pullParam.direction || 'down'}`);\n if (pullParam.startPoint) {\n parts.push(`start: (${pullParam.startPoint.x}, ${pullParam.startPoint.y})`);\n }\n if (pullParam.distance) {\n parts.push(`distance: ${pullParam.distance}`);\n }\n if (pullParam.duration) {\n parts.push(`duration: ${pullParam.duration}ms`);\n }\n return parts.join(', ');\n}\n\nexport function taskTitleStr(\n type:\n | 'Tap'\n | 'Hover'\n | 'Input'\n | 'RightClick'\n | 'KeyboardPress'\n | 'Scroll'\n | 'Action'\n | 'Query'\n | 'Assert'\n | 'WaitFor'\n | 'Locate'\n | 'Boolean'\n | 'Number'\n | 'String',\n prompt: string,\n) {\n if (prompt) {\n return `${type} - ${prompt}`;\n }\n return type;\n}\n\nexport function paramStr(task: ExecutionTask) {\n let value: string | undefined | object;\n if (task.type === 'Planning') {\n value = (task as ExecutionTaskPlanning)?.param?.userInstruction;\n }\n\n if (task.type === 'Insight') {\n value =\n (task as ExecutionTaskInsightLocate)?.param?.prompt ||\n (task as ExecutionTaskInsightLocate)?.param?.id ||\n (task as ExecutionTaskInsightQuery)?.param?.dataDemand ||\n (task as ExecutionTaskInsightAssertion)?.param?.assertion;\n }\n\n if (task.type === 'Action') {\n const locate = (task as ExecutionTaskAction)?.locate;\n const locateStr = locate ? locateParamStr(locate) : '';\n\n value = task.thought || '';\n if (typeof (task as ExecutionTaskAction)?.param?.timeMs === 'number') {\n value = `${(task as ExecutionTaskAction)?.param?.timeMs}ms`;\n } else if (\n typeof (task as ExecutionTaskAction)?.param?.scrollType === 'string'\n ) {\n value = scrollParamStr((task as ExecutionTaskAction)?.param);\n } else if (\n typeof (task as ExecutionTaskAction)?.param?.direction === 'string' &&\n (task as ExecutionTaskAction)?.subType === 'AndroidPull'\n ) {\n value = pullParamStr((task as ExecutionTaskAction)?.param);\n } else if (\n typeof (task as ExecutionTaskAction)?.param?.value !== 'undefined'\n ) {\n value = (task as ExecutionTaskAction)?.param?.value;\n }\n\n if (locateStr) {\n if (value) {\n value = `${locateStr} - ${value}`;\n } else {\n value = locateStr;\n }\n }\n }\n\n if (typeof value === 'undefined') return '';\n return typeof value === 'string'\n ? value\n : JSON.stringify(value, undefined, 2);\n}\n\nexport const limitOpenNewTabScript = `\nif (!window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__) {\n window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__ = true;\n\n // Intercept the window.open method (only once)\n window.open = function(url) {\n console.log('Blocked window.open:', url);\n window.location.href = url;\n return null;\n };\n\n // Block all a tag clicks with target=\"_blank\" (only once)\n document.addEventListener('click', function(e) {\n const target = e.target.closest('a');\n if (target && target.target === '_blank') {\n e.preventDefault();\n console.log('Blocked new tab:', target.href);\n window.location.href = target.href;\n target.removeAttribute('target');\n }\n }, true);\n}\n`;\n","import type { StaticPage } from '@/playground';\nimport type {\n BaseElement,\n ElementTreeNode,\n ExecutionDump,\n ExecutionTask,\n PlanningLocateParam,\n PlaywrightParserOpt,\n TMultimodalPrompt,\n TUserPrompt,\n UIContext,\n} from '@midscene/core';\nimport { elementByPositionWithElementInfo } from '@midscene/core/ai-model';\nimport { uploadTestInfoToServer } from '@midscene/core/utils';\nimport { MIDSCENE_REPORT_TAG_NAME, getAIConfig } from '@midscene/shared/env';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport {\n generateElementByPosition,\n getNodeFromCacheList,\n traverseTree,\n} from '@midscene/shared/extractor';\nimport { resizeImgBase64 } from '@midscene/shared/img';\nimport { type DebugFunction, getDebug } from '@midscene/shared/logger';\nimport { assert, logMsg, uuid } from '@midscene/shared/utils';\nimport dayjs from 'dayjs';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport type { Page as PuppeteerPage } from 'puppeteer';\nimport { WebElementInfo, type WebUIContext } from '../web-element';\nimport type { WebPage } from './page';\nimport { debug as cacheDebug } from './task-cache';\nimport type { PageTaskExecutor } from './tasks';\n\nconst debug = getDebug('tool:profile');\n\nexport async function parseContextFromWebPage(\n page: WebPage,\n _opt?: PlaywrightParserOpt,\n): Promise<WebUIContext> {\n assert(page, 'page is required');\n if ((page as StaticPage)._forceUsePageContext) {\n return await (page as any)._forceUsePageContext();\n }\n\n debug('Getting page URL');\n const url = await page.url();\n debug('URL end');\n\n debug('Uploading test info to server');\n uploadTestInfoToServer({ testUrl: url });\n debug('UploadTestInfoToServer end');\n\n let screenshotBase64: string;\n let tree: ElementTreeNode<ElementInfo>;\n\n debug('Starting parallel operations: screenshot and element tree');\n await Promise.all([\n page.screenshotBase64().then((base64) => {\n screenshotBase64 = base64;\n debug('ScreenshotBase64 end');\n }),\n page.getElementsNodeTree().then(async (treeRoot) => {\n tree = treeRoot;\n debug('GetElementsNodeTree end');\n }),\n ]);\n debug('ParseContextFromWebPage end');\n debug('Traversing element tree');\n const webTree = traverseTree(tree!, (elementInfo) => {\n const { rect, id, content, attributes, indexId, isVisible } = elementInfo;\n return new WebElementInfo({\n rect,\n id,\n content,\n attributes,\n indexId,\n isVisible,\n });\n });\n debug('TraverseTree end');\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n const size = await page.size();\n\n debug(`size: ${size.width}x${size.height} dpr: ${size.dpr}`);\n\n if (size.dpr && size.dpr > 1) {\n debug('Resizing screenshot for high DPR display');\n screenshotBase64 = await resizeImgBase64(screenshotBase64, {\n width: size.width,\n height: size.height,\n });\n debug('ResizeImgBase64 end');\n }\n\n return {\n tree: webTree,\n size,\n screenshotBase64: screenshotBase64!,\n url,\n };\n}\n\nexport function getReportFileName(tag = 'web') {\n const reportTagName = getAIConfig(MIDSCENE_REPORT_TAG_NAME);\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss');\n // ensure uniqueness at the same time\n const uniqueId = uuid().substring(0, 8);\n return `${reportTagName || tag}-${dateTimeInFileName}-${uniqueId}`;\n}\n\nexport function printReportMsg(filepath: string) {\n logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\n/**\n * Get the current execution file name\n * @returns The name of the current execution file\n */\nexport function getCurrentExecutionFile(trace?: string): string | false {\n const error = new Error();\n const stackTrace = trace || error.stack;\n const pkgDir = process.cwd() || '';\n if (stackTrace) {\n const stackLines = stackTrace.split('\\n');\n for (const line of stackLines) {\n if (\n line.includes('.spec.') ||\n line.includes('.test.') ||\n line.includes('.ts') ||\n line.includes('.js')\n ) {\n const match = line.match(/(?:at\\s+)?(.*?\\.(?:spec|test)\\.[jt]s)/);\n if (match?.[1]) {\n const targetFileName = match[1]\n .replace(pkgDir, '')\n .trim()\n .replace('at ', '');\n return targetFileName;\n }\n }\n }\n }\n return false;\n}\n\nconst testFileIndex = new Map<string, number>();\n\nexport function generateCacheId(fileName?: string): string {\n let taskFile = fileName || getCurrentExecutionFile();\n if (!taskFile) {\n taskFile = uuid();\n console.warn(\n 'Midscene - using random UUID for cache id. Cache may be invalid.',\n );\n }\n\n if (testFileIndex.has(taskFile)) {\n const currentIndex = testFileIndex.get(taskFile);\n if (currentIndex !== undefined) {\n testFileIndex.set(taskFile, currentIndex + 1);\n }\n } else {\n testFileIndex.set(taskFile, 1);\n }\n return `${taskFile}-${testFileIndex.get(taskFile)}`;\n}\n\nexport const ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED =\n 'NOT_IMPLEMENTED_AS_DESIGNED';\n\nexport function replaceIllegalPathCharsAndSpace(str: string) {\n // Only replace characters that are illegal in filenames, but preserve path separators\n return str.replace(/[:*?\"<>| ]/g, '-');\n}\n\nexport function forceClosePopup(\n page: PuppeteerPage | PlaywrightPage,\n debug: DebugFunction,\n) {\n page.on('popup', async (popup) => {\n if (!popup) {\n console.warn('got a popup event, but the popup is not ready yet, skip');\n return;\n }\n const url = await (popup as PuppeteerPage).url();\n console.log(`Popup opened: ${url}`);\n if (!(popup as PuppeteerPage).isClosed()) {\n try {\n await (popup as PuppeteerPage).close(); // Close the newly opened TAB\n } catch (error) {\n debug(`failed to close popup ${url}, error: ${error}`);\n }\n } else {\n debug(`popup is already closed, skip close ${url}`);\n }\n\n if (!page.isClosed()) {\n try {\n await page.goto(url);\n } catch (error) {\n debug(`failed to goto ${url}, error: ${error}`);\n }\n } else {\n debug(`page is already closed, skip goto ${url}`);\n }\n });\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n tree: ElementTreeNode<BaseElement>,\n) {\n if (!planLocateParam) {\n return undefined;\n }\n if (planLocateParam.id) {\n return getNodeFromCacheList(planLocateParam.id);\n }\n\n if (planLocateParam.bbox) {\n const centerPosition = {\n x: Math.floor((planLocateParam.bbox[0] + planLocateParam.bbox[2]) / 2),\n y: Math.floor((planLocateParam.bbox[1] + planLocateParam.bbox[3]) / 2),\n };\n let element = elementByPositionWithElementInfo(tree, centerPosition);\n\n if (!element) {\n element = generateElementByPosition(centerPosition) as BaseElement;\n }\n\n return element;\n }\n\n return undefined;\n}\n\nexport async function matchElementFromCache(\n taskExecutor: PageTaskExecutor,\n xpaths: string[] | undefined,\n cachePrompt: TUserPrompt,\n cacheable: boolean | undefined,\n) {\n try {\n if (\n xpaths?.length &&\n taskExecutor.taskCache?.isCacheResultUsed &&\n cacheable !== false\n ) {\n // hit cache, use new id\n for (let i = 0; i < xpaths.length; i++) {\n const element = await taskExecutor.page.getElementInfoByXpath(\n xpaths[i],\n );\n\n if (element?.id) {\n cacheDebug('cache hit, prompt: %s', cachePrompt);\n cacheDebug(\n 'found a new element with same xpath, xpath: %s, id: %s',\n xpaths[i],\n element?.id,\n );\n return element;\n }\n }\n }\n } catch (error) {\n cacheDebug('get element info by xpath error: ', error);\n }\n}\n\nexport function trimContextByViewport(execution: ExecutionDump) {\n function filterVisibleTree(\n node: ElementTreeNode<BaseElement>,\n ): ElementTreeNode<BaseElement> | null {\n if (!node) return null;\n\n // recursively process all children\n const filteredChildren = Array.isArray(node.children)\n ? (node.children\n .map(filterVisibleTree)\n .filter((child) => child !== null) as ElementTreeNode<BaseElement>[])\n : [];\n\n // if the current node is visible, keep it and the filtered children\n if (node.node && node.node.isVisible === true) {\n return {\n ...node,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible, but has visible children, create an empty node to include these children\n if (filteredChildren.length > 0) {\n return {\n node: null,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible and has no visible children, return null\n return null;\n }\n\n return {\n ...execution,\n tasks: Array.isArray(execution.tasks)\n ? execution.tasks.map((task: ExecutionTask) => {\n const newTask = { ...task };\n if (task.pageContext?.tree) {\n newTask.pageContext = {\n ...task.pageContext,\n tree: filterVisibleTree(task.pageContext.tree) || {\n node: null,\n children: [],\n },\n };\n }\n return newTask;\n })\n : execution.tasks,\n };\n}\n\nexport const parsePrompt = (\n prompt: TUserPrompt,\n): {\n textPrompt: string;\n multimodalPrompt?: TMultimodalPrompt;\n} => {\n if (typeof prompt === 'string') {\n return {\n textPrompt: prompt,\n multimodalPrompt: undefined,\n };\n }\n return {\n textPrompt: prompt.prompt,\n multimodalPrompt: prompt.images\n ? {\n images: prompt.images,\n convertHttpImage2Base64: !!prompt.convertHttpImage2Base64,\n }\n : undefined,\n };\n};\n","import type { BaseElement, Rect, UIContext } from '@midscene/core';\nimport type { NodeType } from '@midscene/shared/constants';\nexport interface WebElementInfoType extends BaseElement {\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n}\n\nexport class WebElementInfo implements BaseElement {\n content: string;\n\n rect: Rect;\n\n center: [number, number];\n\n id: string;\n\n indexId: number;\n\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n\n xpaths?: string[];\n\n isVisible: boolean;\n\n constructor({\n content,\n rect,\n id,\n attributes,\n indexId,\n xpaths,\n isVisible,\n }: {\n content: string;\n rect: Rect;\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n indexId: number;\n xpaths?: string[];\n isVisible: boolean;\n }) {\n this.content = content;\n this.rect = rect;\n this.center = [\n Math.floor(rect.left + rect.width / 2),\n Math.floor(rect.top + rect.height / 2),\n ];\n this.id = id;\n this.attributes = attributes;\n this.indexId = indexId;\n this.xpaths = xpaths;\n this.isVisible = isVisible;\n }\n}\n\nexport type WebUIContext = UIContext<WebElementInfo> & {\n url: string;\n _isFrozen?: boolean;\n};\n","import assert from 'node:assert';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport type { TUserPrompt } from '@midscene/core';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\nimport {\n MIDSCENE_CACHE_MAX_FILENAME_LENGTH,\n getAIConfigInNumber,\n} from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { ifInBrowser, ifInWorker } from '@midscene/shared/utils';\nimport { generateHashId } from '@midscene/shared/utils';\nimport yaml from 'js-yaml';\nimport semver from 'semver';\nimport { version } from '../../package.json';\nimport { replaceIllegalPathCharsAndSpace } from './utils';\n\nconst DEFAULT_CACHE_MAX_FILENAME_LENGTH = 200;\n\nexport const debug = getDebug('cache');\n\nexport interface PlanningCache {\n type: 'plan';\n prompt: string;\n yamlWorkflow: string;\n}\n\nexport interface LocateCache {\n type: 'locate';\n prompt: TUserPrompt;\n xpaths: string[];\n}\n\nexport interface MatchCacheResult<T extends PlanningCache | LocateCache> {\n cacheContent: T;\n updateFn: (cb: (cache: T) => void) => void;\n}\n\nexport type CacheFileContent = {\n midsceneVersion: string;\n cacheId: string;\n caches: Array<PlanningCache | LocateCache>;\n};\n\nconst lowestSupportedMidsceneVersion = '0.16.10';\nexport const cacheFileExt = '.cache.yaml';\n\nexport class TaskCache {\n cacheId: string;\n\n cacheFilePath?: string;\n\n cache: CacheFileContent;\n\n isCacheResultUsed: boolean; // a flag to indicate if the cache result should be used\n cacheOriginalLength: number;\n\n private matchedCacheIndices: Set<string> = new Set(); // Track matched records\n\n constructor(\n cacheId: string,\n isCacheResultUsed: boolean,\n cacheFilePath?: string,\n ) {\n assert(cacheId, 'cacheId is required');\n let safeCacheId = replaceIllegalPathCharsAndSpace(cacheId);\n const cacheMaxFilenameLength =\n getAIConfigInNumber(MIDSCENE_CACHE_MAX_FILENAME_LENGTH) ||\n DEFAULT_CACHE_MAX_FILENAME_LENGTH;\n if (Buffer.byteLength(safeCacheId, 'utf8') > cacheMaxFilenameLength) {\n const prefix = safeCacheId.slice(0, 32);\n const hash = generateHashId(undefined, safeCacheId);\n safeCacheId = `${prefix}-${hash}`;\n }\n this.cacheId = safeCacheId;\n\n this.cacheFilePath =\n ifInBrowser || ifInWorker\n ? undefined\n : cacheFilePath ||\n join(getMidsceneRunSubDir('cache'), `${this.cacheId}${cacheFileExt}`);\n this.isCacheResultUsed = isCacheResultUsed;\n\n let cacheContent;\n if (this.cacheFilePath) {\n cacheContent = this.loadCacheFromFile();\n }\n if (!cacheContent) {\n cacheContent = {\n midsceneVersion: version,\n cacheId: this.cacheId,\n caches: [],\n };\n }\n this.cache = cacheContent;\n this.cacheOriginalLength = this.cache.caches.length;\n }\n\n matchCache(\n prompt: TUserPrompt,\n type: 'plan' | 'locate',\n ): MatchCacheResult<PlanningCache | LocateCache> | undefined {\n // Find the first unused matching cache\n for (let i = 0; i < this.cacheOriginalLength; i++) {\n const item = this.cache.caches[i];\n const promptStr =\n typeof prompt === 'string' ? prompt : JSON.stringify(prompt);\n const key = `${type}:${promptStr}:${i}`;\n if (\n item.type === type &&\n isDeepStrictEqual(item.prompt, prompt) &&\n !this.matchedCacheIndices.has(key)\n ) {\n this.matchedCacheIndices.add(key);\n debug(\n 'cache found and marked as used, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n return {\n cacheContent: item,\n updateFn: (cb: (cache: PlanningCache | LocateCache) => void) => {\n debug(\n 'will call updateFn to update cache, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n cb(item);\n debug(\n 'cache updated, will flush to file, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n this.flushCacheToFile();\n },\n };\n }\n }\n debug('no unused cache found, type: %s, prompt: %s', type, prompt);\n return undefined;\n }\n\n matchPlanCache(prompt: string): MatchCacheResult<PlanningCache> | undefined {\n return this.matchCache(prompt, 'plan') as\n | MatchCacheResult<PlanningCache>\n | undefined;\n }\n\n matchLocateCache(\n prompt: TUserPrompt,\n ): MatchCacheResult<LocateCache> | undefined {\n return this.matchCache(prompt, 'locate') as\n | MatchCacheResult<LocateCache>\n | undefined;\n }\n\n appendCache(cache: PlanningCache | LocateCache) {\n debug('will append cache', cache);\n this.cache.caches.push(cache);\n this.flushCacheToFile();\n }\n\n loadCacheFromFile() {\n const cacheFile = this.cacheFilePath;\n assert(cacheFile, 'cache file path is required');\n\n if (!existsSync(cacheFile)) {\n debug('no cache file found, path: %s', cacheFile);\n return undefined;\n }\n\n // detect old cache file\n const jsonTypeCacheFile = cacheFile.replace(cacheFileExt, '.json');\n if (existsSync(jsonTypeCacheFile) && this.isCacheResultUsed) {\n console.warn(\n `An outdated cache file from an earlier version of Midscene has been detected. Since version 0.17, we have implemented an improved caching strategy. Please delete the old file located at: ${jsonTypeCacheFile}.`,\n );\n return undefined;\n }\n\n try {\n const data = readFileSync(cacheFile, 'utf8');\n const jsonData = yaml.load(data) as CacheFileContent;\n\n if (!version) {\n debug('no midscene version info, will not read cache from file');\n return undefined;\n }\n\n if (\n semver.lt(jsonData.midsceneVersion, lowestSupportedMidsceneVersion) &&\n !jsonData.midsceneVersion.includes('beta') // for internal test\n ) {\n console.warn(\n `You are using an old version of Midscene cache file, and we cannot match any info from it. Starting from Midscene v0.17, we changed our strategy to use xpath for cache info, providing better performance.\\nPlease delete the existing cache and rebuild it. Sorry for the inconvenience.\\ncache file: ${cacheFile}`,\n );\n return undefined;\n }\n\n debug(\n 'cache loaded from file, path: %s, cache version: %s, record length: %s',\n cacheFile,\n jsonData.midsceneVersion,\n jsonData.caches.length,\n );\n jsonData.midsceneVersion = version; // update the version\n return jsonData;\n } catch (err) {\n debug(\n 'cache file exists but load failed, path: %s, error: %s',\n cacheFile,\n err,\n );\n return undefined;\n }\n }\n\n flushCacheToFile() {\n if (!version) {\n debug('no midscene version info, will not write cache to file');\n return;\n }\n\n if (!this.cacheFilePath) {\n debug('no cache file path, will not write cache to file');\n return;\n }\n\n try {\n const dir = dirname(this.cacheFilePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n debug('created cache directory: %s', dir);\n }\n\n // Sort caches to ensure plan entries come before locate entries for better readability\n const sortedCaches = [...this.cache.caches].sort((a, b) => {\n if (a.type === 'plan' && b.type === 'locate') return -1;\n if (a.type === 'locate' && b.type === 'plan') return 1;\n return 0;\n });\n\n const cacheToWrite = {\n ...this.cache,\n caches: sortedCaches,\n };\n\n const yamlData = yaml.dump(cacheToWrite);\n writeFileSync(this.cacheFilePath, yamlData);\n debug('cache flushed to file: %s', this.cacheFilePath);\n } catch (err) {\n debug(\n 'write cache to file failed, path: %s, error: %s',\n this.cacheFilePath,\n err,\n );\n }\n }\n\n updateOrAppendCacheRecord(\n newRecord: PlanningCache | LocateCache,\n cachedRecord?: MatchCacheResult<PlanningCache | LocateCache>,\n ) {\n if (cachedRecord) {\n // update existing record\n if (newRecord.type === 'plan') {\n cachedRecord.updateFn((cache) => {\n (cache as PlanningCache).yamlWorkflow = newRecord.yamlWorkflow;\n });\n } else {\n cachedRecord.updateFn((cache) => {\n (cache as LocateCache).xpaths = newRecord.xpaths;\n });\n }\n } else {\n this.appendCache(newRecord);\n }\n }\n}\n","{\n \"name\": \"@midscene/web\",\n \"description\": \"Automate browser actions, extract data, and perform assertions using AI. It offers JavaScript SDK, Chrome extension, and support for scripting in YAML. See https://midscenejs.com/ for details.\",\n \"keywords\": [\n \"AI UI automation\",\n \"AI testing\",\n \"Computer use\",\n \"Browser use\",\n \"Android use\"\n ],\n \"version\": \"0.26.0\",\n \"repository\": \"https://github.com/web-infra-dev/midscene\",\n \"homepage\": \"https://midscenejs.com/\",\n \"jsnext:source\": \"./src/index.ts\",\n \"main\": \"./dist/lib/index.js\",\n \"types\": \"./dist/types/index.d.ts\",\n \"bin\": {\n \"midscene-playground\": \"./bin/midscene-playground\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/types/index.d.ts\",\n \"default\": \"./dist/lib/index.js\"\n },\n \"./bridge-mode\": {\n \"types\": \"./dist/types/bridge-mode.d.ts\",\n \"default\": \"./dist/lib/bridge-mode.js\"\n },\n \"./bridge-mode-browser\": {\n \"types\": \"./dist/types/bridge-mode-browser.d.ts\",\n \"default\": \"./dist/lib/bridge-mode-browser.js\"\n },\n \"./utils\": {\n \"types\": \"./dist/types/utils.d.ts\",\n \"default\": \"./dist/lib/utils.js\"\n },\n \"./ui-utils\": {\n \"types\": \"./dist/types/ui-utils.d.ts\",\n \"default\": \"./dist/lib/ui-utils.js\"\n },\n \"./puppeteer\": {\n \"types\": \"./dist/types/puppeteer.d.ts\",\n \"default\": \"./dist/lib/puppeteer.js\"\n },\n \"./puppeteer-agent-launcher\": {\n \"types\": \"./dist/types/puppeteer-agent-launcher.d.ts\",\n \"default\": \"./dist/lib/puppeteer-agent-launcher.js\"\n },\n \"./playwright\": {\n \"types\": \"./dist/types/playwright.d.ts\",\n \"default\": \"./dist/lib/playwright.js\"\n },\n \"./playwright-report\": {\n \"types\": \"./dist/types/playwright-report.d.ts\",\n \"default\": \"./dist/lib/playwright-report.js\"\n },\n \"./playwright-reporter\": {\n \"types\": \"./dist/types/playwright-reporter.d.ts\",\n \"default\": \"./dist/lib/playwright-reporter.js\"\n },\n \"./playground\": {\n \"types\": \"./dist/types/playground.d.ts\",\n \"default\": \"./dist/lib/playground.js\"\n },\n \"./midscene-playground\": {\n \"types\": \"./dist/types/midscene-playground.d.ts\",\n \"default\": \"./dist/lib/midscene-playground.js\"\n },\n \"./midscene-server\": {\n \"types\": \"./dist/types/midscene-server.d.ts\",\n \"default\": \"./dist/lib/midscene-server.js\"\n },\n \"./chrome-extension\": {\n \"types\": \"./dist/types/chrome-extension.d.ts\",\n \"default\": \"./dist/lib/chrome-extension.js\"\n },\n \"./yaml\": {\n \"types\": \"./dist/types/yaml.d.ts\",\n \"default\": \"./dist/lib/yaml.js\"\n },\n \"./agent\": {\n \"types\": \"./dist/types/agent.d.ts\",\n \"default\": \"./dist/lib/agent.js\"\n }\n },\n \"typesVersions\": {\n \"*\": {\n \".\": [\n \"./dist/types/index.d.ts\"\n ],\n \"bridge-mode\": [\n \"./dist/types/bridge-mode.d.ts\"\n ],\n \"bridge-mode-browser\": [\n \"./dist/types/bridge-mode-browser.d.ts\"\n ],\n \"utils\": [\n \"./dist/types/utils.d.ts\"\n ],\n \"ui-utils\": [\n \"./dist/types/ui-utils.d.ts\"\n ],\n \"puppeteer\": [\n \"./dist/types/puppeteer.d.ts\"\n ],\n \"puppeteer-agent-launcher\": [\n \"./dist/types/puppeteer-agent-launcher.d.ts\"\n ],\n \"playwright\": [\n \"./dist/types/playwright.d.ts\"\n ],\n \"playwright-report\": [\n \"./dist/types/playwright-report.d.ts\"\n ],\n \"playwright-reporter\": [\n \"./dist/types/playwright-reporter.d.ts\"\n ],\n \"playground\": [\n \"./dist/types/playground.d.ts\"\n ],\n \"midscene-playground\": [\n \"./dist/types/midscene-playground.d.ts\"\n ],\n \"midscene-server\": [\n \"./dist/types/midscene-server.d.ts\"\n ],\n \"chrome-extension\": [\n \"./dist/types/chrome-extension.d.ts\"\n ],\n \"yaml\": [\n \"./dist/types/yaml.d.ts\"\n ],\n \"agent\": [\n \"./dist/types/agent.d.ts\"\n ]\n }\n },\n \"watch\": {\n \"build\": {\n \"patterns\": [\n \"src\"\n ],\n \"extensions\": \"tsx,less,scss,css,js,jsx,ts\",\n \"quiet\": false\n }\n },\n \"scripts\": {\n \"dev\": \"npm run build && npx npm-watch\",\n \"dev:server\": \"npm run build && ./bin/midscene-playground\",\n \"build\": \"modern build -c ./modern.config.ts\",\n \"postbuild\": \"node scripts/check-exports.js\",\n \"build:watch\": \"modern build -w -c ./modern.config.ts --no-clear\",\n \"test\": \"vitest --run\",\n \"test:u\": \"vitest --run -u\",\n \"test:ai\": \"AI_TEST_TYPE=web npm run test\",\n \"test:ai:cache\": \"MIDSCENE_CACHE=true npm run test:ai\",\n \"upgrade\": \"modern upgrade\",\n \"e2e\": \"playwright test --config=tests/playwright.config.ts\",\n \"e2e:report\": \"MIDSCENE_REPORT=true playwright test --config=tests/playwright.config.ts\",\n \"e2e:cache\": \"MIDSCENE_CACHE=true playwright test --config=tests/playwright.config.ts\",\n \"e2e:ui\": \"playwright test --config=tests/playwright.config.ts --ui\",\n \"e2e:ui:cache\": \"MIDSCENE_CACHE=true playwright test --config=tests/playwright.config.ts --ui\"\n },\n \"files\": [\n \"static\",\n \"dist\",\n \"iife-script\",\n \"README.md\",\n \"bin\"\n ],\n \"dependencies\": {\n \"@midscene/core\": \"workspace:*\",\n \"@midscene/shared\": \"workspace:*\",\n \"@xmldom/xmldom\": \"0.8.10\",\n \"cors\": \"2.8.5\",\n \"dayjs\": \"^1.11.11\",\n \"devtools-protocol\": \"0.0.1380148\",\n \"dotenv\": \"16.4.5\",\n \"express\": \"^4.21.2\",\n \"fs-extra\": \"11.2.0\",\n \"http-server\": \"14.1.1\",\n \"inquirer\": \"10.1.5\",\n \"js-sha256\": \"0.11.0\",\n \"js-yaml\": \"4.1.0\",\n \"openai\": \"4.81.0\",\n \"semver\": \"7.5.2\",\n \"socket.io\": \"^4.8.1\",\n \"socket.io-client\": \"4.8.1\"\n },\n \"devDependencies\": {\n \"@modern-js/module-tools\": \"2.60.6\",\n \"@playwright/test\": \"^1.44.1\",\n \"@types/chrome\": \"0.0.279\",\n \"@types/cors\": \"2.8.12\",\n \"@types/express\": \"^4.17.21\",\n \"@types/fs-extra\": \"11.0.4\",\n \"@types/http-server\": \"^0.12.4\",\n \"@types/js-yaml\": \"4.0.9\",\n \"@types/node\": \"^18.0.0\",\n \"@types/semver\": \"7.7.0\",\n \"playwright\": \"1.44.1\",\n \"puppeteer\": \"24.2.0\",\n \"typescript\": \"^5.8.3\",\n \"vitest\": \"3.0.5\"\n },\n \"peerDependencies\": {\n \"@playwright/test\": \"^1.44.1\",\n \"playwright\": \"^1.44.1\",\n \"puppeteer\": \">=20.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"@playwright/test\": {\n \"optional\": true\n },\n \"puppeteer\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=18.0.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org\"\n },\n \"license\": \"MIT\"\n}\n","import type {\n DetailedLocateParam,\n MidsceneYamlFlowItem,\n PlanningAction,\n PlanningActionParamInputOrKeyPress,\n PlanningActionParamScroll,\n PlanningActionParamSleep,\n PlanningActionParamTap,\n PlanningLocateParam,\n} from '@midscene/core';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nconst debug = getDebug('plan-builder');\n\nexport function buildPlans(\n type: PlanningAction['type'],\n locateParam?: DetailedLocateParam,\n param?:\n | PlanningActionParamInputOrKeyPress\n | PlanningActionParamScroll\n | PlanningActionParamSleep,\n): PlanningAction[] {\n let returnPlans: PlanningAction[] = [];\n const locatePlan: PlanningAction<PlanningLocateParam> | null = locateParam\n ? {\n type: 'Locate',\n locate: locateParam,\n param: locateParam,\n thought: '',\n }\n : null;\n if (type === 'Tap' || type === 'Hover' || type === 'RightClick') {\n assert(locateParam, `missing locate info for action \"${type}\"`);\n assert(locatePlan, `missing locate info for action \"${type}\"`);\n const tapPlan: PlanningAction<PlanningActionParamTap> = {\n type,\n param: null,\n thought: '',\n locate: locateParam,\n };\n\n returnPlans = [locatePlan, tapPlan];\n }\n if (type === 'Input' || type === 'KeyboardPress') {\n if (type === 'Input') {\n assert(locateParam, `missing locate info for action \"${type}\"`);\n }\n assert(param, `missing param for action \"${type}\"`);\n\n const inputPlan: PlanningAction<PlanningActionParamInputOrKeyPress> = {\n type,\n param: param as PlanningActionParamInputOrKeyPress,\n thought: '',\n locate: locateParam!,\n };\n\n if (locatePlan) {\n returnPlans = [locatePlan, inputPlan];\n } else {\n returnPlans = [inputPlan];\n }\n }\n\n if (type === 'Scroll') {\n assert(param, `missing param for action \"${type}\"`);\n\n const scrollPlan: PlanningAction<PlanningActionParamScroll> = {\n type,\n param: param as PlanningActionParamScroll,\n thought: '',\n locate: locateParam,\n };\n\n if (locatePlan) {\n returnPlans = [locatePlan, scrollPlan];\n } else {\n returnPlans = [scrollPlan];\n }\n }\n\n if (type === 'Sleep') {\n assert(param, `missing param for action \"${type}\"`);\n\n const sleepPlan: PlanningAction<PlanningActionParamSleep> = {\n type,\n param: param as PlanningActionParamSleep,\n thought: '',\n locate: null,\n };\n\n returnPlans = [sleepPlan];\n }\n\n if (type === 'Locate') {\n assert(locateParam, `missing locate info for action \"${type}\"`);\n const locatePlan: PlanningAction<PlanningLocateParam> = {\n type,\n param: locateParam as PlanningLocateParam,\n locate: locateParam,\n thought: '',\n };\n returnPlans = [locatePlan];\n }\n\n if (returnPlans) {\n debug('buildPlans', returnPlans);\n return returnPlans;\n }\n\n throw new Error(`Not supported type: ${type}`);\n}\n","import {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@midscene/shared/constants';\nimport type { Page as PlaywrightPageType } from 'playwright';\nimport type { WebPageOpt } from '../common/agent';\nimport { Page as BasePage } from '../puppeteer/base-page';\n\nexport class WebPage extends BasePage<'playwright', PlaywrightPageType> {\n waitForNavigationTimeout: number;\n waitForNetworkIdleTimeout: number;\n\n constructor(page: PlaywrightPageType, opts?: WebPageOpt) {\n super(page, 'playwright', opts);\n const {\n waitForNavigationTimeout = DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n waitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n } = opts ?? {};\n this.waitForNavigationTimeout = waitForNavigationTimeout;\n this.waitForNetworkIdleTimeout = waitForNetworkIdleTimeout;\n }\n}\n","import type { ElementTreeNode, Point, Size } from '@midscene/core';\nimport { sleep } from '@midscene/core/utils';\nimport { DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT } from '@midscene/shared/constants';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport { treeToList } from '@midscene/shared/extractor';\nimport {\n getElementInfosScriptContent,\n getExtraReturnLogic,\n} from '@midscene/shared/fs';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport type { Page as PuppeteerPage } from 'puppeteer';\nimport type { WebKeyInput } from '../common/page';\nimport type { AbstractPage } from '../page';\nimport type { MouseButton } from '../page';\n\nexport const debugPage = getDebug('web:page');\n\nexport class Page<\n AgentType extends 'puppeteer' | 'playwright',\n PageType extends PuppeteerPage | PlaywrightPage,\n> implements AbstractPage\n{\n underlyingPage: PageType;\n protected waitForNavigationTimeout: number;\n private viewportSize?: Size;\n\n pageType: AgentType;\n\n private async evaluate<R>(\n pageFunction: string | ((...args: any[]) => R | Promise<R>),\n arg?: any,\n ): Promise<R> {\n let result: R;\n debugPage('evaluate function begin');\n if (this.pageType === 'puppeteer') {\n result = await (this.underlyingPage as PuppeteerPage).evaluate(\n pageFunction,\n arg,\n );\n } else {\n result = await (this.underlyingPage as PlaywrightPage).evaluate(\n pageFunction,\n arg,\n );\n }\n debugPage('evaluate function end');\n return result;\n }\n\n constructor(\n underlyingPage: PageType,\n pageType: AgentType,\n opts?: {\n waitForNavigationTimeout?: number;\n },\n ) {\n this.underlyingPage = underlyingPage;\n this.pageType = pageType;\n this.waitForNavigationTimeout =\n opts?.waitForNavigationTimeout ?? DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;\n }\n\n async evaluateJavaScript<T = any>(script: string): Promise<T> {\n return this.evaluate(script);\n }\n\n async waitForNavigation() {\n if (this.waitForNavigationTimeout === 0) {\n debugPage('waitForNavigation timeout is 0, skip waiting');\n return;\n }\n\n // issue: https://github.com/puppeteer/puppeteer/issues/3323\n if (this.pageType === 'puppeteer' || this.pageType === 'playwright') {\n debugPage('waitForNavigation begin');\n debugPage(`waitForNavigation timeout: ${this.waitForNavigationTimeout}`);\n try {\n await (this.underlyingPage as PuppeteerPage).waitForSelector('html', {\n timeout: this.waitForNavigationTimeout,\n });\n } catch (error) {\n // Ignore timeout error, continue execution\n console.warn(\n '[midscene:warning] Waiting for the navigation has timed out, but Midscene will continue execution. Please check https://midscenejs.com/faq.html#customize-the-network-timeout for more information on customizing the network timeout',\n );\n }\n debugPage('waitForNavigation end');\n }\n }\n\n // @deprecated\n async getElementsInfo() {\n // const scripts = await getExtraReturnLogic();\n // const captureElementSnapshot = await this.evaluate(scripts);\n // return captureElementSnapshot as ElementInfo[];\n await this.waitForNavigation();\n debugPage('getElementsInfo begin');\n const tree = await this.getElementsNodeTree();\n debugPage('getElementsInfo end');\n return treeToList(tree);\n }\n\n async getXpathsById(id: string) {\n const elementInfosScriptContent = getElementInfosScriptContent();\n\n return this.evaluateJavaScript(\n `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${id}')`,\n );\n }\n\n async getXpathsByPoint(point: Point, isOrderSensitive: boolean) {\n const elementInfosScriptContent = getElementInfosScriptContent();\n\n return this.evaluateJavaScript(\n `${elementInfosScriptContent}midscene_element_inspector.getXpathsByPoint({left: ${point.left}, top: ${point.top}}, ${isOrderSensitive})`,\n );\n }\n\n async getElementInfoByXpath(xpath: string) {\n const elementInfosScriptContent = getElementInfosScriptContent();\n\n return this.evaluateJavaScript(\n `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpath}')`,\n );\n }\n\n async getElementsNodeTree() {\n // ref: packages/web-integration/src/playwright/ai-fixture.ts popup logic\n // During test execution, a new page might be opened through a connection, and the page remains confined to the same page instance.\n // The page may go through opening, closing, and reopening; if the page is closed, evaluate may return undefined, which can lead to errors.\n await this.waitForNavigation();\n const scripts = await getExtraReturnLogic(true);\n assert(scripts, 'scripts should be set before writing report in browser');\n const startTime = Date.now();\n const captureElementSnapshot = await this.evaluate(scripts);\n const endTime = Date.now();\n debugPage(`getElementsNodeTree end, cost: ${endTime - startTime}ms`);\n return captureElementSnapshot as ElementTreeNode<ElementInfo>;\n }\n\n async size(): Promise<Size> {\n if (this.viewportSize) return this.viewportSize;\n const sizeInfo: Size = await this.evaluate(() => {\n return {\n width: document.documentElement.clientWidth,\n height: document.documentElement.clientHeight,\n dpr: window.devicePixelRatio,\n };\n });\n this.viewportSize = sizeInfo;\n return sizeInfo;\n }\n\n async screenshotBase64(): Promise<string> {\n const imgType = 'jpeg';\n const quality = 90;\n await this.waitForNavigation();\n const startTime = Date.now();\n debugPage('screenshotBase64 begin');\n\n let base64: string;\n if (this.pageType === 'puppeteer') {\n const result = await (this.underlyingPage as PuppeteerPage).screenshot({\n type: imgType,\n quality,\n encoding: 'base64',\n });\n base64 = `data:image/jpeg;base64,${result}`;\n } else if (this.pageType === 'playwright') {\n const buffer = await (this.underlyingPage as PlaywrightPage).screenshot({\n type: imgType,\n quality,\n timeout: 10 * 1000,\n });\n base64 = `data:image/jpeg;base64,${buffer.toString('base64')}`;\n } else {\n throw new Error('Unsupported page type for screenshot');\n }\n const endTime = Date.now();\n debugPage(`screenshotBase64 end, cost: ${endTime - startTime}ms`);\n return base64;\n }\n\n async url(): Promise<string> {\n return this.underlyingPage.url();\n }\n\n get mouse() {\n return {\n click: async (\n x: number,\n y: number,\n options?: { button?: MouseButton; count?: number },\n ) => {\n await this.mouse.move(x, y);\n debugPage(`mouse click ${x}, ${y}`);\n this.underlyingPage.mouse.click(x, y, {\n button: options?.button || 'left',\n count: options?.count || 1,\n });\n },\n wheel: async (deltaX: number, deltaY: number) => {\n debugPage(`mouse wheel ${deltaX}, ${deltaY}`);\n if (this.pageType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).mouse.wheel({\n deltaX,\n deltaY,\n });\n } else if (this.pageType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).mouse.wheel(\n deltaX,\n deltaY,\n );\n }\n },\n move: async (x: number, y: number) => {\n this.everMoved = true;\n debugPage(`mouse move to ${x}, ${y}`);\n return this.underlyingPage.mouse.move(x, y);\n },\n drag: async (\n from: { x: number; y: number },\n to: { x: number; y: number },\n ) => {\n debugPage(`mouse drag from ${from.x}, ${from.y} to ${to.x}, ${to.y}`);\n if (this.pageType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).mouse.drag(\n {\n x: from.x,\n y: from.y,\n },\n {\n x: to.x,\n y: to.y,\n },\n );\n } else if (this.pageType === 'playwright') {\n // Playwright doesn't have a drag method, so we need to simulate it\n await (this.underlyingPage as PlaywrightPage).mouse.move(\n from.x,\n from.y,\n );\n await (this.underlyingPage as PlaywrightPage).mouse.down();\n await (this.underlyingPage as PlaywrightPage).mouse.move(to.x, to.y);\n await (this.underlyingPage as PlaywrightPage).mouse.up();\n }\n },\n };\n }\n\n get keyboard() {\n return {\n type: async (text: string) => {\n debugPage(`keyboard type ${text}`);\n return this.underlyingPage.keyboard.type(text, { delay: 80 });\n },\n press: async (\n action:\n | { key: WebKeyInput; command?: string }\n | { key: WebKeyInput; command?: string }[],\n ) => {\n const keys = Array.isArray(action) ? action : [action];\n debugPage('keyboard press', keys);\n for (const k of keys) {\n const commands = k.command ? [k.command] : [];\n await this.underlyingPage.keyboard.down(k.key, { commands });\n }\n for (const k of [...keys].reverse()) {\n await this.underlyingPage.keyboard.up(k.key);\n }\n },\n down: async (key: WebKeyInput) => {\n debugPage(`keyboard down ${key}`);\n this.underlyingPage.keyboard.down(key);\n },\n up: async (key: WebKeyInput) => {\n debugPage(`keyboard up ${key}`);\n this.underlyingPage.keyboard.up(key);\n },\n };\n }\n\n async clearInput(element: ElementInfo): Promise<void> {\n if (!element) {\n console.warn('No element to clear input');\n return;\n }\n\n const backspace = async () => {\n await sleep(100);\n await this.keyboard.press([{ key: 'Backspace' }]);\n };\n\n const isMac = process.platform === 'darwin';\n debugPage('clearInput begin');\n if (isMac) {\n if (this.pageType === 'puppeteer') {\n // https://github.com/segment-boneyard/nightmare/issues/810#issuecomment-452669866\n await this.mouse.click(element.center[0], element.center[1], {\n count: 3,\n });\n await backspace();\n }\n\n await this.mouse.click(element.center[0], element.center[1]);\n await this.underlyingPage.keyboard.down('Meta');\n await this.underlyingPage.keyboard.press('a');\n await this.underlyingPage.keyboard.up('Meta');\n await backspace();\n } else {\n await this.mouse.click(element.center[0], element.center[1]);\n await this.underlyingPage.keyboard.down('Control');\n await this.underlyingPage.keyboard.press('a');\n await this.underlyingPage.keyboard.up('Control');\n await backspace();\n }\n debugPage('clearInput end');\n }\n\n private everMoved = false;\n private async moveToPointBeforeScroll(point?: Point): Promise<void> {\n if (point) {\n await this.mouse.move(point.left, point.top);\n } else if (!this.everMoved) {\n // If the mouse has never moved, move it to the center of the page\n const size = await this.size();\n const targetX = Math.floor(size.width / 2);\n const targetY = Math.floor(size.height / 2);\n await this.mouse.move(targetX, targetY);\n }\n }\n\n async scrollUntilTop(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, -9999999);\n }\n\n async scrollUntilBottom(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, 9999999);\n }\n\n async scrollUntilLeft(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(-9999999, 0);\n }\n\n async scrollUntilRight(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(9999999, 0);\n }\n\n async scrollUp(distance?: number, startingPoint?: Point): Promise<void> {\n const innerHeight = await this.evaluate(() => window.innerHeight);\n const scrollDistance = distance || innerHeight * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, -scrollDistance);\n }\n\n async scrollDown(distance?: number, startingPoint?: Point): Promise<void> {\n const innerHeight = await this.evaluate(() => window.innerHeight);\n const scrollDistance = distance || innerHeight * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, scrollDistance);\n }\n\n async scrollLeft(distance?: number, startingPoint?: Point): Promise<void> {\n const innerWidth = await this.evaluate(() => window.innerWidth);\n const scrollDistance = distance || innerWidth * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(-scrollDistance, 0);\n }\n\n async scrollRight(distance?: number, startingPoint?: Point): Promise<void> {\n const innerWidth = await this.evaluate(() => window.innerWidth);\n const scrollDistance = distance || innerWidth * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(scrollDistance, 0);\n }\n\n async navigate(url: string): Promise<void> {\n debugPage(`navigate to ${url}`);\n if (this.pageType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).goto(url);\n } else if (this.pageType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).goto(url);\n } else {\n throw new Error('Unsupported page type for navigate');\n }\n }\n\n async destroy(): Promise<void> {}\n}\n","import { randomUUID } from 'node:crypto';\nimport type { PageAgent, PageAgentOpt, WebPageAgentOpt } from '@/common/agent';\nimport { replaceIllegalPathCharsAndSpace } from '@/common/utils';\nimport { PlaywrightAgent } from '@/playwright/index';\nimport type { AgentWaitForOpt } from '@midscene/core';\nimport {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@midscene/shared/constants';\nimport { getDebug } from '@midscene/shared/logger';\nimport { type TestInfo, type TestType, test } from '@playwright/test';\nimport type { Page as OriginPlaywrightPage } from 'playwright';\nexport type APITestType = Pick<TestType<any, any>, 'step'>;\n\nconst debugPage = getDebug('web:playwright:ai-fixture');\n\nconst groupAndCaseForTest = (testInfo: TestInfo) => {\n let taskFile: string;\n let taskTitle: string;\n const titlePath = [...testInfo.titlePath];\n\n if (titlePath.length > 1) {\n taskFile = titlePath.shift() || 'unnamed';\n taskTitle = titlePath.join('__');\n } else if (titlePath.length === 1) {\n taskTitle = titlePath[0];\n taskFile = `${taskTitle}`;\n } else {\n taskTitle = 'unnamed';\n taskFile = 'unnamed';\n }\n\n const taskTitleWithRetry = `${taskTitle}${testInfo.retry ? `(retry #${testInfo.retry})` : ''}`;\n\n return {\n file: taskFile,\n id: replaceIllegalPathCharsAndSpace(`${taskFile}(${taskTitle})`),\n title: replaceIllegalPathCharsAndSpace(taskTitleWithRetry),\n };\n};\n\nconst midsceneAgentKeyId = '_midsceneAgentId';\nexport const midsceneDumpAnnotationId = 'MIDSCENE_DUMP_ANNOTATION';\n\nexport const PlaywrightAiFixture = (options?: {\n forceSameTabNavigation?: boolean;\n waitForNetworkIdleTimeout?: number;\n waitForNavigationTimeout?: number;\n}) => {\n const {\n forceSameTabNavigation = true,\n waitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n waitForNavigationTimeout = DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n } = options ?? {};\n const pageAgentMap: Record<string, PageAgent> = {};\n const createOrReuseAgentForPage = (\n page: OriginPlaywrightPage,\n testInfo: TestInfo, // { testId: string; taskFile: string; taskTitle: string },\n opts?: WebPageAgentOpt,\n ) => {\n let idForPage = (page as any)[midsceneAgentKeyId];\n if (!idForPage) {\n idForPage = randomUUID();\n (page as any)[midsceneAgentKeyId] = idForPage;\n const { testId } = testInfo;\n const { file, id, title } = groupAndCaseForTest(testInfo);\n pageAgentMap[idForPage] = new PlaywrightAgent(page, {\n testId: `playwright-${testId}-${idForPage}`,\n forceSameTabNavigation,\n cacheId: id,\n groupName: title,\n groupDescription: file,\n generateReport: false, // we will generate it in the reporter\n ...opts,\n });\n\n pageAgentMap[idForPage].onDumpUpdate = (dump: string) => {\n updateDumpAnnotation(testInfo, dump);\n };\n\n page.on('close', () => {\n debugPage('page closed');\n pageAgentMap[idForPage].destroy();\n delete pageAgentMap[idForPage];\n });\n }\n\n return pageAgentMap[idForPage];\n };\n\n async function generateAiFunction(options: {\n page: OriginPlaywrightPage;\n testInfo: TestInfo;\n use: any;\n aiActionType:\n | 'ai'\n | 'aiAction'\n | 'aiHover'\n | 'aiInput'\n | 'aiKeyboardPress'\n | 'aiScroll'\n | 'aiTap'\n | 'aiRightClick'\n | 'aiQuery'\n | 'aiAssert'\n | 'aiWaitFor'\n | 'aiLocate'\n | 'aiNumber'\n | 'aiString'\n | 'aiBoolean'\n | 'aiAsk';\n }) {\n const { page, testInfo, use, aiActionType } = options;\n const agent = createOrReuseAgentForPage(page, testInfo, {\n waitForNavigationTimeout,\n waitForNetworkIdleTimeout,\n }) as PlaywrightAgent;\n\n await use(async (taskPrompt: string, ...args: any[]) => {\n return new Promise((resolve, reject) => {\n test.step(`ai-${aiActionType} - ${JSON.stringify(taskPrompt)}`, async () => {\n try {\n debugPage(\n `waitForNetworkIdle timeout: ${waitForNetworkIdleTimeout}`,\n );\n await agent.waitForNetworkIdle(waitForNetworkIdleTimeout);\n } catch (error) {\n console.warn(\n '[midscene:warning] Waiting for network idle has timed out, but Midscene will continue execution. Please check https://midscenejs.com/faq.html#customize-the-network-timeout for more information on customizing the network timeout',\n );\n }\n try {\n type AgentMethod = (\n prompt: string,\n ...restArgs: any[]\n ) => Promise<any>;\n const result = await (agent[aiActionType] as AgentMethod)(\n taskPrompt,\n ...(args || []),\n );\n resolve(result);\n } catch (error) {\n reject(error);\n }\n });\n });\n });\n }\n\n const updateDumpAnnotation = (test: TestInfo, dump: string) => {\n const currentAnnotation = test.annotations.find((item) => {\n return item.type === midsceneDumpAnnotationId;\n });\n if (currentAnnotation) {\n currentAnnotation.description = dump;\n } else {\n test.annotations.push({\n type: midsceneDumpAnnotationId,\n description: dump,\n });\n }\n };\n\n return {\n agentForPage: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await use(\n async (\n propsPage?: OriginPlaywrightPage | undefined,\n opts?: PageAgentOpt,\n ) => {\n const agent = createOrReuseAgentForPage(propsPage || page, testInfo, {\n waitForNavigationTimeout,\n waitForNetworkIdleTimeout,\n ...opts,\n });\n return agent;\n },\n );\n },\n ai: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'ai',\n });\n },\n aiAction: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAction',\n });\n },\n aiTap: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiTap',\n });\n },\n aiRightClick: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiRightClick',\n });\n },\n aiHover: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiHover',\n });\n },\n aiInput: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiInput',\n });\n },\n aiKeyboardPress: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiKeyboardPress',\n });\n },\n aiScroll: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiScroll',\n });\n },\n aiQuery: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiQuery',\n });\n },\n aiAssert: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAssert',\n });\n },\n aiWaitFor: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiWaitFor',\n });\n },\n aiLocate: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiLocate',\n });\n },\n aiNumber: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiNumber',\n });\n },\n aiString: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiString',\n });\n },\n aiBoolean: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiBoolean',\n });\n },\n aiAsk: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAsk',\n });\n },\n };\n};\n\nexport type PlayWrightAiFixtureType = {\n agentForPage: (page?: any, opts?: any) => Promise<PageAgent>;\n ai: <T = any>(prompt: string) => Promise<T>;\n aiAction: (taskPrompt: string) => ReturnType<PageAgent['aiAction']>;\n aiTap: (\n ...args: Parameters<PageAgent['aiTap']>\n ) => ReturnType<PageAgent['aiTap']>;\n aiRightClick: (\n ...args: Parameters<PageAgent['aiRightClick']>\n ) => ReturnType<PageAgent['aiRightClick']>;\n aiHover: (\n ...args: Parameters<PageAgent['aiHover']>\n ) => ReturnType<PageAgent['aiHover']>;\n aiInput: (\n ...args: Parameters<PageAgent['aiInput']>\n ) => ReturnType<PageAgent['aiInput']>;\n aiKeyboardPress: (\n ...args: Parameters<PageAgent['aiKeyboardPress']>\n ) => ReturnType<PageAgent['aiKeyboardPress']>;\n aiScroll: (\n ...args: Parameters<PageAgent['aiScroll']>\n ) => ReturnType<PageAgent['aiScroll']>;\n aiQuery: <T = any>(\n ...args: Parameters<PageAgent['aiQuery']>\n ) => ReturnType<PageAgent['aiQuery']>;\n aiAssert: (\n ...args: Parameters<PageAgent['aiAssert']>\n ) => ReturnType<PageAgent['aiAssert']>;\n aiWaitFor: (assertion: string, opt?: AgentWaitForOpt) => Promise<void>;\n aiLocate: (\n ...args: Parameters<PageAgent['aiLocate']>\n ) => ReturnType<PageAgent['aiLocate']>;\n aiNumber: (\n ...args: Parameters<PageAgent['aiNumber']>\n ) => ReturnType<PageAgent['aiNumber']>;\n aiString: (\n ...args: Parameters<PageAgent['aiString']>\n ) => ReturnType<PageAgent['aiString']>;\n aiBoolean: (\n ...args: Parameters<PageAgent['aiBoolean']>\n ) => ReturnType<PageAgent['aiBoolean']>;\n aiAsk: (\n ...args: Parameters<PageAgent['aiAsk']>\n ) => ReturnType<PageAgent['aiAsk']>;\n};\n","import { PageAgent, type WebPageAgentOpt } from '@/common/agent';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport { WebPage as PlaywrightWebPage } from './page';\n\nexport type { PlayWrightAiFixtureType } from './ai-fixture';\nexport { PlaywrightAiFixture } from './ai-fixture';\nexport { overrideAIConfig } from '@midscene/shared/env';\nexport { WebPage as PlaywrightWebPage } from './page';\nimport { forceClosePopup } from '@/common/utils';\nimport { getDebug } from '@midscene/shared/logger';\n\nconst debug = getDebug('playwright:agent');\n\nexport class PlaywrightAgent extends PageAgent<PlaywrightWebPage> {\n constructor(page: PlaywrightPage, opts?: WebPageAgentOpt) {\n const webPage = new PlaywrightWebPage(page, opts);\n super(webPage, opts);\n\n const { forceSameTabNavigation = true } = opts ?? {};\n\n if (forceSameTabNavigation) {\n forceClosePopup(page, debug);\n }\n }\n\n async waitForNetworkIdle(timeout = 1000) {\n await this.page.underlyingPage.waitForLoadState('networkidle', { timeout });\n }\n}\n","import { PageAgent, type WebPageAgentOpt } from '@/common/agent';\nimport { forceClosePopup } from '@/common/utils';\nimport { getDebug } from '@midscene/shared/logger';\nimport type { Page as PuppeteerPage } from 'puppeteer';\nimport type { AndroidDeviceInputOpt } from '../common/page';\nimport { WebPage as PuppeteerWebPage } from './page';\n\nconst debug = getDebug('puppeteer:agent');\n\nexport { WebPage as PuppeteerWebPage } from './page';\nexport type { AndroidDeviceInputOpt };\n\nexport class PuppeteerAgent extends PageAgent<PuppeteerWebPage> {\n constructor(page: PuppeteerPage, opts?: WebPageAgentOpt) {\n const webPage = new PuppeteerWebPage(page, opts);\n super(webPage, opts);\n\n const { forceSameTabNavigation = true } = opts ?? {};\n\n if (forceSameTabNavigation) {\n forceClosePopup(page, debug);\n }\n }\n}\n\nexport { overrideAIConfig } from '@midscene/shared/env';\n\n// Do NOT export this since it requires puppeteer\n// export { puppeteerAgentForTarget } from './agent-launcher';\n","import {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@midscene/shared/constants';\nimport type { Page as PuppeteerPageType } from 'puppeteer';\nimport type { WebPageOpt } from '../common/agent';\nimport { Page as BasePage, debugPage } from './base-page';\n\nexport class WebPage extends BasePage<'puppeteer', PuppeteerPageType> {\n waitForNavigationTimeout: number;\n waitForNetworkIdleTimeout: number;\n\n constructor(page: PuppeteerPageType, opts?: WebPageOpt) {\n super(page, 'puppeteer', opts);\n const {\n waitForNavigationTimeout = DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n waitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n } = opts ?? {};\n this.waitForNavigationTimeout = waitForNavigationTimeout;\n this.waitForNetworkIdleTimeout = waitForNetworkIdleTimeout;\n }\n\n async waitUntilNetworkIdle(options?: {\n idleTime?: number;\n concurrency?: number;\n timeout?: number;\n }): Promise<void> {\n if (this.waitForNetworkIdleTimeout === 0) {\n debugPage('waitUntilNetworkIdle timeout is 0, skip waiting');\n return;\n }\n await this.underlyingPage.waitForNetworkIdle({\n idleTime: options?.idleTime ?? this.waitForNetworkIdleTimeout,\n concurrency:\n options?.concurrency ?? DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY,\n timeout: options?.timeout ?? this.waitForNetworkIdleTimeout,\n });\n }\n}\n","import { PageAgent } from '@/common/agent';\nimport type StaticPage from './static-page';\n\nexport class StaticPageAgent extends PageAgent {\n constructor(page: StaticPage) {\n super(page, {});\n this.dryMode = true;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"mappings":"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","names":["import_core","import_js_yaml","resolve","import_utils","yaml","import_constants","import_env","import_logger","import_ai_model","import_node_fs","import_node_path","import_common","assert","semver","debug","dayjs","plan","log","sleep","thought","locatePlan","executor","import_extractor","debugPage","options","test","WebPage"],"ignoreList":[],"sources":["../../src/index.ts","../../src/common/agent.ts","../../src/yaml/player.ts","../../src/yaml/builder.ts","../../src/yaml/utils.ts","../../src/common/tasks.ts","../../src/common/ui-utils.ts","../../src/common/utils.ts","../../src/web-element.ts","../../src/common/task-cache.ts","../../package.json","../../src/common/plan-builder.ts","../../src/playwright/page.ts","../../src/puppeteer/base-page.ts","../../src/playwright/ai-fixture.ts","../../src/playwright/index.ts","../../src/puppeteer/index.ts","../../src/puppeteer/page.ts","../../src/playground/agent.ts"],"sourcesContent":["export { PlaywrightAiFixture } from './playwright';\nexport type { PlayWrightAiFixtureType } from './playwright';\nexport type {\n WebPage,\n AndroidDevicePage,\n AndroidDeviceInputOpt,\n} from './common/page';\nexport type { AbstractPage } from './page';\nexport type { WebUIContext } from './web-element';\n\nexport { PageAgent, type PageAgentOpt } from './common/agent';\nexport { PuppeteerAgent } from './puppeteer';\nexport { PlaywrightAgent } from './playwright';\nexport { StaticPageAgent } from './playground/agent';\n\nexport { ScriptPlayer, parseYamlScript } from './yaml';\nexport { parseContextFromWebPage } from './common/utils';\n","import type { WebPage } from '@/common/page';\nimport {\n type AgentAssertOpt,\n type AgentDescribeElementAtPointResult,\n type AgentWaitForOpt,\n type DetailedLocateParam,\n type ExecutionDump,\n type ExecutionRecorderItem,\n type ExecutionTask,\n type ExecutionTaskLog,\n type Executor,\n type GroupedActionDump,\n Insight,\n type InsightAction,\n type InsightExtractOption,\n type InsightExtractParam,\n type LocateOption,\n type LocateResultElement,\n type LocateValidatorResult,\n type LocatorValidatorOption,\n type MidsceneYamlScript,\n type OnTaskStartTip,\n type PlanningActionParamScroll,\n type Rect,\n type TUserPrompt,\n} from '@midscene/core';\n\nimport yaml from 'js-yaml';\n\nimport { ScriptPlayer, parseYamlScript } from '@/yaml/index';\nimport {\n groupedActionDumpFileExt,\n reportHTMLContent,\n stringifyDumpData,\n writeLogFile,\n} from '@midscene/core/utils';\nimport {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@midscene/shared/constants';\nimport { getAIConfigInBoolean, vlLocateMode } from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport { PageTaskExecutor } from '../common/tasks';\nimport type { PlaywrightWebPage } from '../playwright';\nimport type { PuppeteerWebPage } from '../puppeteer';\nimport type { WebElementInfo, WebUIContext } from '../web-element';\nimport type { AndroidDeviceInputOpt } from './page';\nimport { buildPlans } from './plan-builder';\nimport { TaskCache } from './task-cache';\nimport {\n locateParamStr,\n paramStr,\n scrollParamStr,\n taskTitleStr,\n typeStr,\n} from './ui-utils';\nimport { getReportFileName, printReportMsg } from './utils';\nimport { parseContextFromWebPage } from './utils';\nimport { trimContextByViewport } from './utils';\n\nconst debug = getDebug('web-integration');\n\nconst distanceOfTwoPoints = (p1: [number, number], p2: [number, number]) => {\n const [x1, y1] = p1;\n const [x2, y2] = p2;\n return Math.round(Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2));\n};\n\nconst includedInRect = (point: [number, number], rect: Rect) => {\n const [x, y] = point;\n const { left, top, width, height } = rect;\n return x >= left && x <= left + width && y >= top && y <= top + height;\n};\n\nconst defaultInsightExtractOption: InsightExtractOption = {\n domIncluded: false,\n screenshotIncluded: true,\n};\n\nexport interface PageAgentOpt {\n forceSameTabNavigation?: boolean /* if limit the new tab to the current page, default true */;\n testId?: string;\n cacheId?: string;\n groupName?: string;\n groupDescription?: string;\n /* if auto generate report, default true */\n generateReport?: boolean;\n /* if auto print report msg, default true */\n autoPrintReportMsg?: boolean;\n onTaskStartTip?: OnTaskStartTip;\n aiActionContext?: string;\n /* custom report file name */\n reportFileName?: string;\n}\n\nexport type WebPageAgentOpt = PageAgentOpt & WebPageOpt;\nexport type WebPageOpt = {\n waitForNavigationTimeout?: number;\n waitForNetworkIdleTimeout?: number;\n};\n\nexport class PageAgent<PageType extends WebPage = WebPage> {\n page: PageType;\n\n insight: Insight<WebElementInfo, WebUIContext>;\n\n dump: GroupedActionDump;\n\n reportFile?: string | null;\n\n reportFileName?: string;\n\n taskExecutor: PageTaskExecutor;\n\n opts: PageAgentOpt;\n\n /**\n * If true, the agent will not perform any actions\n */\n dryMode = false;\n\n onTaskStartTip?: OnTaskStartTip;\n\n taskCache?: TaskCache;\n\n onDumpUpdate?: (dump: string) => void;\n\n destroyed = false;\n\n /**\n * Frozen page context for consistent AI operations\n */\n private frozenPageContext?: WebUIContext;\n\n constructor(page: PageType, opts?: PageAgentOpt) {\n this.page = page;\n this.opts = Object.assign(\n {\n generateReport: true,\n autoPrintReportMsg: true,\n groupName: 'Midscene Report',\n groupDescription: '',\n },\n opts || {},\n );\n\n if (\n this.page.pageType === 'puppeteer' ||\n this.page.pageType === 'playwright'\n ) {\n (\n this.page as PuppeteerWebPage | PlaywrightWebPage\n ).waitForNavigationTimeout =\n (this.opts as WebPageAgentOpt).waitForNavigationTimeout ??\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;\n (\n this.page as PuppeteerWebPage | PlaywrightWebPage\n ).waitForNetworkIdleTimeout =\n (this.opts as WebPageAgentOpt).waitForNetworkIdleTimeout ??\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n }\n\n this.onTaskStartTip = this.opts.onTaskStartTip;\n // get the parent browser of the puppeteer page\n // const browser = (this.page as PuppeteerWebPage).browser();\n\n this.insight = new Insight<WebElementInfo, WebUIContext>(\n async (action: InsightAction) => {\n return this.getUIContext(action);\n },\n );\n\n if (opts?.cacheId && this.page.pageType !== 'android') {\n this.taskCache = new TaskCache(\n opts.cacheId,\n getAIConfigInBoolean('MIDSCENE_CACHE'), // if we should use cache to match the element\n );\n }\n\n this.taskExecutor = new PageTaskExecutor(this.page, this.insight, {\n taskCache: this.taskCache,\n onTaskStart: this.callbackOnTaskStartTip.bind(this),\n });\n this.dump = this.resetDump();\n this.reportFileName =\n opts?.reportFileName ||\n getReportFileName(opts?.testId || this.page.pageType || 'web');\n }\n\n async getUIContext(action?: InsightAction): Promise<WebUIContext> {\n // If page context is frozen, return the frozen context for all actions\n if (this.frozenPageContext) {\n debug('Using frozen page context for action:', action);\n return this.frozenPageContext;\n }\n\n // Otherwise, get fresh context based on the action type\n if (action && (action === 'extract' || action === 'assert')) {\n return await parseContextFromWebPage(this.page, {\n ignoreMarker: true,\n });\n }\n return await parseContextFromWebPage(this.page, {\n ignoreMarker: !!vlLocateMode(),\n });\n }\n\n async _snapshotContext(): Promise<WebUIContext> {\n return await this.getUIContext('locate');\n }\n\n async setAIActionContext(prompt: string) {\n this.opts.aiActionContext = prompt;\n }\n\n resetDump() {\n this.dump = {\n groupName: this.opts.groupName!,\n groupDescription: this.opts.groupDescription,\n executions: [],\n };\n\n return this.dump;\n }\n\n appendExecutionDump(execution: ExecutionDump) {\n // use trimContextByViewport to process execution\n const trimmedExecution = trimContextByViewport(execution);\n const currentDump = this.dump;\n currentDump.executions.push(trimmedExecution);\n }\n\n dumpDataString() {\n // update dump info\n this.dump.groupName = this.opts.groupName!;\n this.dump.groupDescription = this.opts.groupDescription;\n return stringifyDumpData(this.dump);\n }\n\n reportHTMLString() {\n return reportHTMLContent(this.dumpDataString());\n }\n\n writeOutActionDumps() {\n if (this.destroyed) {\n throw new Error(\n 'PageAgent has been destroyed. Cannot update report file.',\n );\n }\n const { generateReport, autoPrintReportMsg } = this.opts;\n this.reportFile = writeLogFile({\n fileName: this.reportFileName!,\n fileExt: groupedActionDumpFileExt,\n fileContent: this.dumpDataString(),\n type: 'dump',\n generateReport,\n });\n debug('writeOutActionDumps', this.reportFile);\n if (generateReport && autoPrintReportMsg && this.reportFile) {\n printReportMsg(this.reportFile);\n }\n }\n\n private async callbackOnTaskStartTip(task: ExecutionTask) {\n const param = paramStr(task);\n const tip = param ? `${typeStr(task)} - ${param}` : typeStr(task);\n\n if (this.onTaskStartTip) {\n await this.onTaskStartTip(tip);\n }\n }\n\n private async afterTaskRunning(executor: Executor, doNotThrowError = false) {\n this.appendExecutionDump(executor.dump());\n\n try {\n await this.onDumpUpdate?.(this.dumpDataString());\n } catch (error) {\n console.error('Error in onDumpUpdate', error);\n }\n\n this.writeOutActionDumps();\n\n if (executor.isInErrorState() && !doNotThrowError) {\n const errorTask = executor.latestErrorTask();\n throw new Error(`${errorTask?.errorMessage}\\n${errorTask?.errorStack}`, {\n cause: errorTask?.error,\n });\n }\n }\n\n private buildDetailedLocateParam(\n locatePrompt: TUserPrompt,\n opt?: LocateOption,\n ): DetailedLocateParam {\n assert(locatePrompt, 'missing locate prompt');\n\n if (typeof opt === 'object' && opt !== null) {\n const prompt = locatePrompt;\n const deepThink = opt.deepThink ?? false;\n const cacheable = opt.cacheable ?? true;\n const xpath = opt.xpath;\n\n return {\n prompt,\n deepThink,\n cacheable,\n xpath,\n };\n }\n\n return {\n prompt: locatePrompt,\n };\n }\n\n async aiTap(locatePrompt: TUserPrompt, opt?: LocateOption) {\n const detailedLocateParam = this.buildDetailedLocateParam(\n locatePrompt,\n opt,\n );\n const plans = buildPlans('Tap', detailedLocateParam);\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Tap', locateParamStr(detailedLocateParam)),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiRightClick(locatePrompt: TUserPrompt, opt?: LocateOption) {\n const detailedLocateParam = this.buildDetailedLocateParam(\n locatePrompt,\n opt,\n );\n const plans = buildPlans('RightClick', detailedLocateParam);\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('RightClick', locateParamStr(detailedLocateParam)),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiHover(locatePrompt: TUserPrompt, opt?: LocateOption) {\n const detailedLocateParam = this.buildDetailedLocateParam(\n locatePrompt,\n opt,\n );\n const plans = buildPlans('Hover', detailedLocateParam);\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Hover', locateParamStr(detailedLocateParam)),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiInput(\n value: string,\n locatePrompt: TUserPrompt,\n opt?: AndroidDeviceInputOpt & LocateOption,\n ) {\n assert(\n typeof value === 'string',\n 'input value must be a string, use empty string if you want to clear the input',\n );\n assert(locatePrompt, 'missing locate prompt for input');\n const detailedLocateParam = this.buildDetailedLocateParam(\n locatePrompt,\n opt,\n );\n const plans = buildPlans('Input', detailedLocateParam, {\n value,\n autoDismissKeyboard: opt?.autoDismissKeyboard,\n });\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Input', locateParamStr(detailedLocateParam)),\n plans,\n {\n cacheable: opt?.cacheable,\n },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiKeyboardPress(\n keyName: string,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ) {\n assert(keyName, 'missing keyName for keyboard press');\n const detailedLocateParam = locatePrompt\n ? this.buildDetailedLocateParam(locatePrompt, opt)\n : undefined;\n const plans = buildPlans('KeyboardPress', detailedLocateParam, {\n value: keyName,\n });\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('KeyboardPress', locateParamStr(detailedLocateParam)),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiScroll(\n scrollParam: PlanningActionParamScroll,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ) {\n const detailedLocateParam = locatePrompt\n ? this.buildDetailedLocateParam(locatePrompt, opt)\n : undefined;\n const plans = buildPlans('Scroll', detailedLocateParam, scrollParam);\n const paramInTitle = locatePrompt\n ? `${locateParamStr(detailedLocateParam)} - ${scrollParamStr(scrollParam)}`\n : scrollParamStr(scrollParam);\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Scroll', paramInTitle),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiAction(\n taskPrompt: string,\n opt?: {\n cacheable?: boolean;\n },\n ) {\n const cacheable = opt?.cacheable;\n // if vlm-ui-tars, plan cache is not used\n const isVlmUiTars = vlLocateMode() === 'vlm-ui-tars';\n const matchedCache =\n isVlmUiTars || cacheable === false\n ? undefined\n : this.taskCache?.matchPlanCache(taskPrompt);\n if (matchedCache && this.taskCache?.isCacheResultUsed) {\n // log into report file\n const { executor } = await this.taskExecutor.loadYamlFlowAsPlanning(\n taskPrompt,\n matchedCache.cacheContent?.yamlWorkflow,\n );\n\n await await this.afterTaskRunning(executor);\n\n debug('matched cache, will call .runYaml to run the action');\n const yaml = matchedCache.cacheContent?.yamlWorkflow;\n return this.runYaml(yaml);\n }\n\n const { output, executor } = await (isVlmUiTars\n ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable })\n : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext, {\n cacheable,\n }));\n\n // update cache\n if (this.taskCache && output?.yamlFlow && cacheable !== false) {\n const yamlContent: MidsceneYamlScript = {\n tasks: [\n {\n name: taskPrompt,\n flow: output.yamlFlow,\n },\n ],\n };\n const yamlFlowStr = yaml.dump(yamlContent);\n this.taskCache.updateOrAppendCacheRecord(\n {\n type: 'plan',\n prompt: taskPrompt,\n yamlWorkflow: yamlFlowStr,\n },\n matchedCache,\n );\n }\n\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiQuery(\n demand: InsightExtractParam,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ) {\n const { output, executor } = await this.taskExecutor.query(demand, opt);\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiBoolean(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ) {\n const { output, executor } = await this.taskExecutor.boolean(prompt, opt);\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiNumber(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ) {\n const { output, executor } = await this.taskExecutor.number(prompt, opt);\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiString(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ) {\n const { output, executor } = await this.taskExecutor.string(prompt, opt);\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiAsk(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ) {\n return this.aiString(prompt, opt);\n }\n\n async describeElementAtPoint(\n center: [number, number],\n opt?: {\n verifyPrompt?: boolean;\n retryLimit?: number;\n deepThink?: boolean;\n } & LocatorValidatorOption,\n ): Promise<AgentDescribeElementAtPointResult> {\n const { verifyPrompt = true, retryLimit = 3 } = opt || {};\n\n let success = false;\n let retryCount = 0;\n let resultPrompt = '';\n let deepThink = opt?.deepThink || false;\n let verifyResult: LocateValidatorResult | undefined;\n\n while (!success && retryCount < retryLimit) {\n if (retryCount >= 2) {\n deepThink = true;\n }\n debug(\n 'aiDescribe',\n center,\n 'verifyPrompt',\n verifyPrompt,\n 'retryCount',\n retryCount,\n 'deepThink',\n deepThink,\n );\n const text = await this.insight.describe(center, { deepThink });\n debug('aiDescribe text', text);\n assert(text.description, `failed to describe element at [${center}]`);\n resultPrompt = text.description;\n\n verifyResult = await this.verifyLocator(\n resultPrompt,\n deepThink ? { deepThink: true } : undefined,\n center,\n opt,\n );\n if (verifyResult.pass) {\n success = true;\n } else {\n retryCount++;\n }\n }\n\n return {\n prompt: resultPrompt,\n deepThink,\n verifyResult,\n };\n }\n\n async verifyLocator(\n prompt: string,\n locateOpt: LocateOption | undefined,\n expectCenter: [number, number],\n verifyLocateOption?: LocatorValidatorOption,\n ): Promise<LocateValidatorResult> {\n debug('verifyLocator', prompt, locateOpt, expectCenter, verifyLocateOption);\n\n const { center: verifyCenter, rect: verifyRect } = await this.aiLocate(\n prompt,\n locateOpt,\n );\n const distance = distanceOfTwoPoints(expectCenter, verifyCenter);\n const included = includedInRect(expectCenter, verifyRect);\n const pass =\n distance <= (verifyLocateOption?.centerDistanceThreshold || 20) ||\n included;\n const verifyResult = {\n pass,\n rect: verifyRect,\n center: verifyCenter,\n centerDistance: distance,\n };\n debug('aiDescribe verifyResult', verifyResult);\n return verifyResult;\n }\n\n async aiLocate(prompt: TUserPrompt, opt?: LocateOption) {\n const detailedLocateParam = this.buildDetailedLocateParam(prompt, opt);\n const plans = buildPlans('Locate', detailedLocateParam);\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Locate', locateParamStr(detailedLocateParam)),\n plans,\n { cacheable: opt?.cacheable },\n );\n await this.afterTaskRunning(executor);\n\n const { element } = output;\n\n return {\n rect: element?.rect,\n center: element?.center,\n scale: (await this.page.size()).dpr,\n } as Pick<LocateResultElement, 'rect' | 'center'> & {\n scale: number;\n };\n }\n\n async aiAssert(assertion: TUserPrompt, msg?: string, opt?: AgentAssertOpt) {\n const { output, executor, thought } = await this.taskExecutor.assert(\n assertion,\n {\n returnThought: true,\n },\n );\n await this.afterTaskRunning(executor, true);\n\n if (opt?.keepRawResponse) {\n return {\n pass: output,\n thought,\n };\n }\n\n if (!output) {\n const errMsg = msg || `Assertion failed: ${assertion}`;\n const reasonMsg = `Reason: ${\n thought || executor.latestErrorTask()?.error || '(no_reason)'\n }`;\n throw new Error(`${errMsg}\\n${reasonMsg}`);\n }\n }\n\n async aiWaitFor(assertion: string, opt?: AgentWaitForOpt) {\n const { executor } = await this.taskExecutor.waitFor(assertion, {\n timeoutMs: opt?.timeoutMs || 15 * 1000,\n checkIntervalMs: opt?.checkIntervalMs || 3 * 1000,\n assertion,\n });\n await this.afterTaskRunning(executor, true);\n\n if (executor.isInErrorState()) {\n const errorTask = executor.latestErrorTask();\n throw new Error(`${errorTask?.error}\\n${errorTask?.errorStack}`);\n }\n }\n\n async ai(taskPrompt: string, type = 'action') {\n if (type === 'action') {\n return this.aiAction(taskPrompt);\n }\n if (type === 'query') {\n return this.aiQuery(taskPrompt);\n }\n\n if (type === 'assert') {\n return this.aiAssert(taskPrompt);\n }\n\n if (type === 'tap') {\n return this.aiTap(taskPrompt);\n }\n\n if (type === 'rightClick') {\n return this.aiRightClick(taskPrompt);\n }\n\n throw new Error(\n `Unknown type: ${type}, only support 'action', 'query', 'assert', 'tap', 'rightClick'`,\n );\n }\n\n async runYaml(yamlScriptContent: string): Promise<{\n result: Record<string, any>;\n }> {\n const script = parseYamlScript(yamlScriptContent, 'yaml', true);\n const player = new ScriptPlayer(script, async (target) => {\n return { agent: this, freeFn: [] };\n });\n await player.run();\n\n if (player.status === 'error') {\n const errors = player.taskStatusList\n .filter((task) => task.status === 'error')\n .map((task) => {\n return `task - ${task.name}: ${task.error?.message}`;\n })\n .join('\\n');\n throw new Error(`Error(s) occurred in running yaml script:\\n${errors}`);\n }\n\n return {\n result: player.result,\n };\n }\n\n async evaluateJavaScript(script: string) {\n assert(\n this.page.evaluateJavaScript,\n 'evaluateJavaScript is not supported in current agent',\n );\n return this.page.evaluateJavaScript(script);\n }\n\n async destroy() {\n await this.page.destroy();\n this.resetDump(); // reset dump to release memory\n this.destroyed = true;\n }\n\n async logScreenshot(\n title?: string,\n opt?: {\n content: string;\n },\n ) {\n // 1. screenshot\n const base64 = await this.page.screenshotBase64();\n const now = Date.now();\n // 2. build recorder\n const recorder: ExecutionRecorderItem[] = [\n {\n type: 'screenshot',\n ts: now,\n screenshot: base64,\n },\n ];\n // 3. build ExecutionTaskLog\n const task: ExecutionTaskLog = {\n type: 'Log',\n subType: 'Screenshot',\n status: 'finished',\n recorder,\n timing: {\n start: now,\n end: now,\n cost: 0,\n },\n param: {\n content: opt?.content || '',\n },\n executor: async () => {},\n };\n // 4. build ExecutionDump\n const executionDump: ExecutionDump = {\n sdkVersion: '',\n logTime: now,\n model_name: '',\n model_description: '',\n name: `Log - ${title || 'untitled'}`,\n description: opt?.content || '',\n tasks: [task],\n };\n // 5. append to execution dump\n this.appendExecutionDump(executionDump);\n\n try {\n this.onDumpUpdate?.(this.dumpDataString());\n } catch (error) {\n console.error('Failed to update dump', error);\n }\n\n this.writeOutActionDumps();\n }\n\n _unstableLogContent() {\n const { groupName, groupDescription, executions } = this.dump;\n const newExecutions = Array.isArray(executions)\n ? executions.map((execution: any) => {\n const { tasks, ...restExecution } = execution;\n let newTasks = tasks;\n if (Array.isArray(tasks)) {\n newTasks = tasks.map((task: any) => {\n // only remove pageContext and log from task\n const { pageContext, log, ...restTask } = task;\n return restTask;\n });\n }\n return { ...restExecution, ...(newTasks ? { tasks: newTasks } : {}) };\n })\n : [];\n return {\n groupName,\n groupDescription,\n executions: newExecutions,\n };\n }\n\n /**\n * Freezes the current page context to be reused in subsequent AI operations\n * This avoids recalculating page context for each operation\n */\n async freezePageContext(): Promise<void> {\n debug('Freezing page context');\n const context = await this._snapshotContext();\n // Mark the context as frozen\n context._isFrozen = true;\n this.frozenPageContext = context;\n debug('Page context frozen successfully');\n }\n\n /**\n * Unfreezes the page context, allowing AI operations to calculate context dynamically\n */\n async unfreezePageContext(): Promise<void> {\n debug('Unfreezing page context');\n this.frozenPageContext = undefined;\n debug('Page context unfrozen successfully');\n }\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { assert, ifInBrowser, ifInWorker } from '@midscene/shared/utils';\n\nimport type { PageAgent } from '@/common/agent';\nimport type {\n FreeFn,\n MidsceneYamlFlowItemAIAction,\n MidsceneYamlFlowItemAIAsk,\n MidsceneYamlFlowItemAIAssert,\n MidsceneYamlFlowItemAIBoolean,\n MidsceneYamlFlowItemAIHover,\n MidsceneYamlFlowItemAIInput,\n MidsceneYamlFlowItemAIKeyboardPress,\n MidsceneYamlFlowItemAILocate,\n MidsceneYamlFlowItemAINumber,\n MidsceneYamlFlowItemAIQuery,\n MidsceneYamlFlowItemAIRightClick,\n MidsceneYamlFlowItemAIScroll,\n MidsceneYamlFlowItemAIString,\n MidsceneYamlFlowItemAITap,\n MidsceneYamlFlowItemAIWaitFor,\n MidsceneYamlFlowItemEvaluateJavaScript,\n MidsceneYamlFlowItemLogScreenshot,\n MidsceneYamlFlowItemSleep,\n MidsceneYamlScript,\n MidsceneYamlScriptEnv,\n ScriptPlayerStatusValue,\n ScriptPlayerTaskStatus,\n} from '@midscene/core';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\n\nexport class ScriptPlayer<T extends MidsceneYamlScriptEnv> {\n public currentTaskIndex?: number;\n public taskStatusList: ScriptPlayerTaskStatus[] = [];\n public status: ScriptPlayerStatusValue = 'init';\n public reportFile?: string | null;\n public result: Record<string, any>;\n private unnamedResultIndex = 0;\n public output?: string | null;\n public unstableLogContent?: string | null;\n public errorInSetup?: Error;\n private pageAgent: PageAgent | null = null;\n public agentStatusTip?: string;\n public target?: MidsceneYamlScriptEnv;\n private scriptPath?: string;\n constructor(\n private script: MidsceneYamlScript,\n private setupAgent: (platform: T) => Promise<{\n agent: PageAgent;\n freeFn: FreeFn[];\n }>,\n public onTaskStatusChange?: (taskStatus: ScriptPlayerTaskStatus) => void,\n scriptPath?: string,\n ) {\n this.scriptPath = scriptPath;\n this.result = {};\n\n this.target = script.target || script.web || script.android;\n\n if (ifInBrowser || ifInWorker) {\n this.output = undefined;\n } else if (this.target?.output) {\n this.output = resolve(process.cwd(), this.target.output);\n } else {\n const scriptName = this.scriptPath\n ? basename(this.scriptPath, '.yaml').replace(/\\.(ya?ml)$/i, '')\n : 'script';\n this.output = join(\n getMidsceneRunSubDir('output'),\n `${scriptName}-${Date.now()}.json`,\n );\n }\n\n if (ifInBrowser || ifInWorker) {\n this.unstableLogContent = undefined;\n } else if (typeof this.target?.unstableLogContent === 'string') {\n this.unstableLogContent = resolve(\n process.cwd(),\n this.target.unstableLogContent,\n );\n } else if (this.target?.unstableLogContent === true) {\n this.unstableLogContent = join(\n getMidsceneRunSubDir('output'),\n 'unstableLogContent.json',\n );\n }\n\n this.taskStatusList = (script.tasks || []).map((task, taskIndex) => ({\n ...task,\n index: taskIndex,\n status: 'init',\n totalSteps: task.flow?.length || 0,\n }));\n }\n\n private setResult(key: string | undefined, value: any) {\n const keyToUse = key || this.unnamedResultIndex++;\n if (this.result[keyToUse]) {\n console.warn(`result key ${keyToUse} already exists, will overwrite`);\n }\n this.result[keyToUse] = value;\n\n return this.flushResult();\n }\n\n private setPlayerStatus(status: ScriptPlayerStatusValue, error?: Error) {\n this.status = status;\n this.errorInSetup = error;\n }\n\n private notifyCurrentTaskStatusChange(taskIndex?: number) {\n const taskIndexToNotify =\n typeof taskIndex === 'number' ? taskIndex : this.currentTaskIndex;\n\n if (typeof taskIndexToNotify !== 'number') {\n return;\n }\n\n const taskStatus = this.taskStatusList[taskIndexToNotify];\n if (this.onTaskStatusChange) {\n this.onTaskStatusChange(taskStatus);\n }\n }\n\n private async setTaskStatus(\n index: number,\n statusValue: ScriptPlayerStatusValue,\n error?: Error,\n ) {\n this.taskStatusList[index].status = statusValue;\n if (error) {\n this.taskStatusList[index].error = error;\n }\n\n this.notifyCurrentTaskStatusChange(index);\n }\n\n private setTaskIndex(taskIndex: number) {\n this.currentTaskIndex = taskIndex;\n }\n\n private flushResult() {\n if (this.output) {\n const output = resolve(process.cwd(), this.output);\n const outputDir = dirname(output);\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(output, JSON.stringify(this.result || {}, undefined, 2));\n }\n }\n\n private flushUnstableLogContent() {\n if (this.unstableLogContent) {\n const content = this.pageAgent?._unstableLogContent();\n const filePath = resolve(process.cwd(), this.unstableLogContent);\n const outputDir = dirname(filePath);\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(filePath, JSON.stringify(content, null, 2));\n }\n }\n\n async playTask(taskStatus: ScriptPlayerTaskStatus, agent: PageAgent) {\n const { flow } = taskStatus;\n assert(flow, 'missing flow in task');\n\n for (const flowItemIndex in flow) {\n const currentStep = Number.parseInt(flowItemIndex, 10);\n taskStatus.currentStep = currentStep;\n const flowItem = flow[flowItemIndex];\n if (\n 'aiAction' in (flowItem as MidsceneYamlFlowItemAIAction) ||\n 'ai' in (flowItem as MidsceneYamlFlowItemAIAction)\n ) {\n const actionTask = flowItem as MidsceneYamlFlowItemAIAction;\n const prompt = actionTask.aiAction || actionTask.ai;\n assert(prompt, 'missing prompt for ai (aiAction)');\n assert(\n typeof prompt === 'string',\n 'prompt for aiAction must be a string',\n );\n await agent.aiAction(prompt, {\n cacheable: actionTask.cacheable,\n });\n } else if ('aiAssert' in (flowItem as MidsceneYamlFlowItemAIAssert)) {\n const assertTask = flowItem as MidsceneYamlFlowItemAIAssert;\n const prompt = assertTask.aiAssert;\n const msg = assertTask.errorMessage;\n assert(prompt, 'missing prompt for aiAssert');\n assert(\n typeof prompt === 'string',\n 'prompt for aiAssert must be a string',\n );\n await agent.aiAssert(prompt, msg);\n } else if ('aiQuery' in (flowItem as MidsceneYamlFlowItemAIQuery)) {\n const queryTask = flowItem as MidsceneYamlFlowItemAIQuery;\n const prompt = queryTask.aiQuery;\n const options = {\n domIncluded: queryTask.domIncluded,\n screenshotIncluded: queryTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiQuery');\n assert(\n typeof prompt === 'string',\n 'prompt for aiQuery must be a string',\n );\n const queryResult = await agent.aiQuery(prompt, options);\n this.setResult(queryTask.name, queryResult);\n } else if ('aiNumber' in (flowItem as MidsceneYamlFlowItemAINumber)) {\n const numberTask = flowItem as MidsceneYamlFlowItemAINumber;\n const prompt = numberTask.aiNumber;\n const options = {\n domIncluded: numberTask.domIncluded,\n screenshotIncluded: numberTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiNumber');\n assert(\n typeof prompt === 'string',\n 'prompt for number must be a string',\n );\n const numberResult = await agent.aiNumber(prompt, options);\n this.setResult(numberTask.name, numberResult);\n } else if ('aiString' in (flowItem as MidsceneYamlFlowItemAIString)) {\n const stringTask = flowItem as MidsceneYamlFlowItemAIString;\n const prompt = stringTask.aiString;\n const options = {\n domIncluded: stringTask.domIncluded,\n screenshotIncluded: stringTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiString');\n assert(\n typeof prompt === 'string',\n 'prompt for string must be a string',\n );\n const stringResult = await agent.aiString(prompt, options);\n this.setResult(stringTask.name, stringResult);\n } else if ('aiBoolean' in (flowItem as MidsceneYamlFlowItemAIBoolean)) {\n const booleanTask = flowItem as MidsceneYamlFlowItemAIBoolean;\n const prompt = booleanTask.aiBoolean;\n const options = {\n domIncluded: booleanTask.domIncluded,\n screenshotIncluded: booleanTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiBoolean');\n assert(\n typeof prompt === 'string',\n 'prompt for boolean must be a string',\n );\n const booleanResult = await agent.aiBoolean(prompt, options);\n this.setResult(booleanTask.name, booleanResult);\n } else if ('aiAsk' in (flowItem as MidsceneYamlFlowItemAIAsk)) {\n const askTask = flowItem as MidsceneYamlFlowItemAIAsk;\n const prompt = askTask.aiAsk;\n assert(prompt, 'missing prompt for aiAsk');\n assert(typeof prompt === 'string', 'prompt for aiAsk must be a string');\n const askResult = await agent.aiAsk(prompt);\n this.setResult(askTask.name, askResult);\n } else if ('aiLocate' in (flowItem as MidsceneYamlFlowItemAILocate)) {\n const locateTask = flowItem as MidsceneYamlFlowItemAILocate;\n const prompt = locateTask.aiLocate;\n assert(prompt, 'missing prompt for aiLocate');\n assert(\n typeof prompt === 'string',\n 'prompt for aiLocate must be a string',\n );\n const locateResult = await agent.aiLocate(prompt, locateTask);\n this.setResult(locateTask.name, locateResult);\n } else if ('aiWaitFor' in (flowItem as MidsceneYamlFlowItemAIWaitFor)) {\n const waitForTask = flowItem as MidsceneYamlFlowItemAIWaitFor;\n const prompt = waitForTask.aiWaitFor;\n assert(prompt, 'missing prompt for aiWaitFor');\n assert(\n typeof prompt === 'string',\n 'prompt for aiWaitFor must be a string',\n );\n const timeout = waitForTask.timeout;\n await agent.aiWaitFor(prompt, { timeoutMs: timeout });\n } else if ('sleep' in (flowItem as MidsceneYamlFlowItemSleep)) {\n const sleepTask = flowItem as MidsceneYamlFlowItemSleep;\n const ms = sleepTask.sleep;\n let msNumber = ms;\n if (typeof ms === 'string') {\n msNumber = Number.parseInt(ms, 10);\n }\n assert(\n msNumber && msNumber > 0,\n `ms for sleep must be greater than 0, but got ${ms}`,\n );\n await new Promise((resolve) => setTimeout(resolve, msNumber));\n } else if ('aiTap' in (flowItem as MidsceneYamlFlowItemAITap)) {\n const tapTask = flowItem as MidsceneYamlFlowItemAITap;\n await agent.aiTap(tapTask.aiTap, tapTask);\n } else if (\n 'aiRightClick' in (flowItem as MidsceneYamlFlowItemAIRightClick)\n ) {\n const rightClickTask = flowItem as MidsceneYamlFlowItemAIRightClick;\n await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);\n } else if ('aiHover' in (flowItem as MidsceneYamlFlowItemAIHover)) {\n const hoverTask = flowItem as MidsceneYamlFlowItemAIHover;\n await agent.aiHover(hoverTask.aiHover, hoverTask);\n } else if ('aiInput' in (flowItem as MidsceneYamlFlowItemAIInput)) {\n // may be input empty string ''\n const inputTask = flowItem as MidsceneYamlFlowItemAIInput;\n await agent.aiInput(inputTask.aiInput, inputTask.locate, inputTask);\n } else if (\n 'aiKeyboardPress' in (flowItem as MidsceneYamlFlowItemAIKeyboardPress)\n ) {\n const keyboardPressTask =\n flowItem as MidsceneYamlFlowItemAIKeyboardPress;\n await agent.aiKeyboardPress(\n keyboardPressTask.aiKeyboardPress,\n keyboardPressTask.locate,\n keyboardPressTask,\n );\n } else if ('aiScroll' in (flowItem as MidsceneYamlFlowItemAIScroll)) {\n const scrollTask = flowItem as MidsceneYamlFlowItemAIScroll;\n await agent.aiScroll(scrollTask, scrollTask.locate, scrollTask);\n } else if (\n 'javascript' in (flowItem as MidsceneYamlFlowItemEvaluateJavaScript)\n ) {\n const evaluateJavaScriptTask =\n flowItem as MidsceneYamlFlowItemEvaluateJavaScript;\n\n const result = await agent.evaluateJavaScript(\n evaluateJavaScriptTask.javascript,\n );\n this.setResult(evaluateJavaScriptTask.name, result);\n } else if (\n 'logScreenshot' in (flowItem as MidsceneYamlFlowItemLogScreenshot)\n ) {\n const logScreenshotTask = flowItem as MidsceneYamlFlowItemLogScreenshot;\n await agent.logScreenshot(logScreenshotTask.logScreenshot, {\n content: logScreenshotTask.content || '',\n });\n } else {\n throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);\n }\n }\n this.reportFile = agent.reportFile;\n await this.flushUnstableLogContent();\n }\n\n async run() {\n const { target, web, android, tasks } = this.script;\n const webEnv = web || target;\n const androidEnv = android;\n const platform = webEnv || androidEnv;\n\n this.setPlayerStatus('running');\n\n let agent: PageAgent | null = null;\n let freeFn: FreeFn[] = [];\n try {\n const { agent: newAgent, freeFn: newFreeFn } = await this.setupAgent(\n platform as T,\n );\n agent = newAgent;\n const originalOnTaskStartTip = agent.onTaskStartTip;\n agent.onTaskStartTip = (tip) => {\n if (this.status === 'running') {\n this.agentStatusTip = tip;\n }\n originalOnTaskStartTip?.(tip);\n };\n freeFn = [\n ...(newFreeFn || []),\n {\n name: 'restore-agent-onTaskStartTip',\n fn: () => {\n if (agent) {\n agent.onTaskStartTip = originalOnTaskStartTip;\n }\n },\n },\n ];\n } catch (e) {\n this.setPlayerStatus('error', e as Error);\n return;\n }\n this.pageAgent = agent;\n\n let taskIndex = 0;\n this.setPlayerStatus('running');\n let errorFlag = false;\n while (taskIndex < tasks.length) {\n const taskStatus = this.taskStatusList[taskIndex];\n this.setTaskStatus(taskIndex, 'running' as any);\n this.setTaskIndex(taskIndex);\n\n try {\n await this.playTask(taskStatus, this.pageAgent);\n this.setTaskStatus(taskIndex, 'done' as any);\n } catch (e) {\n this.setTaskStatus(taskIndex, 'error' as any, e as Error);\n\n if (taskStatus.continueOnError) {\n // nothing more to do\n } else {\n this.reportFile = agent.reportFile;\n errorFlag = true;\n break;\n }\n }\n this.reportFile = agent?.reportFile;\n taskIndex++;\n }\n\n if (errorFlag) {\n this.setPlayerStatus('error');\n } else {\n this.setPlayerStatus('done');\n }\n this.agentStatusTip = '';\n\n // free the resources\n for (const fn of freeFn) {\n try {\n // console.log('freeing', fn.name);\n await fn.fn();\n // console.log('freed', fn.name);\n } catch (e) {\n // console.error('error freeing', fn.name, e);\n }\n }\n }\n}\n","import type {\n MidsceneYamlScript,\n MidsceneYamlScriptWebEnv,\n MidsceneYamlTask,\n} from '@midscene/core';\nimport yaml from 'js-yaml';\n\nexport function buildYaml(\n env: MidsceneYamlScriptWebEnv,\n tasks: MidsceneYamlTask[],\n) {\n const result: MidsceneYamlScript = {\n target: env,\n tasks,\n };\n\n return yaml.dump(result, {\n indent: 2,\n });\n}\n","import { assert } from '@midscene/shared/utils';\nimport yaml from 'js-yaml';\n\nimport type { MidsceneYamlScript } from '@midscene/core';\n\nexport function interpolateEnvVars(content: string): string {\n return content.replace(/\\$\\{([^}]+)\\}/g, (_, envVar) => {\n const value = process.env[envVar.trim()];\n if (value === undefined) {\n throw new Error(`Environment variable \"${envVar.trim()}\" is not defined`);\n }\n return value;\n });\n}\n\nexport function parseYamlScript(\n content: string,\n filePath?: string,\n ignoreCheckingTarget?: boolean,\n): MidsceneYamlScript {\n let processedContent = content;\n if (content.indexOf('android') !== -1 && content.match(/deviceId:\\s*(\\d+)/)) {\n let matchedDeviceId;\n processedContent = content.replace(\n /deviceId:\\s*(\\d+)/g,\n (match, deviceId) => {\n matchedDeviceId = deviceId;\n return `deviceId: '${deviceId}'`;\n },\n );\n console.warn(\n `please use string-style deviceId in yaml script, for example: deviceId: \"${matchedDeviceId}\"`,\n );\n }\n const interpolatedContent = interpolateEnvVars(processedContent);\n const obj = yaml.load(interpolatedContent, {\n schema: yaml.JSON_SCHEMA,\n }) as MidsceneYamlScript;\n\n const pathTip = filePath ? `, failed to load ${filePath}` : '';\n const android =\n typeof obj.android !== 'undefined'\n ? Object.assign({}, obj.android || {})\n : undefined;\n const webConfig = obj.web || obj.target; // no need to handle null case, because web has required parameters url\n const web =\n typeof webConfig !== 'undefined'\n ? Object.assign({}, webConfig || {})\n : undefined;\n\n if (!ignoreCheckingTarget) {\n // make sure at least one of target/web/android is provided\n assert(\n web || android,\n `at least one of \"target\", \"web\", or \"android\" properties is required in yaml script${pathTip}`,\n );\n\n // make sure only one of target/web/android is provided\n assert(\n (web && !android) || (!web && android),\n `only one of \"target\", \"web\", or \"android\" properties is allowed in yaml script${pathTip}`,\n );\n\n // make sure the config is valid\n if (web || android) {\n assert(\n typeof web === 'object' || typeof android === 'object',\n `property \"target/web/android\" must be an object${pathTip}`,\n );\n }\n }\n\n assert(obj.tasks, `property \"tasks\" is required in yaml script ${pathTip}`);\n assert(\n Array.isArray(obj.tasks),\n `property \"tasks\" must be an array in yaml script, but got ${obj.tasks}`,\n );\n return obj;\n}\n","import type { AndroidDevicePage, WebPage } from '@/common/page';\nimport type { PuppeteerWebPage } from '@/puppeteer';\nimport {\n type AIUsageInfo,\n type BaseElement,\n type DumpSubscriber,\n type ExecutionRecorderItem,\n type ExecutionTaskActionApply,\n type ExecutionTaskApply,\n type ExecutionTaskHitBy,\n type ExecutionTaskInsightLocateApply,\n type ExecutionTaskInsightQueryApply,\n type ExecutionTaskPlanning,\n type ExecutionTaskPlanningApply,\n type ExecutionTaskProgressOptions,\n Executor,\n type ExecutorContext,\n type Insight,\n type InsightAssertionResponse,\n type InsightDump,\n type InsightExtractOption,\n type InsightExtractParam,\n type LocateResultElement,\n type MidsceneYamlFlowItem,\n type PageType,\n type PlanningAIResponse,\n type PlanningAction,\n type PlanningActionParamAndroidLongPress,\n type PlanningActionParamAndroidPull,\n type PlanningActionParamAssert,\n type PlanningActionParamError,\n type PlanningActionParamHover,\n type PlanningActionParamInputOrKeyPress,\n type PlanningActionParamScroll,\n type PlanningActionParamSleep,\n type PlanningActionParamTap,\n type PlanningActionParamWaitFor,\n type TMultimodalPrompt,\n type TUserPrompt,\n type UIContext,\n plan,\n} from '@midscene/core';\nimport {\n type ChatCompletionMessageParam,\n elementByPositionWithElementInfo,\n resizeImageForUiTars,\n vlmPlanning,\n} from '@midscene/core/ai-model';\nimport { sleep } from '@midscene/core/utils';\nimport { NodeType } from '@midscene/shared/constants';\nimport {\n MIDSCENE_REPLANNING_CYCLE_LIMIT,\n getAIConfigInNumber,\n} from '@midscene/shared/env';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport type { WebElementInfo, WebUIContext } from '../web-element';\nimport type { TaskCache } from './task-cache';\nimport { getKeyCommands, taskTitleStr } from './ui-utils';\nimport {\n matchElementFromCache,\n matchElementFromPlan,\n parsePrompt,\n} from './utils';\n\ninterface ExecutionResult<OutputType = any> {\n output: OutputType;\n thought?: string;\n executor: Executor;\n}\n\nconst debug = getDebug('page-task-executor');\nconst defaultReplanningCycleLimit = 10;\n\nconst isAndroidPage = (page: WebPage): page is AndroidDevicePage => {\n return page.pageType === 'android';\n};\n\nexport class PageTaskExecutor {\n page: WebPage;\n\n insight: Insight<WebElementInfo, WebUIContext>;\n\n taskCache?: TaskCache;\n\n conversationHistory: ChatCompletionMessageParam[] = [];\n\n onTaskStartCallback?: ExecutionTaskProgressOptions['onTaskStart'];\n\n constructor(\n page: WebPage,\n insight: Insight<WebElementInfo, WebUIContext>,\n opts: {\n taskCache?: TaskCache;\n onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];\n },\n ) {\n this.page = page;\n this.insight = insight;\n\n this.taskCache = opts.taskCache;\n\n this.onTaskStartCallback = opts?.onTaskStart;\n }\n\n private async recordScreenshot(timing: ExecutionRecorderItem['timing']) {\n const base64 = await this.page.screenshotBase64();\n const item: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: Date.now(),\n screenshot: base64,\n timing,\n };\n return item;\n }\n\n private async getElementXpath(\n pageContext: UIContext<BaseElement>,\n element: LocateResultElement,\n ): Promise<string[] | undefined> {\n let elementId = element?.id;\n if (element?.isOrderSensitive !== undefined) {\n const xpaths = await this.page.getXpathsByPoint(\n {\n left: element.center[0],\n top: element.center[1],\n },\n element?.isOrderSensitive,\n );\n\n return xpaths;\n }\n\n // find the nearest xpath for the element\n if (element?.attributes?.nodeType === NodeType.POSITION) {\n await this.insight.contextRetrieverFn('locate');\n const info = elementByPositionWithElementInfo(\n pageContext.tree,\n {\n x: element.center[0],\n y: element.center[1],\n },\n {\n requireStrictDistance: false,\n filterPositionElements: true,\n },\n );\n if (info?.id) {\n elementId = info.id;\n } else {\n debug(\n 'no element id found for position node, will not update cache',\n element,\n );\n }\n }\n\n if (!elementId) {\n return undefined;\n }\n try {\n const result = await this.page.getXpathsById(elementId);\n return result;\n } catch (error) {\n debug('getXpathsById error: ', error);\n }\n }\n\n private prependExecutorWithScreenshot(\n taskApply: ExecutionTaskApply,\n appendAfterExecution = false,\n ): ExecutionTaskApply {\n const taskWithScreenshot: ExecutionTaskApply = {\n ...taskApply,\n executor: async (param, context, ...args) => {\n const recorder: ExecutionRecorderItem[] = [];\n const { task } = context;\n // set the recorder before executor in case of error\n task.recorder = recorder;\n const shot = await this.recordScreenshot(`before ${task.type}`);\n recorder.push(shot);\n const result = await taskApply.executor(param, context, ...args);\n if (taskApply.type === 'Action') {\n await Promise.all([\n (async () => {\n await sleep(100);\n if ((this.page as PuppeteerWebPage).waitUntilNetworkIdle) {\n try {\n await (this.page as PuppeteerWebPage).waitUntilNetworkIdle();\n } catch (error) {\n // console.error('waitUntilNetworkIdle error', error);\n }\n }\n })(),\n sleep(200),\n ]);\n }\n if (appendAfterExecution) {\n const shot2 = await this.recordScreenshot('after Action');\n recorder.push(shot2);\n }\n return result;\n },\n };\n return taskWithScreenshot;\n }\n\n public async convertPlanToExecutable(\n plans: PlanningAction[],\n opts?: {\n cacheable?: boolean;\n },\n ) {\n const tasks: ExecutionTaskApply[] = [];\n plans.forEach((plan) => {\n if (plan.type === 'Locate') {\n if (\n plan.locate === null ||\n plan.locate?.id === null ||\n plan.locate?.id === 'null'\n ) {\n // console.warn('Locate action with id is null, will be ignored');\n return;\n }\n const taskFind: ExecutionTaskInsightLocateApply = {\n type: 'Insight',\n subType: 'Locate',\n param: plan.locate\n ? {\n ...plan.locate,\n cacheable: opts?.cacheable,\n }\n : undefined,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param, taskContext) => {\n const { task } = taskContext;\n assert(\n param?.prompt || param?.id || param?.bbox,\n 'No prompt or id or position or bbox to locate',\n );\n let insightDump: InsightDump | undefined;\n let usage: AIUsageInfo | undefined;\n const dumpCollector: DumpSubscriber = (dump) => {\n insightDump = dump;\n usage = dump?.taskInfo?.usage;\n\n task.log = {\n dump: insightDump,\n };\n\n task.usage = usage;\n };\n this.insight.onceDumpUpdatedFn = dumpCollector;\n const shotTime = Date.now();\n\n // Get context through contextRetrieverFn which handles frozen context\n const pageContext = await this.insight.contextRetrieverFn('locate');\n task.pageContext = pageContext;\n\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: pageContext.screenshotBase64,\n timing: 'before Insight',\n };\n task.recorder = [recordItem];\n\n // try matching xpath\n const elementFromXpath = param.xpath\n ? await this.page.getElementInfoByXpath(param.xpath)\n : undefined;\n const userExpectedPathHitFlag = !!elementFromXpath;\n\n // try matching cache\n const cachePrompt = param.prompt;\n const locateCacheRecord =\n this.taskCache?.matchLocateCache(cachePrompt);\n const xpaths = locateCacheRecord?.cacheContent?.xpaths;\n const elementFromCache = userExpectedPathHitFlag\n ? null\n : await matchElementFromCache(\n this,\n xpaths,\n cachePrompt,\n param.cacheable,\n );\n const cacheHitFlag = !!elementFromCache;\n\n // try matching plan\n const elementFromPlan =\n !userExpectedPathHitFlag && !cacheHitFlag\n ? matchElementFromPlan(param, pageContext.tree)\n : undefined;\n const planHitFlag = !!elementFromPlan;\n\n // try ai locate\n const elementFromAiLocate =\n !userExpectedPathHitFlag && !cacheHitFlag && !planHitFlag\n ? (\n await this.insight.locate(param, {\n // fallback to ai locate\n context: pageContext,\n })\n ).element\n : undefined;\n const aiLocateHitFlag = !!elementFromAiLocate;\n\n const element =\n elementFromXpath || // highest priority\n elementFromCache || // second priority\n elementFromPlan || // third priority\n elementFromAiLocate;\n\n // update cache\n let currentXpaths: string[] | undefined;\n if (\n element &&\n this.taskCache &&\n !cacheHitFlag &&\n param?.cacheable !== false\n ) {\n const elementXpaths = await this.getElementXpath(\n pageContext,\n element,\n );\n if (elementXpaths?.length) {\n currentXpaths = elementXpaths;\n this.taskCache.updateOrAppendCacheRecord(\n {\n type: 'locate',\n prompt: cachePrompt,\n xpaths: elementXpaths,\n },\n locateCacheRecord,\n );\n } else {\n debug(\n 'no xpaths found, will not update cache',\n cachePrompt,\n elementXpaths,\n );\n }\n }\n if (!element) {\n throw new Error(`Element not found: ${param.prompt}`);\n }\n\n let hitBy: ExecutionTaskHitBy | undefined;\n\n if (userExpectedPathHitFlag) {\n hitBy = {\n from: 'User expected path',\n context: {\n xpath: param.xpath,\n },\n };\n } else if (cacheHitFlag) {\n hitBy = {\n from: 'Cache',\n context: {\n xpathsFromCache: xpaths,\n xpathsToSave: currentXpaths,\n },\n };\n } else if (planHitFlag) {\n hitBy = {\n from: 'Planning',\n context: {\n id: elementFromPlan?.id,\n bbox: elementFromPlan?.bbox,\n },\n };\n } else if (aiLocateHitFlag) {\n hitBy = {\n from: 'AI model',\n context: {\n prompt: param.prompt,\n },\n };\n }\n\n return {\n output: {\n element,\n },\n pageContext,\n hitBy,\n };\n },\n };\n tasks.push(taskFind);\n } else if (plan.type === 'Assert' || plan.type === 'AssertWithoutThrow') {\n const assertPlan = plan as PlanningAction<PlanningActionParamAssert>;\n const taskAssert: ExecutionTaskApply = {\n type: 'Insight',\n subType: 'Assert',\n param: assertPlan.param,\n thought: assertPlan.thought,\n locate: assertPlan.locate,\n executor: async (param, taskContext) => {\n const { task } = taskContext;\n let insightDump: InsightDump | undefined;\n const dumpCollector: DumpSubscriber = (dump) => {\n insightDump = dump;\n };\n this.insight.onceDumpUpdatedFn = dumpCollector;\n const shotTime = Date.now();\n const pageContext = await this.insight.contextRetrieverFn('assert');\n task.pageContext = pageContext;\n\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: pageContext.screenshotBase64,\n timing: 'before Insight',\n };\n task.recorder = [recordItem];\n\n const assertion = await this.insight.assert(\n assertPlan.param.assertion,\n );\n\n if (!assertion.pass) {\n if (plan.type === 'Assert') {\n task.output = assertion;\n task.log = {\n dump: insightDump,\n };\n throw new Error(\n assertion.thought || 'Assertion failed without reason',\n );\n }\n\n task.error = new Error(assertion.thought);\n }\n\n return {\n output: assertion,\n pageContext,\n log: {\n dump: insightDump,\n },\n usage: assertion.usage,\n };\n },\n };\n tasks.push(taskAssert);\n } else if (plan.type === 'Input') {\n const taskActionInput: ExecutionTaskActionApply<PlanningActionParamInputOrKeyPress> =\n {\n type: 'Action',\n subType: 'Input',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam, { element }) => {\n if (element) {\n await this.page.clearInput(element as unknown as ElementInfo);\n\n if (!taskParam || !taskParam.value) {\n return;\n }\n }\n\n await this.page.keyboard.type(taskParam.value, {\n autoDismissKeyboard: taskParam.autoDismissKeyboard,\n });\n },\n };\n tasks.push(taskActionInput);\n } else if (plan.type === 'KeyboardPress') {\n const taskActionKeyboardPress: ExecutionTaskActionApply<PlanningActionParamInputOrKeyPress> =\n {\n type: 'Action',\n subType: 'KeyboardPress',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam) => {\n const keys = getKeyCommands(taskParam.value);\n\n await this.page.keyboard.press(keys);\n },\n };\n tasks.push(taskActionKeyboardPress);\n } else if (plan.type === 'Tap') {\n const taskActionTap: ExecutionTaskActionApply<PlanningActionParamTap> =\n {\n type: 'Action',\n subType: 'Tap',\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param, { element }) => {\n assert(element, 'Element not found, cannot tap');\n await this.page.mouse.click(element.center[0], element.center[1]);\n },\n };\n tasks.push(taskActionTap);\n } else if (plan.type === 'RightClick') {\n const taskActionRightClick: ExecutionTaskActionApply<PlanningActionParamTap> =\n {\n type: 'Action',\n subType: 'RightClick',\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param, { element }) => {\n assert(element, 'Element not found, cannot right click');\n await this.page.mouse.click(\n element.center[0],\n element.center[1],\n { button: 'right' },\n );\n },\n };\n tasks.push(taskActionRightClick);\n } else if (plan.type === 'Drag') {\n const taskActionDrag: ExecutionTaskActionApply<{\n start_box: { x: number; y: number };\n end_box: { x: number; y: number };\n }> = {\n type: 'Action',\n subType: 'Drag',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam) => {\n assert(\n taskParam?.start_box && taskParam?.end_box,\n 'No start_box or end_box to drag',\n );\n await this.page.mouse.drag(taskParam.start_box, taskParam.end_box);\n },\n };\n tasks.push(taskActionDrag);\n } else if (plan.type === 'Hover') {\n const taskActionHover: ExecutionTaskActionApply<PlanningActionParamHover> =\n {\n type: 'Action',\n subType: 'Hover',\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param, { element }) => {\n assert(element, 'Element not found, cannot hover');\n await this.page.mouse.move(element.center[0], element.center[1]);\n },\n };\n tasks.push(taskActionHover);\n } else if (plan.type === 'Scroll') {\n const taskActionScroll: ExecutionTaskActionApply<PlanningActionParamScroll> =\n {\n type: 'Action',\n subType: 'Scroll',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam, { element }) => {\n const startingPoint = element\n ? {\n left: element.center[0],\n top: element.center[1],\n }\n : undefined;\n const scrollToEventName = taskParam?.scrollType;\n if (scrollToEventName === 'untilTop') {\n await this.page.scrollUntilTop(startingPoint);\n } else if (scrollToEventName === 'untilBottom') {\n await this.page.scrollUntilBottom(startingPoint);\n } else if (scrollToEventName === 'untilRight') {\n await this.page.scrollUntilRight(startingPoint);\n } else if (scrollToEventName === 'untilLeft') {\n await this.page.scrollUntilLeft(startingPoint);\n } else if (scrollToEventName === 'once' || !scrollToEventName) {\n if (\n taskParam?.direction === 'down' ||\n !taskParam ||\n !taskParam.direction\n ) {\n await this.page.scrollDown(\n taskParam?.distance || undefined,\n startingPoint,\n );\n } else if (taskParam.direction === 'up') {\n await this.page.scrollUp(\n taskParam.distance || undefined,\n startingPoint,\n );\n } else if (taskParam.direction === 'left') {\n await this.page.scrollLeft(\n taskParam.distance || undefined,\n startingPoint,\n );\n } else if (taskParam.direction === 'right') {\n await this.page.scrollRight(\n taskParam.distance || undefined,\n startingPoint,\n );\n } else {\n throw new Error(\n `Unknown scroll direction: ${taskParam.direction}`,\n );\n }\n // until mouse event is done\n await sleep(500);\n } else {\n throw new Error(\n `Unknown scroll event type: ${scrollToEventName}, taskParam: ${JSON.stringify(\n taskParam,\n )}`,\n );\n }\n },\n };\n tasks.push(taskActionScroll);\n } else if (plan.type === 'Sleep') {\n const taskActionSleep: ExecutionTaskActionApply<PlanningActionParamSleep> =\n {\n type: 'Action',\n subType: 'Sleep',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam) => {\n await sleep(taskParam?.timeMs || 3000);\n },\n };\n tasks.push(taskActionSleep);\n } else if (plan.type === 'Error') {\n const taskActionError: ExecutionTaskActionApply<PlanningActionParamError> =\n {\n type: 'Action',\n subType: 'Error',\n param: plan.param,\n thought: plan.thought || plan.param?.thought,\n locate: plan.locate,\n executor: async () => {\n throw new Error(\n plan?.thought || plan.param?.thought || 'error without thought',\n );\n },\n };\n tasks.push(taskActionError);\n } else if (plan.type === 'ExpectedFalsyCondition') {\n const taskActionFalsyConditionStatement: ExecutionTaskActionApply<null> =\n {\n type: 'Action',\n subType: 'ExpectedFalsyCondition',\n param: null,\n thought: plan.param?.reason,\n locate: plan.locate,\n executor: async () => {\n // console.warn(`[warn]falsy condition: ${plan.thought}`);\n },\n };\n tasks.push(taskActionFalsyConditionStatement);\n } else if (plan.type === 'Finished') {\n const taskActionFinished: ExecutionTaskActionApply<null> = {\n type: 'Action',\n subType: 'Finished',\n param: null,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {},\n };\n tasks.push(taskActionFinished);\n } else if (plan.type === 'AndroidHomeButton') {\n const taskActionAndroidHomeButton: ExecutionTaskActionApply<null> = {\n type: 'Action',\n subType: 'AndroidHomeButton',\n param: null,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {\n // Check if the page has back method (Android devices)\n assert(\n isAndroidPage(this.page),\n 'Cannot use home button on non-Android devices',\n );\n await this.page.home();\n },\n };\n tasks.push(taskActionAndroidHomeButton);\n } else if (plan.type === 'AndroidBackButton') {\n const taskActionAndroidBackButton: ExecutionTaskActionApply<null> = {\n type: 'Action',\n subType: 'AndroidBackButton',\n param: null,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {\n assert(\n isAndroidPage(this.page),\n 'Cannot use back button on non-Android devices',\n );\n await this.page.back();\n },\n };\n tasks.push(taskActionAndroidBackButton);\n } else if (plan.type === 'AndroidRecentAppsButton') {\n const taskActionAndroidRecentAppsButton: ExecutionTaskActionApply<null> =\n {\n type: 'Action',\n subType: 'AndroidRecentAppsButton',\n param: null,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {\n assert(\n isAndroidPage(this.page),\n 'Cannot use recent apps button on non-Android devices',\n );\n await this.page.recentApps();\n },\n };\n tasks.push(taskActionAndroidRecentAppsButton);\n } else if (plan.type === 'AndroidLongPress') {\n const taskActionAndroidLongPress: ExecutionTaskActionApply<PlanningActionParamAndroidLongPress> =\n {\n type: 'Action',\n subType: 'AndroidLongPress',\n param: plan.param as PlanningActionParamAndroidLongPress,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {\n assert(\n isAndroidPage(this.page),\n 'Cannot use long press on non-Android devices',\n );\n const { x, y, duration } = param;\n await this.page.longPress(x, y, duration);\n },\n };\n tasks.push(taskActionAndroidLongPress);\n } else if (plan.type === 'AndroidPull') {\n const taskActionAndroidPull: ExecutionTaskActionApply<PlanningActionParamAndroidPull> =\n {\n type: 'Action',\n subType: 'AndroidPull',\n param: plan.param as PlanningActionParamAndroidPull,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {\n assert(\n isAndroidPage(this.page),\n 'Cannot use pull action on non-Android devices',\n );\n const { direction, startPoint, distance, duration } = param;\n\n const convertedStartPoint = startPoint\n ? { left: startPoint.x, top: startPoint.y }\n : undefined;\n\n if (direction === 'down') {\n await this.page.pullDown(\n convertedStartPoint,\n distance,\n duration,\n );\n } else if (direction === 'up') {\n await this.page.pullUp(convertedStartPoint, distance, duration);\n } else {\n throw new Error(`Unknown pull direction: ${direction}`);\n }\n },\n };\n tasks.push(taskActionAndroidPull);\n } else {\n throw new Error(`Unknown or unsupported task type: ${plan.type}`);\n }\n });\n\n const wrappedTasks = tasks.map(\n (task: ExecutionTaskApply, index: number) => {\n if (task.type === 'Action') {\n return this.prependExecutorWithScreenshot(\n task,\n index === tasks.length - 1,\n );\n }\n return task;\n },\n );\n\n return {\n tasks: wrappedTasks,\n };\n }\n\n private async setupPlanningContext(executorContext: ExecutorContext) {\n const shotTime = Date.now();\n const pageContext = await this.insight.contextRetrieverFn('locate');\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: pageContext.screenshotBase64,\n timing: 'before Planning',\n };\n\n executorContext.task.recorder = [recordItem];\n (executorContext.task as ExecutionTaskPlanning).pageContext = pageContext;\n\n return {\n pageContext,\n };\n }\n\n async loadYamlFlowAsPlanning(userInstruction: string, yamlString: string) {\n const taskExecutor = new Executor(taskTitleStr('Action', userInstruction), {\n onTaskStart: this.onTaskStartCallback,\n });\n\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'LoadYaml',\n locate: null,\n param: {\n userInstruction,\n },\n executor: async (param, executorContext) => {\n await this.setupPlanningContext(executorContext);\n return {\n output: {\n actions: [],\n more_actions_needed_by_instruction: false,\n log: '',\n yamlString,\n },\n cache: {\n hit: true,\n },\n };\n },\n };\n\n await taskExecutor.append(task);\n await taskExecutor.flush();\n\n return {\n executor: taskExecutor,\n };\n }\n\n private planningTaskFromPrompt(\n userInstruction: string,\n log?: string,\n actionContext?: string,\n ) {\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'Plan',\n locate: null,\n param: {\n userInstruction,\n log,\n },\n executor: async (param, executorContext) => {\n const startTime = Date.now();\n const { pageContext } =\n await this.setupPlanningContext(executorContext);\n\n const planResult = await plan(param.userInstruction, {\n context: pageContext,\n log: param.log,\n actionContext,\n pageType: this.page.pageType as PageType,\n });\n\n const {\n actions,\n log,\n more_actions_needed_by_instruction,\n error,\n usage,\n rawResponse,\n sleep,\n } = planResult;\n\n executorContext.task.log = {\n ...(executorContext.task.log || {}),\n rawResponse,\n };\n executorContext.task.usage = usage;\n\n let stopCollecting = false;\n let bboxCollected = false;\n let planParsingError = '';\n const finalActions = (actions || []).reduce<PlanningAction[]>(\n (acc, planningAction) => {\n if (stopCollecting) {\n return acc;\n }\n\n if (planningAction.locate) {\n // we only collect bbox once, let qwen re-locate in the following steps\n if (bboxCollected && planningAction.locate.bbox) {\n // biome-ignore lint/performance/noDelete: <explanation>\n delete planningAction.locate.bbox;\n }\n\n if (planningAction.locate.bbox) {\n bboxCollected = true;\n }\n\n acc.push({\n type: 'Locate',\n locate: planningAction.locate,\n param: null,\n // thought is prompt created by ai, always a string\n thought: planningAction.locate.prompt as string,\n });\n } else if (\n ['Tap', 'Hover', 'Input'].includes(planningAction.type)\n ) {\n planParsingError = `invalid planning response: ${JSON.stringify(planningAction)}`;\n // should include locate but get null\n stopCollecting = true;\n return acc;\n }\n acc.push(planningAction);\n return acc;\n },\n [],\n );\n\n if (sleep) {\n const timeNow = Date.now();\n const timeRemaining = sleep - (timeNow - startTime);\n if (timeRemaining > 0) {\n finalActions.push({\n type: 'Sleep',\n param: {\n timeMs: timeRemaining,\n },\n locate: null,\n } as PlanningAction<PlanningActionParamSleep>);\n }\n }\n\n if (finalActions.length === 0) {\n assert(\n !more_actions_needed_by_instruction || sleep,\n error\n ? `Failed to plan: ${error}`\n : planParsingError || 'No plan found',\n );\n }\n\n return {\n output: {\n actions: finalActions,\n more_actions_needed_by_instruction,\n log,\n yamlFlow: planResult.yamlFlow,\n },\n cache: {\n hit: false,\n },\n pageContext,\n };\n },\n };\n\n return task;\n }\n\n private planningTaskToGoal(userInstruction: string) {\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'Plan',\n locate: null,\n param: {\n userInstruction,\n },\n executor: async (param, executorContext) => {\n const { pageContext } =\n await this.setupPlanningContext(executorContext);\n\n const imagePayload = await resizeImageForUiTars(\n pageContext.screenshotBase64,\n pageContext.size,\n );\n\n this.appendConversationHistory({\n role: 'user',\n content: [\n {\n type: 'image_url',\n image_url: {\n url: imagePayload,\n },\n },\n ],\n });\n const planResult: {\n actions: PlanningAction<any>[];\n action_summary: string;\n usage?: AIUsageInfo;\n yamlFlow?: MidsceneYamlFlowItem[];\n rawResponse?: string;\n } = await vlmPlanning({\n userInstruction: param.userInstruction,\n conversationHistory: this.conversationHistory,\n size: pageContext.size,\n });\n\n const { actions, action_summary, usage } = planResult;\n executorContext.task.log = {\n ...(executorContext.task.log || {}),\n rawResponse: planResult.rawResponse,\n };\n executorContext.task.usage = usage;\n this.appendConversationHistory({\n role: 'assistant',\n content: action_summary,\n });\n return {\n output: {\n actions,\n thought: actions[0]?.thought,\n actionType: actions[0].type,\n more_actions_needed_by_instruction: true,\n log: '',\n yamlFlow: planResult.yamlFlow,\n },\n cache: {\n hit: false,\n },\n };\n },\n };\n\n return task;\n }\n\n async runPlans(\n title: string,\n plans: PlanningAction[],\n opts?: {\n cacheable?: boolean;\n },\n ): Promise<ExecutionResult> {\n const taskExecutor = new Executor(title, {\n onTaskStart: this.onTaskStartCallback,\n });\n const { tasks } = await this.convertPlanToExecutable(plans, opts);\n await taskExecutor.append(tasks);\n const result = await taskExecutor.flush();\n const { output } = result!;\n return {\n output,\n executor: taskExecutor,\n };\n }\n\n async action(\n userPrompt: string,\n actionContext?: string,\n opts?: {\n cacheable?: boolean;\n },\n ): Promise<\n ExecutionResult<\n | {\n yamlFlow?: MidsceneYamlFlowItem[]; // for cache use\n }\n | undefined\n >\n > {\n const taskExecutor = new Executor(taskTitleStr('Action', userPrompt), {\n onTaskStart: this.onTaskStartCallback,\n });\n\n let planningTask: ExecutionTaskPlanningApply | null =\n this.planningTaskFromPrompt(userPrompt, undefined, actionContext);\n let replanCount = 0;\n const logList: string[] = [];\n\n const yamlFlow: MidsceneYamlFlowItem[] = [];\n const replanningCycleLimit =\n getAIConfigInNumber(MIDSCENE_REPLANNING_CYCLE_LIMIT) ||\n defaultReplanningCycleLimit;\n while (planningTask) {\n if (replanCount > replanningCycleLimit) {\n const errorMsg =\n 'Replanning too many times, please split the task into multiple steps';\n\n return this.appendErrorPlan(taskExecutor, errorMsg);\n }\n\n // plan\n await taskExecutor.append(planningTask);\n const result = await taskExecutor.flush();\n const planResult: PlanningAIResponse = result?.output;\n if (taskExecutor.isInErrorState()) {\n return {\n output: planResult,\n executor: taskExecutor,\n };\n }\n\n const plans = planResult.actions || [];\n yamlFlow.push(...(planResult.yamlFlow || []));\n\n let executables: Awaited<ReturnType<typeof this.convertPlanToExecutable>>;\n try {\n executables = await this.convertPlanToExecutable(plans, opts);\n taskExecutor.append(executables.tasks);\n } catch (error) {\n return this.appendErrorPlan(\n taskExecutor,\n `Error converting plans to executable tasks: ${error}, plans: ${JSON.stringify(\n plans,\n )}`,\n );\n }\n\n await taskExecutor.flush();\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n if (planResult?.log) {\n logList.push(planResult.log);\n }\n\n if (!planResult.more_actions_needed_by_instruction) {\n planningTask = null;\n break;\n }\n planningTask = this.planningTaskFromPrompt(\n userPrompt,\n logList.length > 0 ? `- ${logList.join('\\n- ')}` : undefined,\n actionContext,\n );\n replanCount++;\n }\n\n return {\n output: {\n yamlFlow,\n },\n executor: taskExecutor,\n };\n }\n\n async actionToGoal(\n userPrompt: string,\n opts?: {\n cacheable?: boolean;\n },\n ): Promise<\n ExecutionResult<\n | {\n yamlFlow?: MidsceneYamlFlowItem[]; // for cache use\n }\n | undefined\n >\n > {\n const taskExecutor = new Executor(taskTitleStr('Action', userPrompt), {\n onTaskStart: this.onTaskStartCallback,\n });\n this.conversationHistory = [];\n const isCompleted = false;\n let currentActionNumber = 0;\n const maxActionNumber = 40;\n\n const yamlFlow: MidsceneYamlFlowItem[] = [];\n while (!isCompleted && currentActionNumber < maxActionNumber) {\n currentActionNumber++;\n const planningTask: ExecutionTaskPlanningApply =\n this.planningTaskToGoal(userPrompt);\n await taskExecutor.append(planningTask);\n const result = await taskExecutor.flush();\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function actionToGoal',\n );\n }\n const { output } = result;\n const plans = output.actions;\n yamlFlow.push(...(output.yamlFlow || []));\n let executables: Awaited<ReturnType<typeof this.convertPlanToExecutable>>;\n try {\n executables = await this.convertPlanToExecutable(plans, opts);\n taskExecutor.append(executables.tasks);\n } catch (error) {\n return this.appendErrorPlan(\n taskExecutor,\n `Error converting plans to executable tasks: ${error}, plans: ${JSON.stringify(\n plans,\n )}`,\n );\n }\n\n await taskExecutor.flush();\n\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n if (plans[0].type === 'Finished') {\n break;\n }\n }\n return {\n output: {\n yamlFlow,\n },\n executor: taskExecutor,\n };\n }\n\n private async createTypeQueryTask<T>(\n type: 'Query' | 'Boolean' | 'Number' | 'String' | 'Assert',\n demand: InsightExtractParam,\n opt?: InsightExtractOption,\n multimodalPrompt?: TMultimodalPrompt,\n ): Promise<ExecutionResult<T>> {\n const taskExecutor = new Executor(\n taskTitleStr(\n type,\n typeof demand === 'string' ? demand : JSON.stringify(demand),\n ),\n {\n onTaskStart: this.onTaskStartCallback,\n },\n );\n\n const queryTask: ExecutionTaskInsightQueryApply = {\n type: 'Insight',\n subType: type,\n locate: null,\n param: {\n // TODO: display image thumbnail in report\n dataDemand: multimodalPrompt\n ? ({\n demand,\n multimodalPrompt,\n } as never)\n : demand, // for user param presentation in report right sidebar\n },\n executor: async (param, taskContext) => {\n const { task } = taskContext;\n let insightDump: InsightDump | undefined;\n const dumpCollector: DumpSubscriber = (dump) => {\n insightDump = dump;\n };\n this.insight.onceDumpUpdatedFn = dumpCollector;\n\n // Get page context for query operations\n const shotTime = Date.now();\n const pageContext = await this.insight.contextRetrieverFn('extract');\n task.pageContext = pageContext;\n\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: pageContext.screenshotBase64,\n timing: 'before Extract',\n };\n task.recorder = [recordItem];\n\n const ifTypeRestricted = type !== 'Query';\n let demandInput = demand;\n if (ifTypeRestricted) {\n demandInput = {\n result: `${type}, ${demand}`,\n };\n }\n\n const { data, usage, thought } = await this.insight.extract<any>(\n demandInput,\n opt,\n multimodalPrompt,\n );\n\n let outputResult = data;\n if (ifTypeRestricted) {\n assert(data?.result !== undefined, 'No result in query data');\n outputResult = (data as any).result;\n }\n\n return {\n output: outputResult,\n log: { dump: insightDump },\n usage,\n thought,\n };\n },\n };\n\n await taskExecutor.append(this.prependExecutorWithScreenshot(queryTask));\n const result = await taskExecutor.flush();\n\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function createTypeQueryTask',\n );\n }\n\n const { output, thought } = result;\n\n return {\n output,\n thought,\n executor: taskExecutor,\n };\n }\n\n async query(\n demand: InsightExtractParam,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult> {\n return this.createTypeQueryTask('Query', demand, opt);\n }\n\n async boolean(\n prompt: TUserPrompt,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult<boolean>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n return this.createTypeQueryTask<boolean>(\n 'Boolean',\n textPrompt,\n opt,\n multimodalPrompt,\n );\n }\n\n async number(\n prompt: TUserPrompt,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult<number>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n return this.createTypeQueryTask<number>(\n 'Number',\n textPrompt,\n opt,\n multimodalPrompt,\n );\n }\n\n async string(\n prompt: TUserPrompt,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult<string>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n return this.createTypeQueryTask<string>(\n 'String',\n textPrompt,\n opt,\n multimodalPrompt,\n );\n }\n\n async assert(\n assertion: TUserPrompt,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult<boolean>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(assertion);\n return await this.createTypeQueryTask<boolean>(\n 'Assert',\n textPrompt,\n opt,\n multimodalPrompt,\n );\n }\n\n /**\n * Append a message to the conversation history\n * For user messages with images:\n * - Keep max 4 user image messages in history\n * - Remove oldest user image message when limit reached\n * For assistant messages:\n * - Simply append to history\n * @param conversationHistory Message to append\n */\n private appendConversationHistory(\n conversationHistory: ChatCompletionMessageParam,\n ) {\n if (conversationHistory.role === 'user') {\n // Get all existing user messages with images\n const userImgItems = this.conversationHistory.filter(\n (item) => item.role === 'user',\n );\n\n // If we already have 4 user image messages\n if (userImgItems.length >= 4 && conversationHistory.role === 'user') {\n // Remove first user image message when we already have 4, before adding new one\n const firstUserImgIndex = this.conversationHistory.findIndex(\n (item) => item.role === 'user',\n );\n if (firstUserImgIndex >= 0) {\n this.conversationHistory.splice(firstUserImgIndex, 1);\n }\n }\n }\n // For non-user messages, simply append to history\n this.conversationHistory.push(conversationHistory);\n }\n\n private async appendErrorPlan(taskExecutor: Executor, errorMsg: string) {\n const errorPlan: PlanningAction<PlanningActionParamError> = {\n type: 'Error',\n param: {\n thought: errorMsg,\n },\n locate: null,\n };\n const { tasks } = await this.convertPlanToExecutable([errorPlan]);\n await taskExecutor.append(this.prependExecutorWithScreenshot(tasks[0]));\n await taskExecutor.flush();\n\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n async waitFor(\n assertion: string,\n opt: PlanningActionParamWaitFor,\n ): Promise<ExecutionResult<void>> {\n const description = `waitFor: ${assertion}`;\n const taskExecutor = new Executor(taskTitleStr('WaitFor', description), {\n onTaskStart: this.onTaskStartCallback,\n });\n const { timeoutMs, checkIntervalMs } = opt;\n\n assert(assertion, 'No assertion for waitFor');\n assert(timeoutMs, 'No timeoutMs for waitFor');\n assert(checkIntervalMs, 'No checkIntervalMs for waitFor');\n\n const overallStartTime = Date.now();\n let startTime = Date.now();\n let errorThought = '';\n while (Date.now() - overallStartTime < timeoutMs) {\n startTime = Date.now();\n const assertPlan: PlanningAction<PlanningActionParamAssert> = {\n type: 'AssertWithoutThrow',\n param: {\n assertion,\n },\n locate: null,\n };\n const { tasks: assertTasks } = await this.convertPlanToExecutable([\n assertPlan,\n ]);\n await taskExecutor.append(\n this.prependExecutorWithScreenshot(assertTasks[0]),\n );\n const result = await taskExecutor.flush();\n\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function waitFor',\n );\n }\n\n const { output } = result as { output: InsightAssertionResponse };\n\n if (output?.pass) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n errorThought =\n output?.thought ||\n `unknown error when waiting for assertion: ${assertion}`;\n const now = Date.now();\n if (now - startTime < checkIntervalMs) {\n const timeRemaining = checkIntervalMs - (now - startTime);\n const sleepPlan: PlanningAction<PlanningActionParamSleep> = {\n type: 'Sleep',\n param: {\n timeMs: timeRemaining,\n },\n locate: null,\n };\n const { tasks: sleepTasks } = await this.convertPlanToExecutable([\n sleepPlan,\n ]);\n await taskExecutor.append(\n this.prependExecutorWithScreenshot(sleepTasks[0]),\n );\n await taskExecutor.flush();\n }\n }\n\n return this.appendErrorPlan(\n taskExecutor,\n `waitFor timeout: ${errorThought}`,\n );\n }\n}\n","import type {\n DetailedLocateParam,\n ExecutionTask,\n ExecutionTaskAction,\n ExecutionTaskInsightAssertion,\n ExecutionTaskInsightLocate,\n ExecutionTaskInsightQuery,\n ExecutionTaskPlanning,\n PlanningActionParamAndroidPull,\n PlanningActionParamScroll,\n} from '@midscene/core';\n\nexport function typeStr(task: ExecutionTask) {\n return task.subType && task.subType !== 'Plan'\n ? `${task.type} / ${task.subType || ''}`\n : task.type;\n}\n\nexport function getKeyCommands(\n value: string | string[],\n): Array<{ key: string; command?: string }> {\n // Ensure value is an array of keys\n const keys = Array.isArray(value) ? value : [value];\n\n // Process each key to attach a corresponding command if needed, based on the presence of 'Meta' or 'Control' in the keys array.\n // ref: https://github.com/puppeteer/puppeteer/pull/9357/files#diff-32cf475237b000f980eb214a0a823e45a902bddb7d2426d677cae96397aa0ae4R94\n return keys.reduce((acc: Array<{ key: string; command?: string }>, k) => {\n const includeMeta = keys.includes('Meta') || keys.includes('Control');\n if (includeMeta && (k === 'a' || k === 'A')) {\n return acc.concat([{ key: k, command: 'SelectAll' }]);\n }\n if (includeMeta && (k === 'c' || k === 'C')) {\n return acc.concat([{ key: k, command: 'Copy' }]);\n }\n if (includeMeta && (k === 'v' || k === 'V')) {\n return acc.concat([{ key: k, command: 'Paste' }]);\n }\n return acc.concat([{ key: k }]);\n }, []);\n}\n\nexport function locateParamStr(locate?: DetailedLocateParam) {\n if (!locate) {\n return '';\n }\n\n if (typeof locate === 'string') {\n return locate;\n }\n\n return typeof locate.prompt === 'string'\n ? locate.prompt\n : locate.prompt.prompt;\n}\n\nexport function scrollParamStr(scrollParam?: PlanningActionParamScroll) {\n if (!scrollParam) {\n return '';\n }\n return `${scrollParam.direction || 'down'}, ${scrollParam.scrollType || 'once'}, ${scrollParam.distance || 'distance-not-set'}`;\n}\n\nexport function pullParamStr(pullParam?: PlanningActionParamAndroidPull) {\n if (!pullParam) {\n return '';\n }\n const parts: string[] = [];\n parts.push(`direction: ${pullParam.direction || 'down'}`);\n if (pullParam.startPoint) {\n parts.push(`start: (${pullParam.startPoint.x}, ${pullParam.startPoint.y})`);\n }\n if (pullParam.distance) {\n parts.push(`distance: ${pullParam.distance}`);\n }\n if (pullParam.duration) {\n parts.push(`duration: ${pullParam.duration}ms`);\n }\n return parts.join(', ');\n}\n\nexport function taskTitleStr(\n type:\n | 'Tap'\n | 'Hover'\n | 'Input'\n | 'RightClick'\n | 'KeyboardPress'\n | 'Scroll'\n | 'Action'\n | 'Query'\n | 'Assert'\n | 'WaitFor'\n | 'Locate'\n | 'Boolean'\n | 'Number'\n | 'String',\n prompt: string,\n) {\n if (prompt) {\n return `${type} - ${prompt}`;\n }\n return type;\n}\n\nexport function paramStr(task: ExecutionTask) {\n let value: string | undefined | object;\n if (task.type === 'Planning') {\n value = (task as ExecutionTaskPlanning)?.param?.userInstruction;\n }\n\n if (task.type === 'Insight') {\n value =\n (task as ExecutionTaskInsightLocate)?.param?.prompt ||\n (task as ExecutionTaskInsightLocate)?.param?.id ||\n (task as ExecutionTaskInsightQuery)?.param?.dataDemand ||\n (task as ExecutionTaskInsightAssertion)?.param?.assertion;\n }\n\n if (task.type === 'Action') {\n const locate = (task as ExecutionTaskAction)?.locate;\n const locateStr = locate ? locateParamStr(locate) : '';\n\n value = task.thought || '';\n if (typeof (task as ExecutionTaskAction)?.param?.timeMs === 'number') {\n value = `${(task as ExecutionTaskAction)?.param?.timeMs}ms`;\n } else if (\n typeof (task as ExecutionTaskAction)?.param?.scrollType === 'string'\n ) {\n value = scrollParamStr((task as ExecutionTaskAction)?.param);\n } else if (\n typeof (task as ExecutionTaskAction)?.param?.direction === 'string' &&\n (task as ExecutionTaskAction)?.subType === 'AndroidPull'\n ) {\n value = pullParamStr((task as ExecutionTaskAction)?.param);\n } else if (\n typeof (task as ExecutionTaskAction)?.param?.value !== 'undefined'\n ) {\n value = (task as ExecutionTaskAction)?.param?.value;\n }\n\n if (locateStr) {\n if (value) {\n value = `${locateStr} - ${value}`;\n } else {\n value = locateStr;\n }\n }\n }\n\n if (typeof value === 'undefined') return '';\n return typeof value === 'string'\n ? value\n : JSON.stringify(value, undefined, 2);\n}\n\nexport const limitOpenNewTabScript = `\nif (!window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__) {\n window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__ = true;\n\n // Intercept the window.open method (only once)\n window.open = function(url) {\n console.log('Blocked window.open:', url);\n window.location.href = url;\n return null;\n };\n\n // Block all a tag clicks with target=\"_blank\" (only once)\n document.addEventListener('click', function(e) {\n const target = e.target.closest('a');\n if (target && target.target === '_blank') {\n e.preventDefault();\n console.log('Blocked new tab:', target.href);\n window.location.href = target.href;\n target.removeAttribute('target');\n }\n }, true);\n}\n`;\n","import type { StaticPage } from '@/playground';\nimport type {\n BaseElement,\n ElementTreeNode,\n ExecutionDump,\n ExecutionTask,\n PlanningLocateParam,\n PlaywrightParserOpt,\n TMultimodalPrompt,\n TUserPrompt,\n UIContext,\n} from '@midscene/core';\nimport { elementByPositionWithElementInfo } from '@midscene/core/ai-model';\nimport { uploadTestInfoToServer } from '@midscene/core/utils';\nimport { MIDSCENE_REPORT_TAG_NAME, getAIConfig } from '@midscene/shared/env';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport {\n generateElementByPosition,\n getNodeFromCacheList,\n traverseTree,\n} from '@midscene/shared/extractor';\nimport { resizeImgBase64 } from '@midscene/shared/img';\nimport { type DebugFunction, getDebug } from '@midscene/shared/logger';\nimport { assert, logMsg, uuid } from '@midscene/shared/utils';\nimport dayjs from 'dayjs';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport type { Page as PuppeteerPage } from 'puppeteer';\nimport { WebElementInfo, type WebUIContext } from '../web-element';\nimport type { WebPage } from './page';\nimport { debug as cacheDebug } from './task-cache';\nimport type { PageTaskExecutor } from './tasks';\n\nconst debug = getDebug('tool:profile');\n\nexport async function parseContextFromWebPage(\n page: WebPage,\n _opt?: PlaywrightParserOpt,\n): Promise<WebUIContext> {\n assert(page, 'page is required');\n if ((page as StaticPage)._forceUsePageContext) {\n return await (page as any)._forceUsePageContext();\n }\n\n debug('Getting page URL');\n const url = await page.url();\n debug('URL end');\n\n debug('Uploading test info to server');\n uploadTestInfoToServer({ testUrl: url });\n debug('UploadTestInfoToServer end');\n\n let screenshotBase64: string;\n let tree: ElementTreeNode<ElementInfo>;\n\n debug('Starting parallel operations: screenshot and element tree');\n await Promise.all([\n page.screenshotBase64().then((base64) => {\n screenshotBase64 = base64;\n debug('ScreenshotBase64 end');\n }),\n page.getElementsNodeTree().then(async (treeRoot) => {\n tree = treeRoot;\n debug('GetElementsNodeTree end');\n }),\n ]);\n debug('ParseContextFromWebPage end');\n debug('Traversing element tree');\n const webTree = traverseTree(tree!, (elementInfo) => {\n const { rect, id, content, attributes, indexId, isVisible } = elementInfo;\n return new WebElementInfo({\n rect,\n id,\n content,\n attributes,\n indexId,\n isVisible,\n });\n });\n debug('TraverseTree end');\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n const size = await page.size();\n\n debug(`size: ${size.width}x${size.height} dpr: ${size.dpr}`);\n\n if (size.dpr && size.dpr > 1) {\n debug('Resizing screenshot for high DPR display');\n screenshotBase64 = await resizeImgBase64(screenshotBase64, {\n width: size.width,\n height: size.height,\n });\n debug('ResizeImgBase64 end');\n }\n\n return {\n tree: webTree,\n size,\n screenshotBase64: screenshotBase64!,\n url,\n };\n}\n\nexport function getReportFileName(tag = 'web') {\n const reportTagName = getAIConfig(MIDSCENE_REPORT_TAG_NAME);\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss');\n // ensure uniqueness at the same time\n const uniqueId = uuid().substring(0, 8);\n return `${reportTagName || tag}-${dateTimeInFileName}-${uniqueId}`;\n}\n\nexport function printReportMsg(filepath: string) {\n logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\n/**\n * Get the current execution file name\n * @returns The name of the current execution file\n */\nexport function getCurrentExecutionFile(trace?: string): string | false {\n const error = new Error();\n const stackTrace = trace || error.stack;\n const pkgDir = process.cwd() || '';\n if (stackTrace) {\n const stackLines = stackTrace.split('\\n');\n for (const line of stackLines) {\n if (\n line.includes('.spec.') ||\n line.includes('.test.') ||\n line.includes('.ts') ||\n line.includes('.js')\n ) {\n const match = line.match(/(?:at\\s+)?(.*?\\.(?:spec|test)\\.[jt]s)/);\n if (match?.[1]) {\n const targetFileName = match[1]\n .replace(pkgDir, '')\n .trim()\n .replace('at ', '');\n return targetFileName;\n }\n }\n }\n }\n return false;\n}\n\nconst testFileIndex = new Map<string, number>();\n\nexport function generateCacheId(fileName?: string): string {\n let taskFile = fileName || getCurrentExecutionFile();\n if (!taskFile) {\n taskFile = uuid();\n console.warn(\n 'Midscene - using random UUID for cache id. Cache may be invalid.',\n );\n }\n\n if (testFileIndex.has(taskFile)) {\n const currentIndex = testFileIndex.get(taskFile);\n if (currentIndex !== undefined) {\n testFileIndex.set(taskFile, currentIndex + 1);\n }\n } else {\n testFileIndex.set(taskFile, 1);\n }\n return `${taskFile}-${testFileIndex.get(taskFile)}`;\n}\n\nexport const ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED =\n 'NOT_IMPLEMENTED_AS_DESIGNED';\n\nexport function replaceIllegalPathCharsAndSpace(str: string) {\n // Only replace characters that are illegal in filenames, but preserve path separators\n return str.replace(/[:*?\"<>| ]/g, '-');\n}\n\nexport function forceClosePopup(\n page: PuppeteerPage | PlaywrightPage,\n debug: DebugFunction,\n) {\n page.on('popup', async (popup) => {\n if (!popup) {\n console.warn('got a popup event, but the popup is not ready yet, skip');\n return;\n }\n const url = await (popup as PuppeteerPage).url();\n console.log(`Popup opened: ${url}`);\n if (!(popup as PuppeteerPage).isClosed()) {\n try {\n await (popup as PuppeteerPage).close(); // Close the newly opened TAB\n } catch (error) {\n debug(`failed to close popup ${url}, error: ${error}`);\n }\n } else {\n debug(`popup is already closed, skip close ${url}`);\n }\n\n if (!page.isClosed()) {\n try {\n await page.goto(url);\n } catch (error) {\n debug(`failed to goto ${url}, error: ${error}`);\n }\n } else {\n debug(`page is already closed, skip goto ${url}`);\n }\n });\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n tree: ElementTreeNode<BaseElement>,\n) {\n if (!planLocateParam) {\n return undefined;\n }\n if (planLocateParam.id) {\n return getNodeFromCacheList(planLocateParam.id);\n }\n\n if (planLocateParam.bbox) {\n const centerPosition = {\n x: Math.floor((planLocateParam.bbox[0] + planLocateParam.bbox[2]) / 2),\n y: Math.floor((planLocateParam.bbox[1] + planLocateParam.bbox[3]) / 2),\n };\n let element = elementByPositionWithElementInfo(tree, centerPosition);\n\n if (!element) {\n element = generateElementByPosition(centerPosition) as BaseElement;\n }\n\n return element;\n }\n\n return undefined;\n}\n\nexport async function matchElementFromCache(\n taskExecutor: PageTaskExecutor,\n xpaths: string[] | undefined,\n cachePrompt: TUserPrompt,\n cacheable: boolean | undefined,\n) {\n try {\n if (\n xpaths?.length &&\n taskExecutor.taskCache?.isCacheResultUsed &&\n cacheable !== false\n ) {\n // hit cache, use new id\n for (let i = 0; i < xpaths.length; i++) {\n const element = await taskExecutor.page.getElementInfoByXpath(\n xpaths[i],\n );\n\n if (element?.id) {\n cacheDebug('cache hit, prompt: %s', cachePrompt);\n cacheDebug(\n 'found a new element with same xpath, xpath: %s, id: %s',\n xpaths[i],\n element?.id,\n );\n return element;\n }\n }\n }\n } catch (error) {\n cacheDebug('get element info by xpath error: ', error);\n }\n}\n\nexport function trimContextByViewport(execution: ExecutionDump) {\n function filterVisibleTree(\n node: ElementTreeNode<BaseElement>,\n ): ElementTreeNode<BaseElement> | null {\n if (!node) return null;\n\n // recursively process all children\n const filteredChildren = Array.isArray(node.children)\n ? (node.children\n .map(filterVisibleTree)\n .filter((child) => child !== null) as ElementTreeNode<BaseElement>[])\n : [];\n\n // if the current node is visible, keep it and the filtered children\n if (node.node && node.node.isVisible === true) {\n return {\n ...node,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible, but has visible children, create an empty node to include these children\n if (filteredChildren.length > 0) {\n return {\n node: null,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible and has no visible children, return null\n return null;\n }\n\n return {\n ...execution,\n tasks: Array.isArray(execution.tasks)\n ? execution.tasks.map((task: ExecutionTask) => {\n const newTask = { ...task };\n if (task.pageContext?.tree) {\n newTask.pageContext = {\n ...task.pageContext,\n tree: filterVisibleTree(task.pageContext.tree) || {\n node: null,\n children: [],\n },\n };\n }\n return newTask;\n })\n : execution.tasks,\n };\n}\n\nexport const parsePrompt = (\n prompt: TUserPrompt,\n): {\n textPrompt: string;\n multimodalPrompt?: TMultimodalPrompt;\n} => {\n if (typeof prompt === 'string') {\n return {\n textPrompt: prompt,\n multimodalPrompt: undefined,\n };\n }\n return {\n textPrompt: prompt.prompt,\n multimodalPrompt: prompt.images\n ? {\n images: prompt.images,\n convertHttpImage2Base64: !!prompt.convertHttpImage2Base64,\n }\n : undefined,\n };\n};\n","import type { BaseElement, Rect, UIContext } from '@midscene/core';\nimport type { NodeType } from '@midscene/shared/constants';\nexport interface WebElementInfoType extends BaseElement {\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n}\n\nexport class WebElementInfo implements BaseElement {\n content: string;\n\n rect: Rect;\n\n center: [number, number];\n\n id: string;\n\n indexId: number;\n\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n\n xpaths?: string[];\n\n isVisible: boolean;\n\n constructor({\n content,\n rect,\n id,\n attributes,\n indexId,\n xpaths,\n isVisible,\n }: {\n content: string;\n rect: Rect;\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n indexId: number;\n xpaths?: string[];\n isVisible: boolean;\n }) {\n this.content = content;\n this.rect = rect;\n this.center = [\n Math.floor(rect.left + rect.width / 2),\n Math.floor(rect.top + rect.height / 2),\n ];\n this.id = id;\n this.attributes = attributes;\n this.indexId = indexId;\n this.xpaths = xpaths;\n this.isVisible = isVisible;\n }\n}\n\nexport type WebUIContext = UIContext<WebElementInfo> & {\n url: string;\n _isFrozen?: boolean;\n};\n","import assert from 'node:assert';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport type { TUserPrompt } from '@midscene/core';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\nimport {\n MIDSCENE_CACHE_MAX_FILENAME_LENGTH,\n getAIConfigInNumber,\n} from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { ifInBrowser, ifInWorker } from '@midscene/shared/utils';\nimport { generateHashId } from '@midscene/shared/utils';\nimport yaml from 'js-yaml';\nimport semver from 'semver';\nimport { version } from '../../package.json';\nimport { replaceIllegalPathCharsAndSpace } from './utils';\n\nconst DEFAULT_CACHE_MAX_FILENAME_LENGTH = 200;\n\nexport const debug = getDebug('cache');\n\nexport interface PlanningCache {\n type: 'plan';\n prompt: string;\n yamlWorkflow: string;\n}\n\nexport interface LocateCache {\n type: 'locate';\n prompt: TUserPrompt;\n xpaths: string[];\n}\n\nexport interface MatchCacheResult<T extends PlanningCache | LocateCache> {\n cacheContent: T;\n updateFn: (cb: (cache: T) => void) => void;\n}\n\nexport type CacheFileContent = {\n midsceneVersion: string;\n cacheId: string;\n caches: Array<PlanningCache | LocateCache>;\n};\n\nconst lowestSupportedMidsceneVersion = '0.16.10';\nexport const cacheFileExt = '.cache.yaml';\n\nexport class TaskCache {\n cacheId: string;\n\n cacheFilePath?: string;\n\n cache: CacheFileContent;\n\n isCacheResultUsed: boolean; // a flag to indicate if the cache result should be used\n cacheOriginalLength: number;\n\n private matchedCacheIndices: Set<string> = new Set(); // Track matched records\n\n constructor(\n cacheId: string,\n isCacheResultUsed: boolean,\n cacheFilePath?: string,\n ) {\n assert(cacheId, 'cacheId is required');\n let safeCacheId = replaceIllegalPathCharsAndSpace(cacheId);\n const cacheMaxFilenameLength =\n getAIConfigInNumber(MIDSCENE_CACHE_MAX_FILENAME_LENGTH) ||\n DEFAULT_CACHE_MAX_FILENAME_LENGTH;\n if (Buffer.byteLength(safeCacheId, 'utf8') > cacheMaxFilenameLength) {\n const prefix = safeCacheId.slice(0, 32);\n const hash = generateHashId(undefined, safeCacheId);\n safeCacheId = `${prefix}-${hash}`;\n }\n this.cacheId = safeCacheId;\n\n this.cacheFilePath =\n ifInBrowser || ifInWorker\n ? undefined\n : cacheFilePath ||\n join(getMidsceneRunSubDir('cache'), `${this.cacheId}${cacheFileExt}`);\n this.isCacheResultUsed = isCacheResultUsed;\n\n let cacheContent;\n if (this.cacheFilePath) {\n cacheContent = this.loadCacheFromFile();\n }\n if (!cacheContent) {\n cacheContent = {\n midsceneVersion: version,\n cacheId: this.cacheId,\n caches: [],\n };\n }\n this.cache = cacheContent;\n this.cacheOriginalLength = this.cache.caches.length;\n }\n\n matchCache(\n prompt: TUserPrompt,\n type: 'plan' | 'locate',\n ): MatchCacheResult<PlanningCache | LocateCache> | undefined {\n // Find the first unused matching cache\n for (let i = 0; i < this.cacheOriginalLength; i++) {\n const item = this.cache.caches[i];\n const promptStr =\n typeof prompt === 'string' ? prompt : JSON.stringify(prompt);\n const key = `${type}:${promptStr}:${i}`;\n if (\n item.type === type &&\n isDeepStrictEqual(item.prompt, prompt) &&\n !this.matchedCacheIndices.has(key)\n ) {\n this.matchedCacheIndices.add(key);\n debug(\n 'cache found and marked as used, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n return {\n cacheContent: item,\n updateFn: (cb: (cache: PlanningCache | LocateCache) => void) => {\n debug(\n 'will call updateFn to update cache, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n cb(item);\n debug(\n 'cache updated, will flush to file, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n this.flushCacheToFile();\n },\n };\n }\n }\n debug('no unused cache found, type: %s, prompt: %s', type, prompt);\n return undefined;\n }\n\n matchPlanCache(prompt: string): MatchCacheResult<PlanningCache> | undefined {\n return this.matchCache(prompt, 'plan') as\n | MatchCacheResult<PlanningCache>\n | undefined;\n }\n\n matchLocateCache(\n prompt: TUserPrompt,\n ): MatchCacheResult<LocateCache> | undefined {\n return this.matchCache(prompt, 'locate') as\n | MatchCacheResult<LocateCache>\n | undefined;\n }\n\n appendCache(cache: PlanningCache | LocateCache) {\n debug('will append cache', cache);\n this.cache.caches.push(cache);\n this.flushCacheToFile();\n }\n\n loadCacheFromFile() {\n const cacheFile = this.cacheFilePath;\n assert(cacheFile, 'cache file path is required');\n\n if (!existsSync(cacheFile)) {\n debug('no cache file found, path: %s', cacheFile);\n return undefined;\n }\n\n // detect old cache file\n const jsonTypeCacheFile = cacheFile.replace(cacheFileExt, '.json');\n if (existsSync(jsonTypeCacheFile) && this.isCacheResultUsed) {\n console.warn(\n `An outdated cache file from an earlier version of Midscene has been detected. Since version 0.17, we have implemented an improved caching strategy. Please delete the old file located at: ${jsonTypeCacheFile}.`,\n );\n return undefined;\n }\n\n try {\n const data = readFileSync(cacheFile, 'utf8');\n const jsonData = yaml.load(data) as CacheFileContent;\n\n if (!version) {\n debug('no midscene version info, will not read cache from file');\n return undefined;\n }\n\n if (\n semver.lt(jsonData.midsceneVersion, lowestSupportedMidsceneVersion) &&\n !jsonData.midsceneVersion.includes('beta') // for internal test\n ) {\n console.warn(\n `You are using an old version of Midscene cache file, and we cannot match any info from it. Starting from Midscene v0.17, we changed our strategy to use xpath for cache info, providing better performance.\\nPlease delete the existing cache and rebuild it. Sorry for the inconvenience.\\ncache file: ${cacheFile}`,\n );\n return undefined;\n }\n\n debug(\n 'cache loaded from file, path: %s, cache version: %s, record length: %s',\n cacheFile,\n jsonData.midsceneVersion,\n jsonData.caches.length,\n );\n jsonData.midsceneVersion = version; // update the version\n return jsonData;\n } catch (err) {\n debug(\n 'cache file exists but load failed, path: %s, error: %s',\n cacheFile,\n err,\n );\n return undefined;\n }\n }\n\n flushCacheToFile() {\n if (!version) {\n debug('no midscene version info, will not write cache to file');\n return;\n }\n\n if (!this.cacheFilePath) {\n debug('no cache file path, will not write cache to file');\n return;\n }\n\n try {\n const dir = dirname(this.cacheFilePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n debug('created cache directory: %s', dir);\n }\n\n // Sort caches to ensure plan entries come before locate entries for better readability\n const sortedCaches = [...this.cache.caches].sort((a, b) => {\n if (a.type === 'plan' && b.type === 'locate') return -1;\n if (a.type === 'locate' && b.type === 'plan') return 1;\n return 0;\n });\n\n const cacheToWrite = {\n ...this.cache,\n caches: sortedCaches,\n };\n\n const yamlData = yaml.dump(cacheToWrite);\n writeFileSync(this.cacheFilePath, yamlData);\n debug('cache flushed to file: %s', this.cacheFilePath);\n } catch (err) {\n debug(\n 'write cache to file failed, path: %s, error: %s',\n this.cacheFilePath,\n err,\n );\n }\n }\n\n updateOrAppendCacheRecord(\n newRecord: PlanningCache | LocateCache,\n cachedRecord?: MatchCacheResult<PlanningCache | LocateCache>,\n ) {\n if (cachedRecord) {\n // update existing record\n if (newRecord.type === 'plan') {\n cachedRecord.updateFn((cache) => {\n (cache as PlanningCache).yamlWorkflow = newRecord.yamlWorkflow;\n });\n } else {\n cachedRecord.updateFn((cache) => {\n (cache as LocateCache).xpaths = newRecord.xpaths;\n });\n }\n } else {\n this.appendCache(newRecord);\n }\n }\n}\n","{\n \"name\": \"@midscene/web\",\n \"description\": \"Automate browser actions, extract data, and perform assertions using AI. It offers JavaScript SDK, Chrome extension, and support for scripting in YAML. See https://midscenejs.com/ for details.\",\n \"keywords\": [\n \"AI UI automation\",\n \"AI testing\",\n \"Computer use\",\n \"Browser use\",\n \"Android use\"\n ],\n \"version\": \"0.26.1\",\n \"repository\": \"https://github.com/web-infra-dev/midscene\",\n \"homepage\": \"https://midscenejs.com/\",\n \"jsnext:source\": \"./src/index.ts\",\n \"main\": \"./dist/lib/index.js\",\n \"types\": \"./dist/types/index.d.ts\",\n \"bin\": {\n \"midscene-playground\": \"./bin/midscene-playground\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/types/index.d.ts\",\n \"default\": \"./dist/lib/index.js\"\n },\n \"./bridge-mode\": {\n \"types\": \"./dist/types/bridge-mode.d.ts\",\n \"default\": \"./dist/lib/bridge-mode.js\"\n },\n \"./bridge-mode-browser\": {\n \"types\": \"./dist/types/bridge-mode-browser.d.ts\",\n \"default\": \"./dist/lib/bridge-mode-browser.js\"\n },\n \"./utils\": {\n \"types\": \"./dist/types/utils.d.ts\",\n \"default\": \"./dist/lib/utils.js\"\n },\n \"./ui-utils\": {\n \"types\": \"./dist/types/ui-utils.d.ts\",\n \"default\": \"./dist/lib/ui-utils.js\"\n },\n \"./puppeteer\": {\n \"types\": \"./dist/types/puppeteer.d.ts\",\n \"default\": \"./dist/lib/puppeteer.js\"\n },\n \"./puppeteer-agent-launcher\": {\n \"types\": \"./dist/types/puppeteer-agent-launcher.d.ts\",\n \"default\": \"./dist/lib/puppeteer-agent-launcher.js\"\n },\n \"./playwright\": {\n \"types\": \"./dist/types/playwright.d.ts\",\n \"default\": \"./dist/lib/playwright.js\"\n },\n \"./playwright-report\": {\n \"types\": \"./dist/types/playwright-report.d.ts\",\n \"default\": \"./dist/lib/playwright-report.js\"\n },\n \"./playwright-reporter\": {\n \"types\": \"./dist/types/playwright-reporter.d.ts\",\n \"default\": \"./dist/lib/playwright-reporter.js\"\n },\n \"./playground\": {\n \"types\": \"./dist/types/playground.d.ts\",\n \"default\": \"./dist/lib/playground.js\"\n },\n \"./midscene-playground\": {\n \"types\": \"./dist/types/midscene-playground.d.ts\",\n \"default\": \"./dist/lib/midscene-playground.js\"\n },\n \"./midscene-server\": {\n \"types\": \"./dist/types/midscene-server.d.ts\",\n \"default\": \"./dist/lib/midscene-server.js\"\n },\n \"./chrome-extension\": {\n \"types\": \"./dist/types/chrome-extension.d.ts\",\n \"default\": \"./dist/lib/chrome-extension.js\"\n },\n \"./yaml\": {\n \"types\": \"./dist/types/yaml.d.ts\",\n \"default\": \"./dist/lib/yaml.js\"\n },\n \"./agent\": {\n \"types\": \"./dist/types/agent.d.ts\",\n \"default\": \"./dist/lib/agent.js\"\n }\n },\n \"typesVersions\": {\n \"*\": {\n \".\": [\n \"./dist/types/index.d.ts\"\n ],\n \"bridge-mode\": [\n \"./dist/types/bridge-mode.d.ts\"\n ],\n \"bridge-mode-browser\": [\n \"./dist/types/bridge-mode-browser.d.ts\"\n ],\n \"utils\": [\n \"./dist/types/utils.d.ts\"\n ],\n \"ui-utils\": [\n \"./dist/types/ui-utils.d.ts\"\n ],\n \"puppeteer\": [\n \"./dist/types/puppeteer.d.ts\"\n ],\n \"puppeteer-agent-launcher\": [\n \"./dist/types/puppeteer-agent-launcher.d.ts\"\n ],\n \"playwright\": [\n \"./dist/types/playwright.d.ts\"\n ],\n \"playwright-report\": [\n \"./dist/types/playwright-report.d.ts\"\n ],\n \"playwright-reporter\": [\n \"./dist/types/playwright-reporter.d.ts\"\n ],\n \"playground\": [\n \"./dist/types/playground.d.ts\"\n ],\n \"midscene-playground\": [\n \"./dist/types/midscene-playground.d.ts\"\n ],\n \"midscene-server\": [\n \"./dist/types/midscene-server.d.ts\"\n ],\n \"chrome-extension\": [\n \"./dist/types/chrome-extension.d.ts\"\n ],\n \"yaml\": [\n \"./dist/types/yaml.d.ts\"\n ],\n \"agent\": [\n \"./dist/types/agent.d.ts\"\n ]\n }\n },\n \"watch\": {\n \"build\": {\n \"patterns\": [\n \"src\"\n ],\n \"extensions\": \"tsx,less,scss,css,js,jsx,ts\",\n \"quiet\": false\n }\n },\n \"scripts\": {\n \"dev\": \"npm run build && npx npm-watch\",\n \"dev:server\": \"npm run build && ./bin/midscene-playground\",\n \"build\": \"modern build -c ./modern.config.ts\",\n \"postbuild\": \"node scripts/check-exports.js\",\n \"build:watch\": \"modern build -w -c ./modern.config.ts --no-clear\",\n \"test\": \"vitest --run\",\n \"test:u\": \"vitest --run -u\",\n \"test:ai\": \"AI_TEST_TYPE=web npm run test\",\n \"test:ai:cache\": \"MIDSCENE_CACHE=true npm run test:ai\",\n \"upgrade\": \"modern upgrade\",\n \"e2e\": \"playwright test --config=tests/playwright.config.ts\",\n \"e2e:report\": \"MIDSCENE_REPORT=true playwright test --config=tests/playwright.config.ts\",\n \"e2e:cache\": \"MIDSCENE_CACHE=true playwright test --config=tests/playwright.config.ts\",\n \"e2e:ui\": \"playwright test --config=tests/playwright.config.ts --ui\",\n \"e2e:ui:cache\": \"MIDSCENE_CACHE=true playwright test --config=tests/playwright.config.ts --ui\"\n },\n \"files\": [\n \"static\",\n \"dist\",\n \"iife-script\",\n \"README.md\",\n \"bin\"\n ],\n \"dependencies\": {\n \"@midscene/core\": \"workspace:*\",\n \"@midscene/shared\": \"workspace:*\",\n \"@xmldom/xmldom\": \"0.8.10\",\n \"cors\": \"2.8.5\",\n \"dayjs\": \"^1.11.11\",\n \"devtools-protocol\": \"0.0.1380148\",\n \"dotenv\": \"16.4.5\",\n \"express\": \"^4.21.2\",\n \"fs-extra\": \"11.2.0\",\n \"http-server\": \"14.1.1\",\n \"inquirer\": \"10.1.5\",\n \"js-sha256\": \"0.11.0\",\n \"js-yaml\": \"4.1.0\",\n \"openai\": \"4.81.0\",\n \"semver\": \"7.5.2\",\n \"socket.io\": \"^4.8.1\",\n \"socket.io-client\": \"4.8.1\"\n },\n \"devDependencies\": {\n \"@modern-js/module-tools\": \"2.60.6\",\n \"@playwright/test\": \"^1.44.1\",\n \"@types/chrome\": \"0.0.279\",\n \"@types/cors\": \"2.8.12\",\n \"@types/express\": \"^4.17.21\",\n \"@types/fs-extra\": \"11.0.4\",\n \"@types/http-server\": \"^0.12.4\",\n \"@types/js-yaml\": \"4.0.9\",\n \"@types/node\": \"^18.0.0\",\n \"@types/semver\": \"7.7.0\",\n \"playwright\": \"1.44.1\",\n \"puppeteer\": \"24.2.0\",\n \"typescript\": \"^5.8.3\",\n \"vitest\": \"3.0.5\"\n },\n \"peerDependencies\": {\n \"@playwright/test\": \"^1.44.1\",\n \"playwright\": \"^1.44.1\",\n \"puppeteer\": \">=20.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"@playwright/test\": {\n \"optional\": true\n },\n \"puppeteer\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=18.0.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org\"\n },\n \"license\": \"MIT\"\n}\n","import type {\n DetailedLocateParam,\n MidsceneYamlFlowItem,\n PlanningAction,\n PlanningActionParamInputOrKeyPress,\n PlanningActionParamScroll,\n PlanningActionParamSleep,\n PlanningActionParamTap,\n PlanningLocateParam,\n} from '@midscene/core';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nconst debug = getDebug('plan-builder');\n\nexport function buildPlans(\n type: PlanningAction['type'],\n locateParam?: DetailedLocateParam,\n param?:\n | PlanningActionParamInputOrKeyPress\n | PlanningActionParamScroll\n | PlanningActionParamSleep,\n): PlanningAction[] {\n let returnPlans: PlanningAction[] = [];\n const locatePlan: PlanningAction<PlanningLocateParam> | null = locateParam\n ? {\n type: 'Locate',\n locate: locateParam,\n param: locateParam,\n thought: '',\n }\n : null;\n if (type === 'Tap' || type === 'Hover' || type === 'RightClick') {\n assert(locateParam, `missing locate info for action \"${type}\"`);\n assert(locatePlan, `missing locate info for action \"${type}\"`);\n const tapPlan: PlanningAction<PlanningActionParamTap> = {\n type,\n param: null,\n thought: '',\n locate: locateParam,\n };\n\n returnPlans = [locatePlan, tapPlan];\n }\n if (type === 'Input' || type === 'KeyboardPress') {\n if (type === 'Input') {\n assert(locateParam, `missing locate info for action \"${type}\"`);\n }\n assert(param, `missing param for action \"${type}\"`);\n\n const inputPlan: PlanningAction<PlanningActionParamInputOrKeyPress> = {\n type,\n param: param as PlanningActionParamInputOrKeyPress,\n thought: '',\n locate: locateParam!,\n };\n\n if (locatePlan) {\n returnPlans = [locatePlan, inputPlan];\n } else {\n returnPlans = [inputPlan];\n }\n }\n\n if (type === 'Scroll') {\n assert(param, `missing param for action \"${type}\"`);\n\n const scrollPlan: PlanningAction<PlanningActionParamScroll> = {\n type,\n param: param as PlanningActionParamScroll,\n thought: '',\n locate: locateParam,\n };\n\n if (locatePlan) {\n returnPlans = [locatePlan, scrollPlan];\n } else {\n returnPlans = [scrollPlan];\n }\n }\n\n if (type === 'Sleep') {\n assert(param, `missing param for action \"${type}\"`);\n\n const sleepPlan: PlanningAction<PlanningActionParamSleep> = {\n type,\n param: param as PlanningActionParamSleep,\n thought: '',\n locate: null,\n };\n\n returnPlans = [sleepPlan];\n }\n\n if (type === 'Locate') {\n assert(locateParam, `missing locate info for action \"${type}\"`);\n const locatePlan: PlanningAction<PlanningLocateParam> = {\n type,\n param: locateParam as PlanningLocateParam,\n locate: locateParam,\n thought: '',\n };\n returnPlans = [locatePlan];\n }\n\n if (returnPlans) {\n debug('buildPlans', returnPlans);\n return returnPlans;\n }\n\n throw new Error(`Not supported type: ${type}`);\n}\n","import {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@midscene/shared/constants';\nimport type { Page as PlaywrightPageType } from 'playwright';\nimport type { WebPageOpt } from '../common/agent';\nimport { Page as BasePage } from '../puppeteer/base-page';\n\nexport class WebPage extends BasePage<'playwright', PlaywrightPageType> {\n waitForNavigationTimeout: number;\n waitForNetworkIdleTimeout: number;\n\n constructor(page: PlaywrightPageType, opts?: WebPageOpt) {\n super(page, 'playwright', opts);\n const {\n waitForNavigationTimeout = DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n waitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n } = opts ?? {};\n this.waitForNavigationTimeout = waitForNavigationTimeout;\n this.waitForNetworkIdleTimeout = waitForNetworkIdleTimeout;\n }\n}\n","import type { ElementTreeNode, Point, Size } from '@midscene/core';\nimport { sleep } from '@midscene/core/utils';\nimport { DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT } from '@midscene/shared/constants';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport { treeToList } from '@midscene/shared/extractor';\nimport {\n getElementInfosScriptContent,\n getExtraReturnLogic,\n} from '@midscene/shared/fs';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport type { Page as PuppeteerPage } from 'puppeteer';\nimport type { WebKeyInput } from '../common/page';\nimport type { AbstractPage } from '../page';\nimport type { MouseButton } from '../page';\n\nexport const debugPage = getDebug('web:page');\n\nexport class Page<\n AgentType extends 'puppeteer' | 'playwright',\n PageType extends PuppeteerPage | PlaywrightPage,\n> implements AbstractPage\n{\n underlyingPage: PageType;\n protected waitForNavigationTimeout: number;\n private viewportSize?: Size;\n\n pageType: AgentType;\n\n private async evaluate<R>(\n pageFunction: string | ((...args: any[]) => R | Promise<R>),\n arg?: any,\n ): Promise<R> {\n let result: R;\n debugPage('evaluate function begin');\n if (this.pageType === 'puppeteer') {\n result = await (this.underlyingPage as PuppeteerPage).evaluate(\n pageFunction,\n arg,\n );\n } else {\n result = await (this.underlyingPage as PlaywrightPage).evaluate(\n pageFunction,\n arg,\n );\n }\n debugPage('evaluate function end');\n return result;\n }\n\n constructor(\n underlyingPage: PageType,\n pageType: AgentType,\n opts?: {\n waitForNavigationTimeout?: number;\n },\n ) {\n this.underlyingPage = underlyingPage;\n this.pageType = pageType;\n this.waitForNavigationTimeout =\n opts?.waitForNavigationTimeout ?? DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;\n }\n\n async evaluateJavaScript<T = any>(script: string): Promise<T> {\n return this.evaluate(script);\n }\n\n async waitForNavigation() {\n if (this.waitForNavigationTimeout === 0) {\n debugPage('waitForNavigation timeout is 0, skip waiting');\n return;\n }\n\n // issue: https://github.com/puppeteer/puppeteer/issues/3323\n if (this.pageType === 'puppeteer' || this.pageType === 'playwright') {\n debugPage('waitForNavigation begin');\n debugPage(`waitForNavigation timeout: ${this.waitForNavigationTimeout}`);\n try {\n await (this.underlyingPage as PuppeteerPage).waitForSelector('html', {\n timeout: this.waitForNavigationTimeout,\n });\n } catch (error) {\n // Ignore timeout error, continue execution\n console.warn(\n '[midscene:warning] Waiting for the navigation has timed out, but Midscene will continue execution. Please check https://midscenejs.com/faq.html#customize-the-network-timeout for more information on customizing the network timeout',\n );\n }\n debugPage('waitForNavigation end');\n }\n }\n\n // @deprecated\n async getElementsInfo() {\n // const scripts = await getExtraReturnLogic();\n // const captureElementSnapshot = await this.evaluate(scripts);\n // return captureElementSnapshot as ElementInfo[];\n await this.waitForNavigation();\n debugPage('getElementsInfo begin');\n const tree = await this.getElementsNodeTree();\n debugPage('getElementsInfo end');\n return treeToList(tree);\n }\n\n async getXpathsById(id: string) {\n const elementInfosScriptContent = getElementInfosScriptContent();\n\n return this.evaluateJavaScript(\n `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${id}')`,\n );\n }\n\n async getXpathsByPoint(point: Point, isOrderSensitive: boolean) {\n const elementInfosScriptContent = getElementInfosScriptContent();\n\n return this.evaluateJavaScript(\n `${elementInfosScriptContent}midscene_element_inspector.getXpathsByPoint({left: ${point.left}, top: ${point.top}}, ${isOrderSensitive})`,\n );\n }\n\n async getElementInfoByXpath(xpath: string) {\n const elementInfosScriptContent = getElementInfosScriptContent();\n\n return this.evaluateJavaScript(\n `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpath}')`,\n );\n }\n\n async getElementsNodeTree() {\n // ref: packages/web-integration/src/playwright/ai-fixture.ts popup logic\n // During test execution, a new page might be opened through a connection, and the page remains confined to the same page instance.\n // The page may go through opening, closing, and reopening; if the page is closed, evaluate may return undefined, which can lead to errors.\n await this.waitForNavigation();\n const scripts = await getExtraReturnLogic(true);\n assert(scripts, 'scripts should be set before writing report in browser');\n const startTime = Date.now();\n const captureElementSnapshot = await this.evaluate(scripts);\n const endTime = Date.now();\n debugPage(`getElementsNodeTree end, cost: ${endTime - startTime}ms`);\n return captureElementSnapshot as ElementTreeNode<ElementInfo>;\n }\n\n async size(): Promise<Size> {\n if (this.viewportSize) return this.viewportSize;\n const sizeInfo: Size = await this.evaluate(() => {\n return {\n width: document.documentElement.clientWidth,\n height: document.documentElement.clientHeight,\n dpr: window.devicePixelRatio,\n };\n });\n this.viewportSize = sizeInfo;\n return sizeInfo;\n }\n\n async screenshotBase64(): Promise<string> {\n const imgType = 'jpeg';\n const quality = 90;\n await this.waitForNavigation();\n const startTime = Date.now();\n debugPage('screenshotBase64 begin');\n\n let base64: string;\n if (this.pageType === 'puppeteer') {\n const result = await (this.underlyingPage as PuppeteerPage).screenshot({\n type: imgType,\n quality,\n encoding: 'base64',\n });\n base64 = `data:image/jpeg;base64,${result}`;\n } else if (this.pageType === 'playwright') {\n const buffer = await (this.underlyingPage as PlaywrightPage).screenshot({\n type: imgType,\n quality,\n timeout: 10 * 1000,\n });\n base64 = `data:image/jpeg;base64,${buffer.toString('base64')}`;\n } else {\n throw new Error('Unsupported page type for screenshot');\n }\n const endTime = Date.now();\n debugPage(`screenshotBase64 end, cost: ${endTime - startTime}ms`);\n return base64;\n }\n\n async url(): Promise<string> {\n return this.underlyingPage.url();\n }\n\n get mouse() {\n return {\n click: async (\n x: number,\n y: number,\n options?: { button?: MouseButton; count?: number },\n ) => {\n await this.mouse.move(x, y);\n debugPage(`mouse click ${x}, ${y}`);\n this.underlyingPage.mouse.click(x, y, {\n button: options?.button || 'left',\n count: options?.count || 1,\n });\n },\n wheel: async (deltaX: number, deltaY: number) => {\n debugPage(`mouse wheel ${deltaX}, ${deltaY}`);\n if (this.pageType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).mouse.wheel({\n deltaX,\n deltaY,\n });\n } else if (this.pageType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).mouse.wheel(\n deltaX,\n deltaY,\n );\n }\n },\n move: async (x: number, y: number) => {\n this.everMoved = true;\n debugPage(`mouse move to ${x}, ${y}`);\n return this.underlyingPage.mouse.move(x, y);\n },\n drag: async (\n from: { x: number; y: number },\n to: { x: number; y: number },\n ) => {\n debugPage(`mouse drag from ${from.x}, ${from.y} to ${to.x}, ${to.y}`);\n if (this.pageType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).mouse.drag(\n {\n x: from.x,\n y: from.y,\n },\n {\n x: to.x,\n y: to.y,\n },\n );\n } else if (this.pageType === 'playwright') {\n // Playwright doesn't have a drag method, so we need to simulate it\n await (this.underlyingPage as PlaywrightPage).mouse.move(\n from.x,\n from.y,\n );\n await (this.underlyingPage as PlaywrightPage).mouse.down();\n await (this.underlyingPage as PlaywrightPage).mouse.move(to.x, to.y);\n await (this.underlyingPage as PlaywrightPage).mouse.up();\n }\n },\n };\n }\n\n get keyboard() {\n return {\n type: async (text: string) => {\n debugPage(`keyboard type ${text}`);\n return this.underlyingPage.keyboard.type(text, { delay: 80 });\n },\n press: async (\n action:\n | { key: WebKeyInput; command?: string }\n | { key: WebKeyInput; command?: string }[],\n ) => {\n const keys = Array.isArray(action) ? action : [action];\n debugPage('keyboard press', keys);\n for (const k of keys) {\n const commands = k.command ? [k.command] : [];\n await this.underlyingPage.keyboard.down(k.key, { commands });\n }\n for (const k of [...keys].reverse()) {\n await this.underlyingPage.keyboard.up(k.key);\n }\n },\n down: async (key: WebKeyInput) => {\n debugPage(`keyboard down ${key}`);\n this.underlyingPage.keyboard.down(key);\n },\n up: async (key: WebKeyInput) => {\n debugPage(`keyboard up ${key}`);\n this.underlyingPage.keyboard.up(key);\n },\n };\n }\n\n async clearInput(element: ElementInfo): Promise<void> {\n if (!element) {\n console.warn('No element to clear input');\n return;\n }\n\n const backspace = async () => {\n await sleep(100);\n await this.keyboard.press([{ key: 'Backspace' }]);\n };\n\n const isMac = process.platform === 'darwin';\n debugPage('clearInput begin');\n if (isMac) {\n if (this.pageType === 'puppeteer') {\n // https://github.com/segment-boneyard/nightmare/issues/810#issuecomment-452669866\n await this.mouse.click(element.center[0], element.center[1], {\n count: 3,\n });\n await backspace();\n }\n\n await this.mouse.click(element.center[0], element.center[1]);\n await this.underlyingPage.keyboard.down('Meta');\n await this.underlyingPage.keyboard.press('a');\n await this.underlyingPage.keyboard.up('Meta');\n await backspace();\n } else {\n await this.mouse.click(element.center[0], element.center[1]);\n await this.underlyingPage.keyboard.down('Control');\n await this.underlyingPage.keyboard.press('a');\n await this.underlyingPage.keyboard.up('Control');\n await backspace();\n }\n debugPage('clearInput end');\n }\n\n private everMoved = false;\n private async moveToPointBeforeScroll(point?: Point): Promise<void> {\n if (point) {\n await this.mouse.move(point.left, point.top);\n } else if (!this.everMoved) {\n // If the mouse has never moved, move it to the center of the page\n const size = await this.size();\n const targetX = Math.floor(size.width / 2);\n const targetY = Math.floor(size.height / 2);\n await this.mouse.move(targetX, targetY);\n }\n }\n\n async scrollUntilTop(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, -9999999);\n }\n\n async scrollUntilBottom(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, 9999999);\n }\n\n async scrollUntilLeft(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(-9999999, 0);\n }\n\n async scrollUntilRight(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(9999999, 0);\n }\n\n async scrollUp(distance?: number, startingPoint?: Point): Promise<void> {\n const innerHeight = await this.evaluate(() => window.innerHeight);\n const scrollDistance = distance || innerHeight * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, -scrollDistance);\n }\n\n async scrollDown(distance?: number, startingPoint?: Point): Promise<void> {\n const innerHeight = await this.evaluate(() => window.innerHeight);\n const scrollDistance = distance || innerHeight * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, scrollDistance);\n }\n\n async scrollLeft(distance?: number, startingPoint?: Point): Promise<void> {\n const innerWidth = await this.evaluate(() => window.innerWidth);\n const scrollDistance = distance || innerWidth * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(-scrollDistance, 0);\n }\n\n async scrollRight(distance?: number, startingPoint?: Point): Promise<void> {\n const innerWidth = await this.evaluate(() => window.innerWidth);\n const scrollDistance = distance || innerWidth * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(scrollDistance, 0);\n }\n\n async navigate(url: string): Promise<void> {\n debugPage(`navigate to ${url}`);\n if (this.pageType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).goto(url);\n } else if (this.pageType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).goto(url);\n } else {\n throw new Error('Unsupported page type for navigate');\n }\n }\n\n async destroy(): Promise<void> {}\n}\n","import { randomUUID } from 'node:crypto';\nimport type { PageAgent, PageAgentOpt, WebPageAgentOpt } from '@/common/agent';\nimport { replaceIllegalPathCharsAndSpace } from '@/common/utils';\nimport { PlaywrightAgent } from '@/playwright/index';\nimport type { AgentWaitForOpt } from '@midscene/core';\nimport {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@midscene/shared/constants';\nimport { getDebug } from '@midscene/shared/logger';\nimport { type TestInfo, type TestType, test } from '@playwright/test';\nimport type { Page as OriginPlaywrightPage } from 'playwright';\nexport type APITestType = Pick<TestType<any, any>, 'step'>;\n\nconst debugPage = getDebug('web:playwright:ai-fixture');\n\nconst groupAndCaseForTest = (testInfo: TestInfo) => {\n let taskFile: string;\n let taskTitle: string;\n const titlePath = [...testInfo.titlePath];\n\n if (titlePath.length > 1) {\n taskFile = titlePath.shift() || 'unnamed';\n taskTitle = titlePath.join('__');\n } else if (titlePath.length === 1) {\n taskTitle = titlePath[0];\n taskFile = `${taskTitle}`;\n } else {\n taskTitle = 'unnamed';\n taskFile = 'unnamed';\n }\n\n const taskTitleWithRetry = `${taskTitle}${testInfo.retry ? `(retry #${testInfo.retry})` : ''}`;\n\n return {\n file: taskFile,\n id: replaceIllegalPathCharsAndSpace(`${taskFile}(${taskTitle})`),\n title: replaceIllegalPathCharsAndSpace(taskTitleWithRetry),\n };\n};\n\nconst midsceneAgentKeyId = '_midsceneAgentId';\nexport const midsceneDumpAnnotationId = 'MIDSCENE_DUMP_ANNOTATION';\n\nexport const PlaywrightAiFixture = (options?: {\n forceSameTabNavigation?: boolean;\n waitForNetworkIdleTimeout?: number;\n waitForNavigationTimeout?: number;\n}) => {\n const {\n forceSameTabNavigation = true,\n waitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n waitForNavigationTimeout = DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n } = options ?? {};\n const pageAgentMap: Record<string, PageAgent> = {};\n const createOrReuseAgentForPage = (\n page: OriginPlaywrightPage,\n testInfo: TestInfo, // { testId: string; taskFile: string; taskTitle: string },\n opts?: WebPageAgentOpt,\n ) => {\n let idForPage = (page as any)[midsceneAgentKeyId];\n if (!idForPage) {\n idForPage = randomUUID();\n (page as any)[midsceneAgentKeyId] = idForPage;\n const { testId } = testInfo;\n const { file, id, title } = groupAndCaseForTest(testInfo);\n pageAgentMap[idForPage] = new PlaywrightAgent(page, {\n testId: `playwright-${testId}-${idForPage}`,\n forceSameTabNavigation,\n cacheId: id,\n groupName: title,\n groupDescription: file,\n generateReport: false, // we will generate it in the reporter\n ...opts,\n });\n\n pageAgentMap[idForPage].onDumpUpdate = (dump: string) => {\n updateDumpAnnotation(testInfo, dump);\n };\n\n page.on('close', () => {\n debugPage('page closed');\n pageAgentMap[idForPage].destroy();\n delete pageAgentMap[idForPage];\n });\n }\n\n return pageAgentMap[idForPage];\n };\n\n async function generateAiFunction(options: {\n page: OriginPlaywrightPage;\n testInfo: TestInfo;\n use: any;\n aiActionType:\n | 'ai'\n | 'aiAction'\n | 'aiHover'\n | 'aiInput'\n | 'aiKeyboardPress'\n | 'aiScroll'\n | 'aiTap'\n | 'aiRightClick'\n | 'aiQuery'\n | 'aiAssert'\n | 'aiWaitFor'\n | 'aiLocate'\n | 'aiNumber'\n | 'aiString'\n | 'aiBoolean'\n | 'aiAsk'\n | 'runYaml'\n | 'setAIActionContext'\n | 'evaluateJavaScript'\n | 'logScreenshot'\n | 'freezePageContext'\n | 'unfreezePageContext';\n }) {\n const { page, testInfo, use, aiActionType } = options;\n const agent = createOrReuseAgentForPage(page, testInfo, {\n waitForNavigationTimeout,\n waitForNetworkIdleTimeout,\n }) as PlaywrightAgent;\n\n await use(async (taskPrompt: string, ...args: any[]) => {\n return new Promise((resolve, reject) => {\n test.step(`ai-${aiActionType} - ${JSON.stringify(taskPrompt)}`, async () => {\n try {\n debugPage(\n `waitForNetworkIdle timeout: ${waitForNetworkIdleTimeout}`,\n );\n await agent.waitForNetworkIdle(waitForNetworkIdleTimeout);\n } catch (error) {\n console.warn(\n '[midscene:warning] Waiting for network idle has timed out, but Midscene will continue execution. Please check https://midscenejs.com/faq.html#customize-the-network-timeout for more information on customizing the network timeout',\n );\n }\n try {\n type AgentMethod = (\n prompt: string,\n ...restArgs: any[]\n ) => Promise<any>;\n const result = await (agent[aiActionType] as AgentMethod)(\n taskPrompt,\n ...(args || []),\n );\n resolve(result);\n } catch (error) {\n reject(error);\n }\n });\n });\n });\n }\n\n const updateDumpAnnotation = (test: TestInfo, dump: string) => {\n const currentAnnotation = test.annotations.find((item) => {\n return item.type === midsceneDumpAnnotationId;\n });\n if (currentAnnotation) {\n currentAnnotation.description = dump;\n } else {\n test.annotations.push({\n type: midsceneDumpAnnotationId,\n description: dump,\n });\n }\n };\n\n return {\n agentForPage: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await use(\n async (\n propsPage?: OriginPlaywrightPage | undefined,\n opts?: PageAgentOpt,\n ) => {\n const agent = createOrReuseAgentForPage(propsPage || page, testInfo, {\n waitForNavigationTimeout,\n waitForNetworkIdleTimeout,\n ...opts,\n });\n return agent;\n },\n );\n },\n ai: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'ai',\n });\n },\n aiAction: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAction',\n });\n },\n aiTap: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiTap',\n });\n },\n aiRightClick: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiRightClick',\n });\n },\n aiHover: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiHover',\n });\n },\n aiInput: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiInput',\n });\n },\n aiKeyboardPress: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiKeyboardPress',\n });\n },\n aiScroll: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiScroll',\n });\n },\n aiQuery: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiQuery',\n });\n },\n aiAssert: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAssert',\n });\n },\n aiWaitFor: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiWaitFor',\n });\n },\n aiLocate: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiLocate',\n });\n },\n aiNumber: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiNumber',\n });\n },\n aiString: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiString',\n });\n },\n aiBoolean: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiBoolean',\n });\n },\n aiAsk: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAsk',\n });\n },\n runYaml: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'runYaml',\n });\n },\n setAIActionContext: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'setAIActionContext',\n });\n },\n evaluateJavaScript: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'evaluateJavaScript',\n });\n },\n logScreenshot: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'logScreenshot',\n });\n },\n freezePageContext: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'freezePageContext',\n });\n },\n unfreezePageContext: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'unfreezePageContext',\n });\n },\n };\n};\n\nexport type PlayWrightAiFixtureType = {\n agentForPage: (page?: any, opts?: any) => Promise<PageAgent>;\n ai: <T = any>(prompt: string) => Promise<T>;\n aiAction: (taskPrompt: string) => ReturnType<PageAgent['aiAction']>;\n aiTap: (\n ...args: Parameters<PageAgent['aiTap']>\n ) => ReturnType<PageAgent['aiTap']>;\n aiRightClick: (\n ...args: Parameters<PageAgent['aiRightClick']>\n ) => ReturnType<PageAgent['aiRightClick']>;\n aiHover: (\n ...args: Parameters<PageAgent['aiHover']>\n ) => ReturnType<PageAgent['aiHover']>;\n aiInput: (\n ...args: Parameters<PageAgent['aiInput']>\n ) => ReturnType<PageAgent['aiInput']>;\n aiKeyboardPress: (\n ...args: Parameters<PageAgent['aiKeyboardPress']>\n ) => ReturnType<PageAgent['aiKeyboardPress']>;\n aiScroll: (\n ...args: Parameters<PageAgent['aiScroll']>\n ) => ReturnType<PageAgent['aiScroll']>;\n aiQuery: <T = any>(\n ...args: Parameters<PageAgent['aiQuery']>\n ) => ReturnType<PageAgent['aiQuery']>;\n aiAssert: (\n ...args: Parameters<PageAgent['aiAssert']>\n ) => ReturnType<PageAgent['aiAssert']>;\n aiWaitFor: (assertion: string, opt?: AgentWaitForOpt) => Promise<void>;\n aiLocate: (\n ...args: Parameters<PageAgent['aiLocate']>\n ) => ReturnType<PageAgent['aiLocate']>;\n aiNumber: (\n ...args: Parameters<PageAgent['aiNumber']>\n ) => ReturnType<PageAgent['aiNumber']>;\n aiString: (\n ...args: Parameters<PageAgent['aiString']>\n ) => ReturnType<PageAgent['aiString']>;\n aiBoolean: (\n ...args: Parameters<PageAgent['aiBoolean']>\n ) => ReturnType<PageAgent['aiBoolean']>;\n aiAsk: (\n ...args: Parameters<PageAgent['aiAsk']>\n ) => ReturnType<PageAgent['aiAsk']>;\n runYaml: (\n ...args: Parameters<PageAgent['runYaml']>\n ) => ReturnType<PageAgent['runYaml']>;\n setAIActionContext: (\n ...args: Parameters<PageAgent['setAIActionContext']>\n ) => ReturnType<PageAgent['setAIActionContext']>;\n evaluateJavaScript: (\n ...args: Parameters<PageAgent['evaluateJavaScript']>\n ) => ReturnType<PageAgent['evaluateJavaScript']>;\n logScreenshot: (\n ...args: Parameters<PageAgent['logScreenshot']>\n ) => ReturnType<PageAgent['logScreenshot']>;\n freezePageContext: (\n ...args: Parameters<PageAgent['freezePageContext']>\n ) => ReturnType<PageAgent['freezePageContext']>;\n unfreezePageContext: (\n ...args: Parameters<PageAgent['unfreezePageContext']>\n ) => ReturnType<PageAgent['unfreezePageContext']>;\n};\n","import { PageAgent, type WebPageAgentOpt } from '@/common/agent';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport { WebPage as PlaywrightWebPage } from './page';\n\nexport type { PlayWrightAiFixtureType } from './ai-fixture';\nexport { PlaywrightAiFixture } from './ai-fixture';\nexport { overrideAIConfig } from '@midscene/shared/env';\nexport { WebPage as PlaywrightWebPage } from './page';\nimport { forceClosePopup } from '@/common/utils';\nimport { getDebug } from '@midscene/shared/logger';\n\nconst debug = getDebug('playwright:agent');\n\nexport class PlaywrightAgent extends PageAgent<PlaywrightWebPage> {\n constructor(page: PlaywrightPage, opts?: WebPageAgentOpt) {\n const webPage = new PlaywrightWebPage(page, opts);\n super(webPage, opts);\n\n const { forceSameTabNavigation = true } = opts ?? {};\n\n if (forceSameTabNavigation) {\n forceClosePopup(page, debug);\n }\n }\n\n async waitForNetworkIdle(timeout = 1000) {\n await this.page.underlyingPage.waitForLoadState('networkidle', { timeout });\n }\n}\n","import { PageAgent, type WebPageAgentOpt } from '@/common/agent';\nimport { forceClosePopup } from '@/common/utils';\nimport { getDebug } from '@midscene/shared/logger';\nimport type { Page as PuppeteerPage } from 'puppeteer';\nimport type { AndroidDeviceInputOpt } from '../common/page';\nimport { WebPage as PuppeteerWebPage } from './page';\n\nconst debug = getDebug('puppeteer:agent');\n\nexport { WebPage as PuppeteerWebPage } from './page';\nexport type { AndroidDeviceInputOpt };\n\nexport class PuppeteerAgent extends PageAgent<PuppeteerWebPage> {\n constructor(page: PuppeteerPage, opts?: WebPageAgentOpt) {\n const webPage = new PuppeteerWebPage(page, opts);\n super(webPage, opts);\n\n const { forceSameTabNavigation = true } = opts ?? {};\n\n if (forceSameTabNavigation) {\n forceClosePopup(page, debug);\n }\n }\n}\n\nexport { overrideAIConfig } from '@midscene/shared/env';\n\n// Do NOT export this since it requires puppeteer\n// export { puppeteerAgentForTarget } from './agent-launcher';\n","import {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@midscene/shared/constants';\nimport type { Page as PuppeteerPageType } from 'puppeteer';\nimport type { WebPageOpt } from '../common/agent';\nimport { Page as BasePage, debugPage } from './base-page';\n\nexport class WebPage extends BasePage<'puppeteer', PuppeteerPageType> {\n waitForNavigationTimeout: number;\n waitForNetworkIdleTimeout: number;\n\n constructor(page: PuppeteerPageType, opts?: WebPageOpt) {\n super(page, 'puppeteer', opts);\n const {\n waitForNavigationTimeout = DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n waitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n } = opts ?? {};\n this.waitForNavigationTimeout = waitForNavigationTimeout;\n this.waitForNetworkIdleTimeout = waitForNetworkIdleTimeout;\n }\n\n async waitUntilNetworkIdle(options?: {\n idleTime?: number;\n concurrency?: number;\n timeout?: number;\n }): Promise<void> {\n if (this.waitForNetworkIdleTimeout === 0) {\n debugPage('waitUntilNetworkIdle timeout is 0, skip waiting');\n return;\n }\n await this.underlyingPage.waitForNetworkIdle({\n idleTime: options?.idleTime ?? this.waitForNetworkIdleTimeout,\n concurrency:\n options?.concurrency ?? DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY,\n timeout: options?.timeout ?? this.waitForNetworkIdleTimeout,\n });\n }\n}\n","import { PageAgent } from '@/common/agent';\nimport type StaticPage from './static-page';\n\nexport class StaticPageAgent extends PageAgent {\n constructor(page: StaticPage) {\n super(page, {});\n this.dryMode = true;\n }\n}\n"]}
|