patreon-dl 3.7.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +29 -1
  2. package/dist/browse/api/CampaignAPIMixin.d.ts +1 -1
  3. package/dist/browse/api/ContentAPIMixin.d.ts +3 -3
  4. package/dist/browse/api/FilterAPIMixin.d.ts +1 -1
  5. package/dist/browse/api/index.d.ts +10 -10
  6. package/dist/browse/db/CampaignDBMixin.d.ts +3 -3
  7. package/dist/browse/db/ContentDBMixin.d.ts +13 -13
  8. package/dist/browse/db/index.d.ts +16 -16
  9. package/dist/browse/web/assets/index-CQnQD2xz.css +1 -0
  10. package/dist/browse/web/assets/index-CtZbx-Du.js +218 -0
  11. package/dist/browse/web/index.html +2 -2
  12. package/dist/cli/CLIOptions.js +2 -0
  13. package/dist/cli/CLIOptions.js.map +1 -1
  14. package/dist/cli/CommandLineParser.d.ts +4 -0
  15. package/dist/cli/CommandLineParser.js +65 -32
  16. package/dist/cli/CommandLineParser.js.map +1 -1
  17. package/dist/cli/ConfigFileParser.js +2 -0
  18. package/dist/cli/ConfigFileParser.js.map +1 -1
  19. package/dist/cli/helper/PostList.d.ts +6 -0
  20. package/dist/cli/helper/PostList.js +106 -0
  21. package/dist/cli/helper/PostList.js.map +1 -0
  22. package/dist/cli/index.js +73 -53
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/downloaders/Bootstrap.d.ts +5 -0
  25. package/dist/downloaders/Bootstrap.js +10 -0
  26. package/dist/downloaders/Bootstrap.js.map +1 -1
  27. package/dist/downloaders/Downloader.d.ts +4 -4
  28. package/dist/downloaders/Downloader.js +5 -58
  29. package/dist/downloaders/Downloader.js.map +1 -1
  30. package/dist/downloaders/DownloaderOptions.d.ts +1 -0
  31. package/dist/downloaders/DownloaderOptions.js +2 -0
  32. package/dist/downloaders/DownloaderOptions.js.map +1 -1
  33. package/dist/downloaders/IncludeCriteriaHelper.d.ts +25 -0
  34. package/dist/downloaders/IncludeCriteriaHelper.js +160 -0
  35. package/dist/downloaders/IncludeCriteriaHelper.js.map +1 -0
  36. package/dist/downloaders/InitialData.js +20 -6
  37. package/dist/downloaders/InitialData.js.map +1 -1
  38. package/dist/downloaders/PostDownloader.js +62 -98
  39. package/dist/downloaders/PostDownloader.js.map +1 -1
  40. package/dist/downloaders/PostsFetcher.js +4 -2
  41. package/dist/downloaders/PostsFetcher.js.map +1 -1
  42. package/dist/downloaders/ProductDownloader.js +31 -21
  43. package/dist/downloaders/ProductDownloader.js.map +1 -1
  44. package/dist/downloaders/task/M3U8DownloadTask.d.ts +1 -0
  45. package/dist/downloaders/task/M3U8DownloadTask.js +137 -39
  46. package/dist/downloaders/task/M3U8DownloadTask.js.map +1 -1
  47. package/dist/downloaders/task/YouTubeDownloadTask.js +1 -3
  48. package/dist/downloaders/task/YouTubeDownloadTask.js.map +1 -1
  49. package/dist/parsers/PageParser.js +8 -3
  50. package/dist/parsers/PageParser.js.map +1 -1
  51. package/dist/utils/Fetcher.d.ts +4 -1
  52. package/dist/utils/Fetcher.js +6 -1
  53. package/dist/utils/Fetcher.js.map +1 -1
  54. package/dist/utils/URLHelper.d.ts +4 -0
  55. package/dist/utils/URLHelper.js +17 -0
  56. package/dist/utils/URLHelper.js.map +1 -1
  57. package/dist/utils/YouTubeCredentialsCapturer.js +1 -1
  58. package/dist/utils/YouTubeCredentialsCapturer.js.map +1 -1
  59. package/dist/utils/logging/ConsoleLogger.js +5 -0
  60. package/dist/utils/logging/ConsoleLogger.js.map +1 -1
  61. package/dist/utils/yt/InnertubeLoader.d.ts +4 -6
  62. package/dist/utils/yt/InnertubeLoader.js +14 -14
  63. package/dist/utils/yt/InnertubeLoader.js.map +1 -1
  64. package/dist/utils/yt/PoToken.js +53 -27
  65. package/dist/utils/yt/PoToken.js.map +1 -1
  66. package/package.json +12 -8
  67. package/dist/browse/web/assets/index-CW4CUoWl.css +0 -1
  68. package/dist/browse/web/assets/index-CziUWlSw.js +0 -218
@@ -1 +1 @@
1
- {"version":3,"file":"PostDownloader.js","sourceRoot":"","sources":["../../src/downloaders/PostDownloader.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,SAAS,MAAM,uBAAuB,CAAC;AAC9C,OAAO,UAAiE,MAAM,iBAAiB,CAAC;AAChG,OAAO,UAAU,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAqB,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAChF,OAAO,WAAgD,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACxF,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,mBAAmB,MAAM,+BAA+B,CAAC;AAChE,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAC7C,OAAO,aAAa,MAAM,6BAA6B,CAAC;AAExD,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAQzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAQ1E,MAAqB,cAAe,SAAQ,UAAgB;IAS1D,YACE,MAA8B,EAC9B,EAA6B,EAC7B,MAAsB,EACtB,OAA+B;QAE/B,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;;QAX5B,SAAI,GAAG,gBAAgB,CAAC;QAExB,uCAAsC,IAAI,EAAC;QAC3C,0CAA8C;QAS5C,uBAAA,IAAI,2BAAY;YACd,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,IAAI,KAAK;YACpD,cAAc,EAAE,OAAO,EAAE,cAAc,IAAI,KAAK;YAChD,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,KAAK;SACzC,MAAA,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,MAA8B;QACpC,IAAI,uBAAA,IAAI,oCAAc,EAAE,CAAC;YACvB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC5C,CAAC;QACD,uBAAA,IAAI,gCAAiB,uBAAA,IAAI,0DAAS,MAAb,IAAI,EAAU,MAAM,CAAC;aACvC,OAAO,CAAC,GAAG,EAAE;YACZ,uBAAA,IAAI,gCAAiB,IAAI,MAAA,CAAC;QAC5B,CAAC,CAAC,MAAA,CAAC;QACL,OAAO,uBAAA,IAAI,oCAAc,CAAC;IAC5B,CAAC;IAklBD,KAAK,CAAC,aAAa,CAAC,MAAoB;QACtC,IAAI,GAAkB,CAAC;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QACxC,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,KAAK,QAAQ;gBACX,GAAG,GAAG,SAAS,CAAC,wBAAwB,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;gBACvE,MAAM;YACR,KAAK,UAAU;gBACb,GAAG,GAAG,SAAS,CAAC,wBAAwB,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;gBACvE,MAAM;YACR;gBACE,GAAG,GAAG,IAAI,CAAC;QACf,CAAC;QACD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;YACpC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM;SACP,CAAC,CAAC;QACH,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAC9D,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACjD,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACd,MAAM,GAAG,CAAC,KAAK,CAAC;QAClB,CAAC;QACD,OAAO,WAAW,CAAC,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;;4JAhnBD,KAAK,kCAAU,MAA8B;IAC3C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QACxC,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,EAAE,EAAE,CAAC;QAE3B,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,uBAAuB,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QAC/D,CAAC;aACI,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,4BAA4B,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QACnE,CAAC;aACI,IAAI,SAAS,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAC3C,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,kCAAkC,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC;QAC/E,CAAC;aACI,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,qCAAqC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC;QAC/E,CAAC;aACI,CAAC,CAAC,SAAS;YACd,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,uBAAA,IAAI,0EAAyB,MAA7B,IAAI,EAA0B,SAAS,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YAClE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAE,GAAG,EAAE,KAAK,CAAE,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1G,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,SAAS,EAAE,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;QAED,gDAAgD;QAChD,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;YACpC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM;SACP,CAAC,CAAC;QACH,YAAY,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAC,OAAO,EAAC,EAAE,EAAE;YAC5C,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,UAAU,EAAE,YAAY,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC,CAAC,CAAC;QACH,YAAY,CAAC,KAAK,EAAE,CAAC;QAErB,8CAA8C;QAC9C,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,iBAAiB,GAAG,CAAC,CAAC;QAC1B,IAAI,gBAAgB,GAAG,CAAC,CAAC;QACzB,IAAI,6BAA6B,GAAG,CAAC,CAAC;QACtC,IAAI,gBAAgB,GAAG,CAAC,CAAC;QACzB,IAAI,4BAA4B,GAAG,CAAC,CAAC;QACrC,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,IAAI,gBAAgB,GAAG,KAAK,CAAC;QAC7B,MAAM,kBAAkB,GAAa,EAAE,CAAC;QACxC,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChD,OAAO,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;YAC9B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;YAC3D,IAAI,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC;gBACrB,MAAM;YACR,CAAC;YACD,IAAI,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC;gBACnB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;gBAC3E,OAAO;YACT,CAAC;YACD,IAAI,CAAC,uBAAA,IAAI,+BAAS,CAAC,gBAAgB,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;gBACjF,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAC5D,aAAa,GAAG,IAAI,CAAC;gBACrB,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;oBAClC,OAAO;gBACT,CAAC;YACH,CAAC;YAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAE/B,IAAI,gBAAgB,EAAE,CAAC;oBACrB,MAAM;gBACR,CAAC;gBAED,IAAI,IAAI,GAAG,KAAK,CAAC;gBAEjB,cAAc;gBACd,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACtC,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBAC1C,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;4BAChD,IAAI,CAAC;gCACH,MAAM,uBAAA,IAAI,iEAAgB,MAApB,IAAI,EAAiB,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gCACtD,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;4BACzC,CAAC;4BACD,OAAO,KAAK,EAAE,CAAC;gCACb,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,8BAA8B,UAAU,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;4BAC3E,CAAC;wBACH,CAAC;6BACI,CAAC;4BACJ,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,UAAU,CAAC,EAAE,oBAAoB,CAAC,CAAC;wBACtE,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,uBAAA,IAAI,0EAAyB,MAA7B,IAAI,EAA0B,SAAS,CAAC,EAAE,CAAC;oBAC7C,iDAAiD;oBACjD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,iBAAiB,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC/C,MAAM,OAAO,GAAG,SAAS,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;oBACrE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;oBAC5D,IAAI,SAAS,GAAgB,IAAI,CAAC;oBAClC,IAAI,IAAI,EAAE,CAAC;wBACT,SAAS,GAAG,WAAW,CAAC,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;wBAC9E,IAAI,CAAC,SAAS,EAAE,CAAC;4BACf,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,KAAK,CAAC,EAAE,mDAAmD,CAAC,CAAC;wBACnG,CAAC;6BACI,IAAI,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,EAAE,CAAC;4BACnC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,KAAK,CAAC,EAAE,+CAA+C,CAAC,CAAC;4BAC7F,SAAS,GAAG,IAAI,CAAC;wBACnB,CAAC;oBACH,CAAC;yBACI,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;wBACvC,OAAO;oBACT,CAAC;yBACI,CAAC;wBACJ,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,2BAA2B,KAAK,CAAC,EAAE,+BAA+B,CAAC,CAAC;oBACvF,CAAC;oBACD,IAAI,SAAS,EAAE,CAAC;wBACd,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,4BAA4B,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;wBAC9D,IAAI,GAAG,SAAS,CAAC;oBACnB,CAAC;gBACH,CAAC;gBAED,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBAE3C,6BAA6B;gBAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBACjD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,mBAAmB,EAAE,QAAQ,CAAC,CAAC;gBAEjD,oCAAoC;gBACpC,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC5F,MAAM,qBAAqB,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;gBACpF,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,CAAC;oBACvC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,6BAA6B,IAAI,CAAC,EAAE,kEAAkE,CAAC,CAAC;oBACzH,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;wBACrB,MAAM,EAAE,IAAI;wBACZ,SAAS,EAAE,IAAI;wBACf,UAAU,EAAE,gBAAgB,CAAC,iBAAiB;wBAC9C,WAAW,EAAE,uEAAuE;qBACrF,CAAC,CAAC;oBACH,gBAAgB,EAAE,CAAC;oBACnB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,0BAA0B;wBACnD,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,sBAAsB,EAC7C,CAAC;wBACD,gBAAgB,GAAG,IAAI,CAAC;oBAC1B,CAAC;oBACD,SAAS;gBACX,CAAC;gBAED,QAAQ,CAAC,MAAM,uBAAA,IAAI,6DAAY,MAAhB,IAAI,EACjB,IAAI,EACJ,QAAQ,EACR,qBAAqB,CAAC,KAAK,EAC3B,WAAW,EACX,EAAE,EACF,MAAM,CACP,CAAC,CAAC,MAAM,EAAE,CAAC;oBACV,KAAK,SAAS;wBACZ,OAAO;oBACT,KAAK,YAAY;wBACf,UAAU,EAAE,CAAC;wBACb,MAAM;oBACR,KAAK,kBAAkB;wBACrB,gBAAgB,EAAE,CAAC;wBACnB,MAAM;oBACR,KAAK,8BAA8B;wBACjC,4BAA4B,EAAE,CAAC;wBAC/B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,2BAA2B;4BACpD,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,uBAAuB,EAC9C,CAAC;4BACD,gBAAgB,GAAG,IAAI,CAAC;wBAC1B,CAAC;wBACD,MAAM;oBACR,KAAK,+BAA+B;wBAClC,6BAA6B,EAAE,CAAC;wBAChC,MAAM;oBACR,KAAK,mBAAmB;wBACtB,iBAAiB,EAAE,CAAC;wBACpB,MAAM;gBACV,CAAC;gBAED,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;oBAClC,OAAO;gBACT,CAAC;YACH,CAAC;YAED,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,IAAI,gBAAgB,IAAI,uBAAA,IAAI,0EAAyB,MAA7B,IAAI,EAA0B,SAAS,CAAC,EAAE,CAAC;YACjE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,oCAAoC,IAAI,CAAC,MAAM,CAAC,MAAM,OAAO,CAAC,CAAA;QACjF,CAAC;QAED,OAAO;QACP,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,8BAA8B,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QACtE,CAAC;aACI,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mCAAmC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1E,CAAC;aACI,IAAI,SAAS,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAC3C,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,yCAAyC,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC;QACtF,CAAC;aACI,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mCAAmC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC;QAC7E,CAAC;aACI,CAAC;YACJ,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,0BAA0B,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,UAAU,GAAG,MAAM,CAAC;QACxB,IAAI,uBAAA,IAAI,0EAAyB,MAA7B,IAAI,EAA0B,SAAS,CAAC,EAAE,CAAC;YAC7C,MAAM,eAAe,GAAa,EAAE,CAAC;YACrC,IAAI,iBAAiB,EAAE,CAAC;gBACtB,eAAe,CAAC,IAAI,CAAC,GAAG,iBAAiB,aAAa,CAAC,CAAC;YAC1D,CAAC;YACD,IAAI,gBAAgB,EAAE,CAAC;gBACrB,eAAe,CAAC,IAAI,CAAC,GAAG,gBAAgB,YAAY,CAAC,CAAC;YACxD,CAAC;YACD,IAAI,6BAA6B,EAAE,CAAC;gBAClC,eAAe,CAAC,IAAI,CAAC,GAAG,6BAA6B,iCAAiC,CAAC,CAAC;YAC1F,CAAC;YACD,IAAI,gBAAgB,EAAE,CAAC;gBACrB,eAAe,CAAC,IAAI,CAAC,GAAG,gBAAgB,cAAc,CAAC,CAAC;YAC1D,CAAC;YACD,IAAI,4BAA4B,EAAE,CAAC;gBACjC,eAAe,CAAC,IAAI,CAAC,GAAG,4BAA4B,iCAAiC,CAAC,CAAC;YACzF,CAAC;YACD,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjG,UAAU,GAAG,SAAS,UAAU,MAAM,YAAY,CAAC,QAAQ,EAAE,mBAAmB,UAAU,EAAE,CAAC;YAC7F,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5D,CAAC;YACO,CAAC;QACP,IAAI,CAAC,uBAAA,IAAI,+BAAS,CAAC,UAAU,EAAE,CAAC;YAC9B,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,uBAAA,IAAI,+BAAS,CAAC,cAAc,EAAE,CAAC;YACjD,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;AACH,CAAC,+BAED,KAAK,qCACH,IAAU,EACV,QAAyB,EACzB,KAAuC,EACvC,WAAwB,EACxB,EAAc,EACd,MAAoB;IAEpB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IAE9D,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,gBAAgB,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAEpD,gDAAgD;IAChD,qBAAqB;IACrB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YACtC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,EAAE,kCAAkC,CAAC,CAAC;QACvE,CAAC;aACI,CAAC;YACJ,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,6BAA6B,IAAI,CAAC,EAAE,gCAAgC,CAAC,CAAC;YACvF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBACrB,MAAM,EAAE,IAAI;gBACZ,SAAS,EAAE,IAAI;gBACf,UAAU,EAAE,gBAAgB,CAAC,YAAY;gBACzC,WAAW,EAAE,wCAAwC;aACtD,CAAC,CAAC;YACH,OAAO;gBACL,MAAM,EAAE,mBAAmB;aAC5B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,oDAAoD;IACpD,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC;IAClE,IAAI,kBAAkB,KAAK,KAAK,EAAE,CAAC;QACjC,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3I,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAA;QAE7C,IAAI,IAAI,GAAG,KAAK,CAAC;QACjB,IAAI,kBAAkB,KAAK,MAAM,EAAE,CAAC;YAClC,IAAI,GAAG,cAAc,IAAI,QAAQ,IAAI,SAAS,IAAI,QAAQ,CAAC;QAC7D,CAAC;aACI,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC3C,IAAI,GAAG,CAAC,CACN,CAAC,kBAAkB,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,cAAc,CAAC;gBAC7D,CAAC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC;gBAClD,CAAC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC;gBACnD,CAAC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC;gBAClD,CAAC,kBAAkB,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;QACrF,CAAC;QAED,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,6BAA6B,IAAI,CAAC,EAAE,6BAA6B,CAAC,CAAC;YACpF,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,wBAAwB,EAAE,sCAAsC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,cAAc,IAAI,CAAC,EAAE,GAAG,EAAE;gBAC5I,cAAc;gBACd,QAAQ;gBACR,SAAS;gBACT,QAAQ;aACT,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBACrB,MAAM,EAAE,IAAI;gBACZ,SAAS,EAAE,IAAI;gBACf,UAAU,EAAE,gBAAgB,CAAC,sBAAsB;gBACnD,WAAW,EAAE,0CAA0C;aACxD,CAAC,CAAC;YACH,OAAO;gBACL,MAAM,EAAE,+BAA+B;aACxC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;IACpD,MAAM,SAAS,GAAG,WAAW,KAAK,KAAK,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACvE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACtG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,kEAAkE,CAAC,CAAC;QACvF,CAAC;aACI,CAAC;YACJ,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,kDAAkD,EAAE,iBAAiB,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,IAAI,GAAG,KAAK,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,GAAG,KAAK,CAAC;QACf,CAAC;aACI,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;aACI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE,CAAC;YAC3D,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACrF,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,6BAA6B,IAAI,CAAC,EAAE,eAAe,CAAC,CAAC;YACtE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,cAAc,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAClJ,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBACrB,MAAM,EAAE,IAAI;gBACZ,SAAS,EAAE,IAAI;gBACf,UAAU,EAAE,gBAAgB,CAAC,SAAS;gBACtC,WAAW,EAAE,oBAAoB;aAClC,CAAC,CAAC;YACH,OAAO;gBACL,MAAM,EAAE,kBAAkB;aAC3B,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,oBAAoB,EAAE,+BAA+B,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,cAAc,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAChJ,CAAC;IACH,CAAC;IAED,gDAAgD;IAChD,IAAI,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,OAAO;YACL,MAAM,EAAE,8BAA8B;SACvC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,YAAY,IAAI,gBAAgB,EAAE,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,+BAA+B,IAAI,CAAC,EAAE,0BAA0B,CAAC,CAAC;IACrF,CAAC;IAED,IAAI,oBAAoB,GAAG,KAAK,CAAC;IACjC,IAAI,YAAY,EAAE,CAAC;QACjB,yBAAyB;QACzB,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACpC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/C,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;YAC7D,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACvC,wFAAwF;YACxF,2BAA2B;YAC3B,sHAAsH;YACtH,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,GAAG,MAAM,IAAI,CAAC,cAAc,CAC5D,SAAS,CAAC,oBAAoB,CAAC;gBAC7B,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE;aAC9B,CAAC,EACF,MAAM,CACP,CAAC;YAEF,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClC,OAAO;oBACL,MAAM,EAAE,SAAS;iBAClB,CAAC;YACJ,CAAC;YAED,oCAAoC;YACpC,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAC5D,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACrH,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;YAErE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;YACjE,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CACzD,WAAW,EAAE,kBAAkB,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;YACrF,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;YACtE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;YAE3D,8DAA8D;QAChE,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YACzE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAChE,CAAC;QAED,0BAA0B;QAC1B,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YACnD,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,4BAA4B,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACxC,MAAM,YAAY,GAAG,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1D,IAAI,aAAa,CAAC;YAClB,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBACxB,KAAK,YAAY;oBACf,aAAa,GAAG,oBAAoB,CAAC;oBACrC,MAAM;gBACR,KAAK,WAAW;oBACd,aAAa,GAAG,mBAAmB,CAAC;oBACpC,MAAM;gBACR;oBACE,aAAa,GAAG,sBAAsB,CAAC;YAC3C,CAAC;YACD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;YAC9D,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAC3H,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;QACrE,CAAC;QAED,gCAAgC;QAChC,IAAI,oBAAoB,GAAG,CAAC,CAAC;QAC7B,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY;YAClC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY;YAChC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAElC,MAAM,WAAW,GAAG,MAAM,uBAAA,IAAI,iFAAgC,MAApC,IAAI,EAAiC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACvF,MAAM,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC;YAC9B,oBAAoB,IAAI,WAAW,CAAC,UAAU,CAAC;YAE/C,MAAM,YAAY,GAAG,GAAG,EAAE;gBACxB,KAAK,CAAC,KAAK,IAAI,EAAE;oBACf,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;oBAC1C,IAAI,KAAK,EAAE,CAAC;wBACV,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;oBACtB,CAAC;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,CAAC;YACF,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,CAAC;YAED,IAAI,CAAC;gBACH,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;oBAClC,OAAO;wBACL,MAAM,EAAE,SAAS;qBAClB,CAAC;gBACJ,CAAC;gBAED,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;oBACpC,MAAM,YAAY,GAAmB,EAAE,CAAC;oBACxC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;wBACpB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBACrC,CAAC;oBACD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;wBACnB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACpC,CAAC;oBACD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC5B,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAC5D,MAAM,EACN;4BACE,MAAM,EAAE,YAAY;4BACpB,UAAU,EAAE,SAAS,IAAI,CAAC,EAAE,mBAAmB;4BAC/C,GAAG,EAAE,IAAI;4BACT,IAAI,EAAE;gCACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;gCAClF,IAAI,EAAE,QAAQ,CAAC,IAAI;gCACnB,UAAU,EAAE,QAAQ,CAAC,UAAU;6BAChC;4BACD,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI;yBACpD,CACF,CAAC;wBACF,oBAAoB,IAAI,UAAU,CAAC;oBACrC,CAAC;gBACH,CAAC;gBAED,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;oBAClC,OAAO;wBACL,MAAM,EAAE,SAAS;qBAClB,CAAC;gBACJ,CAAC;gBAED,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACjB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,4BAA4B,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,oBAAoB,CAAC,CAAC;gBACjH,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;gBAEzE,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;gBAEpB,oBAAoB,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,oBAAoB,GAAG,CAAC,CAAC;gBAEtF,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;YACxB,CAAC;oBACO,CAAC;gBACP,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,eAAe,EAAC,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YACzE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,OAAO;YACL,MAAM,EAAE,SAAS;SAClB,CAAC;IACJ,CAAC;IAED,uEAAuE;IACvE,IAAI,QAAQ,GAAqB,IAAI,CAAC;IACtC,IAAI,gBAAgB,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACxE,IAAI,IAAI,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;YAC1B,QAAQ,GAAG,MAAM,uBAAA,IAAI,gEAAe,MAAnB,IAAI,EAAgB,IAAI,EAAE,MAAM,CAAC,CAAC;YACnD,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClC,OAAO;oBACL,MAAM,EAAE,SAAS;iBAClB,CAAC;YACJ,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACvC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;gBACjE,MAAM,eAAe,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;gBAC9D,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,YAAY,EAAE,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;gBAC/H,IAAI,CAAC,sBAAsB,CAAC,kBAAkB,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,MAAM,WAAW,CAAC,CAAC;YACvF,CAAC;iBACI,CAAC;gBACJ,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,IAAI,CAAC,YAAY,uBAAuB,IAAI,CAAC,EAAE,eAAe,CAAC,CAAC;YAChG,CAAC;QACH,CAAC;aACI,CAAC;YACJ,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mCAAmC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;QAChE,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,WAAW,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,oBAAoB,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAErF,qBAAqB;IACrB,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACrB,8DAA8D;QAC9D,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,GAAG,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC;IAChD,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACrB,IAAI,QAAQ,EAAE,CAAC;YACb,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;SACI,CAAC;QACJ,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,0CAA0C,IAAI,CAAC,EAAE,wCAAwC,CAAC,CAAC;IAC9G,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAE3D,OAAO;QACL,MAAM,EAAE,YAAY;KACrB,CAAC;AACJ,CAAC,6FAEwB,SAA8C;IACrE,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU,IAAI,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC;AAC3G,CAAC,mDAoCD,KAAK,yDAAiC,IAAU,EAAE,QAAyD,EAAE,MAAoB;IAE/H,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;IAEpD,MAAM,YAAY,GAAG,CAAC,SAAsC,EAAE,EAAE;QAC9D,IAAI,OAAO,UAAU,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,OAAO,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,CAAC,SAAqD,EAAE,EAAE;QAC7E,IAAI,OAAO,UAAU,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,OAAO,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,GAAG,EAAE;QAC1B,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtH,MAAM,mBAAmB,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,kBAAkB,CAAC,CAAC;QACnH,MAAM,mBAAmB,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,kBAAkB,CAAC;QAElH,IAAI,CAAC,mBAAmB,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,mBAAmB,EAAE,CAAC;YAC1E,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/G,OAAO;gBACL,MAAM,EAAE,CAAE,IAAI,CAAC,KAAK,CAAE;gBACtB,UAAU,EAAE,SAAS,IAAI,CAAC,EAAE,gBAAgB,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,SAAS,EAAE;gBAC7E,GAAG,EAAE,IAAI;gBACT,IAAI,EAAE;oBACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;oBAClF,IAAI,EAAE,QAAQ,CAAC,KAAK;oBACpB,UAAU,EAAE,QAAQ,CAAC,UAAU;iBAChC;gBACD,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO;aACvD,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAE7F,MAAM,uBAAA,IAAI,2EAA0B,MAA9B,IAAI,EAA2B,IAAI,CAAC,CAAC;IAC3C,MAAM,6BAA6B,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAsC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACxH,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IAEb,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,6BAA6B,CAAC,CAAC;IAE/E,MAAM,WAAW,GAAG,IAAI,CAAC,uBAAuB,CAC9C,SAAS,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,GAAG,EAClC,MAAM,EAEN,YAAY,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC3C,MAAM,EAAE,CAAE,IAAI,CAAC,YAAY,CAAE;QAC7B,UAAU,EAAE,SAAS,IAAI,CAAC,EAAE,mBAAmB;QAC/C,GAAG,EAAE,IAAI;QACT,IAAI,EAAE;YACJ,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,QAAQ,CAAC,YAAY;YAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC;QACD,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO;KACvD,CAAC,CAAC,CAAC,IAAI,EAER,YAAY,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC3C,MAAM,EAAE,CAAE,IAAI,CAAC,YAAY,CAAE;QAC7B,UAAU,EAAE,SAAS,IAAI,CAAC,EAAE,mBAAmB;QAC/C,GAAG,EAAE,IAAI;QACT,IAAI,EAAE;YACJ,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,QAAQ,CAAC,YAAY;YAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC;QACD,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO;KACvD,CAAC,CAAC,CAAC,IAAI;IAER;;;OAGG;IACH,YAAY,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACpE,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,SAAS,IAAI,CAAC,EAAE,oBAAoB;QAChD,GAAG,EAAE,IAAI;QACT,IAAI,EAAE;YACJ,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,QAAQ,CAAC,aAAa;YAC5B,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC;QACD,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO;KACvD,CAAC,CAAC,CAAC,IAAI;IAER;;;OAGG;IACH,YAAY,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5G,MAAM,EAAE,CAAE,IAAI,CAAC,KAAK,CAAE;QACtB,UAAU,EAAE,SAAS,IAAI,CAAC,EAAE,WAAW;QACvC,GAAG,EAAE,IAAI;QACT,IAAI,EAAE;YACJ,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,QAAQ,CAAC,KAAK;YACpB,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC;QACD,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO;KACvD,CAAC,CAAC,CAAC,IAAI,EAER,YAAY,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACpC,MAAM,EAAE,CAAE,IAAI,CAAC,KAAK,CAAE;QACtB,UAAU,EAAE,SAAS,IAAI,CAAC,EAAE,WAAW;QACvC,GAAG,EAAE,IAAI;QACT,IAAI,EAAE;YACJ,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,QAAQ,CAAC,KAAK;YACpB,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC;QACD,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO;KACvD,CAAC,CAAC,CAAC,IAAI,EAER,YAAY,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACnE,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,SAAS,IAAI,CAAC,EAAE,YAAY;QACxC,GAAG,EAAE,IAAI;QACT,IAAI,EAAE;YACJ,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,QAAQ,CAAC,MAAM;YACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC;QACD,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO;KACvD,CAAC,CAAC,CAAC,IAAI,EAER,YAAY,CAAC,YAAY,CAAC,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,EAAE,cAAc;QACtB,UAAU,EAAE,SAAS,IAAI,CAAC,EAAE,iBAAiB;QAC7C,GAAG,EAAE,IAAI;QACT,IAAI,EAAE;YACJ,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,QAAQ,CAAC,WAAW;YAC1B,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC;QACD,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO;QACtD,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC,CAAC,IAAI,EAER,cAAc,EAAE,CACjB,CAAC;IAEF,OAAO,WAAW,CAAC;AACrB,CAAC,6CAED,KAAK,mDAA2B,IAAU,EAAE,MAAoB;IAC9D,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnE,OAAO;IACT,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,uCAAuC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACpE,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,KAAK,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,GAAG,CAAC;QAChD,kGAAkG;QAClG,4FAA4F;QAC5F,IAAI,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAqB,KAAK,uBAAuB,CAAC,CAAC;QACvE,CAAC;aACI,CAAC;YACJ,MAAM,MAAM,GAAG,SAAS,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;YACrE,IAAI,IAAI,CAAC;YACT,IAAI,CAAC;gBACH,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAqB,KAAK,qBAAqB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC9E,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;oBAC7B,GAAG,EAAE,MAAM;oBACX,IAAI,EAAE,MAAM;oBACZ,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU;oBAC1C,MAAM;iBAAE,CACT,CAAC,CAAC,IAAI,CAAC;YACV,CAAC;YACD,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;oBACpB,MAAM,KAAK,CAAC;gBACd,CAAC;qBACI,CAAC;oBACJ,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,oCAAoC,KAAK,sBAAsB,EAAE,CAAC,MAAM,6BAA6B,MAAM,KAAK,EAAE,KAAK,CAAC,CAAC;gBAC7I,CAAC;gBACD,IAAI,GAAG,IAAI,CAAC;YACd,CAAC;YACD,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAChC,MAAM,UAAU,GAAG,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvE,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,oCAAoC,KAAK,sBAAsB,EAAE,CAAC,MAAM,yCAAyC,MAAM,GAAG,CAAC,CAAC;gBAChJ,CAAC;qBACI,CAAC;oBACJ,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;wBAC3B,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,MAAM,yBAAyB,KAAK,0BAA0B,CAAC,CAAC;oBACtG,CAAC;yBACI,CAAC;wBACJ,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC;wBAC/E,IAAI,CAAC,UAAU,EAAE,CAAC;4BAChB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,wCAAwC,EAAE,CAAC,MAAM,yBAAyB,KAAK,EAAE,CAAC,CAAC;wBACtG,CAAC;6BACI,CAAC;4BACJ,EAAE,CAAC,YAAY,GAAG,UAAU,CAAC;4BAC7B,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,yCAAyC,EAAE,CAAC,MAAM,yBAAyB,KAAK,EAAE,CAAC,CAAC;wBACxG,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC,kCAED,KAAK,wCAAgB,IAAU,EAAE,MAAoB,EAAE,WAAgD;IACrG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,mCAAmC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAChE,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,WAAW,CAAC;IAChB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,4BAA4B,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACxD,WAAW,GAAG,SAAS,CAAC,2BAA2B,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3E,CAAC;SACI,CAAC;QACJ,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,0CAA0C,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACvE,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC;IACpC,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,QAAQ,GAAG,MAAM,CAAC,wBAAwB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACpE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,QAAQ,CAAC,KAAK,CAAC,MAAM,uBAAuB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACpF,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YAClD,IAAI,IAAI,CAAC;YACT,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,IAAI,GAAG;oBACL,GAAG,EAAE,QAAQ,CAAC,GAAG;oBACjB,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,KAAK,EAAE,QAAQ,CAAC,KAAK;iBACtB,CAAC;YACJ,CAAC;iBACI,CAAC;gBACJ,IAAI,GAAG,WAAW,CAAC;gBACnB,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC;gBACxB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACnC,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;YAClC,CAAC;YACD,OAAO,uBAAA,IAAI,gEAAe,MAAnB,IAAI,EAAgB,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACjD,CAAC;aACI,CAAC;YACJ,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAE,GAAG,WAAW,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC1F,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,MAAM,CAAC,MAAM,+BAA+B,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YAClF,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;gBAC7B,IAAI,OAAO,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;oBAC3B,OAAO,CAAC,OAAO,GAAG,MAAM,uBAAA,IAAI,sEAAqB,MAAzB,IAAI,EAAsB,OAAO,EAAE,MAAM,CAAC,CAAC;gBACrE,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;SACI,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,OAAO,EAAE,CAAC;IACZ,CAAC;SACI,CAAC;QACJ,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,sCAAsC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAClE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,wCAED,KAAK,8CAAsB,OAAgB,EAAE,MAAoB,EAAE,WAAqD;IACtH,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,oCAAoC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QACpE,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,UAAU,CAAC;IACf,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,6BAA6B,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7D,UAAU,GAAG,SAAS,CAAC,2BAA2B,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/F,CAAC;SACI,CAAC;QACJ,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,2CAA2C,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3E,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC;IACnC,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,OAAO,GAAG,MAAM,CAAC,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QACxE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,OAAO,CAAC,KAAK,CAAC,MAAM,wBAAwB,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QACvF,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YAChD,IAAI,IAAI,CAAC;YACT,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,IAAI,GAAG;oBACL,GAAG,EAAE,OAAO,CAAC,GAAG;oBAChB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,KAAK,EAAE,OAAO,CAAC,KAAK;iBACrB,CAAC;YACJ,CAAC;iBACI,CAAC;gBACJ,IAAI,GAAG,WAAW,CAAC;gBACnB,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;gBACvB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;gBAClC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;YACjC,CAAC;YACD,OAAO,uBAAA,IAAI,sEAAqB,MAAzB,IAAI,EAAsB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC1D,CAAC;aACI,CAAC;YACJ,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAE,GAAG,WAAW,CAAC,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;YACxF,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,MAAM,CAAC,MAAM,iCAAiC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YACvF,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;SACI,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,OAAO,EAAE,CAAC;IACZ,CAAC;SACI,CAAC;QACJ,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,uCAAuC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QACtE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,mCAED,KAAK,yCAAiB,UAAsB,EAAE,QAAkB,EAAE,MAAoB;IACpF,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,EAAE,EAAE,CAAC;IAC3B,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,OAAO;IACT,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QACrC,EAAE,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACxC,OAAO;IACT,CAAC;IAED,IAAI,KAAK,GAA6B,IAAI,CAAC;IAC3C,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,CAAC;IACF,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,yBAAyB,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACjD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IAEnE,wCAAwC;IACxC,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC7E,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,wBAAwB,EAAE,cAAc,CAAC,CAAC;IAC5D,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAE7C,oCAAoC;IACpC,MAAM,OAAO,GAAG,yBAAyB,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAClE,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACrH,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,EAAE,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAEjF,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;IACnF,MAAM,uBAAuB,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAC/D,iBAAiB,EAAE,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC3E,IAAI,CAAC,sBAAsB,CAAC,uBAAuB,EAAE,UAAU,EAAE,qBAAqB,CAAC,CAAC;IAExF,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IAEjE,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,OAAO;IACT,CAAC;IAED,0CAA0C;IAC1C,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QACpE,MAAM,eAAe,GAAmB;YACtC,UAAU,CAAC,SAAS;SACrB,CAAC;QACF,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,uBAAuB,CACzC,eAAe,UAAU,CAAC,EAAE,KAAK,UAAU,CAAC,KAAK,GAAG,EACpD,MAAM,EACN;YACE,MAAM,EAAE,eAAe;YACvB,UAAU,EAAE,eAAe,QAAQ,CAAC,EAAE,eAAe;YACrD,GAAG,EAAE,UAAU;YACf,IAAI,EAAE;gBACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,IAAI;gBACtD,IAAI,EAAE,cAAc,CAAC,IAAI;gBACzB,UAAU,EAAE,IAAI;aACjB;YACD,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI;SACpD,CACF,CAAC,CAAC,KAAK,CAAC;QACT,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QACD,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/E,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;QACpB,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAElE,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,EAAE,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAExC,OAAO;IACP,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;IAChD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;AACnE,CAAC;AA/jCM,sBAAO,GAAG,OAAO,AAAV,CAAW;eAFN,cAAc","sourcesContent":["import URLHelper from '../utils/URLHelper.js';\nimport Downloader, { type DownloaderConfig, type DownloaderStartParams } from './Downloader.js';\nimport PostParser from '../parsers/PostParser.js';\nimport { type Collection, type Post } from '../entities/Post.js';\nimport { type Downloadable, isYouTubeEmbed } from '../entities/Downloadable.js';\nimport StatusCache, { type StatusCacheValidationScope } from './cache/StatusCache.js';\nimport { generatePostEmbedSummary, generatePostSummary } from './templates/PostInfo.js';\nimport path from 'path';\nimport { TargetSkipReason } from './DownloaderEvent.js';\nimport DownloadTaskFactory from './task/DownloadTaskFactory.js';\nimport PostsFetcher from './PostsFetcher.js';\nimport CommentParser from '../parsers/CommentParser.js';\nimport { type Comment, type CommentList, type CommentReply, type CommentReplyList } from '../entities/Comment.js';\nimport { generatePostCommentsSummary } from './templates/CommentInfo.js';\nimport { type PostDirectories } from '../utils/FSHelper.js';\nimport { type DBInstance } from '../browse/db/index.js';\nimport { type AttachmentMediaItem } from '../entities/MediaItem.js';\nimport type Logger from '../utils/logging/Logger.js';\nimport { type DeepRequired } from '../utils/Misc.js';\nimport { type Campaign } from '../entities/Campaign.js';\nimport type DownloadTaskBatch from './task/DownloadTaskBatch.js';\nimport { generateCollectionSummary } from './templates/CollectionInfo.js';\n\nexport interface PostDownloaderContext {\n skipSaveCampaign?: boolean;\n keepLoggerOpen?: boolean;\n keepDBOpen?: boolean;\n}\n\nexport default class PostDownloader extends Downloader<Post> {\n\n static version = '1.1.1';\n\n name = 'PostDownloader';\n\n #startPromise: Promise<void> | null = null;\n #context: DeepRequired<PostDownloaderContext>;\n\n constructor(\n config: DownloaderConfig<Post>,\n db: () => Promise<DBInstance>,\n logger?: Logger | null,\n context?: PostDownloaderContext\n ) {\n super(config, db, logger);\n this.#context = {\n skipSaveCampaign: context?.skipSaveCampaign ?? false,\n keepLoggerOpen: context?.keepLoggerOpen ?? false,\n keepDBOpen: context?.keepDBOpen ?? false\n };\n }\n\n doStart(params?: DownloaderStartParams): Promise<void> {\n if (this.#startPromise) {\n throw Error('Downloader already running');\n }\n this.#startPromise = this.#doStart(params)\n .finally(() => {\n this.#startPromise = null;\n });\n return this.#startPromise;\n }\n\n async #doStart(params?: DownloaderStartParams): Promise<void> {\n try {\n const { signal } = params || {};\n const postFetch = this.config.postFetch;\n const db = await this.db();\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (postFetch.type === 'byUser') {\n this.log('info', `Targeting posts by '${postFetch.vanity}'`);\n }\n else if (postFetch.type === 'byUserId') {\n this.log('info', `Targeting posts by user #${postFetch.userId}`);\n }\n else if (postFetch.type === 'byCollection') {\n this.log('info', `Targeting posts in collection #${postFetch.collectionId}`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Target post given by API data in \"${postFetch.filePath}\"`);\n }\n else { // Single\n this.log('info', `Targeting post #${postFetch.postId}`);\n }\n if (this.#isFetchingMultiplePosts(postFetch) && postFetch.filters) {\n const filterStr = Object.entries(postFetch.filters).map(([ key, value ]) => `${key}=${value}`).join('; ');\n if (filterStr) {\n this.log('info', `Filters: ${filterStr}`);\n }\n }\n\n // Step 1: Get posts (if by user) or target post\n const postsFetcher = new PostsFetcher({\n config: this.config,\n fetcher: this.fetcher,\n logger: this.logger,\n signal\n });\n postsFetcher.on('statusChange', ({current}) => {\n if (current.status === 'running') {\n this.emit('fetchBegin', { targetType: postsFetcher.getTargetType() });\n }\n });\n postsFetcher.begin();\n\n // Step 2: download posts in each fetched list\n let downloaded = 0;\n let skippedUnviewable = 0;\n let skippedRedundant = 0;\n let skippedUnmetMediaTypeCriteria = 0;\n let skippedNotInTier = 0;\n let skippedPublishDateOutOfRange = 0;\n let campaignSaved = false;\n let stopConditionMet = false;\n const savedCollectionIds: string[] = [];\n const postsParser = new PostParser(this.logger);\n while (postsFetcher.hasNext()) {\n const { list, aborted, error } = await postsFetcher.next();\n if (!list || aborted) {\n break;\n }\n if (!list && error) {\n this.emit('end', { aborted: false, error, message: 'PostsFetcher error' });\n return;\n }\n if (!this.#context.skipSaveCampaign && !campaignSaved && list.items[0]?.campaign) {\n await this.saveCampaignInfo(list.items[0].campaign, signal);\n campaignSaved = true;\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n for (const _post of list.items) {\n\n if (stopConditionMet) {\n break;\n }\n\n let post = _post;\n\n // Collections\n if (post.campaign && post.collections) {\n for (const collection of post.collections) {\n if (!savedCollectionIds.includes(collection.id)) {\n try {\n await this.#saveCollection(collection, post.campaign);\n savedCollectionIds.push(collection.id);\n }\n catch (error) {\n this.log('error', `Failed to save collection #${collection.id}:`, error);\n }\n }\n else {\n this.log('debug', `Collection #${collection.id} already processed`);\n }\n }\n }\n\n if (this.#isFetchingMultiplePosts(postFetch)) {\n // Refresh to ensure media links have not expired\n this.log('debug', `Refresh post #${_post.id}`);\n const postURL = URLHelper.constructPostsAPIURL({ postId: _post.id });\n const { json } = await this.commonFetchAPI(postURL, signal);\n let refreshed: Post | null = null;\n if (json) {\n refreshed = postsParser.parsePostsAPIResponse(json, postURL).items[0] || null;\n if (!refreshed) {\n this.log('warn', `Refreshed post #${_post.id} but got empty value - going to use existing data`);\n }\n else if (refreshed.id !== _post.id) {\n this.log('warn', `Refreshed post #${_post.id} but ID mismatch - going to use existing data`);\n refreshed = null;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return;\n }\n else {\n this.log('warn', `Failed to refresh post #${_post.id} - going to use existing data`);\n }\n if (refreshed) {\n this.log('debug', `Use refreshed post data #${refreshed.id}`);\n post = refreshed;\n }\n }\n\n this.emit('targetBegin', { target: post });\n\n // Step 4.1: post directories\n const postDirs = this.fsHelper.getPostDirs(post);\n this.log('debug', 'Post directories:', postDirs);\n\n // Step 4.2: Check with status cache\n const statusCache = StatusCache.getInstance(this.config, postDirs.statusCache, this.logger);\n const statusCacheValidation = statusCache.validate(post, postDirs.root, this.config)\n if (!statusCacheValidation.invalidated) {\n this.log('info', `Skipped downloading post #${post.id}: already downloaded and nothing has changed since last download`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.AlreadyDownloaded,\n skipMessage: 'Target already downloaded and nothing has changed since last download'\n });\n skippedRedundant++;\n if (this.config.stopOn === 'postPreviouslyDownloaded' || \n this.config.stopOn === 'previouslyDownloaded'\n ) {\n stopConditionMet = true;\n }\n continue;\n }\n \n switch ((await this.#doDownload(\n post,\n postDirs,\n statusCacheValidation.scope,\n statusCache,\n db,\n signal\n )).status) {\n case 'aborted':\n return;\n case 'downloaded':\n downloaded++;\n break;\n case 'skippedNotInTier':\n skippedNotInTier++;\n break;\n case 'skippedPublishDateOutOfRange':\n skippedPublishDateOutOfRange++;\n if (this.config.stopOn === 'postPublishDateOutOfRange' ||\n this.config.stopOn === 'publishDateOutOfRange'\n ) {\n stopConditionMet = true;\n }\n break;\n case 'skippedUnmetMediaTypeCriteria':\n skippedUnmetMediaTypeCriteria++;\n break;\n case 'skippedUnviewable':\n skippedUnviewable++;\n break;\n }\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n if (stopConditionMet) {\n break;\n }\n }\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (stopConditionMet && this.#isFetchingMultiplePosts(postFetch)) {\n this.log('info', `Stop downloader: stop condition \"${this.config.stopOn}\" met`)\n }\n\n // Done\n if (postFetch.type === 'byUser') {\n this.log('info', `Done downloading posts by '${postFetch.vanity}'`);\n }\n else if (postFetch.type === 'byUserId') {\n this.log('info', `Done downloading posts by user #${postFetch.userId}`);\n }\n else if (postFetch.type === 'byCollection') {\n this.log('info', `Done downloading posts in collection #${postFetch.collectionId}`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Done downloading post given in \"${postFetch.filePath}\"`);\n }\n else {\n this.log('info', `Done downloading post #${postFetch.postId}`);\n }\n let endMessage = 'Done';\n if (this.#isFetchingMultiplePosts(postFetch)) {\n const skippedStrParts: string[] = [];\n if (skippedUnviewable) {\n skippedStrParts.push(`${skippedUnviewable} unviewable`);\n }\n if (skippedRedundant) {\n skippedStrParts.push(`${skippedRedundant} redundant`);\n }\n if (skippedUnmetMediaTypeCriteria) {\n skippedStrParts.push(`${skippedUnmetMediaTypeCriteria} with unmet media type criteria`);\n }\n if (skippedNotInTier) {\n skippedStrParts.push(`${skippedNotInTier} not in tier`);\n }\n if (skippedPublishDateOutOfRange) {\n skippedStrParts.push(`${skippedPublishDateOutOfRange} with publish date out of range`);\n }\n const skippedStr = skippedStrParts.length > 0 ? ` (skipped: ${skippedStrParts.join(', ')})` : '';\n endMessage = `Total ${downloaded} / ${postsFetcher.getTotal()} posts processed${skippedStr}`;\n this.log('info', endMessage);\n }\n this.emit('end', { aborted: false, message: endMessage });\n }\n finally {\n if (!this.#context.keepDBOpen) {\n await this.closeDB();\n }\n if (this.logger && !this.#context.keepLoggerOpen) {\n await this.logger.end();\n }\n }\n }\n\n async #doDownload(\n post: Post,\n postDirs: PostDirectories,\n scope: StatusCacheValidationScope<Post>,\n statusCache: StatusCache,\n db: DBInstance,\n signal?: AbortSignal\n ): Promise<{status: 'skippedUnviewable' | 'skippedUnmetMediaTypeCriteria' | 'skippedNotInTier' | 'skippedPublishDateOutOfRange' | 'aborted' | 'downloaded' }> {\n this.log('info', `Download post #${post.id} (${post.title})`);\n\n const downloadPost = scope.includes('post');\n const downloadComments = scope.includes('comments');\n \n // Step 1: Check whether we should download post\n // -- 1.1 Viewability\n if (!post.isViewable) {\n if (this.config.include.lockedContent) {\n this.log('warn', `Post #${post.id} is not viewable by current user`);\n }\n else {\n this.log('warn', `Skipped downloading post #${post.id}: not viewable by current user`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.Inaccessible,\n skipMessage: 'Target is not viewable by current user'\n });\n return {\n status: 'skippedUnviewable'\n };\n }\n }\n\n // -- 1.2 Config option 'include.postsWithMediaType'\n const postsWithMediaType = this.config.include.postsWithMediaType;\n if (postsWithMediaType !== 'any') {\n const hasAttachments = post.attachments.length > 0;\n const hasAudio = !!post.audio || !!post.audioPreview;\n const hasImages = post.images.length > 0;\n const hasVideo = !!post.video || !!post.videoPreview || !!(post.embed && (post.embed.type === 'videoEmbed' || isYouTubeEmbed(post.embed)));\n const isPodcast = post.postType === 'podcast'\n\n let skip = false;\n if (postsWithMediaType === 'none') {\n skip = hasAttachments || hasAudio || hasImages || hasVideo;\n }\n else if (Array.isArray(postsWithMediaType)) {\n skip = !(\n (postsWithMediaType.includes('attachment') && hasAttachments) ||\n (postsWithMediaType.includes('audio') && hasAudio) ||\n (postsWithMediaType.includes('image') && hasImages) ||\n (postsWithMediaType.includes('video') && hasVideo) ||\n (postsWithMediaType.includes('podcast') && isPodcast && (hasAudio || hasVideo)));\n }\n\n if (skip) {\n this.log('warn', `Skipped downloading post #${post.id}: unmet media type criteria`);\n this.log('debug', 'Match criteria failed:', `config.include.postsWithMediaType: ${JSON.stringify(postsWithMediaType)} <-> post #${post.id}:`, {\n hasAttachments,\n hasAudio,\n hasImages,\n hasVideo\n });\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.UnmetMediaTypeCriteria,\n skipMessage: 'Target does not meet media type criteria'\n });\n return {\n status: 'skippedUnmetMediaTypeCriteria'\n };\n }\n }\n\n // -- 1.3 Config option 'include.postsInTier'\n const postsInTier = this.config.include.postsInTier;\n const isAnyTier = postsInTier === 'any' || postsInTier.includes('any');\n if (!isAnyTier) {\n const applicableTierIds = postsInTier.filter((id) => post.campaign?.rewards.find((r) => r.id === id));\n if (!post.campaign) {\n this.log('warn', 'config.include.postsInTier: ignored - post missing campaign info');\n }\n else {\n this.log('debug', 'config.include.postsInTier: applicable tier IDs:', applicableTierIds);\n }\n let skip = false;\n if (!post.campaign) {\n skip = false;\n }\n else if (applicableTierIds.length === 0) {\n skip = true;\n }\n else if (!post.tiers.find((tier) => tier.id === 'patrons')) {\n skip = applicableTierIds.every((id) => !post.tiers.find((tier) => tier.id === id));\n }\n if (skip) {\n this.log('warn', `Skipped downloading post #${post.id}: not in tier`);\n this.log('debug', 'Match criteria failed:', `config.include.postsInTier: ${JSON.stringify(applicableTierIds)} <-> post #${post.id}:`, post.tiers);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.NotInTier,\n skipMessage: 'Target not in tier'\n });\n return {\n status: 'skippedNotInTier'\n };\n }\n if (post.campaign) {\n this.log('debug', 'Match criteria OK:', `config.include.postsInTier: ${JSON.stringify(applicableTierIds)} <-> post #${post.id}:`, post.tiers);\n }\n }\n\n // -- 1.4 Config option 'include.postsPublished'\n if (this.isPublishDateOutOfRange(post)) {\n return {\n status: 'skippedPublishDateOutOfRange'\n };\n }\n\n if (!downloadPost && downloadComments) {\n this.log('info', `Previously downloaded post #${post.id} - refresh comments only`);\n }\n\n let hasDownloadPostError = false;\n if (downloadPost) {\n // Step 2: Save post info\n if (this.config.include.contentInfo) {\n this.log('info', `Save post info #${post.id}`);\n this.emit('phaseBegin', { target: post, phase: 'saveInfo' });\n this.fsHelper.createDir(postDirs.info);\n // Post raw data might not be complete or consistent with other posts in the collection.\n // Fetch directly from API.\n // Strictly speaking, we should check for 'error' in results, but since it's not going to be fatal we'll just skip it.\n const { json: fetchedPostAPIData } = await this.commonFetchAPI(\n URLHelper.constructPostsAPIURL({\n postId: post.id,\n campaignId: post.campaign?.id\n }),\n signal\n );\n\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n\n // Step 3. Save summary and raw json\n const summary = generatePostSummary(post);\n const summaryFile = path.resolve(postDirs.info, 'info.txt');\n const saveSummaryResult = await this.fsHelper.writeTextFile(summaryFile, summary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveSummaryResult, post, 'post summary');\n\n const postRawFile = path.resolve(postDirs.info, 'post-api.json');\n const savePostRawResult = await this.fsHelper.writeTextFile(\n postRawFile, fetchedPostAPIData || post.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(savePostRawResult, post, 'post API data');\n this.emit('phaseEnd', { target: post, phase: 'saveInfo' });\n\n // (Downloading of info media items deferred to the next step)\n }\n\n if (this.config.include.previewMedia || this.config.include.contentMedia) {\n this.emit('phaseBegin', { target: post, phase: 'saveMedia' });\n }\n\n // Step 4: save embed info\n if (post.embed && this.config.include.contentMedia) {\n this.log('info', `Save embed info of post #${post.id}`);\n this.fsHelper.createDir(postDirs.embed);\n const embedSummary = generatePostEmbedSummary(post.embed);\n let embedFilename;\n switch (post.embed.type) {\n case 'videoEmbed':\n embedFilename = 'embedded-video.txt';\n break;\n case 'linkEmbed':\n embedFilename = 'embedded-link.txt';\n break;\n default:\n embedFilename = 'embedded-unknown.txt';\n }\n const embedFile = path.resolve(postDirs.embed, embedFilename);\n const saveSummaryResult = await this.fsHelper.writeTextFile(embedFile, embedSummary, this.config.fileExistsAction.content);\n this.logWriteTextFileResult(saveSummaryResult, post, 'embed info');\n }\n\n // Step 5: create download tasks\n let createTaskErrorCount = 0;\n if (this.config.include.previewMedia ||\n this.config.include.contentMedia ||\n this.config.include.contentInfo) {\n\n const batchResult = await this.#createDownloadTaskBatchForPost(post, postDirs, signal);\n const { batch } = batchResult; \n createTaskErrorCount += batchResult.errorCount;\n\n const abortHandler = () => {\n void (async () => {\n this.log('info', 'Abort signal received');\n if (batch) {\n await batch.abort();\n }\n })();\n };\n if (signal) {\n signal.addEventListener('abort', abortHandler, { once: true });\n }\n\n try {\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n \n if (this.config.include.contentInfo) {\n const infoElements: Downloadable[] = [];\n if (post.coverImage) {\n infoElements.push(post.coverImage);\n }\n if (post.thumbnail) {\n infoElements.push(post.thumbnail);\n }\n if (infoElements.length > 0) {\n const { errorCount } = await this.addToDownloadTaskBatch(batch,\n signal,\n {\n target: infoElements,\n targetName: `post #${post.id} -> info elements`,\n src: post,\n dirs: {\n campaign: post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null,\n main: postDirs.info,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.info\n }\n );\n createTaskErrorCount += errorCount;\n }\n }\n \n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n \n batch.prestart();\n this.log('info', `Download batch created (#${batch.id}): ${batch.getTasks('pending').length} downloads pending`);\n this.emit('phaseBegin', { target: post, phase: 'batchDownload', batch });\n \n await batch.start();\n\n hasDownloadPostError = batch.getTasks('error').length > 0 || createTaskErrorCount > 0;\n\n await batch.destroy();\n }\n finally {\n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n }\n\n this.emit('phaseEnd', { target: post, phase: 'batchDownload'});\n }\n\n if (this.config.include.previewMedia || this.config.include.contentMedia) {\n this.emit('phaseEnd', { target: post, phase: 'saveMedia' });\n }\n }\n\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n\n // Step 6: Fetch and save comments (only available if post is viewable)\n let comments: Comment[] | null = null;\n if (downloadComments && this.config.include.comments && post.isViewable) {\n if (post.commentCount > 0) {\n comments = await this.#fetchComments(post, signal);\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n if (comments.length > 0) {\n this.fsHelper.createDir(postDirs.info);\n const commentsFile = path.resolve(postDirs.info, 'comments.txt');\n const commentsSummary = generatePostCommentsSummary(comments);\n const saveCommentsResult = await this.fsHelper.writeTextFile(commentsFile, commentsSummary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveCommentsResult, post, `${comments.length} comments`);\n }\n else {\n this.log('warn', `Expecting ${post.commentCount} comments for post #${post.id} but got none`);\n }\n }\n else {\n this.log('info', `No comments available for post #${post.id}`)\n }\n }\n\n // Step 7: Update status cache\n statusCache.updateOnDownload(post, postDirs.root, hasDownloadPostError, this.config);\n\n // Step 8: Save to DB\n let skipDB = false;\n if (!post.isViewable) {\n // Skip if existing db record (if any) refers to viewable post\n const dbPost = db.getContent(post.id, 'post');\n skipDB = dbPost !== null && dbPost.isViewable;\n }\n if (!skipDB) {\n db.saveContent(post);\n if (comments) {\n db.savePostComments(post, comments);\n }\n }\n else {\n this.log('info', `Skip overwrite existing viewable post #${post.id} in DB with current unviewable version`);\n }\n\n this.emit('targetEnd', { target: post, isSkipped: false });\n\n return {\n status: 'downloaded'\n };\n }\n\n #isFetchingMultiplePosts(postFetch: DownloaderConfig<Post>['postFetch']): postFetch is DownloaderConfig<Post>['postFetch'] & { type: 'byUser' | 'byUserId' | 'byCollection' } {\n return postFetch.type === 'byUser' || postFetch.type === 'byUserId' || postFetch.type === 'byCollection';\n }\n\n async __getCampaign(signal?: AbortSignal) {\n let url: string | null;\n const postFetch = this.config.postFetch;\n switch (postFetch.type) {\n case 'byUser':\n url = URLHelper.constructCampaignPageURL({ vanity: postFetch.vanity });\n break;\n case 'byUserId':\n url = URLHelper.constructCampaignPageURL({ userId: postFetch.userId });\n break;\n default:\n url = null;\n }\n if (!url) {\n throw Error('Internal error: invalid config');\n }\n const postsFetcher = new PostsFetcher({\n config: this.config,\n fetcher: this.fetcher,\n logger: this.logger,\n signal\n });\n const { campaignId } = await postsFetcher.getInitialData(url);\n const postsParser = new PostParser(this.logger);\n const res = await this.fetchCampaign(campaignId);\n if (signal?.aborted) {\n throw new Error('Aborted');\n }\n if (res.error) {\n throw res.error;\n }\n return postsParser.parseCampaignAPIResponse(res.json);\n }\n\n async #createDownloadTaskBatchForPost(post: Post, postDirs: ReturnType<typeof this.fsHelper['getPostDirs']>, signal?: AbortSignal) {\n\n const incPreview = this.config.include.previewMedia;\n const incContent = this.config.include.contentMedia;\n\n const __incPreview = (mediaType: 'audio' | 'video' | 'image') => {\n if (typeof incPreview === 'boolean') {\n return incPreview;\n }\n return incPreview.includes(mediaType);\n };\n\n const __incContent = (mediaType: 'audio' | 'video' | 'image' | 'attachment') => {\n if (typeof incContent === 'boolean') {\n return incContent;\n }\n return incContent.includes(mediaType);\n };\n\n const __getEmbedTask = () => {\n if (!post.embed) {\n return null;\n }\n\n const hasEmbedDownloader = DownloadTaskFactory.findEmbedDownloader(this.config.embedDownloaders, post.embed.provider);\n const isDownloadableVideo = isYouTubeEmbed(post.embed) || (post.embed.type === 'videoEmbed' && hasEmbedDownloader);\n const isDownloadableOther = !isYouTubeEmbed(post.embed) && post.embed.type !== 'videoEmbed' && hasEmbedDownloader;\n \n if ((isDownloadableVideo && __incContent('video')) || isDownloadableOther) {\n const embedType = post.embed.type === 'videoEmbed' ? ' video' : post.embed.type === 'linkEmbed' ? ' link' : '';\n return {\n target: [ post.embed ],\n targetName: `post #${post.id} -> embedded ${post.embed.provider}${embedType}`,\n src: post,\n dirs: {\n campaign: post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null,\n main: postDirs.embed,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n };\n }\n \n return null;\n }\n\n const campaignDir = post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null;\n\n await this.#processLinkedAttachments(post);\n const downloadableLinkedAttachments = post.linkedAttachments?.reduce<Downloadable<AttachmentMediaItem>[]>((result, att) => {\n if (att.downloadable) {\n result.push(att.downloadable);\n }\n return result;\n }, []) || [];\n\n const allAttachments = [...post.attachments, ...downloadableLinkedAttachments];\n\n const batchResult = this.createDownloadTaskBatch(\n `Post #${post.id} (${post.title})`,\n signal,\n\n __incPreview('audio') && post.audioPreview ? {\n target: [ post.audioPreview ],\n targetName: `post #${post.id} -> audio preview`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.audioPreview,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incPreview('video') && post.videoPreview ? {\n target: [ post.videoPreview ],\n targetName: `post #${post.id} -> video preview`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.videoPreview,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n /**\n * If post is not viewable by current user, its images will be\n * blurry and we should categorize them as image previews.\n */\n __incPreview('image') && post.images.length > 0 && !post.isViewable ? {\n target: post.images,\n targetName: `post #${post.id} -> image previews`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.imagePreviews,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n /**\n * If post is not viewable, audio data should have no URL, so check and\n * skip if this is the case.\n */\n __incContent('audio') && post.audio && (post.isViewable || (post.audio.type === 'audio' && post.audio.url)) ? {\n target: [ post.audio ],\n targetName: `post #${post.id} -> audio`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.audio,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('video') && post.video ? {\n target: [ post.video ],\n targetName: `post #${post.id} -> video`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.video,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('image') && post.images.length > 0 && post.isViewable ? {\n target: post.images,\n targetName: `post #${post.id} -> images`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.images,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('attachment') && allAttachments.length > 0 ? {\n target: allAttachments,\n targetName: `post #${post.id} -> attachments`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.attachments,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content,\n isAttachment: true\n } : null,\n\n __getEmbedTask()\n );\n\n return batchResult;\n }\n\n async #processLinkedAttachments(post: Post, signal?: AbortSignal) {\n if (!post.linkedAttachments || post.linkedAttachments.length === 0) {\n return;\n }\n this.log('debug', `Process linked attachments of post #${post.id}`);\n for (const la of post.linkedAttachments) {\n const laStr = `[#${post.id} -> #${la.mediaId}]`;\n // Only process linked attachment where its postId is not the same as current one being processed.\n // If same as current one, then linked attachment would already be in the current post data.\n if (la.postId === post.id) {\n this.log('debug', `Linked attachment ${laStr} has same parent post`);\n }\n else {\n const apiURL = URLHelper.constructPostsAPIURL({ postId: la.postId });\n let json;\n try {\n this.log('debug', `Linked attachment ${laStr} belongs to post #${la.postId}`);\n json = (await this.fetcher.get({\n url: apiURL,\n type: 'json',\n maxRetries: this.config.request.maxRetries,\n signal }\n )).json;\n }\n catch (error) {\n if (signal?.aborted) {\n throw error;\n }\n else {\n this.log('error', `Error fetching linked attachment ${laStr} from parent post #${la.postId}: API request failed for \"${apiURL}\": `, error);\n }\n json = null;\n }\n if (json) {\n const parser = new PostParser();\n const parentPost = parser.parsePostsAPIResponse(json, apiURL).items[0];\n if (!parentPost) {\n this.log('error', `Error fetching linked attachment ${laStr} from parent post #${la.postId}: post data not found in response of \"${apiURL}\"`);\n }\n else {\n if (!parentPost.isViewable) {\n this.log('warn', `Parent post #${la.postId} of linked attachment ${laStr} is not viewable by user`);\n }\n else {\n const attachment = parentPost.attachments.find((att) => att.id === la.mediaId);\n if (!attachment) {\n this.log('warn', `Attachment not found in parent post #${la.postId} of linked attachment ${laStr}`);\n }\n else {\n la.downloadable = attachment;\n this.log('debug', `Obtained attachment from parent post #${la.postId} of linked attachment ${laStr}`);\n }\n }\n }\n }\n }\n }\n }\n\n async #fetchComments(post: Post, signal?: AbortSignal, accumulated?: CommentList & { nextURL: string; }): Promise<Comment[]> {\n if (!post.commentCount) {\n this.log('debug', `Comment count is zero for post #${post.id}`);\n return [];\n }\n if (this.checkAbortSignal(signal)) {\n return [];\n }\n let commentsURL;\n if (!accumulated) {\n this.log('info', `Fetch comments for post #${post.id}`);\n commentsURL = URLHelper.constructPostCommentsAPIURL({ postId: post.id });\n }\n else {\n this.log('debug', `Fetch next batch of comments for post #${post.id}`);\n commentsURL = accumulated.nextURL;\n }\n const { json } = await this.commonFetchAPI(commentsURL, signal);\n const parser = new CommentParser(this.logger);\n if (json) {\n const comments = parser.parseCommentsAPIResponse(json, commentsURL);\n this.log('debug', `Fetched ${comments.items.length} comments for post #${post.id}`);\n if (comments.items.length > 0 && comments.nextURL) {\n let _acc;\n if (!accumulated) {\n _acc = {\n url: comments.url,\n items: comments.items,\n nextURL: comments.nextURL,\n total: comments.total\n };\n }\n else {\n _acc = accumulated;\n _acc.url = comments.url;\n _acc.items.push(...comments.items);\n _acc.nextURL = comments.nextURL;\n }\n return this.#fetchComments(post, signal, _acc);\n }\n else {\n const result = accumulated ? [ ...accumulated.items, ...comments.items ] : comments.items;\n this.log('debug', `Total ${result.length} comments fetched for post #${post.id}`);\n for (const comment of result) {\n if (comment.replyCount > 0) {\n comment.replies = await this.#fetchCommentReplies(comment, signal);\n }\n }\n return result;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return [];\n }\n else {\n this.log('warn', `Failed to fetch comments for post #${post.id}`);\n return [];\n }\n }\n\n async #fetchCommentReplies(comment: Comment, signal?: AbortSignal, accumulated?: CommentReplyList & { nextURL: string; }): Promise<CommentReply[]> {\n if (!comment.replyCount) {\n this.log('debug', `Reply count is zero for comment #${comment.id}`);\n return [];\n }\n if (this.checkAbortSignal(signal)) {\n return [];\n }\n let repliesURL;\n if (!accumulated) {\n this.log('debug', `Fetch replies to comment #${comment.id}`);\n repliesURL = URLHelper.constructPostCommentsAPIURL({ commentId: comment.id, replies: true });\n }\n else {\n this.log('debug', `Fetch next batch of replies to comment #${comment.id}`);\n repliesURL = accumulated.nextURL;\n }\n const { json } = await this.commonFetchAPI(repliesURL, signal);\n const parser = new CommentParser(this.logger);\n if (json) {\n const replies = parser.parseCommentsAPIResponse(json, repliesURL, true);\n this.log('debug', `Fetched ${replies.items.length} replies to comment #${comment.id}`);\n if (replies.items.length > 0 && replies.nextURL) {\n let _acc;\n if (!accumulated) {\n _acc = {\n url: replies.url,\n items: replies.items,\n nextURL: replies.nextURL,\n total: replies.total\n };\n }\n else {\n _acc = accumulated;\n _acc.url = replies.url;\n _acc.items.push(...replies.items);\n _acc.nextURL = replies.nextURL;\n }\n return this.#fetchCommentReplies(comment, signal, _acc);\n }\n else {\n const result = accumulated ? [ ...accumulated.items, ...replies.items ] : replies.items;\n this.log('debug', `Total ${result.length} replies fetched for comment #${comment.id}`);\n return result;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return [];\n }\n else {\n this.log('warn', `Failed to fetch replies to comment #${comment.id}`);\n return [];\n }\n }\n\n async #saveCollection(collection: Collection, campaign: Campaign, signal?: AbortSignal) {\n const db = await this.db();\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (!this.config.include.contentInfo) {\n db.saveCollection(collection, campaign);\n return;\n }\n\n let batch: DownloadTaskBatch | null = null;\n const abortHandler = () => {\n void (async () => {\n if (batch) {\n await batch.abort();\n }\n })();\n };\n if (signal) {\n signal.addEventListener('abort', abortHandler, { once: true });\n }\n\n this.log('info', `Save collection info #${collection.id}`);\n this.emit('targetBegin', { target: collection });\n this.emit('phaseBegin', { target: collection, phase: 'saveInfo' });\n\n // Step 1: create collection directories\n const collectionDirs = this.fsHelper.getCollectionsDir(campaign, collection);\n this.log('debug', 'Campaign directories: ', collectionDirs);\n this.fsHelper.createDir(collectionDirs.root);\n\n // Step 2: save summary and raw json\n const summary = generateCollectionSummary(collection);\n const summaryFile = path.resolve(collectionDirs.root, 'info.txt');\n const saveSummaryResult = await this.fsHelper.writeTextFile(summaryFile, summary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveSummaryResult, collection, 'collection summary');\n\n const collectionRawFile = path.resolve(collectionDirs.root, 'collection-api.json');\n const saveCollectionRawResult = await this.fsHelper.writeTextFile(\n collectionRawFile, collection.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(saveCollectionRawResult, collection, 'collection API data');\n\n this.emit('phaseEnd', { target: collection, phase: 'saveInfo' });\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n // Step 3: download collection media items\n if (collection.thumbnail) {\n this.emit('phaseBegin', { target: collection, phase: 'saveMedia' });\n const collectionMedia: Downloadable[] = [\n collection.thumbnail\n ];\n batch = (await this.createDownloadTaskBatch(\n `Collection #${collection.id} (${collection.title})`,\n signal,\n {\n target: collectionMedia,\n targetName: `collection #${campaign.id} -> thumbnail`,\n src: collection,\n dirs: {\n campaign: this.fsHelper.getCampaignDirs(campaign).root,\n main: collectionDirs.root,\n thumbnails: null\n },\n fileExistsAction: this.config.fileExistsAction.info\n }\n )).batch;\n if (this.checkAbortSignal(signal)) {\n return;\n }\n batch.prestart();\n this.emit('phaseBegin', { target: collection, phase: 'batchDownload', batch });\n await batch.start();\n await batch.destroy();\n this.emit('phaseEnd', { target: collection, phase: 'batchDownload' });\n this.emit('phaseEnd', { target: collection, phase: 'saveMedia' });\n\n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n // Step 4: save to DB\n db.saveCollection(collection, campaign);\n\n // Done\n this.log('info', 'Done saving collection info');\n this.emit('targetEnd', { target: collection, isSkipped: false });\n }\n\n}\n"]}
1
+ {"version":3,"file":"PostDownloader.js","sourceRoot":"","sources":["../../src/downloaders/PostDownloader.ts"],"names":[],"mappings":"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","sourcesContent":["import URLHelper from '../utils/URLHelper.js';\nimport Downloader, { type DownloaderConfig, type DownloaderStartParams } from './Downloader.js';\nimport PostParser from '../parsers/PostParser.js';\nimport { type Collection, type Post } from '../entities/Post.js';\nimport { type Downloadable, isYouTubeEmbed } from '../entities/Downloadable.js';\nimport StatusCache, { type StatusCacheValidationScope } from './cache/StatusCache.js';\nimport { generatePostEmbedSummary, generatePostSummary } from './templates/PostInfo.js';\nimport path from 'path';\nimport { TargetSkipReason } from './DownloaderEvent.js';\nimport DownloadTaskFactory from './task/DownloadTaskFactory.js';\nimport PostsFetcher from './PostsFetcher.js';\nimport CommentParser from '../parsers/CommentParser.js';\nimport { type Comment, type CommentList, type CommentReply, type CommentReplyList } from '../entities/Comment.js';\nimport { generatePostCommentsSummary } from './templates/CommentInfo.js';\nimport { type PostDirectories } from '../utils/FSHelper.js';\nimport { type DBInstance } from '../browse/db/index.js';\nimport { type AttachmentMediaItem } from '../entities/MediaItem.js';\nimport type Logger from '../utils/logging/Logger.js';\nimport { type DeepRequired } from '../utils/Misc.js';\nimport { type Campaign } from '../entities/Campaign.js';\nimport type DownloadTaskBatch from './task/DownloadTaskBatch.js';\nimport { generateCollectionSummary } from './templates/CollectionInfo.js';\nimport { IncludeCriteriaHelper } from './IncludeCriteriaHelper.js';\n\nexport interface PostDownloaderContext {\n skipSaveCampaign?: boolean;\n keepLoggerOpen?: boolean;\n keepDBOpen?: boolean;\n}\n\nexport default class PostDownloader extends Downloader<Post> {\n\n static version = '1.1.1';\n\n name = 'PostDownloader';\n\n #startPromise: Promise<void> | null = null;\n #context: DeepRequired<PostDownloaderContext>;\n\n constructor(\n config: DownloaderConfig<Post>,\n db: () => Promise<DBInstance>,\n logger?: Logger | null,\n context?: PostDownloaderContext\n ) {\n super(config, db, logger);\n this.#context = {\n skipSaveCampaign: context?.skipSaveCampaign ?? false,\n keepLoggerOpen: context?.keepLoggerOpen ?? false,\n keepDBOpen: context?.keepDBOpen ?? false\n };\n }\n\n doStart(params?: DownloaderStartParams): Promise<void> {\n if (this.#startPromise) {\n throw Error('Downloader already running');\n }\n this.#startPromise = this.#doStart(params)\n .finally(() => {\n this.#startPromise = null;\n });\n return this.#startPromise;\n }\n\n async #doStart(params?: DownloaderStartParams): Promise<void> {\n try {\n const { signal } = params || {};\n const postFetch = this.config.postFetch;\n const db = await this.db();\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (postFetch.type === 'byUser') {\n this.log('info', `Targeting posts by '${postFetch.vanity}'`);\n }\n else if (postFetch.type === 'byUserId') {\n this.log('info', `Targeting posts by user #${postFetch.userId}`);\n }\n else if (postFetch.type === 'byCollection') {\n this.log('info', `Targeting posts in collection #${postFetch.collectionId}`);\n }\n else if (postFetch.type === 'byURL') {\n this.log('info', `Targeting posts at '${postFetch.url}'`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Target post given by API data in \"${postFetch.filePath}\"`);\n }\n else { // Single\n this.log('info', `Targeting post #${postFetch.postId}`);\n }\n if (this.#isFetchingMultiplePosts(postFetch) && postFetch.filters) {\n const filterStr = Object.entries(postFetch.filters).map(([ key, value ]) => `${key}=${value}`).join('; ');\n if (filterStr) {\n this.log('info', `Filters: ${filterStr}`);\n }\n }\n\n // Step 1: Get posts (if by user) or target post\n const postsFetcher = new PostsFetcher({\n config: this.config,\n fetcher: this.fetcher,\n logger: this.logger,\n signal\n });\n postsFetcher.on('statusChange', ({current}) => {\n if (current.status === 'running') {\n this.emit('fetchBegin', { targetType: postsFetcher.getTargetType() });\n }\n });\n postsFetcher.begin();\n\n // Step 2: download posts in each fetched list\n let downloaded = 0;\n let skippedUnviewable = 0;\n let skippedRedundant = 0;\n let skippedUnmetMediaTypeCriteria = 0;\n let skippedNotInTier = 0;\n let skippedPublishDateOutOfRange = 0;\n let campaignSaved = false;\n let stopConditionMet = false;\n const savedCollectionIds: string[] = [];\n const postsParser = new PostParser(this.logger);\n while (postsFetcher.hasNext()) {\n const { list, aborted, error } = await postsFetcher.next();\n if (!list || aborted) {\n break;\n }\n if (!list && error) {\n this.emit('end', { aborted: false, error, message: 'PostsFetcher error' });\n return;\n }\n if (!this.#context.skipSaveCampaign && !campaignSaved && list.items[0]?.campaign) {\n await this.saveCampaignInfo(list.items[0].campaign, signal);\n campaignSaved = true;\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n for (const _post of list.items) {\n\n if (stopConditionMet) {\n break;\n }\n\n let post = _post;\n\n // Collections\n if (post.campaign && post.collections) {\n for (const collection of post.collections) {\n if (!savedCollectionIds.includes(collection.id)) {\n try {\n await this.#saveCollection(collection, post.campaign);\n savedCollectionIds.push(collection.id);\n }\n catch (error) {\n this.log('error', `Failed to save collection #${collection.id}:`, error);\n }\n }\n else {\n this.log('debug', `Collection #${collection.id} already processed`);\n }\n }\n }\n\n if (this.#isFetchingMultiplePosts(postFetch)) {\n // Refresh to ensure media links have not expired\n this.log('debug', `Refresh post #${_post.id}`);\n const postURL = URLHelper.constructPostsAPIURL({ postId: _post.id });\n const { json } = await this.commonFetchAPI(postURL, signal);\n let refreshed: Post | null = null;\n if (json) {\n refreshed = postsParser.parsePostsAPIResponse(json, postURL).items[0] || null;\n if (!refreshed) {\n this.log('warn', `Refreshed post #${_post.id} but got empty value - going to use existing data`);\n }\n else if (refreshed.id !== _post.id) {\n this.log('warn', `Refreshed post #${_post.id} but ID mismatch - going to use existing data`);\n refreshed = null;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return;\n }\n else {\n this.log('warn', `Failed to refresh post #${_post.id} - going to use existing data`);\n }\n if (refreshed) {\n this.log('debug', `Use refreshed post data #${refreshed.id}`);\n post = refreshed;\n }\n }\n\n this.emit('targetBegin', { target: post });\n\n // Step 4.1: post directories\n const postDirs = this.fsHelper.getPostDirs(post);\n this.log('debug', 'Post directories:', postDirs);\n\n // Step 4.2: Check with status cache\n const statusCache = StatusCache.getInstance(this.config, postDirs.statusCache, this.logger);\n const statusCacheValidation = statusCache.validate(post, postDirs.root, this.config)\n if (!statusCacheValidation.invalidated) {\n this.log('info', `Skipped downloading post #${post.id}: already downloaded and nothing has changed since last download`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.AlreadyDownloaded,\n skipMessage: 'Target already downloaded and nothing has changed since last download'\n });\n skippedRedundant++;\n if (this.config.stopOn === 'postPreviouslyDownloaded' || \n this.config.stopOn === 'previouslyDownloaded'\n ) {\n stopConditionMet = true;\n }\n continue;\n }\n \n switch ((await this.#doDownload(\n post,\n postDirs,\n statusCacheValidation.scope,\n statusCache,\n db,\n signal\n )).status) {\n case 'aborted':\n return;\n case 'downloaded':\n downloaded++;\n break;\n case 'skippedNotInTier':\n skippedNotInTier++;\n break;\n case 'skippedPublishDateOutOfRange':\n skippedPublishDateOutOfRange++;\n if (this.config.stopOn === 'postPublishDateOutOfRange' ||\n this.config.stopOn === 'publishDateOutOfRange'\n ) {\n stopConditionMet = true;\n }\n break;\n case 'skippedUnmetMediaTypeCriteria':\n skippedUnmetMediaTypeCriteria++;\n break;\n case 'skippedUnviewable':\n skippedUnviewable++;\n break;\n }\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n if (stopConditionMet) {\n break;\n }\n }\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (stopConditionMet && this.#isFetchingMultiplePosts(postFetch)) {\n this.log('info', `Stop downloader: stop condition \"${this.config.stopOn}\" met`)\n }\n\n // Done\n if (postFetch.type === 'byUser') {\n this.log('info', `Done downloading posts by '${postFetch.vanity}'`);\n }\n else if (postFetch.type === 'byUserId') {\n this.log('info', `Done downloading posts by user #${postFetch.userId}`);\n }\n else if (postFetch.type === 'byCollection') {\n this.log('info', `Done downloading posts in collection #${postFetch.collectionId}`);\n }\n else if (postFetch.type === 'byURL') {\n this.log('info', `Done downloading posts at '${postFetch.url}'`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Done downloading post given in \"${postFetch.filePath}\"`);\n }\n else {\n this.log('info', `Done downloading post #${postFetch.postId}`);\n }\n let endMessage = 'Done';\n if (this.#isFetchingMultiplePosts(postFetch)) {\n const skippedStrParts: string[] = [];\n if (skippedUnviewable) {\n skippedStrParts.push(`${skippedUnviewable} unviewable`);\n }\n if (skippedRedundant) {\n skippedStrParts.push(`${skippedRedundant} redundant`);\n }\n if (skippedUnmetMediaTypeCriteria) {\n skippedStrParts.push(`${skippedUnmetMediaTypeCriteria} with unmet media type criteria`);\n }\n if (skippedNotInTier) {\n skippedStrParts.push(`${skippedNotInTier} not in tier`);\n }\n if (skippedPublishDateOutOfRange) {\n skippedStrParts.push(`${skippedPublishDateOutOfRange} with publish date out of range`);\n }\n const skippedStr = skippedStrParts.length > 0 ? ` (skipped: ${skippedStrParts.join(', ')})` : '';\n endMessage = `Total ${downloaded} / ${postsFetcher.getTotal()} posts processed${skippedStr}`;\n this.log('info', endMessage);\n }\n this.emit('end', { aborted: false, message: endMessage });\n }\n finally {\n if (!this.#context.keepDBOpen) {\n await this.closeDB();\n }\n if (this.logger && !this.#context.keepLoggerOpen) {\n await this.logger.end();\n }\n }\n }\n\n async #doDownload(\n post: Post,\n postDirs: PostDirectories,\n scope: StatusCacheValidationScope<Post>,\n statusCache: StatusCache,\n db: DBInstance,\n signal?: AbortSignal\n ): Promise<{status: 'skippedUnviewable' | 'skippedUnmetMediaTypeCriteria' | 'skippedNotInTier' | 'skippedPublishDateOutOfRange' | 'aborted' | 'downloaded' }> {\n this.log('info', `Download post #${post.id} (${post.title})`);\n\n const downloadPost = scope.includes('post');\n const downloadComments = scope.includes('comments');\n \n // Step 1: Check whether we should download post\n const criteriaHelper = new IncludeCriteriaHelper(this.logger);\n const criteriaCheck = criteriaHelper.checkPost(post, this.config);\n if (!criteriaCheck.ok) {\n switch (criteriaCheck.reason) {\n case 'unviewable': {\n this.log('warn', `Skipped downloading post #${post.id}: not viewable by current user`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.Inaccessible,\n skipMessage: 'Target is not viewable by current user'\n });\n return {\n status: 'skippedUnviewable'\n };\n }\n case 'unmetMediaTypeCriteria': {\n this.log('warn', `Skipped downloading post #${post.id}: unmet media type criteria`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.UnmetMediaTypeCriteria,\n skipMessage: 'Target does not meet media type criteria'\n });\n return {\n status: 'skippedUnmetMediaTypeCriteria'\n };\n }\n case 'notInTier': {\n this.log('warn', `Skipped downloading post #${post.id}: not in tier`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.NotInTier,\n skipMessage: 'Target not in tier'\n });\n return {\n status: 'skippedNotInTier'\n };\n }\n case 'publishDateOutOfRange': {\n this.log('warn', `Skipped downloading post #${post.id}: publish date out of range`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.PublishDateOutOfRange,\n skipMessage: 'Publish date out of range'\n });\n return {\n status: 'skippedPublishDateOutOfRange'\n };\n }\n }\n }\n\n if (!post.isViewable && this.config.include.lockedContent) {\n this.log('warn', `Post #${post.id} is not viewable by current user`);\n }\n\n if (!downloadPost && downloadComments) {\n this.log('info', `Previously downloaded post #${post.id} - refresh comments only`);\n }\n\n let hasDownloadPostError = false;\n if (downloadPost) {\n // Step 2: Save post info\n if (this.config.include.contentInfo) {\n this.log('info', `Save post info #${post.id}`);\n this.emit('phaseBegin', { target: post, phase: 'saveInfo' });\n this.fsHelper.createDir(postDirs.info);\n // Post raw data might not be complete or consistent with other posts in the collection.\n // Fetch directly from API.\n // Strictly speaking, we should check for 'error' in results, but since it's not going to be fatal we'll just skip it.\n const { json: fetchedPostAPIData } = await this.commonFetchAPI(\n URLHelper.constructPostsAPIURL({\n postId: post.id,\n campaignId: post.campaign?.id\n }),\n signal\n );\n\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n\n // Step 3. Save summary and raw json\n const summary = generatePostSummary(post);\n const summaryFile = path.resolve(postDirs.info, 'info.txt');\n const saveSummaryResult = await this.fsHelper.writeTextFile(summaryFile, summary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveSummaryResult, post, 'post summary');\n\n const postRawFile = path.resolve(postDirs.info, 'post-api.json');\n const savePostRawResult = await this.fsHelper.writeTextFile(\n postRawFile, fetchedPostAPIData || post.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(savePostRawResult, post, 'post API data');\n this.emit('phaseEnd', { target: post, phase: 'saveInfo' });\n\n // (Downloading of info media items deferred to the next step)\n }\n\n if (this.config.include.previewMedia || this.config.include.contentMedia) {\n this.emit('phaseBegin', { target: post, phase: 'saveMedia' });\n }\n\n // Step 4: save embed info\n if (post.embed && this.config.include.contentMedia) {\n this.log('info', `Save embed info of post #${post.id}`);\n this.fsHelper.createDir(postDirs.embed);\n const embedSummary = generatePostEmbedSummary(post.embed);\n let embedFilename;\n switch (post.embed.type) {\n case 'videoEmbed':\n embedFilename = 'embedded-video.txt';\n break;\n case 'linkEmbed':\n embedFilename = 'embedded-link.txt';\n break;\n default:\n embedFilename = 'embedded-unknown.txt';\n }\n const embedFile = path.resolve(postDirs.embed, embedFilename);\n const saveSummaryResult = await this.fsHelper.writeTextFile(embedFile, embedSummary, this.config.fileExistsAction.content);\n this.logWriteTextFileResult(saveSummaryResult, post, 'embed info');\n }\n\n // Step 5: create download tasks\n let createTaskErrorCount = 0;\n if (this.config.include.previewMedia ||\n this.config.include.contentMedia ||\n this.config.include.contentInfo) {\n\n const batchResult = await this.#createDownloadTaskBatchForPost(post, postDirs, signal);\n const { batch } = batchResult; \n createTaskErrorCount += batchResult.errorCount;\n\n const abortHandler = () => {\n void (async () => {\n this.log('info', 'Abort signal received');\n if (batch) {\n await batch.abort();\n }\n })();\n };\n if (signal) {\n signal.addEventListener('abort', abortHandler, { once: true });\n }\n\n try {\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n \n if (this.config.include.contentInfo) {\n const infoElements: Downloadable[] = [];\n if (post.coverImage) {\n infoElements.push(post.coverImage);\n }\n if (post.thumbnail) {\n infoElements.push(post.thumbnail);\n }\n if (infoElements.length > 0) {\n const { errorCount } = await this.addToDownloadTaskBatch(batch,\n signal,\n {\n target: infoElements,\n targetName: `post #${post.id} -> info elements`,\n src: post,\n dirs: {\n campaign: post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null,\n main: postDirs.info,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.info\n }\n );\n createTaskErrorCount += errorCount;\n }\n }\n \n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n \n batch.prestart();\n this.log('info', `Download batch created (#${batch.id}): ${batch.getTasks('pending').length} downloads pending`);\n this.emit('phaseBegin', { target: post, phase: 'batchDownload', batch });\n \n await batch.start();\n\n hasDownloadPostError = batch.getTasks('error').length > 0 || createTaskErrorCount > 0;\n\n await batch.destroy();\n }\n finally {\n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n }\n\n this.emit('phaseEnd', { target: post, phase: 'batchDownload'});\n }\n\n if (this.config.include.previewMedia || this.config.include.contentMedia) {\n this.emit('phaseEnd', { target: post, phase: 'saveMedia' });\n }\n }\n\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n\n // Step 6: Fetch and save comments (only available if post is viewable)\n let comments: Comment[] | null = null;\n if (downloadComments && this.config.include.comments && post.isViewable) {\n if (post.commentCount > 0) {\n comments = await this.#fetchComments(post, signal);\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n if (comments.length > 0) {\n this.fsHelper.createDir(postDirs.info);\n const commentsFile = path.resolve(postDirs.info, 'comments.txt');\n const commentsSummary = generatePostCommentsSummary(comments);\n const saveCommentsResult = await this.fsHelper.writeTextFile(commentsFile, commentsSummary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveCommentsResult, post, `${comments.length} comments`);\n }\n else {\n this.log('warn', `Expecting ${post.commentCount} comments for post #${post.id} but got none`);\n }\n }\n else {\n this.log('info', `No comments available for post #${post.id}`)\n }\n }\n\n // Step 7: Update status cache\n statusCache.updateOnDownload(post, postDirs.root, hasDownloadPostError, this.config);\n\n // Step 8: Save to DB\n let skipDB = false;\n if (!post.isViewable) {\n // Skip if existing db record (if any) refers to viewable post\n const dbPost = db.getContent(post.id, 'post');\n skipDB = dbPost !== null && dbPost.isViewable;\n }\n if (!skipDB) {\n db.saveContent(post);\n if (comments) {\n db.savePostComments(post, comments);\n }\n }\n else {\n this.log('info', `Skip overwrite existing viewable post #${post.id} in DB with current unviewable version`);\n }\n\n this.emit('targetEnd', { target: post, isSkipped: false });\n\n return {\n status: 'downloaded'\n };\n }\n\n #isFetchingMultiplePosts(postFetch: DownloaderConfig<Post>['postFetch']): postFetch is DownloaderConfig<Post>['postFetch'] & { type: 'byUser' | 'byUserId' | 'byCollection' | 'byURL' } {\n return postFetch.type === 'byUser' || postFetch.type === 'byUserId' || postFetch.type === 'byCollection' || postFetch.type === 'byURL';\n }\n\n async __getCampaign(signal?: AbortSignal) {\n let url: string | null;\n const postFetch = this.config.postFetch;\n switch (postFetch.type) {\n case 'byUser':\n url = URLHelper.constructCampaignPageURL({ vanity: postFetch.vanity });\n break;\n case 'byUserId':\n url = URLHelper.constructCampaignPageURL({ userId: postFetch.userId });\n break;\n default:\n url = null;\n }\n if (!url) {\n throw Error('Internal error: invalid config');\n }\n const postsFetcher = new PostsFetcher({\n config: this.config,\n fetcher: this.fetcher,\n logger: this.logger,\n signal\n });\n const { campaignId } = await postsFetcher.getInitialData(url);\n const postsParser = new PostParser(this.logger);\n const res = await this.fetchCampaign(campaignId);\n if (signal?.aborted) {\n throw new Error('Aborted');\n }\n if (res.error) {\n throw res.error;\n }\n return postsParser.parseCampaignAPIResponse(res.json);\n }\n\n async #createDownloadTaskBatchForPost(post: Post, postDirs: ReturnType<typeof this.fsHelper['getPostDirs']>, signal?: AbortSignal) {\n\n const incPreview = this.config.include.previewMedia;\n const incContent = this.config.include.contentMedia;\n\n const __incPreview = (mediaType: 'audio' | 'video' | 'image') => {\n if (typeof incPreview === 'boolean') {\n return incPreview;\n }\n return incPreview.includes(mediaType);\n };\n\n const __incContent = (mediaType: 'audio' | 'video' | 'image' | 'attachment') => {\n if (typeof incContent === 'boolean') {\n return incContent;\n }\n return incContent.includes(mediaType);\n };\n\n const __getEmbedTask = () => {\n if (!post.embed) {\n return null;\n }\n\n const hasEmbedDownloader = DownloadTaskFactory.findEmbedDownloader(this.config.embedDownloaders, post.embed.provider);\n const isDownloadableVideo = isYouTubeEmbed(post.embed) || (post.embed.type === 'videoEmbed' && hasEmbedDownloader);\n const isDownloadableOther = !isYouTubeEmbed(post.embed) && post.embed.type !== 'videoEmbed' && hasEmbedDownloader;\n \n if ((isDownloadableVideo && __incContent('video')) || isDownloadableOther) {\n const embedType = post.embed.type === 'videoEmbed' ? ' video' : post.embed.type === 'linkEmbed' ? ' link' : '';\n return {\n target: [ post.embed ],\n targetName: `post #${post.id} -> embedded ${post.embed.provider}${embedType}`,\n src: post,\n dirs: {\n campaign: post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null,\n main: postDirs.embed,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n };\n }\n \n return null;\n }\n\n const campaignDir = post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null;\n\n await this.#processLinkedAttachments(post);\n const downloadableLinkedAttachments = post.linkedAttachments?.reduce<Downloadable<AttachmentMediaItem>[]>((result, att) => {\n if (att.downloadable) {\n result.push(att.downloadable);\n }\n return result;\n }, []) || [];\n\n const allAttachments = [...post.attachments, ...downloadableLinkedAttachments];\n\n const batchResult = this.createDownloadTaskBatch(\n `Post #${post.id} (${post.title})`,\n signal,\n\n __incPreview('audio') && post.audioPreview ? {\n target: [ post.audioPreview ],\n targetName: `post #${post.id} -> audio preview`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.audioPreview,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incPreview('video') && post.videoPreview ? {\n target: [ post.videoPreview ],\n targetName: `post #${post.id} -> video preview`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.videoPreview,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n /**\n * If post is not viewable by current user, its images will be\n * blurry and we should categorize them as image previews.\n */\n __incPreview('image') && post.images.length > 0 && !post.isViewable ? {\n target: post.images,\n targetName: `post #${post.id} -> image previews`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.imagePreviews,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n /**\n * If post is not viewable, audio data should have no URL, so check and\n * skip if this is the case.\n */\n __incContent('audio') && post.audio && (post.isViewable || (post.audio.type === 'audio' && post.audio.url)) ? {\n target: [ post.audio ],\n targetName: `post #${post.id} -> audio`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.audio,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('video') && post.video ? {\n target: [ post.video ],\n targetName: `post #${post.id} -> video`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.video,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('image') && post.images.length > 0 && post.isViewable ? {\n target: post.images,\n targetName: `post #${post.id} -> images`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.images,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('attachment') && allAttachments.length > 0 ? {\n target: allAttachments,\n targetName: `post #${post.id} -> attachments`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.attachments,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content,\n isAttachment: true\n } : null,\n\n __getEmbedTask()\n );\n\n return batchResult;\n }\n\n async #processLinkedAttachments(post: Post, signal?: AbortSignal) {\n if (!post.linkedAttachments || post.linkedAttachments.length === 0) {\n return;\n }\n this.log('debug', `Process linked attachments of post #${post.id}`);\n for (const la of post.linkedAttachments) {\n const laStr = `[#${post.id} -> #${la.mediaId}]`;\n // Only process linked attachment where its postId is not the same as current one being processed.\n // If same as current one, then linked attachment would already be in the current post data.\n if (la.postId === post.id) {\n this.log('debug', `Linked attachment ${laStr} has same parent post`);\n }\n else {\n const apiURL = URLHelper.constructPostsAPIURL({ postId: la.postId });\n let json;\n try {\n this.log('debug', `Linked attachment ${laStr} belongs to post #${la.postId}`);\n json = (await this.fetcher.get({\n url: apiURL,\n type: 'json',\n maxRetries: this.config.request.maxRetries,\n signal }\n )).json;\n }\n catch (error) {\n if (signal?.aborted) {\n throw error;\n }\n else {\n this.log('error', `Error fetching linked attachment ${laStr} from parent post #${la.postId}: API request failed for \"${apiURL}\": `, error);\n }\n json = null;\n }\n if (json) {\n const parser = new PostParser();\n const parentPost = parser.parsePostsAPIResponse(json, apiURL).items[0];\n if (!parentPost) {\n this.log('error', `Error fetching linked attachment ${laStr} from parent post #${la.postId}: post data not found in response of \"${apiURL}\"`);\n }\n else {\n if (!parentPost.isViewable) {\n this.log('warn', `Parent post #${la.postId} of linked attachment ${laStr} is not viewable by user`);\n }\n else {\n const attachment = parentPost.attachments.find((att) => att.id === la.mediaId);\n if (!attachment) {\n this.log('warn', `Attachment not found in parent post #${la.postId} of linked attachment ${laStr}`);\n }\n else {\n la.downloadable = attachment;\n this.log('debug', `Obtained attachment from parent post #${la.postId} of linked attachment ${laStr}`);\n }\n }\n }\n }\n }\n }\n }\n\n async #fetchComments(post: Post, signal?: AbortSignal, accumulated?: CommentList & { nextURL: string; }): Promise<Comment[]> {\n if (!post.commentCount) {\n this.log('debug', `Comment count is zero for post #${post.id}`);\n return [];\n }\n if (this.checkAbortSignal(signal)) {\n return [];\n }\n let commentsURL;\n if (!accumulated) {\n this.log('info', `Fetch comments for post #${post.id}`);\n commentsURL = URLHelper.constructPostCommentsAPIURL({ postId: post.id });\n }\n else {\n this.log('debug', `Fetch next batch of comments for post #${post.id}`);\n commentsURL = accumulated.nextURL;\n }\n const { json } = await this.commonFetchAPI(commentsURL, signal);\n const parser = new CommentParser(this.logger);\n if (json) {\n const comments = parser.parseCommentsAPIResponse(json, commentsURL);\n this.log('debug', `Fetched ${comments.items.length} comments for post #${post.id}`);\n if (comments.items.length > 0 && comments.nextURL) {\n let _acc;\n if (!accumulated) {\n _acc = {\n url: comments.url,\n items: comments.items,\n nextURL: comments.nextURL,\n total: comments.total\n };\n }\n else {\n _acc = accumulated;\n _acc.url = comments.url;\n _acc.items.push(...comments.items);\n _acc.nextURL = comments.nextURL;\n }\n return this.#fetchComments(post, signal, _acc);\n }\n else {\n const result = accumulated ? [ ...accumulated.items, ...comments.items ] : comments.items;\n this.log('debug', `Total ${result.length} comments fetched for post #${post.id}`);\n for (const comment of result) {\n if (comment.replyCount > 0) {\n comment.replies = await this.#fetchCommentReplies(comment, signal);\n }\n }\n return result;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return [];\n }\n else {\n this.log('warn', `Failed to fetch comments for post #${post.id}`);\n return [];\n }\n }\n\n async #fetchCommentReplies(comment: Comment, signal?: AbortSignal, accumulated?: CommentReplyList & { nextURL: string; }): Promise<CommentReply[]> {\n if (!comment.replyCount) {\n this.log('debug', `Reply count is zero for comment #${comment.id}`);\n return [];\n }\n if (this.checkAbortSignal(signal)) {\n return [];\n }\n let repliesURL;\n if (!accumulated) {\n this.log('debug', `Fetch replies to comment #${comment.id}`);\n repliesURL = URLHelper.constructPostCommentsAPIURL({ commentId: comment.id, replies: true });\n }\n else {\n this.log('debug', `Fetch next batch of replies to comment #${comment.id}`);\n repliesURL = accumulated.nextURL;\n }\n const { json } = await this.commonFetchAPI(repliesURL, signal);\n const parser = new CommentParser(this.logger);\n if (json) {\n const replies = parser.parseCommentsAPIResponse(json, repliesURL, true);\n this.log('debug', `Fetched ${replies.items.length} replies to comment #${comment.id}`);\n if (replies.items.length > 0 && replies.nextURL) {\n let _acc;\n if (!accumulated) {\n _acc = {\n url: replies.url,\n items: replies.items,\n nextURL: replies.nextURL,\n total: replies.total\n };\n }\n else {\n _acc = accumulated;\n _acc.url = replies.url;\n _acc.items.push(...replies.items);\n _acc.nextURL = replies.nextURL;\n }\n return this.#fetchCommentReplies(comment, signal, _acc);\n }\n else {\n const result = accumulated ? [ ...accumulated.items, ...replies.items ] : replies.items;\n this.log('debug', `Total ${result.length} replies fetched for comment #${comment.id}`);\n return result;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return [];\n }\n else {\n this.log('warn', `Failed to fetch replies to comment #${comment.id}`);\n return [];\n }\n }\n\n async #saveCollection(collection: Collection, campaign: Campaign, signal?: AbortSignal) {\n const db = await this.db();\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (!this.config.include.contentInfo) {\n db.saveCollection(collection, campaign);\n return;\n }\n\n let batch: DownloadTaskBatch | null = null;\n const abortHandler = () => {\n void (async () => {\n if (batch) {\n await batch.abort();\n }\n })();\n };\n if (signal) {\n signal.addEventListener('abort', abortHandler, { once: true });\n }\n\n this.log('info', `Save collection info #${collection.id}`);\n this.emit('targetBegin', { target: collection });\n this.emit('phaseBegin', { target: collection, phase: 'saveInfo' });\n\n // Step 1: create collection directories\n const collectionDirs = this.fsHelper.getCollectionsDir(campaign, collection);\n this.log('debug', 'Campaign directories: ', collectionDirs);\n this.fsHelper.createDir(collectionDirs.root);\n\n // Step 2: save summary and raw json\n const summary = generateCollectionSummary(collection);\n const summaryFile = path.resolve(collectionDirs.root, 'info.txt');\n const saveSummaryResult = await this.fsHelper.writeTextFile(summaryFile, summary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveSummaryResult, collection, 'collection summary');\n\n const collectionRawFile = path.resolve(collectionDirs.root, 'collection-api.json');\n const saveCollectionRawResult = await this.fsHelper.writeTextFile(\n collectionRawFile, collection.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(saveCollectionRawResult, collection, 'collection API data');\n\n this.emit('phaseEnd', { target: collection, phase: 'saveInfo' });\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n // Step 3: download collection media items\n if (collection.thumbnail) {\n this.emit('phaseBegin', { target: collection, phase: 'saveMedia' });\n const collectionMedia: Downloadable[] = [\n collection.thumbnail\n ];\n batch = (await this.createDownloadTaskBatch(\n `Collection #${collection.id} (${collection.title})`,\n signal,\n {\n target: collectionMedia,\n targetName: `collection #${campaign.id} -> thumbnail`,\n src: collection,\n dirs: {\n campaign: this.fsHelper.getCampaignDirs(campaign).root,\n main: collectionDirs.root,\n thumbnails: null\n },\n fileExistsAction: this.config.fileExistsAction.info\n }\n )).batch;\n if (this.checkAbortSignal(signal)) {\n return;\n }\n batch.prestart();\n this.emit('phaseBegin', { target: collection, phase: 'batchDownload', batch });\n await batch.start();\n await batch.destroy();\n this.emit('phaseEnd', { target: collection, phase: 'batchDownload' });\n this.emit('phaseEnd', { target: collection, phase: 'saveMedia' });\n\n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n // Step 4: save to DB\n db.saveCollection(collection, campaign);\n\n // Done\n this.log('info', 'Done saving collection info');\n this.emit('targetEnd', { target: collection, isSkipped: false });\n }\n\n}\n"]}
@@ -302,7 +302,7 @@ _PostsFetcher_pointers = new WeakMap(), _PostsFetcher_fetched = new WeakMap(), _
302
302
  this.log('error', error);
303
303
  __classPrivateFieldGet(this, _PostsFetcher_instances, "m", _PostsFetcher_setStatus).call(this, { status: 'error', error });
304
304
  }, _PostsFetcher_isFetchingMultiplePosts = function _PostsFetcher_isFetchingMultiplePosts(postFetch) {
305
- return postFetch.type === 'byUser' || postFetch.type === 'byUserId' || postFetch.type === 'byCollection';
305
+ return postFetch.type === 'byUser' || postFetch.type === 'byUserId' || postFetch.type === 'byCollection' || postFetch.type === 'byURL';
306
306
  }, _PostsFetcher_getInitialPostsAPIURL = async function _PostsFetcher_getInitialPostsAPIURL() {
307
307
  if (this.config.postFetch.type === 'byFile') {
308
308
  throw Error('Posts API URL cannot be obtained from file');
@@ -332,8 +332,10 @@ _PostsFetcher_pointers = new WeakMap(), _PostsFetcher_fetched = new WeakMap(), _
332
332
  return URLHelper.constructCampaignPageURL({ userId: postFetch.userId });
333
333
  case 'byCollection':
334
334
  return URLHelper.constructCollectionURL(postFetch.collectionId);
335
+ case 'byURL':
336
+ return postFetch.url;
335
337
  default:
336
- throw Error(`postFetch type mismatch: expecting 'byUser', 'byUserId' or 'byCollection' but got '${postFetch.type}'`);
338
+ throw Error(`postFetch type mismatch: expecting 'byUser', 'byUserId', 'byCollection' or 'byURL' but got '${postFetch.type}'`);
337
339
  }
338
340
  }, _PostsFetcher_fetchAPI = async function _PostsFetcher_fetchAPI(url) {
339
341
  return (await this.fetcher.get({ url, type: 'json', maxRetries: this.config.request.maxRetries, signal: this.signal })).json;
@@ -1 +1 @@
1
- {"version":3,"file":"PostsFetcher.js","sourceRoot":"","sources":["../../src/downloaders/PostsFetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import EventEmitter from 'events';\nimport { type Post } from '../entities/index.js';\nimport { type Logger } from '../utils/logging/index.js';\nimport { type LogLevel, commonLog } from '../utils/logging/Logger.js';\nimport { type DownloaderConfig } from './Downloader.js';\nimport URLHelper, { PostSortOrder } from '../utils/URLHelper.js';\nimport type Fetcher from '../utils/Fetcher.js';\nimport PostParser from '../parsers/PostParser.js';\nimport { type PostList } from '../entities/Post.js';\nimport Sleeper from '../utils/Sleeper.js';\nimport { InitialData } from './InitialData.js';\nimport fse from 'fs-extra';\n\nexport type PostsFetcherStatus = {\n status: 'ready' | 'running' | 'completed' | 'aborted';\n error?: undefined;\n} | {\n status: 'error';\n error: any;\n};\n\nexport type PostsFetcherEvent = 'fetched' | 'statusChange';\nexport type PostsFetcherEventPayload<T extends PostsFetcherEvent> =\n T extends 'fetched' ? {\n list: PostList;\n index: number;\n } :\n T extends 'statusChange' ? {\n current: PostsFetcherStatus;\n old: PostsFetcherStatus;\n } :\n never;\n\nexport interface PostsFetcherResult {\n list: PostList | null;\n error?: any;\n aborted: boolean;\n}\n\nconst SLEEPER_INTERVAL = 900000; // 15 mins\n\nexport default class PostsFetcher extends EventEmitter {\n\n name = 'PostsFetcher';\n\n protected status: PostsFetcherStatus;\n protected config: DownloaderConfig<Post>;\n protected fetcher: Fetcher;\n protected signal?: AbortSignal;\n protected logger?: Logger | null;\n\n #pointers: {\n fetching: number | null;\n lastFetched: number | null;\n returning: number | null;\n lastReturned: number | null; // Last returned in next()\n };\n #fetched: PostList[];\n #total: number | null;\n #nextPromises: Array<Promise<PostsFetcherResult> | undefined>;\n #sleeper: Sleeper | null;\n #noSleep: boolean;\n\n constructor(params: {\n config: DownloaderConfig<Post>,\n fetcher: Fetcher,\n logger?: Logger | null,\n signal?: AbortSignal\n }) {\n super();\n const { config, fetcher, logger, signal } = params;\n this.config = config;\n this.fetcher = fetcher;\n this.logger = logger;\n this.signal = signal;\n this.#fetched = [];\n this.status = { status: 'ready' };\n this.#pointers = {\n fetching: null,\n lastFetched: null,\n returning: null,\n lastReturned: null\n };\n this.#nextPromises = [];\n this.#sleeper = null;\n this.#noSleep = false;\n }\n\n isFetchingMultiple() {\n return this.#isFetchingMultiplePosts(this.config.postFetch);\n }\n\n getTargetType() {\n return this.#isFetchingMultiplePosts(this.config.postFetch) ? 'posts' : 'post';\n }\n\n protected log(level: LogLevel, ...msg: any[]) {\n commonLog(this.logger, level, this.name, ...msg);\n }\n\n #setStatus(status: PostsFetcherStatus) {\n const oldStatus = this.status;\n this.status = status;\n this.emit('statusChange', { current: status, old: oldStatus });\n }\n\n #isRunning() {\n return this.status.status === 'running';\n }\n\n begin() {\n void this.#doBegin();\n }\n\n async #doBegin() {\n if (this.status.status !== 'ready') {\n throw Error('PostsFetcher already running or has ended');\n }\n\n this.#setStatus({ status: 'running' });\n\n this.#pointers.fetching = 0;\n const postFetch = this.config.postFetch;\n \n let postsSrc: string;\n if (postFetch.type !== 'byFile') {\n try {\n postsSrc = await this.#getInitialPostsAPIURL();\n }\n catch (error) {\n this.#handleError(error);\n return;\n }\n }\n else {\n postsSrc = postFetch.filePath;\n }\n \n if (this.#isFetchingMultiplePosts(postFetch)) {\n this.log('info', 'Fetch posts');\n this.log('debug', `Request initial posts from API URL \"${postsSrc}\"`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Read post data from \"${postFetch.filePath}\"`);\n }\n else {\n this.log('info', 'Fetch target post');\n this.log('debug', `Request post #${postFetch.postId} from API URL \"${postsSrc}`);\n }\n\n let json;\n try {\n if (postFetch.type !== 'byFile') {\n json = await this.#fetchAPI(postsSrc);\n }\n else {\n json = fse.readJSONSync(postFetch.filePath);\n }\n }\n catch (error) {\n this.#handleError(error);\n return;\n }\n\n const postsParser = new PostParser(this.logger);\n const list = postsParser.parsePostsAPIResponse(json, postsSrc);\n this.#fetched = [ list ];\n this.#pointers.lastFetched = this.#pointers.fetching;\n this.#pointers.fetching = null;\n this.emit('fetched', { list, index: 0 });\n\n const total = this.#total = this.#fetched[0].total;\n if (this.#isFetchingMultiplePosts(postFetch)) {\n let totalFetched = this.#fetched[0].items.length;\n this.log('info', `Fetched posts: ${totalFetched} / ${total}`);\n let nextURL = this.#fetched[0].nextURL;\n while (nextURL) {\n let json;\n try {\n this.#pointers.fetching = this.#pointers.lastFetched !== null ? this.#pointers.lastFetched + 1 : 1;\n const sleep = !this.#pointers.returning || this.#pointers.returning < this.#pointers.fetching;\n if (sleep && !this.#sleeper) {\n this.log('debug', `Has more posts - will fetch in ${SLEEPER_INTERVAL / 1000} seconds`);\n this.#sleeper = Sleeper.getInstance(SLEEPER_INTERVAL, this.signal);\n await this.#sleeper.start();\n }\n this.log('debug', `Request more posts from API URL \"${nextURL}\"`);\n json = await this.#fetchAPI(nextURL);\n }\n catch (error) {\n this.#handleError(error);\n json = null;\n }\n finally {\n if (this.#sleeper) {\n this.#sleeper.destroy();\n this.#sleeper = null;\n }\n }\n if (!json) {\n nextURL = null;\n }\n else {\n const list = postsParser.parsePostsAPIResponse(json, nextURL);\n this.#fetched.push(list);\n const fetched = list.items.length;\n totalFetched += fetched;\n this.log('info', `Fetched posts: ${totalFetched} / ${total}`);\n nextURL = list.nextURL;\n this.#pointers.lastFetched = this.#pointers.fetching;\n this.#pointers.fetching = null;\n this.emit('fetched', { list, index: this.#fetched.length - 1 });\n }\n }\n if (!this.checkAbortSignal()) {\n if (total && totalFetched < total) {\n this.log('warn', `Done, but some posts were not fetched. Total expected: ${total}; currently fetched: ${totalFetched}`);\n }\n else {\n this.log('info', `Done. ${totalFetched} posts fetched`);\n }\n\n if (this.#isRunning()) {\n this.#setStatus({ status: 'completed' });\n }\n }\n }\n // Set 'completed' if not fetching multiple posts\n else if (!this.checkAbortSignal() && this.#isRunning()) {\n this.#setStatus({ status: 'completed' });\n }\n }\n\n #handleError(error: any) {\n const statusName = this.status.status;\n if (statusName === 'aborted' || statusName === 'completed') {\n return;\n }\n if (this.signal?.aborted) {\n this.log('warn', 'Abort');\n this.#setStatus({ status: 'aborted' });\n return;\n }\n this.log('error', error);\n this.#setStatus({ status: 'error', error });\n }\n\n #isFetchingMultiplePosts(postFetch: DownloaderConfig<Post>['postFetch']): postFetch is DownloaderConfig<Post>['postFetch'] & { type: 'byUser' | 'byUserId' | 'byCollection' } {\n return postFetch.type === 'byUser' || postFetch.type === 'byUserId' || postFetch.type === 'byCollection';\n }\n\n async #getInitialPostsAPIURL() {\n if (this.config.postFetch.type === 'byFile') {\n throw Error('Posts API URL cannot be obtained from file');\n }\n const postFetch = this.config.postFetch;\n if (this.#isFetchingMultiplePosts(postFetch)) {\n const pageURL = this.#getInitialDataPageURL();\n const { campaignId, currentUserId } = await this.getInitialData(pageURL);\n let sort: PostSortOrder | undefined;\n if (postFetch.type === 'byCollection') {\n sort = PostSortOrder.CollectionOrder;\n }\n\n return URLHelper.constructPostsAPIURL({\n campaignId,\n currentUserId: this.config.include.lockedContent ? undefined : currentUserId,\n filters: postFetch.filters,\n sort\n });\n }\n\n return URLHelper.constructPostsAPIURL({ postId: postFetch.postId });\n }\n\n #getInitialDataPageURL() {\n const postFetch = this.config.postFetch;\n switch (postFetch.type) {\n case 'byUser':\n return URLHelper.constructCampaignPageURL({ vanity: postFetch.vanity });\n case 'byUserId':\n return URLHelper.constructCampaignPageURL({ userId: postFetch.userId });\n case 'byCollection':\n return URLHelper.constructCollectionURL(postFetch.collectionId);\n default:\n throw Error(`postFetch type mismatch: expecting 'byUser', 'byUserId' or 'byCollection' but got '${postFetch.type}'`);\n }\n }\n\n getInitialData(url: string) {\n const id = new InitialData(this.config, this.fetcher, this.logger);\n return id.get(url, this.signal);\n }\n\n async #fetchAPI(url: string) {\n return (await this.fetcher.get({ url, type: 'json', maxRetries: this.config.request.maxRetries, signal: this.signal })).json;\n }\n\n protected checkAbortSignal() {\n return this.signal && this.signal.aborted;\n }\n\n hasNext() {\n const lastReturned = this.#pointers.lastReturned !== null ? this.#pointers.lastReturned : -1;\n return this.#isRunning() || (this.#fetched.length > 0 && lastReturned < this.#fetched.length - 1);\n }\n\n async next(): Promise<PostsFetcherResult> {\n this.#pointers.returning = this.#pointers.lastReturned !== null ? this.#pointers.lastReturned + 1 : 0;\n const ptr = this.#pointers.returning;\n this.log('debug', `next() requested (${ptr})`);\n const __parseStatus = (status: PostsFetcherStatus) => {\n let list: PostList | null | undefined;\n let aborted = false;\n let error: any;\n switch (status.status) {\n case 'aborted':\n list = null;\n aborted = true;\n break;\n case 'error':\n if (this.#fetched[ptr]) {\n list = this.#fetched[ptr];\n }\n else {\n list = null;\n error = status.error;\n }\n break;\n case 'completed':\n list = this.#fetched[ptr] || null;\n break;\n default:\n list = this.#fetched[ptr] || undefined;\n }\n return { list, aborted, error };\n };\n if (this.#isRunning() && !this.#fetched[ptr]) {\n let result = this.#nextPromises[ptr];\n if (!result) {\n let resolved = false;\n result = new Promise<PostsFetcherResult>((resolve) => {\n const fetchedListener = () => {\n if (resolved) {\n this.off('fetched', fetchedListener);\n return;\n }\n if (this.#fetched[ptr]) {\n this.off('fetched', fetchedListener);\n resolved = true;\n resolve({\n list: this.#fetched[ptr],\n aborted: false\n });\n }\n };\n const statusListener = (args: { current: PostsFetcherStatus }) => {\n if (resolved) {\n this.off('statusChange', statusListener);\n return;\n }\n const { list, aborted, error } = __parseStatus(args.current);\n if (list !== undefined) {\n this.off('statusChange', statusListener);\n resolved = true;\n resolve({ list, aborted, error });\n }\n };\n this.on('fetched', fetchedListener);\n this.on('statusChange', statusListener);\n if (!this.#noSleep) {\n this.#noSleep = true;\n }\n if (this.#sleeper) {\n this.log('debug', 'Wake up early from sleep');\n this.#sleeper.wake();\n }\n })\n .finally(() => {\n this.#nextPromises[ptr] = undefined;\n this.#noSleep = false;\n this.#pointers.lastReturned = this.#pointers.returning;\n this.#pointers.returning = null;\n if (resolved) {\n this.log('debug', `next() handled (${ptr})`);\n }\n else {\n this.log('debug', `next() handled (${ptr}) - no resolve`);\n }\n });\n this.#nextPromises[ptr] = result;\n }\n return result;\n }\n this.#pointers.lastReturned = this.#pointers.returning;\n this.#pointers.returning = null;\n this.log('debug', `next() handled (${ptr})`);\n return __parseStatus(this.status);\n }\n\n getTotal() {\n return this.#total;\n }\n\n emit<T extends PostsFetcherEvent>(eventName: T, args: PostsFetcherEventPayload<T>): boolean;\n emit(eventName: string | symbol, ...args: any[]): boolean {\n return super.emit(eventName, ...args);\n }\n\n on<T extends PostsFetcherEvent>(eventName: T, listener: (args: PostsFetcherEventPayload<T>) => void): this;\n on(eventName: string | symbol, listener: (...args: any[]) => void): this {\n return super.on(eventName, listener);\n }\n\n off<T extends PostsFetcherEvent>(eventName: T, listener: (args: PostsFetcherEventPayload<T>) => void): this;\n off(eventName: string | symbol, listener: (...args: any[]) => void): this {\n return super.off(eventName, listener);\n }\n}\n"]}
1
+ {"version":3,"file":"PostsFetcher.js","sourceRoot":"","sources":["../../src/downloaders/PostsFetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import EventEmitter from 'events';\nimport { type Post } from '../entities/index.js';\nimport { type Logger } from '../utils/logging/index.js';\nimport { type LogLevel, commonLog } from '../utils/logging/Logger.js';\nimport { type DownloaderConfig } from './Downloader.js';\nimport URLHelper, { PostSortOrder } from '../utils/URLHelper.js';\nimport type Fetcher from '../utils/Fetcher.js';\nimport PostParser from '../parsers/PostParser.js';\nimport { type PostList } from '../entities/Post.js';\nimport Sleeper from '../utils/Sleeper.js';\nimport { InitialData } from './InitialData.js';\nimport fse from 'fs-extra';\n\nexport type PostsFetcherStatus = {\n status: 'ready' | 'running' | 'completed' | 'aborted';\n error?: undefined;\n} | {\n status: 'error';\n error: any;\n};\n\nexport type PostsFetcherEvent = 'fetched' | 'statusChange';\nexport type PostsFetcherEventPayload<T extends PostsFetcherEvent> =\n T extends 'fetched' ? {\n list: PostList;\n index: number;\n } :\n T extends 'statusChange' ? {\n current: PostsFetcherStatus;\n old: PostsFetcherStatus;\n } :\n never;\n\nexport interface PostsFetcherResult {\n list: PostList | null;\n error?: any;\n aborted: boolean;\n}\n\nconst SLEEPER_INTERVAL = 900000; // 15 mins\n\nexport default class PostsFetcher extends EventEmitter {\n\n name = 'PostsFetcher';\n\n protected status: PostsFetcherStatus;\n protected config: DownloaderConfig<Post>;\n protected fetcher: Fetcher;\n protected signal?: AbortSignal;\n protected logger?: Logger | null;\n\n #pointers: {\n fetching: number | null;\n lastFetched: number | null;\n returning: number | null;\n lastReturned: number | null; // Last returned in next()\n };\n #fetched: PostList[];\n #total: number | null;\n #nextPromises: Array<Promise<PostsFetcherResult> | undefined>;\n #sleeper: Sleeper | null;\n #noSleep: boolean;\n\n constructor(params: {\n config: DownloaderConfig<Post>,\n fetcher: Fetcher,\n logger?: Logger | null,\n signal?: AbortSignal\n }) {\n super();\n const { config, fetcher, logger, signal } = params;\n this.config = config;\n this.fetcher = fetcher;\n this.logger = logger;\n this.signal = signal;\n this.#fetched = [];\n this.status = { status: 'ready' };\n this.#pointers = {\n fetching: null,\n lastFetched: null,\n returning: null,\n lastReturned: null\n };\n this.#nextPromises = [];\n this.#sleeper = null;\n this.#noSleep = false;\n }\n\n isFetchingMultiple() {\n return this.#isFetchingMultiplePosts(this.config.postFetch);\n }\n\n getTargetType() {\n return this.#isFetchingMultiplePosts(this.config.postFetch) ? 'posts' : 'post';\n }\n\n protected log(level: LogLevel, ...msg: any[]) {\n commonLog(this.logger, level, this.name, ...msg);\n }\n\n #setStatus(status: PostsFetcherStatus) {\n const oldStatus = this.status;\n this.status = status;\n this.emit('statusChange', { current: status, old: oldStatus });\n }\n\n #isRunning() {\n return this.status.status === 'running';\n }\n\n begin() {\n void this.#doBegin();\n }\n\n async #doBegin() {\n if (this.status.status !== 'ready') {\n throw Error('PostsFetcher already running or has ended');\n }\n\n this.#setStatus({ status: 'running' });\n\n this.#pointers.fetching = 0;\n const postFetch = this.config.postFetch;\n \n let postsSrc: string;\n if (postFetch.type !== 'byFile') {\n try {\n postsSrc = await this.#getInitialPostsAPIURL();\n }\n catch (error) {\n this.#handleError(error);\n return;\n }\n }\n else {\n postsSrc = postFetch.filePath;\n }\n \n if (this.#isFetchingMultiplePosts(postFetch)) {\n this.log('info', 'Fetch posts');\n this.log('debug', `Request initial posts from API URL \"${postsSrc}\"`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Read post data from \"${postFetch.filePath}\"`);\n }\n else {\n this.log('info', 'Fetch target post');\n this.log('debug', `Request post #${postFetch.postId} from API URL \"${postsSrc}`);\n }\n\n let json;\n try {\n if (postFetch.type !== 'byFile') {\n json = await this.#fetchAPI(postsSrc);\n }\n else {\n json = fse.readJSONSync(postFetch.filePath);\n }\n }\n catch (error) {\n this.#handleError(error);\n return;\n }\n\n const postsParser = new PostParser(this.logger);\n const list = postsParser.parsePostsAPIResponse(json, postsSrc);\n this.#fetched = [ list ];\n this.#pointers.lastFetched = this.#pointers.fetching;\n this.#pointers.fetching = null;\n this.emit('fetched', { list, index: 0 });\n\n const total = this.#total = this.#fetched[0].total;\n if (this.#isFetchingMultiplePosts(postFetch)) {\n let totalFetched = this.#fetched[0].items.length;\n this.log('info', `Fetched posts: ${totalFetched} / ${total}`);\n let nextURL = this.#fetched[0].nextURL;\n while (nextURL) {\n let json;\n try {\n this.#pointers.fetching = this.#pointers.lastFetched !== null ? this.#pointers.lastFetched + 1 : 1;\n const sleep = !this.#pointers.returning || this.#pointers.returning < this.#pointers.fetching;\n if (sleep && !this.#sleeper) {\n this.log('debug', `Has more posts - will fetch in ${SLEEPER_INTERVAL / 1000} seconds`);\n this.#sleeper = Sleeper.getInstance(SLEEPER_INTERVAL, this.signal);\n await this.#sleeper.start();\n }\n this.log('debug', `Request more posts from API URL \"${nextURL}\"`);\n json = await this.#fetchAPI(nextURL);\n }\n catch (error) {\n this.#handleError(error);\n json = null;\n }\n finally {\n if (this.#sleeper) {\n this.#sleeper.destroy();\n this.#sleeper = null;\n }\n }\n if (!json) {\n nextURL = null;\n }\n else {\n const list = postsParser.parsePostsAPIResponse(json, nextURL);\n this.#fetched.push(list);\n const fetched = list.items.length;\n totalFetched += fetched;\n this.log('info', `Fetched posts: ${totalFetched} / ${total}`);\n nextURL = list.nextURL;\n this.#pointers.lastFetched = this.#pointers.fetching;\n this.#pointers.fetching = null;\n this.emit('fetched', { list, index: this.#fetched.length - 1 });\n }\n }\n if (!this.checkAbortSignal()) {\n if (total && totalFetched < total) {\n this.log('warn', `Done, but some posts were not fetched. Total expected: ${total}; currently fetched: ${totalFetched}`);\n }\n else {\n this.log('info', `Done. ${totalFetched} posts fetched`);\n }\n\n if (this.#isRunning()) {\n this.#setStatus({ status: 'completed' });\n }\n }\n }\n // Set 'completed' if not fetching multiple posts\n else if (!this.checkAbortSignal() && this.#isRunning()) {\n this.#setStatus({ status: 'completed' });\n }\n }\n\n #handleError(error: any) {\n const statusName = this.status.status;\n if (statusName === 'aborted' || statusName === 'completed') {\n return;\n }\n if (this.signal?.aborted) {\n this.log('warn', 'Abort');\n this.#setStatus({ status: 'aborted' });\n return;\n }\n this.log('error', error);\n this.#setStatus({ status: 'error', error });\n }\n\n #isFetchingMultiplePosts(postFetch: DownloaderConfig<Post>['postFetch']): postFetch is DownloaderConfig<Post>['postFetch'] & { type: 'byUser' | 'byUserId' | 'byCollection' | 'byURL' } {\n return postFetch.type === 'byUser' || postFetch.type === 'byUserId' || postFetch.type === 'byCollection' || postFetch.type === 'byURL';\n }\n\n async #getInitialPostsAPIURL() {\n if (this.config.postFetch.type === 'byFile') {\n throw Error('Posts API URL cannot be obtained from file');\n }\n const postFetch = this.config.postFetch;\n if (this.#isFetchingMultiplePosts(postFetch)) {\n const pageURL = this.#getInitialDataPageURL();\n const { campaignId, currentUserId } = await this.getInitialData(pageURL);\n let sort: PostSortOrder | undefined;\n if (postFetch.type === 'byCollection') {\n sort = PostSortOrder.CollectionOrder;\n }\n\n return URLHelper.constructPostsAPIURL({\n campaignId,\n currentUserId: this.config.include.lockedContent ? undefined : currentUserId,\n filters: postFetch.filters,\n sort\n });\n }\n\n return URLHelper.constructPostsAPIURL({ postId: postFetch.postId });\n }\n\n #getInitialDataPageURL() {\n const postFetch = this.config.postFetch;\n switch (postFetch.type) {\n case 'byUser':\n return URLHelper.constructCampaignPageURL({ vanity: postFetch.vanity });\n case 'byUserId':\n return URLHelper.constructCampaignPageURL({ userId: postFetch.userId });\n case 'byCollection':\n return URLHelper.constructCollectionURL(postFetch.collectionId);\n case 'byURL':\n return postFetch.url;\n default:\n throw Error(`postFetch type mismatch: expecting 'byUser', 'byUserId', 'byCollection' or 'byURL' but got '${postFetch.type}'`);\n }\n }\n\n getInitialData(url: string) {\n const id = new InitialData(this.config, this.fetcher, this.logger);\n return id.get(url, this.signal);\n }\n\n async #fetchAPI(url: string) {\n return (await this.fetcher.get({ url, type: 'json', maxRetries: this.config.request.maxRetries, signal: this.signal })).json;\n }\n\n protected checkAbortSignal() {\n return this.signal && this.signal.aborted;\n }\n\n hasNext() {\n const lastReturned = this.#pointers.lastReturned !== null ? this.#pointers.lastReturned : -1;\n return this.#isRunning() || (this.#fetched.length > 0 && lastReturned < this.#fetched.length - 1);\n }\n\n async next(): Promise<PostsFetcherResult> {\n this.#pointers.returning = this.#pointers.lastReturned !== null ? this.#pointers.lastReturned + 1 : 0;\n const ptr = this.#pointers.returning;\n this.log('debug', `next() requested (${ptr})`);\n const __parseStatus = (status: PostsFetcherStatus) => {\n let list: PostList | null | undefined;\n let aborted = false;\n let error: any;\n switch (status.status) {\n case 'aborted':\n list = null;\n aborted = true;\n break;\n case 'error':\n if (this.#fetched[ptr]) {\n list = this.#fetched[ptr];\n }\n else {\n list = null;\n error = status.error;\n }\n break;\n case 'completed':\n list = this.#fetched[ptr] || null;\n break;\n default:\n list = this.#fetched[ptr] || undefined;\n }\n return { list, aborted, error };\n };\n if (this.#isRunning() && !this.#fetched[ptr]) {\n let result = this.#nextPromises[ptr];\n if (!result) {\n let resolved = false;\n result = new Promise<PostsFetcherResult>((resolve) => {\n const fetchedListener = () => {\n if (resolved) {\n this.off('fetched', fetchedListener);\n return;\n }\n if (this.#fetched[ptr]) {\n this.off('fetched', fetchedListener);\n resolved = true;\n resolve({\n list: this.#fetched[ptr],\n aborted: false\n });\n }\n };\n const statusListener = (args: { current: PostsFetcherStatus }) => {\n if (resolved) {\n this.off('statusChange', statusListener);\n return;\n }\n const { list, aborted, error } = __parseStatus(args.current);\n if (list !== undefined) {\n this.off('statusChange', statusListener);\n resolved = true;\n resolve({ list, aborted, error });\n }\n };\n this.on('fetched', fetchedListener);\n this.on('statusChange', statusListener);\n if (!this.#noSleep) {\n this.#noSleep = true;\n }\n if (this.#sleeper) {\n this.log('debug', 'Wake up early from sleep');\n this.#sleeper.wake();\n }\n })\n .finally(() => {\n this.#nextPromises[ptr] = undefined;\n this.#noSleep = false;\n this.#pointers.lastReturned = this.#pointers.returning;\n this.#pointers.returning = null;\n if (resolved) {\n this.log('debug', `next() handled (${ptr})`);\n }\n else {\n this.log('debug', `next() handled (${ptr}) - no resolve`);\n }\n });\n this.#nextPromises[ptr] = result;\n }\n return result;\n }\n this.#pointers.lastReturned = this.#pointers.returning;\n this.#pointers.returning = null;\n this.log('debug', `next() handled (${ptr})`);\n return __parseStatus(this.status);\n }\n\n getTotal() {\n return this.#total;\n }\n\n emit<T extends PostsFetcherEvent>(eventName: T, args: PostsFetcherEventPayload<T>): boolean;\n emit(eventName: string | symbol, ...args: any[]): boolean {\n return super.emit(eventName, ...args);\n }\n\n on<T extends PostsFetcherEvent>(eventName: T, listener: (args: PostsFetcherEventPayload<T>) => void): this;\n on(eventName: string | symbol, listener: (...args: any[]) => void): this {\n return super.on(eventName, listener);\n }\n\n off<T extends PostsFetcherEvent>(eventName: T, listener: (args: PostsFetcherEventPayload<T>) => void): this;\n off(eventName: string | symbol, listener: (...args: any[]) => void): this {\n return super.off(eventName, listener);\n }\n}\n"]}
@@ -20,6 +20,7 @@ import { TargetSkipReason } from './DownloaderEvent.js';
20
20
  import { ProductType } from '../entities/Product.js';
21
21
  import Bootstrap from './Bootstrap.js';
22
22
  import ProductsFetcher from './ProductsFetcher.js';
23
+ import { IncludeCriteriaHelper } from './IncludeCriteriaHelper.js';
23
24
  class ProductDownloader extends Downloader {
24
25
  constructor() {
25
26
  super(...arguments);
@@ -218,29 +219,38 @@ _ProductDownloader_startPromise = new WeakMap(), _ProductDownloader_instances =
218
219
  }
219
220
  }, _ProductDownloader_doDownload = async function _ProductDownloader_doDownload(product, productDirs, statusCache, db, signal) {
220
221
  // Step 1: Check whether we should download product
221
- // -- 1.1 Accessibility
222
- if (!product.isAccessible) {
223
- if (this.config.include.lockedContent) {
224
- this.log('warn', `Product #${product.id} is not accessible by current user`);
225
- }
226
- else {
227
- this.log('warn', `Skipped downloading product #${product.id}: not accessible by current user`);
228
- this.emit('targetEnd', {
229
- target: product,
230
- isSkipped: true,
231
- skipReason: TargetSkipReason.Inaccessible,
232
- skipMessage: 'Target is not accessible by current user'
233
- });
234
- return {
235
- status: 'skippedUnviewable'
236
- };
222
+ const criteriaHelper = new IncludeCriteriaHelper(this.logger);
223
+ const criteriaCheck = criteriaHelper.checkProduct(product, this.config);
224
+ if (!criteriaCheck.ok) {
225
+ switch (criteriaCheck.reason) {
226
+ case 'unviewable': {
227
+ this.log('warn', `Skipped downloading product #${product.id}: not accessible by current user`);
228
+ this.emit('targetEnd', {
229
+ target: product,
230
+ isSkipped: true,
231
+ skipReason: TargetSkipReason.Inaccessible,
232
+ skipMessage: 'Target is not accessible by current user'
233
+ });
234
+ return {
235
+ status: 'skippedUnviewable'
236
+ };
237
+ }
238
+ case 'publishDateOutOfRange': {
239
+ this.log('warn', `Skipped downloading product #${product.id}: publish date out of range`);
240
+ this.emit('targetEnd', {
241
+ target: product,
242
+ isSkipped: true,
243
+ skipReason: TargetSkipReason.PublishDateOutOfRange,
244
+ skipMessage: 'Publish date out of range'
245
+ });
246
+ return {
247
+ status: 'skippedPublishDateOutOfRange'
248
+ };
249
+ }
237
250
  }
238
251
  }
239
- // -- 1.4 Config option 'include.productsPublished'
240
- if (this.isPublishDateOutOfRange(product)) {
241
- return {
242
- status: 'skippedPublishDateOutOfRange'
243
- };
252
+ if (!product.isAccessible && this.config.include.lockedContent) {
253
+ this.log('warn', `Product #${product.id} is not accessible by current user`);
244
254
  }
245
255
  this.fsHelper.createDir(productDirs.root);
246
256
  // Step 2: save product info