flow-frame-core 0.1.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 (416) hide show
  1. package/README.md +64 -0
  2. package/dist/Dockerfile +86 -0
  3. package/dist/GPU_DEPLOYMENT_README.md +324 -0
  4. package/dist/OPS_AGENT_README.md +174 -0
  5. package/dist/README-H100-VM.md +192 -0
  6. package/dist/README-worker-pools.md +231 -0
  7. package/dist/README.md +8 -0
  8. package/dist/WEB-ELEMENT-REQUESTS-README.md +302 -0
  9. package/dist/append.d.ts +3 -0
  10. package/dist/append.d.ts.map +1 -0
  11. package/dist/append.js +42 -0
  12. package/dist/append.js.map +1 -0
  13. package/dist/audioRoutes.d.ts +2 -0
  14. package/dist/audioRoutes.d.ts.map +1 -0
  15. package/dist/audioRoutes.js +97 -0
  16. package/dist/audioRoutes.js.map +1 -0
  17. package/dist/augment-parallel.d.ts +6 -0
  18. package/dist/augment-parallel.d.ts.map +1 -0
  19. package/dist/augment-parallel.js +128 -0
  20. package/dist/augment-parallel.js.map +1 -0
  21. package/dist/augment-worker.d.ts +2 -0
  22. package/dist/augment-worker.d.ts.map +1 -0
  23. package/dist/augment-worker.js +100 -0
  24. package/dist/augment-worker.js.map +1 -0
  25. package/dist/browerRoutes.d.ts +2 -0
  26. package/dist/browerRoutes.d.ts.map +1 -0
  27. package/dist/browerRoutes.js +323 -0
  28. package/dist/browerRoutes.js.map +1 -0
  29. package/dist/browser-utils/utils.d.ts +6 -0
  30. package/dist/browser-utils/utils.d.ts.map +1 -0
  31. package/dist/browser-utils/utils.js +133 -0
  32. package/dist/browser-utils/utils.js.map +1 -0
  33. package/dist/capture_training_data_endpoints.d.ts +158 -0
  34. package/dist/capture_training_data_endpoints.d.ts.map +1 -0
  35. package/dist/capture_training_data_endpoints.js +1812 -0
  36. package/dist/capture_training_data_endpoints.js.map +1 -0
  37. package/dist/config.json +28 -0
  38. package/dist/configEndpoints.d.ts +2 -0
  39. package/dist/configEndpoints.d.ts.map +1 -0
  40. package/dist/configEndpoints.js +459 -0
  41. package/dist/configEndpoints.js.map +1 -0
  42. package/dist/constants.d.ts +109 -0
  43. package/dist/constants.d.ts.map +1 -0
  44. package/dist/constants.js +110 -0
  45. package/dist/constants.js.map +1 -0
  46. package/dist/docs/workflow_nodes.md +257 -0
  47. package/dist/download.d.ts +11 -0
  48. package/dist/download.d.ts.map +1 -0
  49. package/dist/download.js +31 -0
  50. package/dist/download.js.map +1 -0
  51. package/dist/download.py +61 -0
  52. package/dist/ecosystem.config.json +63 -0
  53. package/dist/email-body-extractor.d.ts +20 -0
  54. package/dist/email-body-extractor.d.ts.map +1 -0
  55. package/dist/email-body-extractor.js +103 -0
  56. package/dist/email-body-extractor.js.map +1 -0
  57. package/dist/express_util.d.ts +2 -0
  58. package/dist/express_util.d.ts.map +1 -0
  59. package/dist/express_util.js +30 -0
  60. package/dist/express_util.js.map +1 -0
  61. package/dist/extension/background.d.ts +2 -0
  62. package/dist/extension/background.d.ts.map +1 -0
  63. package/dist/extension/background.js +268 -0
  64. package/dist/extension/background.js.map +1 -0
  65. package/dist/extension/manifest.json +19 -0
  66. package/dist/extensionUtils.d.ts +2 -0
  67. package/dist/extensionUtils.d.ts.map +1 -0
  68. package/dist/extensionUtils.js +48 -0
  69. package/dist/extensionUtils.js.map +1 -0
  70. package/dist/filter-gmail-poller/README.md +320 -0
  71. package/dist/filter-gmail-poller/demo.d.ts +2 -0
  72. package/dist/filter-gmail-poller/demo.d.ts.map +1 -0
  73. package/dist/filter-gmail-poller/demo.js +79 -0
  74. package/dist/filter-gmail-poller/demo.js.map +1 -0
  75. package/dist/filter-gmail-poller/example-existing-app.d.ts +2 -0
  76. package/dist/filter-gmail-poller/example-existing-app.d.ts.map +1 -0
  77. package/dist/filter-gmail-poller/example-existing-app.js +72 -0
  78. package/dist/filter-gmail-poller/example-existing-app.js.map +1 -0
  79. package/dist/filter-gmail-poller/filter-gmail-poller.d.ts +160 -0
  80. package/dist/filter-gmail-poller/filter-gmail-poller.d.ts.map +1 -0
  81. package/dist/filter-gmail-poller/filter-gmail-poller.js +1048 -0
  82. package/dist/filter-gmail-poller/filter-gmail-poller.js.map +1 -0
  83. package/dist/filter-gmail-poller/index.d.ts +3 -0
  84. package/dist/filter-gmail-poller/index.d.ts.map +1 -0
  85. package/dist/filter-gmail-poller/index.js +18 -0
  86. package/dist/filter-gmail-poller/index.js.map +1 -0
  87. package/dist/filter-gmail-poller/manual-test.d.ts +2 -0
  88. package/dist/filter-gmail-poller/manual-test.d.ts.map +1 -0
  89. package/dist/filter-gmail-poller/manual-test.js +70 -0
  90. package/dist/filter-gmail-poller/manual-test.js.map +1 -0
  91. package/dist/filter-gmail-poller/poller-prompts.d.ts +12 -0
  92. package/dist/filter-gmail-poller/poller-prompts.d.ts.map +1 -0
  93. package/dist/filter-gmail-poller/poller-prompts.js +330 -0
  94. package/dist/filter-gmail-poller/poller-prompts.js.map +1 -0
  95. package/dist/filter-gmail-poller/test.js +69 -0
  96. package/dist/flowframe-auto-firebase-adminsdk.json +13 -0
  97. package/dist/gmail-poller/README-microsoft-email-poller.md +203 -0
  98. package/dist/gmail-poller/README.md +129 -0
  99. package/dist/gmail-poller/example.d.ts +5 -0
  100. package/dist/gmail-poller/example.d.ts.map +1 -0
  101. package/dist/gmail-poller/example.js +83 -0
  102. package/dist/gmail-poller/example.js.map +1 -0
  103. package/dist/gmail-poller/gmail-poller.d.ts +82 -0
  104. package/dist/gmail-poller/gmail-poller.d.ts.map +1 -0
  105. package/dist/gmail-poller/gmail-poller.js +455 -0
  106. package/dist/gmail-poller/gmail-poller.js.map +1 -0
  107. package/dist/gmail-poller/manual-test.d.ts +2 -0
  108. package/dist/gmail-poller/manual-test.d.ts.map +1 -0
  109. package/dist/gmail-poller/manual-test.js +37 -0
  110. package/dist/gmail-poller/manual-test.js.map +1 -0
  111. package/dist/gmail-poller/microsoft-email-example.d.ts +8 -0
  112. package/dist/gmail-poller/microsoft-email-example.d.ts.map +1 -0
  113. package/dist/gmail-poller/microsoft-email-example.js +58 -0
  114. package/dist/gmail-poller/microsoft-email-example.js.map +1 -0
  115. package/dist/gmail-poller/microsoft-email-poller.d.ts +73 -0
  116. package/dist/gmail-poller/microsoft-email-poller.d.ts.map +1 -0
  117. package/dist/gmail-poller/microsoft-email-poller.js +346 -0
  118. package/dist/gmail-poller/microsoft-email-poller.js.map +1 -0
  119. package/dist/gmail-poller/setup-auth.d.ts +3 -0
  120. package/dist/gmail-poller/setup-auth.d.ts.map +1 -0
  121. package/dist/gmail-poller/setup-auth.js +36 -0
  122. package/dist/gmail-poller/setup-auth.js.map +1 -0
  123. package/dist/gmail-poller/test.js +36 -0
  124. package/dist/index.d.ts +10 -0
  125. package/dist/index.d.ts.map +1 -0
  126. package/dist/index.js +28 -0
  127. package/dist/index.js.map +1 -0
  128. package/dist/inference/augment_levels.d.ts +2 -0
  129. package/dist/inference/augment_levels.d.ts.map +1 -0
  130. package/dist/inference/augment_levels.js +1 -0
  131. package/dist/inference/augment_levels.js.map +1 -0
  132. package/dist/inference/capture-overlay.d.ts +13 -0
  133. package/dist/inference/capture-overlay.d.ts.map +1 -0
  134. package/dist/inference/capture-overlay.js +355 -0
  135. package/dist/inference/capture-overlay.js.map +1 -0
  136. package/dist/inference/capturescreenshot.d.ts +12 -0
  137. package/dist/inference/capturescreenshot.d.ts.map +1 -0
  138. package/dist/inference/capturescreenshot.js +157 -0
  139. package/dist/inference/capturescreenshot.js.map +1 -0
  140. package/dist/jsonHandler.d.ts +37 -0
  141. package/dist/jsonHandler.d.ts.map +1 -0
  142. package/dist/jsonHandler.js +191 -0
  143. package/dist/jsonHandler.js.map +1 -0
  144. package/dist/localStorage.json +11 -0
  145. package/dist/media_data_endpoints.d.ts +2 -0
  146. package/dist/media_data_endpoints.d.ts.map +1 -0
  147. package/dist/media_data_endpoints.js +102 -0
  148. package/dist/media_data_endpoints.js.map +1 -0
  149. package/dist/operations/blender-ops.d.ts +4 -0
  150. package/dist/operations/blender-ops.d.ts.map +1 -0
  151. package/dist/operations/blender-ops.js +55 -0
  152. package/dist/operations/blender-ops.js.map +1 -0
  153. package/dist/operations.d.ts +34 -0
  154. package/dist/operations.d.ts.map +1 -0
  155. package/dist/operations.js +1514 -0
  156. package/dist/operations.js.map +1 -0
  157. package/dist/pdfRoutes.d.ts +2 -0
  158. package/dist/pdfRoutes.d.ts.map +1 -0
  159. package/dist/pdfRoutes.js +56 -0
  160. package/dist/pdfRoutes.js.map +1 -0
  161. package/dist/peers.d.ts +9 -0
  162. package/dist/peers.d.ts.map +1 -0
  163. package/dist/peers.js +70 -0
  164. package/dist/peers.js.map +1 -0
  165. package/dist/playparser.d.ts +2 -0
  166. package/dist/playparser.d.ts.map +1 -0
  167. package/dist/playparser.js +281 -0
  168. package/dist/playparser.js.map +1 -0
  169. package/dist/process.d.ts +4 -0
  170. package/dist/process.d.ts.map +1 -0
  171. package/dist/process.js +375 -0
  172. package/dist/process.js.map +1 -0
  173. package/dist/promptRoutes.d.ts +7 -0
  174. package/dist/promptRoutes.d.ts.map +1 -0
  175. package/dist/promptRoutes.js +68 -0
  176. package/dist/promptRoutes.js.map +1 -0
  177. package/dist/queueManager.d.ts +23 -0
  178. package/dist/queueManager.d.ts.map +1 -0
  179. package/dist/queueManager.js +96 -0
  180. package/dist/queueManager.js.map +1 -0
  181. package/dist/run-flow.d.ts +8 -0
  182. package/dist/run-flow.d.ts.map +1 -0
  183. package/dist/run-flow.js +220 -0
  184. package/dist/run-flow.js.map +1 -0
  185. package/dist/scraper.d.ts +2 -0
  186. package/dist/scraper.d.ts.map +1 -0
  187. package/dist/scraper.js +75 -0
  188. package/dist/scraper.js.map +1 -0
  189. package/dist/scraper_endpoints.d.ts +2 -0
  190. package/dist/scraper_endpoints.d.ts.map +1 -0
  191. package/dist/scraper_endpoints.js +40 -0
  192. package/dist/scraper_endpoints.js.map +1 -0
  193. package/dist/server.d.ts +2 -0
  194. package/dist/server.d.ts.map +1 -0
  195. package/dist/server.js +528 -0
  196. package/dist/server.js.map +1 -0
  197. package/dist/services/ModelContext.d.ts +7 -0
  198. package/dist/services/ModelContext.d.ts.map +1 -0
  199. package/dist/services/ModelContext.js +7 -0
  200. package/dist/services/ModelContext.js.map +1 -0
  201. package/dist/services/agenticUiPlanner.d.ts +27 -0
  202. package/dist/services/agenticUiPlanner.d.ts.map +1 -0
  203. package/dist/services/agenticUiPlanner.js +161 -0
  204. package/dist/services/agenticUiPlanner.js.map +1 -0
  205. package/dist/services/apiKeyService.d.ts +3 -0
  206. package/dist/services/apiKeyService.d.ts.map +1 -0
  207. package/dist/services/apiKeyService.js +7 -0
  208. package/dist/services/apiKeyService.js.map +1 -0
  209. package/dist/services/audioService.d.ts +10 -0
  210. package/dist/services/audioService.d.ts.map +1 -0
  211. package/dist/services/audioService.js +140 -0
  212. package/dist/services/audioService.js.map +1 -0
  213. package/dist/services/autoPromptOptimizer.d.ts +44 -0
  214. package/dist/services/autoPromptOptimizer.d.ts.map +1 -0
  215. package/dist/services/autoPromptOptimizer.js +344 -0
  216. package/dist/services/autoPromptOptimizer.js.map +1 -0
  217. package/dist/services/autoPromptOptimizer.manual-test.d.ts +2 -0
  218. package/dist/services/autoPromptOptimizer.manual-test.d.ts.map +1 -0
  219. package/dist/services/autoPromptOptimizer.manual-test.js +27 -0
  220. package/dist/services/autoPromptOptimizer.manual-test.js.map +1 -0
  221. package/dist/services/chainExecutor.d.ts +26 -0
  222. package/dist/services/chainExecutor.d.ts.map +1 -0
  223. package/dist/services/chainExecutor.js +399 -0
  224. package/dist/services/chainExecutor.js.map +1 -0
  225. package/dist/services/classifyImageQuestion.d.ts +55 -0
  226. package/dist/services/classifyImageQuestion.d.ts.map +1 -0
  227. package/dist/services/classifyImageQuestion.js +428 -0
  228. package/dist/services/classifyImageQuestion.js.map +1 -0
  229. package/dist/services/configuration/executor.d.ts +3 -0
  230. package/dist/services/configuration/executor.d.ts.map +1 -0
  231. package/dist/services/configuration/executor.js +795 -0
  232. package/dist/services/configuration/executor.js.map +1 -0
  233. package/dist/services/error.d.ts +13 -0
  234. package/dist/services/error.d.ts.map +1 -0
  235. package/dist/services/error.js +34 -0
  236. package/dist/services/error.js.map +1 -0
  237. package/dist/services/executor.d.ts +11 -0
  238. package/dist/services/executor.d.ts.map +1 -0
  239. package/dist/services/executor.js +1587 -0
  240. package/dist/services/executor.js.map +1 -0
  241. package/dist/services/extractPdf.d.ts +26 -0
  242. package/dist/services/extractPdf.d.ts.map +1 -0
  243. package/dist/services/extractPdf.js +256 -0
  244. package/dist/services/extractPdf.js.map +1 -0
  245. package/dist/services/generateJsTransformFromPrompt.d.ts +11 -0
  246. package/dist/services/generateJsTransformFromPrompt.d.ts.map +1 -0
  247. package/dist/services/generateJsTransformFromPrompt.js +328 -0
  248. package/dist/services/generateJsTransformFromPrompt.js.map +1 -0
  249. package/dist/services/localizeFirebaseMedia.d.ts +20 -0
  250. package/dist/services/localizeFirebaseMedia.d.ts.map +1 -0
  251. package/dist/services/localizeFirebaseMedia.js +135 -0
  252. package/dist/services/localizeFirebaseMedia.js.map +1 -0
  253. package/dist/services/polyfill_canvas.d.ts +2 -0
  254. package/dist/services/polyfill_canvas.d.ts.map +1 -0
  255. package/dist/services/polyfill_canvas.js +19 -0
  256. package/dist/services/polyfill_canvas.js.map +1 -0
  257. package/dist/services/promptRoutes.d.ts +7 -0
  258. package/dist/services/promptRoutes.d.ts.map +1 -0
  259. package/dist/services/promptRoutes.js +70 -0
  260. package/dist/services/promptRoutes.js.map +1 -0
  261. package/dist/services/runPrompt.d.ts +29 -0
  262. package/dist/services/runPrompt.d.ts.map +1 -0
  263. package/dist/services/runPrompt.js +232 -0
  264. package/dist/services/runPrompt.js.map +1 -0
  265. package/dist/services/schemaInference.d.ts +2 -0
  266. package/dist/services/schemaInference.d.ts.map +1 -0
  267. package/dist/services/schemaInference.js +17 -0
  268. package/dist/services/schemaInference.js.map +1 -0
  269. package/dist/services/self-learning/api.d.ts +2 -0
  270. package/dist/services/self-learning/api.d.ts.map +1 -0
  271. package/dist/services/self-learning/api.js +84 -0
  272. package/dist/services/self-learning/api.js.map +1 -0
  273. package/dist/services/self-learning/autolearn.d.ts +23 -0
  274. package/dist/services/self-learning/autolearn.d.ts.map +1 -0
  275. package/dist/services/self-learning/autolearn.js +308 -0
  276. package/dist/services/self-learning/autolearn.js.map +1 -0
  277. package/dist/services/self-learning/discover.d.ts +11 -0
  278. package/dist/services/self-learning/discover.d.ts.map +1 -0
  279. package/dist/services/self-learning/discover.js +446 -0
  280. package/dist/services/self-learning/discover.js.map +1 -0
  281. package/dist/services/self-learning/image.d.ts +10 -0
  282. package/dist/services/self-learning/image.d.ts.map +1 -0
  283. package/dist/services/self-learning/image.js +38 -0
  284. package/dist/services/self-learning/image.js.map +1 -0
  285. package/dist/services/self-learning/injest.d.ts +25 -0
  286. package/dist/services/self-learning/injest.d.ts.map +1 -0
  287. package/dist/services/self-learning/injest.js +110 -0
  288. package/dist/services/self-learning/injest.js.map +1 -0
  289. package/dist/services/self-learning/learn.d.ts +2 -0
  290. package/dist/services/self-learning/learn.d.ts.map +1 -0
  291. package/dist/services/self-learning/learn.js +145 -0
  292. package/dist/services/self-learning/learn.js.map +1 -0
  293. package/dist/services/self-learning/matcher.d.ts +2 -0
  294. package/dist/services/self-learning/matcher.d.ts.map +1 -0
  295. package/dist/services/self-learning/matcher.js +38 -0
  296. package/dist/services/self-learning/matcher.js.map +1 -0
  297. package/dist/services/self-learning/openai.d.ts +8 -0
  298. package/dist/services/self-learning/openai.d.ts.map +1 -0
  299. package/dist/services/self-learning/openai.js +97 -0
  300. package/dist/services/self-learning/openai.js.map +1 -0
  301. package/dist/services/self-learning/phash.d.ts +5 -0
  302. package/dist/services/self-learning/phash.d.ts.map +1 -0
  303. package/dist/services/self-learning/phash.js +68 -0
  304. package/dist/services/self-learning/phash.js.map +1 -0
  305. package/dist/services/self-learning/recognize.d.ts +17 -0
  306. package/dist/services/self-learning/recognize.d.ts.map +1 -0
  307. package/dist/services/self-learning/recognize.js +116 -0
  308. package/dist/services/self-learning/recognize.js.map +1 -0
  309. package/dist/services/self-learning/record_transition.d.ts +8 -0
  310. package/dist/services/self-learning/record_transition.d.ts.map +1 -0
  311. package/dist/services/self-learning/record_transition.js +20 -0
  312. package/dist/services/self-learning/record_transition.js.map +1 -0
  313. package/dist/services/self-learning/registry.d.ts +4 -0
  314. package/dist/services/self-learning/registry.d.ts.map +1 -0
  315. package/dist/services/self-learning/registry.js +19 -0
  316. package/dist/services/self-learning/registry.js.map +1 -0
  317. package/dist/services/self-learning/schema.d.ts +114 -0
  318. package/dist/services/self-learning/schema.d.ts.map +1 -0
  319. package/dist/services/self-learning/schema.js +70 -0
  320. package/dist/services/self-learning/schema.js.map +1 -0
  321. package/dist/services/self-learning/schemaStrictify.d.ts +2 -0
  322. package/dist/services/self-learning/schemaStrictify.d.ts.map +1 -0
  323. package/dist/services/self-learning/schemaStrictify.js +34 -0
  324. package/dist/services/self-learning/schemaStrictify.js.map +1 -0
  325. package/dist/services/self-learning/transition_graph.d.ts +6 -0
  326. package/dist/services/self-learning/transition_graph.d.ts.map +1 -0
  327. package/dist/services/self-learning/transition_graph.js +83 -0
  328. package/dist/services/self-learning/transition_graph.js.map +1 -0
  329. package/dist/services/self-learning/transition_log.d.ts +3 -0
  330. package/dist/services/self-learning/transition_log.d.ts.map +1 -0
  331. package/dist/services/self-learning/transition_log.js +42 -0
  332. package/dist/services/self-learning/transition_log.js.map +1 -0
  333. package/dist/services/self-learning/util.d.ts +3 -0
  334. package/dist/services/self-learning/util.d.ts.map +1 -0
  335. package/dist/services/self-learning/util.js +11 -0
  336. package/dist/services/self-learning/util.js.map +1 -0
  337. package/dist/services/stepByStepAiPlanner.d.ts +39 -0
  338. package/dist/services/stepByStepAiPlanner.d.ts.map +1 -0
  339. package/dist/services/stepByStepAiPlanner.js +379 -0
  340. package/dist/services/stepByStepAiPlanner.js.map +1 -0
  341. package/dist/services/test-genjs.js +39 -0
  342. package/dist/services/test-genjs.manual-test.d.ts +2 -0
  343. package/dist/services/test-genjs.manual-test.d.ts.map +1 -0
  344. package/dist/services/test-genjs.manual-test.js +40 -0
  345. package/dist/services/test-genjs.manual-test.js.map +1 -0
  346. package/dist/services/uiMapPathFinder.d.ts +13 -0
  347. package/dist/services/uiMapPathFinder.d.ts.map +1 -0
  348. package/dist/services/uiMapPathFinder.js +79 -0
  349. package/dist/services/uiMapPathFinder.js.map +1 -0
  350. package/dist/services/uiMapService.d.ts +26 -0
  351. package/dist/services/uiMapService.d.ts.map +1 -0
  352. package/dist/services/uiMapService.js +275 -0
  353. package/dist/services/uiMapService.js.map +1 -0
  354. package/dist/services/uiPlanner.d.ts +54 -0
  355. package/dist/services/uiPlanner.d.ts.map +1 -0
  356. package/dist/services/uiPlanner.js +558 -0
  357. package/dist/services/uiPlanner.js.map +1 -0
  358. package/dist/services/utilityFunctions.d.ts +80 -0
  359. package/dist/services/utilityFunctions.d.ts.map +1 -0
  360. package/dist/services/utilityFunctions.js +352 -0
  361. package/dist/services/utilityFunctions.js.map +1 -0
  362. package/dist/services/variableGenerator.d.ts +39 -0
  363. package/dist/services/variableGenerator.d.ts.map +1 -0
  364. package/dist/services/variableGenerator.js +157 -0
  365. package/dist/services/variableGenerator.js.map +1 -0
  366. package/dist/services/workflow/build-workflow.d.ts +49 -0
  367. package/dist/services/workflow/build-workflow.d.ts.map +1 -0
  368. package/dist/services/workflow/build-workflow.js +119 -0
  369. package/dist/services/workflow/build-workflow.js.map +1 -0
  370. package/dist/standardRoutes.d.ts +2 -0
  371. package/dist/standardRoutes.d.ts.map +1 -0
  372. package/dist/standardRoutes.js +1495 -0
  373. package/dist/standardRoutes.js.map +1 -0
  374. package/dist/stepWorkflowRoutes.d.ts +2 -0
  375. package/dist/stepWorkflowRoutes.d.ts.map +1 -0
  376. package/dist/stepWorkflowRoutes.js +1007 -0
  377. package/dist/stepWorkflowRoutes.js.map +1 -0
  378. package/dist/storage.d.ts +19 -0
  379. package/dist/storage.d.ts.map +1 -0
  380. package/dist/storage.docker.json +61 -0
  381. package/dist/storage.js +131 -0
  382. package/dist/storage.js.map +1 -0
  383. package/dist/storage.json +78 -0
  384. package/dist/storage_cache/boxes.json +48 -0
  385. package/dist/storage_cache/suno_state.json +3 -0
  386. package/dist/suno_download.d.ts +11 -0
  387. package/dist/suno_download.d.ts.map +1 -0
  388. package/dist/suno_download.js +33 -0
  389. package/dist/suno_download.js.map +1 -0
  390. package/dist/suno_download.py +119 -0
  391. package/dist/test-web-element-requests.d.ts +6 -0
  392. package/dist/test-web-element-requests.d.ts.map +1 -0
  393. package/dist/test-web-element-requests.js +114 -0
  394. package/dist/test-web-element-requests.js.map +1 -0
  395. package/dist/test_pdf_render.d.ts +2 -0
  396. package/dist/test_pdf_render.d.ts.map +1 -0
  397. package/dist/test_pdf_render.js +50 -0
  398. package/dist/test_pdf_render.js.map +1 -0
  399. package/dist/training_data_viewer_endpoints.d.ts +2 -0
  400. package/dist/training_data_viewer_endpoints.d.ts.map +1 -0
  401. package/dist/training_data_viewer_endpoints.js +141 -0
  402. package/dist/training_data_viewer_endpoints.js.map +1 -0
  403. package/dist/utils.d.ts +353 -0
  404. package/dist/utils.d.ts.map +1 -0
  405. package/dist/utils.js +1517 -0
  406. package/dist/utils.js.map +1 -0
  407. package/dist/vm-h100.env.template +55 -0
  408. package/dist/web-element-requests.d.ts +102 -0
  409. package/dist/web-element-requests.d.ts.map +1 -0
  410. package/dist/web-element-requests.js +278 -0
  411. package/dist/web-element-requests.js.map +1 -0
  412. package/dist/workflowRoutes.d.ts +2 -0
  413. package/dist/workflowRoutes.d.ts.map +1 -0
  414. package/dist/workflowRoutes.js +441 -0
  415. package/dist/workflowRoutes.js.map +1 -0
  416. package/package.json +109 -0
@@ -0,0 +1,1514 @@
1
+ import robot from 'robotjs';
2
+ import { KEYS } from './constants.js';
3
+ import { setItem, getItem } from './storage.js';
4
+ import os from 'os';
5
+ import fs from 'fs';
6
+ import { fix } from './process.js';
7
+ import path from 'path';
8
+ import { getFiles, findVideoJobs, sanitizeFileName, getDetectOrientation, readProjectFile, saveProjectFile, countFilesInDownloads, findSocialPorterVideos, moveSocialPorterVideos, console_log_it, findFileInDirectoryHasInWithAndEndingWith, pasteText, waitFor, isThere, pressReturn, pause, waitForQueuedRenders, ifYouDontFinish, refreshScreen, extractVersionNumber, getContext, MIDJOURNEY_SELECTOR, findFilesWithString, get, set, getModePositionKey, buildProgressBar, get_jobs_path, processSunoState, getFilesToProcess, workflowOp } from './utils.js';
9
+ // Import missing constants/functions
10
+ import { MODES, SUNO_SELECTORS, YOUTUBE_SELECTORS } from './constants.js';
11
+ import { safeExtractJSON } from './jsonHandler.js';
12
+ const WAIT_FACTOR = 0.25;
13
+ const chrome_offsets = { x: 1, y: 125 };
14
+ export async function moveMouse(position) {
15
+ const { left, top, height, width } = position;
16
+ // {
17
+ // height: 23.99147605895996,
18
+ // left: 419.8692932128906,
19
+ // top: 379.8948860168457,
20
+ // width: 1170.241455078125
21
+ // }
22
+ // Define the target coordinates (x, y)
23
+ const targetX = left + chrome_offsets.x + (width / 2);
24
+ const targetY = top + chrome_offsets.y + (height / 4);
25
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`);
26
+ // Move the mouse smoothly to the target coordinates
27
+ if (isWindows()) {
28
+ robot.moveMouse(targetX, targetY);
29
+ }
30
+ else
31
+ robot.moveMouseSmooth(targetX, targetY);
32
+ }
33
+ export async function mouseClick() {
34
+ await pause(() => {
35
+ robot.mouseClick(); // Performs a left-click.
36
+ }, 1000); // 1 second delay for safety
37
+ }
38
+ function sleep(ms) {
39
+ return new Promise(resolve => setTimeout(resolve, ms));
40
+ }
41
+ export async function pressEscapeAsync() {
42
+ robot.keyToggle("escape", "down"); // press down
43
+ await sleep(500); // wait 0.5 seconds
44
+ robot.keyToggle("escape", "up"); // release
45
+ }
46
+ export async function moveMouseDesktop(position) {
47
+ const { left, top, height, width } = position;
48
+ // {
49
+ // height: 23.99147605895996,
50
+ // left: 419.8692932128906,
51
+ // top: 379.8948860168457,
52
+ // width: 1170.241455078125
53
+ // }
54
+ // Define the target coordinates (x, y)
55
+ const targetX = left + (width / 2);
56
+ const targetY = top + (height / 2);
57
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`, '[moveMouseDesktop]');
58
+ // Move the mouse smoothly to the target coordinates
59
+ if (isWindows()) {
60
+ robot.moveMouse(targetX, targetY);
61
+ }
62
+ else
63
+ robot.moveMouseSmooth(targetX, targetY);
64
+ }
65
+ export async function moveMouseRelative(relative) {
66
+ let mousePos = robot.getMousePos();
67
+ const { left, top } = relative;
68
+ console_log_it(`Moving mouse to relative position (${left}, ${top})...`, '[moveMouseRelativerelativeposition]');
69
+ console_log_it(`Current mouse position: (${JSON.stringify(mousePos, null, 3)})`, '[moveMousePositionRelative]');
70
+ // {
71
+ // height: 23.99147605895996,
72
+ // left: 419.8692932128906,
73
+ // top: 379.8948860168457,
74
+ // width: 1170.241455078125
75
+ // }
76
+ // Define the target coordinates (x, y)
77
+ const targetX = left + (mousePos.x);
78
+ const targetY = top + (mousePos.y);
79
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`, '[moveMouseRelative]');
80
+ // Move the mouse smoothly to the target coordinates
81
+ robot.moveMouseSmooth(targetX, targetY);
82
+ }
83
+ /**
84
+ * Returns true if the current platform is Windows.
85
+ * @returns {boolean}
86
+ */
87
+ export function isWindows() {
88
+ // os.platform() yields 'win32' on Windows (both 32‑bit and 64‑bit)
89
+ return os.platform() === 'win32';
90
+ }
91
+ function pressEscape() {
92
+ // Tap "escape" (down + up)
93
+ robot.keyTap('escape');
94
+ }
95
+ /**
96
+ * Presses (taps) the Down Arrow key once.
97
+ */
98
+ function pressDownArrow() {
99
+ robot.keyTap('down');
100
+ }
101
+ export async function operateMidjourneyDownloadPublicMedia() {
102
+ pressEscape();
103
+ const SPEED = parseInt(get(KEYS.speed) || '5000') || 5000;
104
+ console_log_it('[operateMidjourneyDownloadPublicMedia]', 'func');
105
+ let filesDownloaded = 0;
106
+ try {
107
+ console_log_it('[operateMidjourneyDownloadPublicMedia] waiting for video button', 'func');
108
+ await waitFor(async () => {
109
+ return getModePositionKey(MIDJOURNEY_SELECTOR.videoButton);
110
+ });
111
+ console_log_it('[operateMidjourneyDownloadPublicMedia] moving to video button', 'func');
112
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR.videoButton));
113
+ await pause(() => {
114
+ console_log_it("Performing left click...", 'func');
115
+ robot.mouseClick(); // Performs a left-click.
116
+ }, 1000); // 1 second delay for safety}
117
+ try {
118
+ await pause(() => {
119
+ console_log_it("Waiting for download button to appear...", 'func');
120
+ }, SPEED * 2);
121
+ // Wait for the download button to appear
122
+ while (true) {
123
+ await findSocialPorterVideos()
124
+ .then(files => moveSocialPorterVideos(files, path.join(get(KEYS.images_folder), 'top_ten_videos')))
125
+ .catch(console.error);
126
+ try {
127
+ await waitFor(async () => {
128
+ return getModePositionKey(MIDJOURNEY_SELECTOR.useText);
129
+ }, 2 * 1000);
130
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR.useText));
131
+ await pause(() => {
132
+ console_log_it("Performing left click...", 'func');
133
+ robot.mouseClick(); // Performs a left-click.
134
+ }, 1000); // 1 second delay for safety}
135
+ await pause(() => {
136
+ console_log_it("Performing left click...", 'func');
137
+ robot.mouseClick(); // Performs a left-click.
138
+ }, 1000); // 1 second delay for safety}
139
+ await waitFor(async () => {
140
+ return getModePositionKey(MIDJOURNEY_SELECTOR.lightboxPrompt);
141
+ }, 10 * 1000);
142
+ let { innerText } = getModePositionKey(MIDJOURNEY_SELECTOR.lightboxPrompt);
143
+ let jobs = findVideoJobs(innerText);
144
+ console_log_it(`jobs : ${jobs?.length}..."`, 'jobs');
145
+ let all_jobs_done = jobs.every(job => {
146
+ for (let i = 0; i < job.batch_size; i++) {
147
+ if (!findFileInDirectoryHasInWithAndEndingWith(path.join(get(KEYS.images_folder), 'top_ten_videos'), `${job.id}_${i}`, '.mp4')) {
148
+ return false;
149
+ }
150
+ }
151
+ return true;
152
+ });
153
+ console_log_it(`${all_jobs_done}..."`, 'all_jobs_done');
154
+ if (jobs?.length && all_jobs_done) {
155
+ pressDownArrow();
156
+ await pause(() => {
157
+ console_log_it("Performing left click...", 'func');
158
+ }, 1000); // 1 second delay for safety
159
+ continue;
160
+ }
161
+ }
162
+ catch (e) {
163
+ console_log_it("No prompt found, continuing...", 'error');
164
+ console_log_it(e, 'e');
165
+ pressDownArrow();
166
+ continue;
167
+ }
168
+ try {
169
+ await waitFor(async () => {
170
+ return getModePositionKey(MIDJOURNEY_SELECTOR.optionsButton);
171
+ });
172
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR.optionsButton));
173
+ await pause(() => {
174
+ robot.mouseClick(); // Performs a left-click.
175
+ }, 1000);
176
+ await waitFor(async () => {
177
+ return getModePositionKey(MIDJOURNEY_SELECTOR.optionsDownloadButton);
178
+ });
179
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR.optionsDownloadButton));
180
+ await pause(() => {
181
+ robot.mouseClick(); // Performs a left-click.
182
+ }, 1000);
183
+ }
184
+ catch (e) {
185
+ pressDownArrow();
186
+ await pause(() => {
187
+ console_log_it("Performing left click...", 'func');
188
+ }, 1000); // 1 second delay for safety}
189
+ continue;
190
+ }
191
+ let filesInDownloads = countFilesInDownloads();
192
+ try {
193
+ await waitFor(async () => {
194
+ let currentCount = countFilesInDownloads();
195
+ return filesInDownloads !== currentCount;
196
+ });
197
+ }
198
+ catch (e) {
199
+ console_log_it("No new files in downloads, continuing...", 'error');
200
+ }
201
+ await pause(() => {
202
+ console_log_it("Performing left click...", 'func');
203
+ }, SPEED); // 1 second delay for safety}
204
+ pressDownArrow();
205
+ console_log_it(`Files downloaded: ${filesDownloaded}`, 'files_downloaded');
206
+ console_log_it(buildProgressBar(filesDownloaded, 10), 'progress_bar');
207
+ filesDownloaded++;
208
+ if (filesDownloaded >= 12) {
209
+ console_log_it('Reached 12 files downloaded, stopping...', 'files_downloaded');
210
+ break;
211
+ }
212
+ }
213
+ }
214
+ catch (e) {
215
+ console_log_it(e, 'error');
216
+ console_log_it('Error in operateMidjourneyDownloadPublicMedia', 'func');
217
+ }
218
+ }
219
+ catch (e) {
220
+ console_log_it(e, 'error');
221
+ console_log_it('Error in operateMidjourneyDownloadPublicMedia', 'func');
222
+ throw e;
223
+ }
224
+ console_log_it('[done operateMidjourneyDownloadPublicMedia]', 'func');
225
+ }
226
+ export async function operateMidjourneyDownloadMedia() {
227
+ pressEscape();
228
+ const SPEED = parseInt(get(KEYS.speed) || '5000') || 5000;
229
+ console_log_it('[operateMidjourneyDownloadMedia]', 'func');
230
+ await waitFor(async () => {
231
+ return getModePositionKey(MIDJOURNEY_SELECTOR.firstImageCell);
232
+ });
233
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR.firstImageCell));
234
+ await pause(() => {
235
+ console_log_it("Performing left click...");
236
+ robot.mouseClick(); // Performs a left-click.
237
+ }, 1000); // 1 second delay for safety}
238
+ try {
239
+ await pause(() => {
240
+ console_log_it("Waiting for download button to appear...");
241
+ }, SPEED * 2);
242
+ // Wait for the download button to appear
243
+ while (true) {
244
+ await findSocialPorterVideos()
245
+ .then(files => moveSocialPorterVideos(files, get(KEYS.images_folder)))
246
+ .catch(console.error);
247
+ await waitFor(async () => {
248
+ return getModePositionKey(MIDJOURNEY_SELECTOR.lightboxPrompt);
249
+ });
250
+ try {
251
+ let { innerText } = getModePositionKey(MIDJOURNEY_SELECTOR.lightboxPrompt);
252
+ let jobs = findVideoJobs(innerText);
253
+ console_log_it(`jobs : ${jobs?.length}..."`, 'jobs');
254
+ let all_jobs_done = jobs.every(job => {
255
+ for (let i = 0; i < job.batch_size; i++) {
256
+ if (!findFileInDirectoryHasInWithAndEndingWith(get(KEYS.images_folder), `${job.id}_${i}`, '.mp4')) {
257
+ return false;
258
+ }
259
+ }
260
+ return true;
261
+ });
262
+ console_log_it(`${all_jobs_done}..."`, 'all_jobs_done');
263
+ if (jobs?.length && all_jobs_done) {
264
+ pressDownArrow();
265
+ await pause(() => {
266
+ console_log_it("Performing left click...");
267
+ }, 1000); // 1 second delay for safety
268
+ continue;
269
+ }
270
+ }
271
+ catch (e) {
272
+ console_log_it("No prompt found, continuing...", 'error');
273
+ console_log_it(e, 'e');
274
+ throw e;
275
+ }
276
+ try {
277
+ await waitFor(async () => {
278
+ return getModePositionKey(MIDJOURNEY_SELECTOR.downloadButton);
279
+ });
280
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR.downloadButton));
281
+ }
282
+ catch (e) {
283
+ pressDownArrow();
284
+ await pause(() => {
285
+ console_log_it("Performing left click...");
286
+ }, 1000); // 1 second delay for safety}
287
+ continue;
288
+ }
289
+ let filesIndDownloads = countFilesInDownloads();
290
+ await pause(() => {
291
+ console_log_it("Performing left click...");
292
+ robot.mouseClick(); // Performs a left-click.
293
+ }, 1000); // 1 second delay for safety}
294
+ await waitFor(async () => {
295
+ return getModePositionKey(MIDJOURNEY_SELECTOR.ilikeRadiobutton) && getModePositionKey(MIDJOURNEY_SELECTOR.iNeutralRadiobutton);
296
+ });
297
+ try {
298
+ await waitFor(async () => {
299
+ let currentCount = countFilesInDownloads();
300
+ return filesIndDownloads !== currentCount;
301
+ });
302
+ }
303
+ catch (e) {
304
+ console_log_it("No new files in downloads, continuing...", 'error');
305
+ }
306
+ if (Math.random() < 0.5) {
307
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR.ilikeRadiobutton));
308
+ await pause(() => {
309
+ console_log_it("Performing left click on 'I like' radio button...");
310
+ robot.mouseClick(); // Performs a left-click.
311
+ }, 1000); // 1 second delay for safety}
312
+ }
313
+ else {
314
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR.iNeutralRadiobutton));
315
+ await pause(() => {
316
+ console_log_it("Performing left click on 'Neutral' radio button...");
317
+ robot.mouseClick(); // Performs a left-click.
318
+ }, 1000); // 1 second delay for safety}
319
+ }
320
+ await pause(() => {
321
+ console_log_it("Performing left click...");
322
+ }, SPEED); // 1 second delay for safety}
323
+ pressDownArrow();
324
+ }
325
+ }
326
+ catch (e) {
327
+ console_log_it(e, 'error');
328
+ console_log_it('Error in operateMidjourneyDownloadMedia');
329
+ }
330
+ console_log_it('[done operateMidjourneyDownloadMedia]', 'func');
331
+ }
332
+ export async function operateMidjourneyToImages() {
333
+ const SPEED = parseInt(get(KEYS.speed) || '5000') || 5000;
334
+ let skipped = 0;
335
+ let lastTime = get(KEYS.LastMidjourneyToImages);
336
+ if (!lastTime) {
337
+ set(KEYS.LastMidjourneyToImages, {
338
+ project: 'The Tall Tree / L’Arbre',
339
+ prompt: 8,
340
+ animate: 0
341
+ });
342
+ }
343
+ let failed = false;
344
+ console_log_it('[operateMidjourneyToImages]', 'func');
345
+ try {
346
+ const root_folder = get(KEYS.current_folder);
347
+ const name = getItem('sourceFile');
348
+ let skipping = 0;
349
+ let filesToProcess = [name];
350
+ console_log_it('[operateMidjourneyToImages getFileToProcess]', 'func');
351
+ filesToProcess = getFilesToProcess(name, filesToProcess, root_folder);
352
+ let e1 = [];
353
+ console_log_it(`[operateMidjourneyToImages ${filesToProcess}]`, 'func');
354
+ filesToProcess.filter(x => x.endsWith('.json')).forEach((fileP) => {
355
+ console_log_it(fileP, 'file to operate');
356
+ let projects = readProjectFile(path.join(root_folder, fileP));
357
+ let sub_lyric_projects = projects.map(t => {
358
+ return t.lyrics || [];
359
+ }).flat();
360
+ e1 = [...e1, ...sub_lyric_projects, ...(sub_lyric_projects?.length ? projects : [])];
361
+ });
362
+ let foundFirst = false;
363
+ let skipFirstPrompts = false;
364
+ let skipFirstAnimates = false;
365
+ const SIMULTANEOUS_JOBS = parseInt(get(KEYS.simultaneous_jobs) || '1') || 1;
366
+ let simultaneousJobs = SIMULTANEOUS_JOBS;
367
+ for (let i = 0; i < e1.length; i++) {
368
+ let section = e1[i];
369
+ console_log_it(buildProgressBar(i + 1, e1.length, 20), 'overall-progress');
370
+ const { name, portrait_prompt, prompts, characters, prompts_selection, animated_images = {} } = section;
371
+ // if (lastTime.project) {
372
+ // if (lastTime.project !== name && !foundFirst) {
373
+ // continue;
374
+ // }
375
+ // else if (lastTime.project === name && !foundFirst) {
376
+ // foundFirst = true;
377
+ // skipFirstPrompts = true;
378
+ // }
379
+ // }
380
+ for (let j = 0; j < prompts.length; j++) {
381
+ let prompt = prompts[j];
382
+ console_log_it(buildProgressBar(j + 1, prompts.length, 20), 'prompts-progress');
383
+ let jobs = findVideoJobs(prompt);
384
+ if (jobs.length) {
385
+ console_log_it('Skipping ' + skipped, 'already_done');
386
+ skipped++;
387
+ continue;
388
+ }
389
+ if (skipFirstPrompts) {
390
+ j = Math.min(prompts.length - 1, lastTime.prompt);
391
+ skipFirstPrompts = false;
392
+ skipFirstAnimates = true;
393
+ }
394
+ if (prompt && prompts_selection[prompt]) {
395
+ let imagesToAnimate = prompts_selection[prompt] || [];
396
+ let k_start = 0;
397
+ if (skipFirstAnimates) {
398
+ k_start = lastTime.animate || 0;
399
+ skipFirstAnimates = false;
400
+ }
401
+ let cancelIt = ifYouDontFinish(() => {
402
+ refreshScreen(robot);
403
+ }, 10 * 60 * 1000);
404
+ for (let k = k_start; k < imagesToAnimate.length; k++) {
405
+ console_log_it(buildProgressBar(k, imagesToAnimate.length, 20), 'animate-progress');
406
+ let imageToAnimate = imagesToAnimate[k];
407
+ if (!animated_images?.[imageToAnimate]) {
408
+ await clearMidjourneyImages();
409
+ await animateImageWithMidjourney(imageToAnimate, prompt);
410
+ section.animated_images = {
411
+ ...section.animated_images,
412
+ [imageToAnimate]: true
413
+ };
414
+ set(KEYS.LastMidjourneyToImages, {
415
+ project: name,
416
+ prompt: j,
417
+ animate: k
418
+ });
419
+ await pause(() => { }, SPEED); // wait a second to ensure
420
+ simultaneousJobs--;
421
+ if (simultaneousJobs <= 0) {
422
+ console_log_it('Waiting for rendering to finish...', 'state');
423
+ simultaneousJobs = SIMULTANEOUS_JOBS;
424
+ await waitForRendering(SPEED);
425
+ }
426
+ //save the project again.
427
+ }
428
+ }
429
+ cancelIt();
430
+ }
431
+ }
432
+ }
433
+ }
434
+ catch (e) {
435
+ console_log_it(e, 'error');
436
+ failed = true;
437
+ }
438
+ if (!failed) {
439
+ set(KEYS.LastMidjourneyToImages, {
440
+ project: '',
441
+ prompt: 0,
442
+ animate: 0
443
+ });
444
+ }
445
+ console_log_it('[done operateMidjourneyToImages]', 'func');
446
+ }
447
+ /**
448
+ * Parse an image filename of the form:
449
+ * <username>_<prompt>_i_<guid>_<imageNumber>.png
450
+ *
451
+ * @param {string} filename
452
+ * @returns {{
453
+ * username: string,
454
+ * prompt: string,
455
+ * guid: string,
456
+ * image_number: number
457
+ * }}
458
+ */
459
+ function parseImageName(filename) {
460
+ // Adjust the extension if you support other formats (jpg, webp, etc.)
461
+ const re = /^([^_]+)_(.+)_i_([0-9a-fA-F-]{36})_(\d+)\.png$/;
462
+ const match = filename.match(re);
463
+ if (!match) {
464
+ throw new Error(`Filename "${filename}" does not match expected pattern.`);
465
+ }
466
+ const [, // full match
467
+ username, // group 1
468
+ prompt, // group 2
469
+ guid, // group 3
470
+ imageNumStr // group 4
471
+ ] = match;
472
+ return {
473
+ username,
474
+ prompt,
475
+ guid,
476
+ image_number: parseInt(imageNumStr, 10)
477
+ };
478
+ }
479
+ async function animateImageWithMidjourney(imageFileName, prompt) {
480
+ const SPEED = parseInt(get(KEYS.speed) || '5000') || 5000;
481
+ await openMidjourneyImagePanel();
482
+ await waitFor(async () => {
483
+ return getModePositionKey(MIDJOURNEY_SELECTOR.chooseAnImage);
484
+ });
485
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR.chooseAnImage));
486
+ await pause(() => {
487
+ console_log_it("Uploading image", 'state');
488
+ robot.mouseClick(); // Performs a left-click.
489
+ }, 1000); // 1 second delay for safety}
490
+ await fileModalOperate(path.join(get(KEYS.images_folder), imageFileName));
491
+ await waitFor(async () => {
492
+ return getModePositionKey(MIDJOURNEY_SELECTOR.promptImage);
493
+ });
494
+ await pause(() => { }, SPEED);
495
+ let animateButton = getCenteredRectAtOffset(getModePositionKey(MIDJOURNEY_SELECTOR.promptImage), 20, -20, 20, 20, true);
496
+ await moveMouse(animateButton);
497
+ await pause(() => {
498
+ console_log_it("Deleting image", 'state');
499
+ robot.mouseClick(); // Performs a left-click.
500
+ }, 1000); // 1 second delay for safety}
501
+ pressEscape();
502
+ await pause(() => { }, 3400);
503
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR['[id="desktop_input_bar"]']));
504
+ await pause(() => {
505
+ console_log_it("starting", 'state');
506
+ robot.mouseClick(); // Performs a left-click.
507
+ }, 1000); // 1 second delay for safety}
508
+ if (typeof prompt === 'string') {
509
+ await pasteText(prompt);
510
+ await pause(() => { }, SPEED);
511
+ robot.keyTap('enter');
512
+ await pause(() => { }, SPEED);
513
+ }
514
+ }
515
+ export async function typeText(params) {
516
+ const { keys, ctrl = false, shift = false, alt = false } = params;
517
+ // Build modifier array
518
+ const modifiers = [];
519
+ if (ctrl) {
520
+ modifiers.push(isWindows() ? 'ctrl' : 'command');
521
+ }
522
+ if (shift) {
523
+ modifiers.push('shift');
524
+ }
525
+ if (alt) {
526
+ modifiers.push(isWindows() ? 'alt' : 'option');
527
+ }
528
+ const modifierString = modifiers.length > 0 ? modifiers.join('+') + '+' : '';
529
+ console_log_it(`Typing keys: ${modifierString}${keys}`, '[typeText]');
530
+ // Use robotjs keyTap with modifier array (not string)
531
+ robot.keyTap(keys, modifiers);
532
+ }
533
+ export async function pressKey(params) {
534
+ const { keys, ctrl = false, shift = false, alt = false } = params;
535
+ // Build modifier array
536
+ const modifiers = [];
537
+ if (ctrl) {
538
+ robot.keyToggle(isWindows() ? 'ctrl' : 'command', 'down'); // Ensure control is pressed down
539
+ }
540
+ await pause(() => { }, 100); // Short pause to ensure control is pressed
541
+ // Use robotjs keyTap with modifier array (not string)
542
+ robot.keyTap(keys);
543
+ await pause(() => { }, 100); // Short pause to ensure control is pressed
544
+ if (ctrl) {
545
+ robot.keyToggle(isWindows() ? 'ctrl' : 'command', 'up'); // Ensure control is released
546
+ }
547
+ }
548
+ async function waitForRendering(SPEED) {
549
+ let stillRendering = false;
550
+ do {
551
+ await pause(() => { }, SPEED * 2);
552
+ stillRendering = await isThere(() => {
553
+ return getModePositionKey(MIDJOURNEY_SELECTOR.starting) ||
554
+ getModePositionKey(MIDJOURNEY_SELECTOR.completing) ||
555
+ getModePositionKey(MIDJOURNEY_SELECTOR.queued);
556
+ });
557
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR['[id="desktop_input_bar"]']));
558
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR.addImageBtn));
559
+ console_log_it(getModePositionKey(MIDJOURNEY_SELECTOR.starting), 'starting-position');
560
+ console_log_it(getModePositionKey(MIDJOURNEY_SELECTOR.completing), 'completing-position');
561
+ if (stillRendering) {
562
+ console_log_it(`stilling rendering ${new Date(Date.now()).toISOString()}`, 'state');
563
+ }
564
+ else {
565
+ console_log_it(`done rendering ${new Date(Date.now()).toISOString()}`, 'state');
566
+ }
567
+ } while (stillRendering);
568
+ }
569
+ export async function openMidjourneyImagePanel() {
570
+ pressEscape();
571
+ console_log_it('clear midjourney images', 'operation');
572
+ await waitFor(async () => {
573
+ console_log_it(getModePositionKey(MIDJOURNEY_SELECTOR.addImageBtn));
574
+ return getModePositionKey(MIDJOURNEY_SELECTOR.addImageBtn);
575
+ });
576
+ await moveMouse(getModePositionKey(MIDJOURNEY_SELECTOR.addImageBtn));
577
+ await pause(() => {
578
+ console_log_it("Performing left click...");
579
+ robot.mouseClick(); // Performs a left-click.
580
+ }, 1000); // 1 second delay for safety
581
+ }
582
+ export async function clearMidjourneyImages(all = true) {
583
+ try {
584
+ const SPEED = parseInt(get(KEYS.speed) || '5000') || 5000;
585
+ while (all) {
586
+ await openMidjourneyImagePanel();
587
+ await pause(() => { }, SPEED);
588
+ let deletButton = getCenteredRectAtOffset(getModePositionKey(MIDJOURNEY_SELECTOR.promptImage), -20, -20, 20, 20);
589
+ await moveMouse(deletButton);
590
+ await pause(() => {
591
+ console_log_it("Deleting image", 'state');
592
+ robot.mouseClick(); // Performs a left-click.
593
+ }, 1000); // 1 second delay for safety}
594
+ await pause(() => { }, 3400);
595
+ }
596
+ }
597
+ catch (e) {
598
+ console_log_it('done deleting images', 'state');
599
+ pressEscape();
600
+ }
601
+ }
602
+ /**
603
+ * Returns a rectangle of a given size, centered at an offset from the
604
+ * source rectangle. By default it's offset from the bottom-right.
605
+ * If `left` is true, it's offset from the bottom-left instead.
606
+ *
607
+ * @param {Object} rect – the source rectangle, with numeric top, left, width, height
608
+ * @param {number} offsetX – horizontal offset (default: 10)
609
+ * @param {number} offsetY – vertical offset (default: 10)
610
+ * @param {number} [outWidth] – output rectangle width (default: rect.width)
611
+ * @param {number} [outHeight] – output rectangle height (default: rect.height)
612
+ * @param {boolean} [left=false] – if true, offset from the left side of the source
613
+ * @returns {Object} a new rect { top, left, width, height }
614
+ */
615
+ function getCenteredRectAtOffset(rect, offsetX = 10, offsetY = 10, outWidth = rect.width, outHeight = rect.height, left = false) {
616
+ // Choose the starting X point
617
+ const baseX = left ? rect.left : (rect.left + rect.width);
618
+ const centerX = baseX + offsetX;
619
+ // Always offset from the bottom
620
+ const centerY = rect.top + rect.height + offsetY;
621
+ // Create a new rect centered at (centerX, centerY)
622
+ return {
623
+ top: centerY - outHeight / 2,
624
+ left: centerX - outWidth / 2,
625
+ width: outWidth,
626
+ height: outHeight,
627
+ };
628
+ }
629
+ export async function operateYoutubeMouse() {
630
+ console_log_it('[YOUTUBE]', 'mode-filter');
631
+ let attempts = 10;
632
+ let success = false;
633
+ while (attempts > 0 && !success) {
634
+ try {
635
+ const SPEED = parseInt(get(KEYS.speed) || '5000') || 5000;
636
+ console.clear();
637
+ console_log_it('operate youtube', '[YOUTUBE] func');
638
+ console_log_it(`Operating Youtube with mode: ${get(KEYS.mode)}`, '[YOUTUBE] running-mode');
639
+ let currentSourceFilePath = path.join(get(KEYS.current_folder), get(KEYS.sourceFile));
640
+ let overAllCurrentSources = readProjectFile(currentSourceFilePath);
641
+ let dateOffset = 1;
642
+ try {
643
+ dateOffset = parseFloat(get(KEYS.days_offset)) || 1;
644
+ }
645
+ catch (e) {
646
+ console_log_it('bad date offset', '[YOUTUBE] bad date offset');
647
+ dateOffset = 1;
648
+ }
649
+ let currentSources = [];
650
+ overAllCurrentSources.forEach((source) => {
651
+ currentSources.push(source);
652
+ if (source?.lyrics?.length && source?.lyrics?.length > 0) {
653
+ source.lyrics.forEach((lyric) => { currentSources.push(lyric); });
654
+ }
655
+ });
656
+ let firstIndex = 0;
657
+ let firstVideo = get(KEYS.firstVideoForUpload);
658
+ firstIndex = currentSources.findIndex(d => firstVideo && d.name === firstVideo);
659
+ if (firstIndex === -1) {
660
+ firstIndex = 0;
661
+ }
662
+ console_log_it(`Progress: ${currentSources.length}`, '[YOUTUBE] youtube-progress');
663
+ const PER_DAY = parseInt(get(KEYS.publishPerDay) || '1') || 1;
664
+ let count = 0;
665
+ for (let i = firstIndex; i < currentSources.length; i++) {
666
+ console_log_it(`Current Sources: ${buildProgressBar(i, currentSources.length, 20)}`, '[YOUTUBE] youtube-progress');
667
+ let { name, title, original_name = '', youtubeDescription = null, description = '', uploaded = false, forKids } = currentSources[i];
668
+ if (uploaded) {
669
+ continue;
670
+ }
671
+ if (!name) {
672
+ name = title || original_name;
673
+ }
674
+ if (!name) {
675
+ console_log_it(`Skipping source with no name:`, '[YOUTUBE] youtube-progress');
676
+ continue;
677
+ }
678
+ let youtubeData = safeExtractJSON(youtubeDescription, {
679
+ returnOriginalOnFail: false,
680
+ defaultValue: null,
681
+ });
682
+ description = description.substring(0, 2000);
683
+ console_log_it(`${JSON.stringify(youtubeData)}`, '[YOUTUBE] youtubeData');
684
+ console_log_it(`${JSON.stringify(youtubeDescription)}`, '[YOUTUBE] youtubeDescription');
685
+ if (youtubeData && youtubeData.description) {
686
+ description = youtubeData.description.substring(0, 2000);
687
+ }
688
+ else if (typeof youtubeDescription === 'string') {
689
+ description = youtubeDescription.substring(0, 2000);
690
+ }
691
+ let prefix_name = fix(name);
692
+ prefix_name = sanitizeFileName(prefix_name);
693
+ if (prefix_name?.length >= 3) {
694
+ let filesForUpload = findFilesWithString(get(KEYS.renders_folder), prefix_name);
695
+ console_log_it(`prefix_name: ${prefix_name}`, '[YOUTUBE] prefix_name');
696
+ console_log_it(`currentSource: `, '[YOUTUBE] currentSource');
697
+ for (let j = 0; j < filesForUpload.length; j++) {
698
+ let fileForUpload = filesForUpload[j];
699
+ console_log_it(`filesForUpload: ${buildProgressBar(fileForUpload, filesForUpload.length, 20)}`, '[YOUTUBE] filesForUpload');
700
+ {
701
+ console_log_it(getContext().position?.[MODES.YOUTUBE], '[YOUTUBE] position');
702
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.location, '[YOUTUBE] position-location');
703
+ await waitFor(async () => {
704
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.createtn], '[YOUTUBE] currentelement');
705
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.createtn];
706
+ });
707
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.createtn], '[YOUTUBE] currentelement');
708
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.createtn]);
709
+ await pause(async () => {
710
+ console_log_it("Performing left click...", '[YOUTUBE] state');
711
+ await mouseClick(); // Performs a left-click.
712
+ }, 1000); // 1 second delay for safety
713
+ }
714
+ {
715
+ await pause(() => { }, SPEED); // 1 second delay for safety
716
+ await waitFor(async () => {
717
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.uploadVideo], '[YOUTUBE] currentelement');
718
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.uploadVideo];
719
+ });
720
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.uploadVideo], '[YOUTUBE] currentelement');
721
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.uploadVideo]);
722
+ await pause(async () => {
723
+ console_log_it("Performing left click...", '[YOUTUBE] state');
724
+ await mouseClick(); // Performs a left-click.
725
+ }, 1000); // 1 second delay for safety
726
+ }
727
+ {
728
+ await pause(() => { console_log_it('wait 10s', '[YOUTUBE] '); }, SPEED); // 1 second delay for safety
729
+ await waitFor(async () => {
730
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.selectFilesButton], '[YOUTUBE] currentelement');
731
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.selectFilesButton];
732
+ });
733
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.selectFilesButton], '[YOUTUBE] currentelement');
734
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.selectFilesButton]);
735
+ await pause(async () => {
736
+ console_log_it("Performing left click...", '[YOUTUBE] state');
737
+ await mouseClick(); // Performs a left-click.
738
+ }, 1000); // 1 second delay for safety
739
+ await fileModalOperate(path.join(get(KEYS.renders_folder), fileForUpload));
740
+ }
741
+ {
742
+ await pause(() => { console_log_it('wait 10s', '[YOUTUBE] '); }, SPEED); // 1 second delay for safety
743
+ await waitFor(async () => {
744
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.titleInput], '[YOUTUBE] currentelement');
745
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.titleInput];
746
+ });
747
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.titleInput]);
748
+ console_log_it(`original_name: ${original_name || name}`, '[YOUTUBE] ');
749
+ await pause(async () => {
750
+ console_log_it("Performing left click...", '[YOUTUBE] state');
751
+ await mouseClick(); // Performs a left-click.
752
+ }, 1000); // 1 second delay for safety
753
+ clearAllText();
754
+ await pasteText(`${original_name || name}`.substring(0, 100)); // YouTube title limit is 100 characters
755
+ console_log_it(`pasted title: ${original_name || name}`, '[YOUTUBE] ');
756
+ }
757
+ {
758
+ await pause(() => { console_log_it('wait 10s', '[YOUTUBE] '); }, SPEED); // 1 second delay for safety
759
+ await waitFor(async () => {
760
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.descriptionInput], '[YOUTUBE] currentelement');
761
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.descriptionInput];
762
+ });
763
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.descriptionInput]);
764
+ await pause(async () => {
765
+ console_log_it("Performing left click...", '[YOUTUBE] state');
766
+ await mouseClick(); // Performs a left-click.
767
+ }, 1000); // 1 second delay for safety
768
+ clearAllText();
769
+ await pasteText(`${description || name}`.slice(0, 4999));
770
+ }
771
+ await pause(() => { }, SPEED);
772
+ let point = { ...getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.descriptionInput] };
773
+ point.left = point.left + point.width / 2 + 10;
774
+ scroll(0, -1000); // Scroll down to make sure the styles are visible
775
+ await moveMouse(point);
776
+ scroll(0, -1000);
777
+ {
778
+ scroll(0, -1000); // Scroll down to make sure the styles are visible
779
+ await pause(() => { console_log_it('wait 10s', '[YOUTUBE] '); }, SPEED * 2); // 1 second delay for safety
780
+ if (forKids) {
781
+ await waitFor(async () => {
782
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.yesKidsRadioButton], '[YOUTUBE] currentelement');
783
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.yesKidsRadioButton];
784
+ });
785
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.yesKidsRadioButton]);
786
+ }
787
+ else {
788
+ await waitFor(async () => {
789
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.notKidsRadioButton], '[YOUTUBE] currentelement');
790
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.notKidsRadioButton];
791
+ });
792
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.notKidsRadioButton]);
793
+ }
794
+ await pause(async () => {
795
+ console_log_it("Performing left click...", '[YOUTUBE] state');
796
+ await mouseClick(); // Performs a left-click.
797
+ }, 1000); // 1 second delay for safety
798
+ await pause(async () => {
799
+ console_log_it("Performing left click...", '[YOUTUBE] state');
800
+ await mouseClick(); // Performs a left-click.
801
+ }, 1000); // 1 second delay for safety
802
+ }
803
+ {
804
+ await pause(() => { console_log_it('wait 10s', '[YOUTUBE] '); }, SPEED); // 1 second delay for safety
805
+ await waitFor(async () => {
806
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.nextButton], '[YOUTUBE] currentelement');
807
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.nextButton];
808
+ });
809
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.nextButton]);
810
+ await pause(async () => {
811
+ console_log_it("Performing left click...", '[YOUTUBE] state');
812
+ await mouseClick(); // Performs a left-click.
813
+ }, 1000); // 1 second delay for safety
814
+ }
815
+ {
816
+ await pause(() => { console_log_it('wait 10s', '[YOUTUBE] '); }, SPEED); // 1 second delay for safety
817
+ await waitFor(async () => {
818
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.nextButton], '[YOUTUBE] currentelement');
819
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.nextButton];
820
+ });
821
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.nextButton]);
822
+ await pause(async () => {
823
+ console_log_it("Performing left click...", '[YOUTUBE] state');
824
+ await mouseClick(); // Performs a left-click.
825
+ }, 1000); // 1 second delay for safety
826
+ }
827
+ {
828
+ await pause(() => { console_log_it('wait 10s', '[YOUTUBE] '); }, SPEED); // 1 second delay for safety
829
+ await waitFor(async () => {
830
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.nextButton], '[YOUTUBE] currentelement');
831
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.nextButton];
832
+ });
833
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.nextButton]);
834
+ await pause(async () => {
835
+ console_log_it("Performing left click...", '[YOUTUBE] state');
836
+ await mouseClick(); // Performs a left-click.
837
+ }, 1000); // 1 second delay for safety
838
+ }
839
+ {
840
+ await pause(() => { console_log_it('wait 10s', '[YOUTUBE] '); }, SPEED); // 1 second delay for safety
841
+ await waitFor(async () => {
842
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.scheduleButton], '[YOUTUBE] currentelement');
843
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.scheduleButton];
844
+ });
845
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.scheduleButton]);
846
+ await pause(async () => {
847
+ console_log_it("Performing left click...", '[YOUTUBE] state');
848
+ await mouseClick(); // Performs a left-click.
849
+ }, 1000); // 1 second delay for safety
850
+ }
851
+ {
852
+ await pause(() => { console_log_it('wait 10s', '[YOUTUBE] '); }, SPEED); // 1 second delay for safety
853
+ await waitFor(async () => {
854
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.dateField]);
855
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.dateField];
856
+ });
857
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.dateField]);
858
+ await pause(async () => {
859
+ console_log_it("Performing left click...", '[YOUTUBE] state');
860
+ await mouseClick(); // Performs a left-click.
861
+ }, 1000); // 1 second delay for safety
862
+ clearAllText();
863
+ const today = new Date();
864
+ let additionalDays = extractVersionNumber(fileForUpload);
865
+ if (!additionalDays) {
866
+ additionalDays = 0;
867
+ }
868
+ else {
869
+ additionalDays = additionalDays * 90;
870
+ }
871
+ const future = addDays(today, additionalDays + dateOffset);
872
+ let dayt = (formatMMDDYYYY(future));
873
+ await pasteText(dayt);
874
+ if (PER_DAY) {
875
+ dateOffset += i % PER_DAY === 0 ? 1 : 0;
876
+ }
877
+ else {
878
+ dateOffset++;
879
+ }
880
+ }
881
+ {
882
+ await pause(() => { console_log_it('wait 10s', '[YOUTUBE] '); }, SPEED); // 1 second delay for safety
883
+ await workflowOp(async () => {
884
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.scheduleNavButton], ' [YOUTUBE] currentelement');
885
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.scheduleNavButton];
886
+ }, async () => {
887
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.scheduleNavButton]);
888
+ }, async () => {
889
+ console_log_it("Performing left click...", '[YOUTUBE] state');
890
+ await mouseClick(); // Performs a left-click.
891
+ }, async () => {
892
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.closeButton], '[YOUTUBE] currentelement');
893
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.closeButton];
894
+ }, 10, SPEED * 2, '[YOUTUBE] workflowOp');
895
+ }
896
+ {
897
+ await pause(() => { console_log_it('wait 10s'); }, SPEED); // 1 second delay for safety
898
+ await waitFor(async () => {
899
+ console_log_it(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.closeButton], '[YOUTUBE] currentelement');
900
+ return getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.closeButton];
901
+ });
902
+ await moveMouse(getContext().position?.[MODES.YOUTUBE]?.[YOUTUBE_SELECTORS.closeButton]);
903
+ await pause(async () => {
904
+ console_log_it("Performing left click...");
905
+ await mouseClick(); // Performs a left-click.
906
+ }, 1000); // 1 second delay for safety
907
+ }
908
+ count += 1;
909
+ if (count % 3 === 0 && count > 0) {
910
+ console_log_it(`Waiting for ${(SPEED / 1000) * 12} seconds before next upload...`, '[YOUTUBE] state');
911
+ await pause(() => { }, SPEED * 6); // Wait before next upload
912
+ refreshScreen(robot);
913
+ await pause(() => { }, SPEED * 6); // Wait before next upload
914
+ }
915
+ }
916
+ }
917
+ currentSources[i].uploaded = true;
918
+ saveProjectFile(currentSourceFilePath, overAllCurrentSources);
919
+ 1;
920
+ }
921
+ success = true;
922
+ }
923
+ catch (e) {
924
+ // write out callstack
925
+ console_log_it(e.message, '[YOUTUBE] error');
926
+ console_log_it(e.stack, '[YOUTUBE] errorstatement');
927
+ console_log_it(`[YOUTUBE] error: ${JSON.stringify(e)}`, 'error');
928
+ console_log_it(e, '[YOUTUBE] error_');
929
+ attempts--;
930
+ success = false;
931
+ await pause(() => { }, SPEED * 6); // Wait before next upload
932
+ refreshScreen(robot);
933
+ await pause(() => { }, SPEED * 6); // Wait before next upload
934
+ }
935
+ }
936
+ console_log_it('[DONE] operate youtube', '[YOUTUBE] func');
937
+ console_log_it(`[DONE] Operating Youtube with mode: ${get(KEYS.mode)}`, '[YOUTUBE] running-mode');
938
+ }
939
+ export async function fileModalOperate(filePath) {
940
+ if (process.platform !== 'win32') {
941
+ await pause(() => { goToFolderShortcut(); }, 3000);
942
+ }
943
+ await pause(() => { console_log_it('wait 10s'); }, 5000); // 1 second delay for safety
944
+ await pasteText(filePath);
945
+ await pause(() => { pressReturn(); }, 5000); // 1 second delay for safety
946
+ if (process.platform !== 'win32') {
947
+ await pause(() => { pressReturn(); }, 5000);
948
+ }
949
+ }
950
+ /**
951
+ * Formats a Date object as MM/DD/YYYY.
952
+ * @param {Date} date
953
+ * @returns {string}
954
+ */
955
+ function formatMMDDYYYY(date) {
956
+ const mm = String(date.getMonth() + 1).padStart(2, '0');
957
+ const dd = String(date.getDate()).padStart(2, '0');
958
+ const yyyy = date.getFullYear();
959
+ return `${mm}/${dd}/${yyyy}`;
960
+ }
961
+ /**
962
+ * Adds `days` to the given Date and returns a new Date.
963
+ * @param {Date} date
964
+ * @param {number} days
965
+ * @returns {Date}
966
+ */
967
+ function addDays(date, days) {
968
+ const result = new Date(date);
969
+ result.setDate(result.getDate() + days);
970
+ return result;
971
+ }
972
+ /**
973
+ * Immediately scrolls the mouse wheel.
974
+ *
975
+ * @param {number} x — horizontal scroll amount (positive → right, negative → left)
976
+ * @param {number} y — vertical scroll amount (positive → down, negative → up)
977
+ */
978
+ export function scroll(x = 0, y = 0) {
979
+ robot.scrollMouse(x, y);
980
+ }
981
+ /**
982
+ * Sends the macOS “Go to Folder” shortcut (⌘+⇧+G) to the frontmost window.
983
+ */
984
+ function goToFolderShortcut() {
985
+ // Optional: slow down the key events if your system is too fast
986
+ robot.setKeyboardDelay(100);
987
+ // Tap “g” with Command and Shift held
988
+ robot.keyTap('g', ['command', 'shift']);
989
+ }
990
+ function getSunoPosition(key) {
991
+ return getContext().position?.[MODES.SUNO_FILM]?.[key] || {};
992
+ }
993
+ export async function operateSunoFilmMouse() {
994
+ const SPEED = parseInt(get(KEYS.speed) || '5000') || 5000;
995
+ let output_path = path.join(get(KEYS.current_folder), getItem('sourceFile'));
996
+ let suno_film_audio_tracks_per = parseInt(get(KEYS.suno_film_audio_tracks_per) || '2') || 2;
997
+ console_log_it(`Starting at ${new Date(Date.now()).toISOString()} ---`, 'suno film');
998
+ let projects = readProjectFile(output_path);
999
+ try {
1000
+ for (let i = 0; i < projects.length; i++) {
1001
+ console_log_it(buildProgressBar(i + 1, projects.length, 20), 'suno-film-progress-bar');
1002
+ let project = projects[i];
1003
+ console_log_it(`Starting project ${project?.name}`, 'Suno Film [state]');
1004
+ project.song_sources = project?.song_sources || [];
1005
+ if (project.song_sources.length < suno_film_audio_tracks_per) {
1006
+ let style = project?.style || 'spoken word, slow';
1007
+ if (get(KEYS.ignoreStyle) === 'yes') {
1008
+ style = 'spoken word, slow';
1009
+ }
1010
+ const lyric = project?.lines?.join('\n');
1011
+ if (!lyric) {
1012
+ console_log_it(`has no lyrics`, project.name);
1013
+ continue;
1014
+ }
1015
+ console_log_it(`Has lyrics ${lyric.length}`, 'Suno Film [state]');
1016
+ const name = project.name;
1017
+ suno_film_audio_tracks_per = parseInt(get(KEYS.suno_film_audio_tracks_per) || '2') || 2;
1018
+ const count = suno_film_audio_tracks_per;
1019
+ set(KEYS.current_song_name, name);
1020
+ getContext().list_selectors = Object.values({
1021
+ [getSunoCompletedSongs(name)]: getSunoCompletedSongs(name),
1022
+ [getSunoRequestedSongs(name)]: getSunoRequestedSongs(name)
1023
+ });
1024
+ let all_project_songs_ready = false;
1025
+ console_log_it(`Loading suno state`, 'Suno Film [state]');
1026
+ let suno_state = get(KEYS.suno_state) || {};
1027
+ console_log_it(`${Object.keys(suno_state)?.length}`, 'incomingSongs');
1028
+ let project_song_states = Object.values(suno_state).filter(x => x.name === project.name);
1029
+ let song_states = project_song_states.filter(x => x.name === project.name && x.ready && x.url && x.lyric);
1030
+ let skipsong = false;
1031
+ let skip = false;
1032
+ do {
1033
+ skipsong = false;
1034
+ suno_state = get(KEYS.suno_state) || {};
1035
+ all_project_songs_ready = false;
1036
+ ({
1037
+ suno_state,
1038
+ project_song_states,
1039
+ all_project_songs_ready,
1040
+ song_states,
1041
+ skip
1042
+ } = processSunoState(suno_state, project_song_states, project, all_project_songs_ready, song_states));
1043
+ if (skip) {
1044
+ skipsong = true;
1045
+ }
1046
+ // Move to title
1047
+ if ((project.song_sources?.length || 0) < count && !skipsong) {
1048
+ {
1049
+ const { left, top, height, width } = getSunoPosition(SUNO_SELECTORS.styles);
1050
+ if (left && top) {
1051
+ const targetX = left + chrome_offsets.x + (width / 2);
1052
+ const targetY = top + chrome_offsets.y + (height / 4);
1053
+ robot.moveMouseSmooth(targetX, targetY);
1054
+ scroll(0, -1000); // Scroll down to make sure the styles are visible
1055
+ await pause(() => { }, SPEED * 2); // Wait for the scroll to complete
1056
+ }
1057
+ }
1058
+ {
1059
+ const { left, top, height, width } = getSunoPosition(SUNO_SELECTORS.styles_tags);
1060
+ if (left && top) {
1061
+ const targetX = left + chrome_offsets.x + (width / 2);
1062
+ const targetY = top + chrome_offsets.y + (height / 4);
1063
+ robot.moveMouseSmooth(targetX, targetY);
1064
+ scroll(0, -1000); // Scroll down to make sure the styles are visible
1065
+ await pause(() => { }, SPEED * 2); // Wait for the scroll to complete
1066
+ }
1067
+ }
1068
+ {
1069
+ const { left, top, height, width } = getSunoPosition(SUNO_SELECTORS.title);
1070
+ // Define the target coordinates (x, y)
1071
+ const targetX = left + chrome_offsets.x + (width / 2);
1072
+ const targetY = top + chrome_offsets.y + (height / 4);
1073
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`);
1074
+ // Move the mouse smoothly to the target coordinates
1075
+ console_log_it(`name`, 'Suno Film [state]');
1076
+ robot.moveMouseSmooth(targetX, targetY);
1077
+ await pause(() => {
1078
+ console_log_it("Performing left click...");
1079
+ robot.mouseClick(); // Performs a left-click.
1080
+ robot.mouseClick(); // Performs a left-click.
1081
+ }, 1000); // 1 second delay for safety
1082
+ clearAllText();
1083
+ await pasteText(name);
1084
+ }
1085
+ {
1086
+ const { left, top, height, width } = getSunoPosition(SUNO_SELECTORS.styles);
1087
+ if (left && top) {
1088
+ const targetX = left + chrome_offsets.x + (width / 2);
1089
+ const targetY = top + chrome_offsets.y + (height / 4);
1090
+ robot.moveMouseSmooth(targetX, targetY);
1091
+ scroll(0, 1000); // Scroll down to make sure the styles are visible
1092
+ await pause(() => { }, SPEED * 2); // Wait for the scroll to complete
1093
+ }
1094
+ }
1095
+ {
1096
+ const { left, top, height, width } = getSunoPosition(SUNO_SELECTORS.styles_tags);
1097
+ if (left, top) {
1098
+ const targetX = left + chrome_offsets.x + (width / 2);
1099
+ const targetY = top + chrome_offsets.y + (height / 4);
1100
+ robot.moveMouseSmooth(targetX, targetY);
1101
+ scroll(0, 1000); // Scroll down to make sure the styles are visible
1102
+ await pause(() => { }, SPEED * 2); // Wait for the scroll to complete
1103
+ }
1104
+ }
1105
+ // Move to lyrics
1106
+ {
1107
+ const { left, top, height, width } = getSunoPosition(SUNO_SELECTORS.lyrics);
1108
+ // Define the target coordinates (x, y)
1109
+ const targetX = left + chrome_offsets.x + (width / 2);
1110
+ const targetY = top + chrome_offsets.y + (height / 4);
1111
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`);
1112
+ console_log_it(`lyrics`, 'Suno Film [state]');
1113
+ // Move the mouse smoothly to the target coordinates
1114
+ robot.moveMouseSmooth(targetX, targetY);
1115
+ await pause(() => {
1116
+ console_log_it("Performing left click...");
1117
+ robot.mouseClick(); // Performs a left-click.
1118
+ }, 1000); // 1 second delay for safety
1119
+ clearAllText();
1120
+ if (lyric) {
1121
+ await pasteText(lyric);
1122
+ }
1123
+ }
1124
+ {
1125
+ const { left, top, height, width } = getSunoPosition(SUNO_SELECTORS.styles);
1126
+ const targetX = left + chrome_offsets.x + (width / 2);
1127
+ const targetY = top + chrome_offsets.y + (height / 4);
1128
+ robot.moveMouseSmooth(targetX, targetY);
1129
+ scroll(0, 1000); // Scroll down to make sure the styles are visible
1130
+ await pause(() => { }, SPEED * 2); // Wait for the scroll to complete
1131
+ }
1132
+ {
1133
+ const { left, top, height, width } = getSunoPosition(SUNO_SELECTORS.styles_tags);
1134
+ if (left, top) {
1135
+ const targetX = left + chrome_offsets.x + (width / 2);
1136
+ const targetY = top + chrome_offsets.y + (height / 4);
1137
+ robot.moveMouseSmooth(targetX, targetY);
1138
+ scroll(0, 1000); // Scroll down to make sure the styles are visible
1139
+ await pause(() => { }, SPEED * 2); // Wait for the scroll to complete
1140
+ }
1141
+ }
1142
+ // Move to styles
1143
+ {
1144
+ const { left, top, height, width } = getSunoPosition(SUNO_SELECTORS.styles);
1145
+ if (left && top) {
1146
+ const targetX = left + chrome_offsets.x + (width / 2);
1147
+ const targetY = top + chrome_offsets.y + (height / 4);
1148
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`);
1149
+ console_log_it(`styles`, 'Suno Film [state]');
1150
+ // Move the mouse smoothly to the target coordinates
1151
+ robot.moveMouseSmooth(targetX, targetY);
1152
+ await pause(() => {
1153
+ console_log_it("Performing left click...");
1154
+ robot.mouseClick(); // Performs a left-click.
1155
+ }, 1000); // 1 second delay for safety
1156
+ clearAllText();
1157
+ await pasteText(style);
1158
+ }
1159
+ }
1160
+ {
1161
+ const { left, top, height, width } = getSunoPosition(SUNO_SELECTORS.styles_tags);
1162
+ if (left && top) {
1163
+ const targetX = left + chrome_offsets.x + (width / 2);
1164
+ const targetY = top + chrome_offsets.y + (height / 4);
1165
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`);
1166
+ console_log_it(`styles`, 'Suno Film [state]');
1167
+ // Move the mouse smoothly to the target coordinates
1168
+ robot.moveMouseSmooth(targetX, targetY);
1169
+ await pause(() => {
1170
+ console_log_it("Performing left click...");
1171
+ robot.mouseClick(); // Performs a left-click.
1172
+ }, 1000); // 1 second delay for safety
1173
+ clearAllText();
1174
+ await pasteText(style);
1175
+ }
1176
+ }
1177
+ // Move to button
1178
+ {
1179
+ const { left, top, height, width } = getSunoPosition(SUNO_SELECTORS.createbtn);
1180
+ // Define the target coordinates (x, y)
1181
+ const targetX = left + chrome_offsets.x + (width / 2);
1182
+ const targetY = top + chrome_offsets.y + (height / 4);
1183
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`);
1184
+ // Move the mouse smoothly to the target coordinates
1185
+ let clickcount = Math.max(0, (count - song_states.length) / 2);
1186
+ console_log_it(`create button`, 'Suno Film [state]');
1187
+ for (let k = 0; k < clickcount; k++) {
1188
+ robot.moveMouseSmooth(targetX, targetY);
1189
+ await pause(() => {
1190
+ console_log_it("Performing left click...");
1191
+ robot.mouseClick(); // Performs a left-click.
1192
+ }, 10000); // 1 second delay for safety
1193
+ }
1194
+ }
1195
+ }
1196
+ {
1197
+ await pause(() => {
1198
+ console_log_it("Wait to download songs...");
1199
+ }, 10 * 1000); // 1 second delay for safety
1200
+ }
1201
+ project.lyrics = song_states.map(v => v.lyric);
1202
+ project.song_sources = song_states.map(v => v.url);
1203
+ console_log_it(`${Object.keys(suno_state)?.length}`, 'incomingSongs');
1204
+ let clickcount = Math.max(0, (count - song_states.length) / 2);
1205
+ let maxwaits = 100;
1206
+ all_project_songs_ready = !clickcount;
1207
+ while (!all_project_songs_ready && maxwaits && !skipsong) {
1208
+ await pause(() => { }, 10 * 1000);
1209
+ maxwaits--;
1210
+ console_log_it(maxwaits, 'maxwaits');
1211
+ console_log_it(`waiting ${maxwaits}, all_project_songs_ready ${all_project_songs_ready}`, 'Suno Film [state]');
1212
+ ({ suno_state, project_song_states, all_project_songs_ready, song_states, skip } = processSunoState(suno_state, project_song_states, project, all_project_songs_ready, song_states));
1213
+ skipsong = skip;
1214
+ console_log_it(`get(KEYS.current_song_name) == name: ${get(KEYS.current_song_name) == name}, !all_project_songs_ready ${!all_project_songs_ready} || song_states.length < count ${song_states.length < count}, ${song_states.length} ${count}`, 'Suno Film [state]');
1215
+ }
1216
+ saveProjectFile(output_path, projects);
1217
+ } while (get(KEYS.current_song_name) == name && (!all_project_songs_ready || song_states.length < count) && !skipsong);
1218
+ }
1219
+ else {
1220
+ let all_project_songs_ready = false;
1221
+ let suno_state = get(KEYS.suno_state) || {};
1222
+ let project_song_states = Object.values(suno_state).filter(x => x.name === project.name);
1223
+ let song_states = project_song_states.filter(x => x.name === project.name && x.ready && x.url && x.lyric);
1224
+ let skip = false;
1225
+ all_project_songs_ready = false;
1226
+ ({
1227
+ suno_state,
1228
+ project_song_states,
1229
+ all_project_songs_ready,
1230
+ song_states,
1231
+ skip
1232
+ } = processSunoState(suno_state, project_song_states, project, all_project_songs_ready, song_states));
1233
+ console_log_it(`skip: ${skip}`, 'Suno Film [state]');
1234
+ console_log_it(`there are enough songs ${project.title || project.name} ${project?.song_sources?.length}< ${project?.song_sources?.length}`, 'song count');
1235
+ }
1236
+ }
1237
+ console_log_it(`Finished all`, 'Suno Film [state]');
1238
+ }
1239
+ catch (e) {
1240
+ console_log_it(`Error in operateSunoFilmMouse: ${e.message}`, 'suno film error message');
1241
+ console_log_it(`Stack: ${e.stack}`, 'suno film error stack');
1242
+ console_log_it('something went wrong with ', 'suno film error');
1243
+ console_log_it(e, 'suno film error _');
1244
+ }
1245
+ saveProjectFile(output_path, projects);
1246
+ console_log_it(`Done at ${new Date(Date.now()).toISOString()} ---`, 'suno film');
1247
+ }
1248
+ export async function operateSunoMouse(body) {
1249
+ let song_ideas = readProjectFile(get(KEYS.sunofileName));
1250
+ for (let i = 0; i < song_ideas.length; i++) {
1251
+ const { style, lyric, name, count = 10 } = song_ideas[i];
1252
+ set(KEYS.current_song_name, name);
1253
+ getContext().list_selectors = Object.values({
1254
+ [getSunoCompletedSongs(name)]: getSunoCompletedSongs(name),
1255
+ [getSunoRequestedSongs(name)]: getSunoRequestedSongs(name)
1256
+ });
1257
+ let dir = path.join(get(KEYS.current_folder), 'audio', fix(name));
1258
+ let files = await getFiles(dir);
1259
+ setItem(KEYS.suno_current_name, name);
1260
+ let requestedSongs = getContext().all_positions?.[getSunoRequestedSongs(name)]?.length || 0;
1261
+ let existingSongs = getContext().all_positions?.[getSunoCompletedSongs(name)]?.length || 0;
1262
+ console_log_it(`requestedSongs: ${requestedSongs}`);
1263
+ console_log_it(`existingSongs: ${existingSongs}`);
1264
+ let downloadFailed = false;
1265
+ let targetfolder = path.join(get(KEYS.sunoDownloadFolder), fix(name));
1266
+ let fileCount = fs.existsSync(targetfolder) ? fs.readdirSync(targetfolder).length : 0;
1267
+ if (fileCount < count) {
1268
+ do {
1269
+ downloadFailed = false;
1270
+ // Move to title
1271
+ if (requestedSongs < count) {
1272
+ {
1273
+ const { left, top, height, width } = body[SUNO_SELECTORS.title];
1274
+ // Define the target coordinates (x, y)
1275
+ const targetX = left + chrome_offsets.x + (width / 2);
1276
+ const targetY = top + chrome_offsets.y + (height / 4);
1277
+ console_log_it(`title`, 'operateSunoMouse[state]');
1278
+ // Move the mouse smoothly to the target coordinates
1279
+ robot.moveMouseSmooth(targetX, targetY);
1280
+ await pause(() => {
1281
+ console_log_it("Performing left click...");
1282
+ robot.mouseClick(); // Performs a left-click.
1283
+ robot.mouseClick(); // Performs a left-click.
1284
+ }, 1000); // 1 second delay for safety
1285
+ clearAllText();
1286
+ await pasteText(name);
1287
+ }
1288
+ // Move to lyrics
1289
+ {
1290
+ const { left, top, height, width } = body[SUNO_SELECTORS.lyrics];
1291
+ // Define the target coordinates (x, y)
1292
+ const targetX = left + chrome_offsets.x + (width / 2);
1293
+ const targetY = top + chrome_offsets.y + (height / 4);
1294
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`);
1295
+ console_log_it(`lyrics`, 'operateSunoMouse[state]');
1296
+ // Move the mouse smoothly to the target coordinates
1297
+ robot.moveMouseSmooth(targetX, targetY);
1298
+ await pause(() => {
1299
+ console_log_it("Performing left click...");
1300
+ robot.mouseClick(); // Performs a left-click.
1301
+ }, 1000); // 1 second delay for safety
1302
+ clearAllText();
1303
+ if (lyric) {
1304
+ await pasteText(lyric);
1305
+ }
1306
+ }
1307
+ // Move to styles
1308
+ {
1309
+ const { left, top, height, width } = body[SUNO_SELECTORS.styles];
1310
+ // Define the target coordinates (x, y)
1311
+ const targetX = left + chrome_offsets.x + (width / 2);
1312
+ const targetY = top + chrome_offsets.y + (height / 4);
1313
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`);
1314
+ console_log_it(`styles`, 'operateSunoMouse[state]');
1315
+ // Move the mouse smoothly to the target coordinates
1316
+ robot.moveMouseSmooth(targetX, targetY);
1317
+ await pause(() => {
1318
+ console_log_it("Performing left click...");
1319
+ robot.mouseClick(); // Performs a left-click.
1320
+ }, 1000); // 1 second delay for safety
1321
+ clearAllText();
1322
+ await pasteText(style);
1323
+ }
1324
+ // Move to button
1325
+ {
1326
+ const { left, top, height, width } = body[SUNO_SELECTORS.createbtn];
1327
+ // Define the target coordinates (x, y)
1328
+ const targetX = left + chrome_offsets.x + (width / 2);
1329
+ const targetY = top + chrome_offsets.y + (height / 4);
1330
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`);
1331
+ // Move the mouse smoothly to the target coordinates
1332
+ robot.moveMouseSmooth(targetX, targetY);
1333
+ console_log_it(`create button`, 'operateSunoMouse[state]');
1334
+ await pause(() => {
1335
+ console_log_it("Performing left click...");
1336
+ robot.mouseClick(); // Performs a left-click.
1337
+ }, 1000); // 1 second delay for safety
1338
+ }
1339
+ }
1340
+ {
1341
+ await pause(() => {
1342
+ console_log_it("Wait to download songs...");
1343
+ }, 10 * 1000); // 1 second delay for safety
1344
+ }
1345
+ requestedSongs = getContext().all_positions?.[getSunoRequestedSongs(name)]?.length || 0;
1346
+ existingSongs = getContext().all_positions?.[getSunoCompletedSongs(name)]?.length || 0;
1347
+ console_log_it(`requestedSongs: ${requestedSongs}`);
1348
+ console_log_it(`existingSongs: ${existingSongs}`);
1349
+ let song_list = get(KEYS.song_list);
1350
+ if (song_list) {
1351
+ let urls = song_list;
1352
+ for (let i = 0; i < urls.length; i++) {
1353
+ try {
1354
+ await downloadWithPython(urls[i], get(KEYS.sunoDownloadFolder), fix(name));
1355
+ console_log_it('All done!');
1356
+ }
1357
+ catch (err) {
1358
+ downloadFailed = true;
1359
+ console.error('Download script failed:', err);
1360
+ }
1361
+ }
1362
+ }
1363
+ } while ((!files?.length && count > existingSongs) || downloadFailed);
1364
+ }
1365
+ }
1366
+ }
1367
+ /**
1368
+ * Selects all text in the current focused field and deletes it.
1369
+ */
1370
+ function clearAllText() {
1371
+ // On macOS use 'command', otherwise 'control'
1372
+ const modifier = process.platform === 'darwin' ? 'command' : 'control';
1373
+ // Give a tiny pause to ensure focus is correct (optional)
1374
+ robot.setKeyboardDelay(50);
1375
+ // Select all
1376
+ robot.keyTap('a', modifier);
1377
+ // Delete selected text
1378
+ // On some apps you may prefer 'backspace' instead of 'delete'
1379
+ robot.keyTap('delete');
1380
+ }
1381
+ export function isNoCharacterMode() {
1382
+ return get(KEYS.project_character) === '--no character--';
1383
+ }
1384
+ export function ignoreCharacters() {
1385
+ return get(KEYS.ignoreCharacters) === 'yes';
1386
+ }
1387
+ export async function operateMouse(position, signal, progress) {
1388
+ try {
1389
+ console_log_it(`Midjourney Progress: START`, 'midjourney-progress');
1390
+ const { left, top, height, width } = position;
1391
+ const root_folder = get(KEYS.current_folder);
1392
+ const name = getItem('sourceFile');
1393
+ let skipping = 0;
1394
+ let filesToProcess = [name];
1395
+ filesToProcess = getFilesToProcess(name, filesToProcess, root_folder);
1396
+ let e1 = [];
1397
+ filesToProcess.filter(x => x.endsWith('.json')).forEach((fileP) => {
1398
+ console_log_it(fileP, 'file to operate');
1399
+ let projects = readProjectFile(path.join(root_folder, fileP));
1400
+ let sub_lyric_projects = projects.map(t => {
1401
+ return t.lyrics || [];
1402
+ }).flat();
1403
+ if (sub_lyric_projects?.length) {
1404
+ e1 = [...e1, ...sub_lyric_projects];
1405
+ }
1406
+ else if (projects?.length) {
1407
+ e1 = [...e1, ...projects];
1408
+ }
1409
+ });
1410
+ // {
1411
+ // height: 23.99147605895996,
1412
+ // left: 419.8692932128906,
1413
+ // top: 379.8948860168457,
1414
+ // width: 1170.241455078125
1415
+ // }
1416
+ // Define the target coordinates (x, y)
1417
+ const targetX = left + chrome_offsets.x + (width / 2);
1418
+ const targetY = top + chrome_offsets.y + (height / 4);
1419
+ console_log_it(`Moving mouse to (${targetX}, ${targetY})...`);
1420
+ // Move the mouse smoothly to the target coordinates
1421
+ robot.moveMouseSmooth(targetX, targetY);
1422
+ // Wait briefly before clicking to ensure the mouse has reached the target.
1423
+ await pause(() => {
1424
+ console_log_it("Performing left click...");
1425
+ robot.mouseClick(); // Performs a left-click.
1426
+ }, 1000); // 1 second delay for safety
1427
+ for (let i = 0; i < e1.length; i++) {
1428
+ const SPEED = parseInt(get(KEYS.speed) || 5000) || 5000;
1429
+ let section = e1[i];
1430
+ const { portrait_prompt, prompts, characters } = section;
1431
+ console_log_it(`Midjourney Progress: ${buildProgressBar(i + 1, e1.length, 20)}`, 'midjourney-progress');
1432
+ if (portrait_prompt) {
1433
+ if (!get(KEYS.project_character) || isNoCharacterMode() || ignoreCharacters()) {
1434
+ let waitedAmount = 0;
1435
+ waitedAmount = await waitForQueuedRenders(waitedAmount, SPEED);
1436
+ let existing_images = findExistingImage(portrait_prompt, get(KEYS.ratio));
1437
+ if (!existing_images?.length) {
1438
+ await pasteText(portrait_prompt);
1439
+ await pause(() => { }, WAIT_FACTOR * 13000);
1440
+ robot.keyTap('enter');
1441
+ await pause(() => { }, WAIT_FACTOR * 15000);
1442
+ }
1443
+ else {
1444
+ console_log_it(`skipping: ${portrait_prompt}`);
1445
+ }
1446
+ }
1447
+ }
1448
+ for (let j = 0; j < prompts.length; j++) {
1449
+ console_log_it(`Midjourney Progress: ${buildProgressBar(j + 1, prompts.length, 20)}`, 'midjourney-progress|prompts');
1450
+ let prompt = prompts[j];
1451
+ console_log_it(`${characters?.[i]}`, 'character');
1452
+ console_log_it(`${get(KEYS.project_character)}`, 'project_character');
1453
+ if (!ignoreCharacters())
1454
+ if (get(KEYS.project_character)) {
1455
+ if ((isNoCharacterMode() && !characters?.[i]?.trim())) {
1456
+ console_log_it('not skipping', 'skipping');
1457
+ }
1458
+ else if (characters?.[i] !== get(KEYS.project_character)) {
1459
+ console_log_it(`skipping ${skipping}`, 'skipping');
1460
+ skipping++;
1461
+ continue;
1462
+ }
1463
+ }
1464
+ else {
1465
+ console_log_it('not skipping', 'skipping');
1466
+ }
1467
+ let waitedAmount = 0;
1468
+ waitedAmount = await waitForQueuedRenders(waitedAmount, SPEED);
1469
+ console_log_it(`${characters?.[i]} === ${get(KEYS.project_character)}`, 'check match');
1470
+ console_log_it('didnt skip', 'skipping');
1471
+ if (!findExistingImage(prompt, get(KEYS.ratio)).length) {
1472
+ if (typeof prompt === 'string') {
1473
+ await pasteText(prompt);
1474
+ await pause(() => { }, WAIT_FACTOR * 12000);
1475
+ robot.keyTap('enter');
1476
+ await pause(() => { }, WAIT_FACTOR * 15000);
1477
+ }
1478
+ else {
1479
+ console_log_it(prompt);
1480
+ }
1481
+ }
1482
+ else {
1483
+ console_log_it(`skipping: ${prompt}`);
1484
+ }
1485
+ }
1486
+ console_log_it(`Midjourney prompts:DONE`, 'midjourney-progress|prompts');
1487
+ }
1488
+ }
1489
+ catch (e) {
1490
+ console_log_it(`Error in operateMouse: ${JSON.stringify(e)}`, 'error');
1491
+ console_log_it(e, 'error_');
1492
+ }
1493
+ console_log_it(`Midjourney Progress: DONE`, 'midjourney-progress');
1494
+ }
1495
+ function findExistingImage(prompt, ratio) {
1496
+ let job_file = fs.readFileSync(get_jobs_path(), 'utf-8').split('\n').map(v => JSON.parse(v))
1497
+ .filter(job => getDetectOrientation(job) === ratio).filter(f => `${f.full_command}`.includes(prompt));
1498
+ let jobs = job_file.filter(f => `${f.full_command}`.includes(prompt));
1499
+ let imageFiles = jobs.map((job) => {
1500
+ return findFilesWithString(get(KEYS.images_folder), job.id);
1501
+ }).flat();
1502
+ return imageFiles.filter(fileName => {
1503
+ return true;
1504
+ });
1505
+ }
1506
+ export function getSunoCompletedSongs(name) {
1507
+ console_log_it(`suno_current_name: ${name}`);
1508
+ return `[aria-label="${name}"]@@@button||Edit`;
1509
+ }
1510
+ export function getSunoRequestedSongs(name) {
1511
+ console_log_it(`suno_current_name: ${name}`);
1512
+ return `[aria-label="${name}"]`;
1513
+ }
1514
+ //# sourceMappingURL=operations.js.map