specific-ai-cli 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +177 -0
  3. package/README.ja.md +177 -0
  4. package/README.ko.md +177 -0
  5. package/README.md +174 -2
  6. package/README.zh-TW.md +177 -0
  7. package/assets/banner.txt +3 -0
  8. package/dist/cli/argv.js +98 -0
  9. package/dist/cli/commands/auth.js +11 -0
  10. package/dist/cli/commands/config.js +23 -0
  11. package/dist/cli/commands/doctor.js +134 -0
  12. package/dist/cli/commands/platforms.js +24 -0
  13. package/dist/cli/commands/version.js +4 -0
  14. package/dist/cli/confirm.js +22 -0
  15. package/dist/cli/dispatch.js +440 -0
  16. package/dist/cli/help.js +223 -0
  17. package/dist/cli/hints.js +60 -0
  18. package/dist/cli/main.js +18 -0
  19. package/dist/cli/output.js +66 -0
  20. package/dist/core/auth-handlers.js +41 -0
  21. package/dist/core/auth-store.js +119 -0
  22. package/dist/core/capabilities.js +163 -0
  23. package/dist/core/config.js +121 -0
  24. package/dist/core/cookies.js +164 -0
  25. package/dist/core/errors.js +37 -0
  26. package/dist/core/files.js +89 -0
  27. package/dist/core/fsutil.js +52 -0
  28. package/dist/core/hash.js +4 -0
  29. package/dist/core/http.js +331 -0
  30. package/dist/core/image.js +280 -0
  31. package/dist/core/log.js +40 -0
  32. package/dist/core/login.js +191 -0
  33. package/dist/core/mp4.js +130 -0
  34. package/dist/core/normalize.js +207 -0
  35. package/dist/core/options.js +110 -0
  36. package/dist/core/paths.js +38 -0
  37. package/dist/core/pb.js +59 -0
  38. package/dist/core/py.js +181 -0
  39. package/dist/core/rand.js +131 -0
  40. package/dist/core/registry.js +129 -0
  41. package/dist/core/schemas.js +41 -0
  42. package/dist/core/stream.js +104 -0
  43. package/dist/core/toolkit.js +35 -0
  44. package/dist/core/vm.js +73 -0
  45. package/dist/core/vocab.js +157 -0
  46. package/dist/platforms/_shared/impaas.js +410 -0
  47. package/dist/platforms/bilibili/index.js +216 -0
  48. package/dist/platforms/bilibili/web/api.js +806 -0
  49. package/dist/platforms/bilibili/web/client.js +311 -0
  50. package/dist/platforms/bilibili/web/commands.js +783 -0
  51. package/dist/platforms/bilibili/web/ddddocr.js +342 -0
  52. package/dist/platforms/bilibili/web/gaia.js +130 -0
  53. package/dist/platforms/bilibili/web/geetest-manual.js +154 -0
  54. package/dist/platforms/bilibili/web/geetest-vision.js +232 -0
  55. package/dist/platforms/bilibili/web/geetest.js +450 -0
  56. package/dist/platforms/bilibili/web/normalize.js +234 -0
  57. package/dist/platforms/bilibili/web/profile.js +135 -0
  58. package/dist/platforms/bilibili/web/resolve.js +112 -0
  59. package/dist/platforms/bilibili/web/sign.js +223 -0
  60. package/dist/platforms/bilibili/web/upos.js +102 -0
  61. package/dist/platforms/douyin/index.js +142 -0
  62. package/dist/platforms/douyin/web/api.js +863 -0
  63. package/dist/platforms/douyin/web/client.js +413 -0
  64. package/dist/platforms/douyin/web/commands.js +712 -0
  65. package/dist/platforms/douyin/web/creator.js +601 -0
  66. package/dist/platforms/douyin/web/crypto.js +247 -0
  67. package/dist/platforms/douyin/web/dtrait.js +190 -0
  68. package/dist/platforms/douyin/web/im.js +502 -0
  69. package/dist/platforms/douyin/web/image.js +5 -0
  70. package/dist/platforms/douyin/web/live.js +225 -0
  71. package/dist/platforms/douyin/web/mssdk.js +148 -0
  72. package/dist/platforms/douyin/web/normalize.js +326 -0
  73. package/dist/platforms/douyin/web/passport.js +1247 -0
  74. package/dist/platforms/douyin/web/profile.js +221 -0
  75. package/dist/platforms/douyin/web/proto.js +26 -0
  76. package/dist/platforms/douyin/web/resolve.js +88 -0
  77. package/dist/platforms/douyin/web/sign.js +436 -0
  78. package/dist/platforms/douyin/web/tos.js +78 -0
  79. package/dist/platforms/index.js +17 -0
  80. package/dist/platforms/jd/index.js +67 -0
  81. package/dist/platforms/jd/web/aks.js +115 -0
  82. package/dist/platforms/jd/web/api.js +549 -0
  83. package/dist/platforms/jd/web/chat.js +132 -0
  84. package/dist/platforms/jd/web/client.js +470 -0
  85. package/dist/platforms/jd/web/commands.js +557 -0
  86. package/dist/platforms/jd/web/jcap/helper.js +90 -0
  87. package/dist/platforms/jd/web/jcap/host.js +107 -0
  88. package/dist/platforms/jd/web/jcap/lsd.js +300 -0
  89. package/dist/platforms/jd/web/jcap/solver.js +995 -0
  90. package/dist/platforms/jd/web/jcap.js +150 -0
  91. package/dist/platforms/jd/web/js.js +420 -0
  92. package/dist/platforms/jd/web/login.js +775 -0
  93. package/dist/platforms/jd/web/normalize.js +297 -0
  94. package/dist/platforms/jd/web/profile.js +256 -0
  95. package/dist/platforms/jd/web/util.js +175 -0
  96. package/dist/platforms/jd/web/webm.js +133 -0
  97. package/dist/platforms/kuaishou/index.js +98 -0
  98. package/dist/platforms/kuaishou/web/api.js +694 -0
  99. package/dist/platforms/kuaishou/web/captcha-crypto.js +134 -0
  100. package/dist/platforms/kuaishou/web/captcha-fp.js +180 -0
  101. package/dist/platforms/kuaishou/web/captcha.js +273 -0
  102. package/dist/platforms/kuaishou/web/client.js +487 -0
  103. package/dist/platforms/kuaishou/web/commands.js +863 -0
  104. package/dist/platforms/kuaishou/web/gap.js +144 -0
  105. package/dist/platforms/kuaishou/web/gdfp.js +376 -0
  106. package/dist/platforms/kuaishou/web/gql.js +11 -0
  107. package/dist/platforms/kuaishou/web/live.js +125 -0
  108. package/dist/platforms/kuaishou/web/normalize.js +241 -0
  109. package/dist/platforms/kuaishou/web/oracle.js +329 -0
  110. package/dist/platforms/kuaishou/web/profile.js +259 -0
  111. package/dist/platforms/kuaishou/web/resolve.js +84 -0
  112. package/dist/platforms/kuaishou/web/session.js +592 -0
  113. package/dist/platforms/kuaishou/web/sign.js +568 -0
  114. package/dist/platforms/taobao/index.js +56 -0
  115. package/dist/platforms/taobao/web/api.js +96 -0
  116. package/dist/platforms/taobao/web/client.js +102 -0
  117. package/dist/platforms/taobao/web/commands.js +172 -0
  118. package/dist/platforms/taobao/web/im.js +68 -0
  119. package/dist/platforms/taobao/web/normalize.js +103 -0
  120. package/dist/platforms/taobao/web/profile.js +85 -0
  121. package/dist/platforms/taobao/web/resolve.js +51 -0
  122. package/dist/platforms/taobao/web/sign.js +35 -0
  123. package/dist/platforms/tiktok/index.js +120 -0
  124. package/dist/platforms/tiktok/web/api.js +1234 -0
  125. package/dist/platforms/tiktok/web/client.js +362 -0
  126. package/dist/platforms/tiktok/web/commands.js +821 -0
  127. package/dist/platforms/tiktok/web/im.js +133 -0
  128. package/dist/platforms/tiktok/web/jsrun.js +126 -0
  129. package/dist/platforms/tiktok/web/normalize.js +286 -0
  130. package/dist/platforms/tiktok/web/profile.js +169 -0
  131. package/dist/platforms/tiktok/web/resolve.js +156 -0
  132. package/dist/platforms/tiktok/web/sign.js +585 -0
  133. package/dist/platforms/tiktok/web/upload.js +805 -0
  134. package/dist/platforms/tiktok/web/wire.js +490 -0
  135. package/dist/platforms/weibo/index.js +91 -0
  136. package/dist/platforms/weibo/web/api.js +206 -0
  137. package/dist/platforms/weibo/web/client.js +155 -0
  138. package/dist/platforms/weibo/web/commands.js +202 -0
  139. package/dist/platforms/weibo/web/normalize.js +137 -0
  140. package/dist/platforms/weibo/web/profile.js +246 -0
  141. package/dist/platforms/weibo/web/resolve.js +60 -0
  142. package/dist/platforms/weibo/web/sign.js +85 -0
  143. package/dist/platforms/x/index.js +107 -0
  144. package/dist/platforms/x/web/api.js +443 -0
  145. package/dist/platforms/x/web/article.js +212 -0
  146. package/dist/platforms/x/web/client.js +202 -0
  147. package/dist/platforms/x/web/commands.js +363 -0
  148. package/dist/platforms/x/web/graphql.js +108 -0
  149. package/dist/platforms/x/web/normalize.js +235 -0
  150. package/dist/platforms/x/web/profile.js +99 -0
  151. package/dist/platforms/x/web/resolve.js +44 -0
  152. package/dist/platforms/x/web/transaction.js +171 -0
  153. package/dist/platforms/xhs/index.js +101 -0
  154. package/dist/platforms/xhs/web/api.js +278 -0
  155. package/dist/platforms/xhs/web/client.js +540 -0
  156. package/dist/platforms/xhs/web/commands.js +1046 -0
  157. package/dist/platforms/xhs/web/creator-api.js +609 -0
  158. package/dist/platforms/xhs/web/creator.js +203 -0
  159. package/dist/platforms/xhs/web/js.js +194 -0
  160. package/dist/platforms/xhs/web/login.js +230 -0
  161. package/dist/platforms/xhs/web/normalize.js +166 -0
  162. package/dist/platforms/xhs/web/profile.js +127 -0
  163. package/dist/platforms/xhs/web/push.js +361 -0
  164. package/dist/platforms/xhs/web/resolve.js +69 -0
  165. package/dist/platforms/xhs/web/state.js +368 -0
  166. package/dist/platforms/xianyu/index.js +59 -0
  167. package/dist/platforms/xianyu/web/api.js +312 -0
  168. package/dist/platforms/xianyu/web/client.js +134 -0
  169. package/dist/platforms/xianyu/web/commands.js +305 -0
  170. package/dist/platforms/xianyu/web/im.js +73 -0
  171. package/dist/platforms/xianyu/web/normalize.js +123 -0
  172. package/dist/platforms/xianyu/web/profile.js +146 -0
  173. package/dist/platforms/xianyu/web/resolve.js +48 -0
  174. package/dist/platforms/xianyu/web/sign.js +79 -0
  175. package/package.json +77 -4
  176. package/static/douyin/Live.proto +194 -0
  177. package/static/douyin/Request.proto +89 -0
  178. package/static/douyin/Response.proto +46 -0
  179. package/static/douyin/acrawler_runtime/ac_vm.js +2 -0
  180. package/static/douyin/acrawler_runtime/browser_window_shape.json +1 -0
  181. package/static/douyin/acrawler_runtime/canvas_actual_exact.json +1 -0
  182. package/static/douyin/acrawler_runtime/run_ac_node.js +1005 -0
  183. package/static/douyin/acrawler_runtime/runner_window_keys_baseline.txt +240 -0
  184. package/static/douyin/challenge_profile.json +801 -0
  185. package/static/douyin/challenge_template_runner.js +217 -0
  186. package/static/douyin/dtrait_profile.json +66 -0
  187. package/static/douyin/mstoken_common_profile.json +1 -0
  188. package/static/douyin/mstoken_profile.json +214 -0
  189. package/static/jd/h5st5_env.js +750 -0
  190. package/static/jd/h5st5_lib.js +5 -0
  191. package/static/jd/h5st5_server.js +49 -0
  192. package/static/jd/jcap/env/env_core.js +512 -0
  193. package/static/jd/jcap/env/run.js +1307 -0
  194. package/static/jd/jcap/run/jcap_ujb96b.js +39 -0
  195. package/static/jd/package.json +4 -0
  196. package/static/jd/pc_tk_lib.js +1 -0
  197. package/static/jd/pc_tk_server.js +63 -0
  198. package/static/jd/summer_cryptico_runner.js +50 -0
  199. package/static/jd/webm/env/run.js +453 -0
  200. package/static/jd/webm/run/jdwebm-riskhandle.js +49 -0
  201. package/static/kuaishou/bundles/weapon/kwf-0.0.2.2cee19b4b7dec496.js +1 -0
  202. package/static/kuaishou/bundles/weapon/kws-0-0.0.1-obfuscated.4b7f3de1ab0ddcc2.js +1 -0
  203. package/static/kuaishou/bundles/weapon/kws-1-0.0.1-obfuscated.346ebdb1c78df316.js +1 -0
  204. package/static/kuaishou/bundles/weapon/kws-10-0.0.1-obfuscated.a33db41897b983af.js +1 -0
  205. package/static/kuaishou/bundles/weapon/kws-11-0.0.1-obfuscated.5e0a90af726d8a7e.js +1 -0
  206. package/static/kuaishou/bundles/weapon/kws-12-0.0.1-obfuscated.20ea29345706ec8c.js +1 -0
  207. package/static/kuaishou/bundles/weapon/kws-13-0.0.1-obfuscated.6b74e9640ff18648.js +1 -0
  208. package/static/kuaishou/bundles/weapon/kws-14-0.0.1-obfuscated.551e4429d156bf66.js +1 -0
  209. package/static/kuaishou/bundles/weapon/kws-15-0.0.1-obfuscated.8625b087aaba4a60.js +1 -0
  210. package/static/kuaishou/bundles/weapon/kws-16-0.0.1-obfuscated.d5ffa4020f3be99a.js +1 -0
  211. package/static/kuaishou/bundles/weapon/kws-17-0.0.1-obfuscated.6d13e19b22f50a80.js +1 -0
  212. package/static/kuaishou/bundles/weapon/kws-18-0.0.1-obfuscated.6d31405044166289.js +1 -0
  213. package/static/kuaishou/bundles/weapon/kws-19-0.0.1-obfuscated.a9a8d925942f19e4.js +1 -0
  214. package/static/kuaishou/bundles/weapon/kws-2-0.0.1-obfuscated.b849a136ae4a6b3e.js +1 -0
  215. package/static/kuaishou/bundles/weapon/kws-3-0.0.1-obfuscated.f9e77ebf6186e2ac.js +1 -0
  216. package/static/kuaishou/bundles/weapon/kws-4-0.0.1-obfuscated.2c3c155aa52ceb0e.js +1 -0
  217. package/static/kuaishou/bundles/weapon/kws-5-0.0.1-obfuscated.4e553d17691b3c5a.js +1 -0
  218. package/static/kuaishou/bundles/weapon/kws-6-0.0.1-obfuscated.f73ddd3ff13e1217.js +1 -0
  219. package/static/kuaishou/bundles/weapon/kws-7-0.0.1-obfuscated.1628b8729beaab7e.js +1 -0
  220. package/static/kuaishou/bundles/weapon/kws-8-0.0.1-obfuscated.6da6baef7aa81fff.js +1 -0
  221. package/static/kuaishou/bundles/weapon/kws-9-0.0.1-obfuscated.8645d55e5323b743.js +1 -0
  222. package/static/kuaishou/fixtures/current_follow_script_813.network-response +2 -0
  223. package/static/kuaishou/fixtures/live_ws_maps.json +61 -0
  224. package/static/kuaishou/fixtures/live_ws_proto.json +1342 -0
  225. package/static/kuaishou/js/cp-kwf.js +1 -0
  226. package/static/kuaishou/tools/kwf_oracle.js +799 -0
  227. package/static/kuaishou/tools/kws_oracle.js +885 -0
  228. package/static/kuaishou/tools/like_token_oracle.js +70 -0
  229. package/static/taobao/taobao_js_20260407.js +570 -0
  230. package/static/tiktok/Tiktok_Request.json +597 -0
  231. package/static/tiktok/package.json +3 -0
  232. package/static/tiktok/shop_bsid/core.js +1 -0
  233. package/static/tiktok/shop_bsid/env_core.js +512 -0
  234. package/static/tiktok/shop_bsid/loader.js +1 -0
  235. package/static/tiktok/shop_bsid/run.js +753 -0
  236. package/static/tiktok/shop_bsid/sign.js +100 -0
  237. package/static/tiktok/shop_bsid/webmssdk.js +1 -0
  238. package/static/tiktok/shop_bsid/webmssdk_ex.js +1 -0
  239. package/static/tiktok/signing/env/env_core.js +512 -0
  240. package/static/tiktok/signing/env/sign.js +455 -0
  241. package/static/tiktok/signing/sdk_config.json +230 -0
  242. package/static/tiktok/signing/source/webmssdk.js +1 -0
  243. package/static/tiktok/signing/source/webmssdk_ex.js +1 -0
  244. package/static/tiktok/signing/source/webmssdk_legacy.js +1 -0
  245. package/static/x/graphql.json +7777 -0
  246. package/static/x/transaction_l1.json +12 -0
  247. package/static/xhs/package.json +3 -0
  248. package/static/xhs/xhs_core/js/b1.js +210 -0
  249. package/static/xhs/xhs_core/js/mns.js +340 -0
  250. package/static/xhs/xhs_core/js/mns_0101_keystream.json +5 -0
  251. package/static/xhs/xhs_core/js/mns_keystreams.json +1 -0
  252. package/static/xhs/xhs_core/js/sign.js +225 -0
  253. package/static/xhs/xhs_core/js/websectiga_cli.js +220 -0
  254. package/static/xhs/xhs_core/js/websectiga_env.js +512 -0
  255. package/static/xhs/xhs_core/js/xs_common.js +79 -0
  256. package/static/xhs/xhs_creator/js/profile.js +115 -0
  257. package/static/xhs/xhs_creator/js/rap_fingerprint_creator.json +6 -0
  258. package/static/xhs/xhs_creator/js/reference_profile.json +282 -0
  259. package/static/xhs/xhs_creator/js/xhs_creator_sign.js +29 -0
  260. package/static/xhs/xhs_creator/js/xhs_creator_signature.js +23 -0
  261. package/static/xhs/xhs_pc/js/aes_decrypt.js +22 -0
  262. package/static/xhs/xhs_pc/js/aes_encrypt.js +30 -0
  263. package/static/xhs/xhs_pc/js/b1.js +9 -0
  264. package/static/xhs/xhs_pc/js/deflate.js +320 -0
  265. package/static/xhs/xhs_pc/js/mns.js +4 -0
  266. package/static/xhs/xhs_pc/js/profile.js +141 -0
  267. package/static/xhs/xhs_pc/js/rap.js +173 -0
  268. package/static/xhs/xhs_pc/js/rap_cli.js +30 -0
  269. package/static/xhs/xhs_pc/js/rap_crypto.js +73 -0
  270. package/static/xhs/xhs_pc/js/rap_fingerprint_template.json +8 -0
  271. package/static/xhs/xhs_pc/js/reference_profile.json +262 -0
  272. package/static/xhs/xhs_pc/js/sign.js +6 -0
  273. package/static/xhs/xhs_pc/js/web_ssk.js +82 -0
  274. package/static/xhs/xhs_pc/js/xs_common.js +4 -0
  275. package/static/xianyu/et_f.js +2 -0
  276. package/static/xianyu/gen_tfstk.js +410 -0
  277. package/static/xianyu/goofish_js_version_2.js +568 -0
@@ -0,0 +1,753 @@
1
+ "use strict";
2
+
3
+ // The vendor files in this directory are immutable copies of TikTok Shop's
4
+ // official unisec loader/core. All browser emulation lives in this file.
5
+ const fs = require("fs");
6
+ const path = require("path");
7
+ const vm = require("vm");
8
+ const env = require("./env_core");
9
+
10
+ const nativeConsole = console;
11
+ const nativeProcess = process;
12
+ const quiet = nativeProcess.env.TIKTOK_BSID_QUIET === "1";
13
+ const debugEnvironment = nativeProcess.env.TIKTOK_BSID_DEBUG === "1";
14
+ const sdkConsole = quiet ? {
15
+ log() {}, info() {}, warn() {}, error() {}, debug() {}, trace() {},
16
+ dir() {}, group() {}, groupEnd() {}, time() {}, timeEnd() {},
17
+ } : nativeConsole;
18
+ const nativeFetch = global.fetch;
19
+ const NativeHeaders = global.Headers;
20
+ const NativeRequest = global.Request;
21
+ const NativeResponse = global.Response;
22
+ const NativeTextEncoder = global.TextEncoder;
23
+ const nativeCrypto = global.crypto;
24
+ const nativeAtob = global.atob;
25
+
26
+ const PAGE_URL = "https://shop.tiktok.com/jp/pdp/ruzofo-2-4-ko-setto-silicone-hallux-valgus-correction-tool/1734259790973994282";
27
+ const LOADER_URL = "https://sf16-website-login.neutral.ttwstatic.com/obj/tiktok_web_login_static/oec/unisec/web/loader/1.0.0.52/sg/index.js";
28
+ const CORE_URL = "https://sf16-website-login.neutral.ttwstatic.com/obj/tiktok_web_login_static/oec/unisec/web/1.0.0.65/sg/index.js";
29
+ const WEBMSSDK_URL = "https://sf16-website-login.neutral.ttwstatic.com/obj/tiktok_web_login_static/webmssdk/1.0.0.162/webmssdk.js";
30
+ const WEBMSSDK_EX_URL = "https://sf16-website-login.neutral.ttwstatic.com/obj/tiktok_web_login_static/ttweb_webmssdk_ex/1.0.0.2875/webmssdk_ex.js";
31
+
32
+ const code = {
33
+ loader: fs.readFileSync(path.join(__dirname, "loader.js"), "utf8"),
34
+ core: fs.readFileSync(path.join(__dirname, "core.js"), "utf8"),
35
+ webmssdk: fs.readFileSync(path.join(__dirname, "webmssdk.js"), "utf8"),
36
+ webmssdkEx: fs.readFileSync(path.join(__dirname, "webmssdk_ex.js"), "utf8"),
37
+ };
38
+
39
+ function makeEventTarget(target) {
40
+ const listeners = new Map();
41
+ target.addEventListener = env.setFuncNative(function addEventListener(type, callback) {
42
+ if (!listeners.has(type)) listeners.set(type, []);
43
+ listeners.get(type).push(callback);
44
+ }, "addEventListener", 2);
45
+ target.removeEventListener = env.setFuncNative(function removeEventListener(type, callback) {
46
+ const values = listeners.get(type) || [];
47
+ const index = values.indexOf(callback);
48
+ if (index >= 0) values.splice(index, 1);
49
+ }, "removeEventListener", 2);
50
+ target.dispatchEvent = env.setFuncNative(function dispatchEvent(event) {
51
+ for (const callback of listeners.get(event.type) || []) callback.call(target, event);
52
+ const handler = target[`on${event.type}`];
53
+ if (typeof handler === "function") handler.call(target, event);
54
+ return true;
55
+ }, "dispatchEvent", 1);
56
+ return target;
57
+ }
58
+
59
+ function createStorage(name) {
60
+ const values = Object.create(null);
61
+ const storage = {};
62
+ env.setObjNative(storage, "Storage");
63
+ storage.getItem = env.setFuncNative(function getItem(key) {
64
+ return Object.prototype.hasOwnProperty.call(values, key) ? values[key] : null;
65
+ }, "getItem", 1);
66
+ storage.setItem = env.setFuncNative(function setItem(key, value) {
67
+ values[key] = String(value);
68
+ }, "setItem", 2);
69
+ storage.removeItem = env.setFuncNative(function removeItem(key) { delete values[key]; }, "removeItem", 1);
70
+ storage.clear = env.setFuncNative(function clear() {
71
+ for (const key of Object.keys(values)) delete values[key];
72
+ }, "clear", 0);
73
+ storage.key = env.setFuncNative(function key(index) { return Object.keys(values)[index] || null; }, "key", 1);
74
+ Object.defineProperty(storage, "length", { get() { return Object.keys(values).length; } });
75
+ Object.defineProperty(storage, "_name", { value: name });
76
+ return storage;
77
+ }
78
+
79
+ function illegalConstructor(name) {
80
+ return env.setFuncNative(function () {
81
+ throw new TypeError("Illegal constructor");
82
+ }, name, 0);
83
+ }
84
+
85
+ const EventTarget = illegalConstructor("EventTarget");
86
+ const Node = illegalConstructor("Node");
87
+ const Element = illegalConstructor("Element");
88
+ const HTMLElement = illegalConstructor("HTMLElement");
89
+ const HTMLCanvasElement = illegalConstructor("HTMLCanvasElement");
90
+ const HTMLAnchorElement = illegalConstructor("HTMLAnchorElement");
91
+ const HTMLScriptElement = illegalConstructor("HTMLScriptElement");
92
+ const CanvasRenderingContext2D = illegalConstructor("CanvasRenderingContext2D");
93
+ const WebGLRenderingContext = illegalConstructor("WebGLRenderingContext");
94
+ const CanvasGradient = illegalConstructor("CanvasGradient");
95
+ const ImageData = illegalConstructor("ImageData");
96
+ Object.setPrototypeOf(Node.prototype, EventTarget.prototype);
97
+ Object.setPrototypeOf(Element.prototype, Node.prototype);
98
+ Object.setPrototypeOf(HTMLElement.prototype, Element.prototype);
99
+ for (const ctor of [HTMLCanvasElement, HTMLAnchorElement, HTMLScriptElement]) {
100
+ Object.setPrototypeOf(ctor.prototype, HTMLElement.prototype);
101
+ }
102
+
103
+ const elementDiagnostics = { createdTags: [], canvasCalls: [] };
104
+
105
+ function createElement(tagName) {
106
+ const upper = String(tagName || "").toUpperCase();
107
+ elementDiagnostics.createdTags.push(upper);
108
+ const attributes = Object.create(null);
109
+ const element = makeEventTarget({
110
+ tagName: upper,
111
+ nodeName: upper,
112
+ style: {},
113
+ dataset: {},
114
+ childNodes: [],
115
+ children: [],
116
+ parentNode: null,
117
+ ownerDocument: null,
118
+ innerHTML: "",
119
+ innerText: "",
120
+ textContent: "",
121
+ id: "",
122
+ src: "",
123
+ type: "",
124
+ async: false,
125
+ defer: false,
126
+ onload: null,
127
+ onerror: null,
128
+ });
129
+ Object.setPrototypeOf(
130
+ element,
131
+ upper === "CANVAS" ? HTMLCanvasElement.prototype
132
+ : upper === "A" ? HTMLAnchorElement.prototype
133
+ : upper === "SCRIPT" ? HTMLScriptElement.prototype
134
+ : HTMLElement.prototype,
135
+ );
136
+ element.setAttribute = env.setFuncNative(function setAttribute(name, value) {
137
+ attributes[String(name)] = String(value);
138
+ element[name] = String(value);
139
+ }, "setAttribute", 2);
140
+ element.getAttribute = env.setFuncNative(function getAttribute(name) {
141
+ return Object.prototype.hasOwnProperty.call(attributes, String(name)) ? attributes[String(name)] : null;
142
+ }, "getAttribute", 1);
143
+ element.appendChild = env.setFuncNative(function appendChild(child) {
144
+ child.parentNode = element;
145
+ element.childNodes.push(child);
146
+ element.children.push(child);
147
+ return child;
148
+ }, "appendChild", 1);
149
+ element.removeChild = env.setFuncNative(function removeChild(child) {
150
+ element.childNodes = element.childNodes.filter(item => item !== child);
151
+ element.children = element.children.filter(item => item !== child);
152
+ return child;
153
+ }, "removeChild", 1);
154
+ element.remove = env.setFuncNative(function remove() {
155
+ if (element.parentNode && typeof element.parentNode.removeChild === "function") {
156
+ element.parentNode.removeChild(element);
157
+ }
158
+ }, "remove", 0);
159
+ if (upper === "A") {
160
+ let anchorUrl = new URL(PAGE_URL);
161
+ Object.defineProperty(element, "href", {
162
+ get() { return anchorUrl.href; },
163
+ set(value) { anchorUrl = new URL(String(value), PAGE_URL); },
164
+ configurable: true,
165
+ });
166
+ for (const key of ["protocol", "host", "hostname", "port", "pathname", "search", "hash", "origin"]) {
167
+ Object.defineProperty(element, key, {
168
+ get() { return anchorUrl[key]; },
169
+ configurable: true,
170
+ });
171
+ }
172
+ }
173
+ if (upper === "CANVAS") {
174
+ element.width = 300;
175
+ element.height = 150;
176
+ const context = {};
177
+ env.setObjNative(context, "CanvasRenderingContext2D");
178
+ Object.setPrototypeOf(context, CanvasRenderingContext2D.prototype);
179
+ for (const method of [
180
+ "fillRect", "strokeRect", "clearRect", "fillText", "strokeText",
181
+ "beginPath", "closePath", "moveTo", "lineTo", "arc", "arcTo",
182
+ "bezierCurveTo", "quadraticCurveTo", "fill", "stroke", "clip",
183
+ "rect", "save", "restore", "translate", "rotate", "scale",
184
+ "drawImage", "setTransform", "transform", "putImageData",
185
+ ]) context[method] = env.setFuncNative(function () {
186
+ elementDiagnostics.canvasCalls.push(method);
187
+ }, method);
188
+ context.measureText = env.setFuncNative(function measureText(text) {
189
+ elementDiagnostics.canvasCalls.push("measureText");
190
+ return { width: String(text || "").length * 7.2 };
191
+ }, "measureText", 1);
192
+ context.createLinearGradient = env.setFuncNative(function createLinearGradient() {
193
+ const gradient = { addColorStop: env.setFuncNative(function addColorStop() {}, "addColorStop", 2) };
194
+ Object.setPrototypeOf(gradient, CanvasGradient.prototype);
195
+ return gradient;
196
+ }, "createLinearGradient", 4);
197
+ context.createRadialGradient = env.setFuncNative(function createRadialGradient() {
198
+ const gradient = { addColorStop: env.setFuncNative(function addColorStop() {}, "addColorStop", 2) };
199
+ Object.setPrototypeOf(gradient, CanvasGradient.prototype);
200
+ return gradient;
201
+ }, "createRadialGradient", 6);
202
+ context.getImageData = env.setFuncNative(function getImageData() {
203
+ elementDiagnostics.canvasCalls.push("getImageData");
204
+ return { data: new Uint8ClampedArray(element.width * element.height * 4) };
205
+ }, "getImageData", 4);
206
+ context.createImageData = env.setFuncNative(function createImageData(width, height) {
207
+ return { data: new Uint8ClampedArray(Number(width) * Number(height) * 4) };
208
+ }, "createImageData", 2);
209
+ context.isPointInPath = env.setFuncNative(function isPointInPath() { return false; }, "isPointInPath", 2);
210
+ context.canvas = element;
211
+ context.fillStyle = "#000000";
212
+ context.strokeStyle = "#000000";
213
+ const webglContext = {};
214
+ env.setObjNative(webglContext, "WebGLRenderingContext");
215
+ Object.setPrototypeOf(webglContext, WebGLRenderingContext.prototype);
216
+ const debugRendererInfo = {
217
+ UNMASKED_VENDOR_WEBGL: 37445,
218
+ UNMASKED_RENDERER_WEBGL: 37446,
219
+ };
220
+ webglContext.getExtension = env.setFuncNative(function getExtension(name) {
221
+ elementDiagnostics.canvasCalls.push(`webgl.getExtension:${name}`);
222
+ return name === "WEBGL_debug_renderer_info" ? debugRendererInfo : null;
223
+ }, "getExtension", 1);
224
+ webglContext.getSupportedExtensions = env.setFuncNative(function getSupportedExtensions() {
225
+ elementDiagnostics.canvasCalls.push("webgl.getSupportedExtensions");
226
+ return ["WEBGL_debug_renderer_info"];
227
+ }, "getSupportedExtensions", 0);
228
+ webglContext.getParameter = env.setFuncNative(function getParameter(parameter) {
229
+ elementDiagnostics.canvasCalls.push(`webgl.getParameter:${parameter}`);
230
+ return ({
231
+ 37445: "Google Inc. (NVIDIA)",
232
+ 37446: "ANGLE (NVIDIA, NVIDIA GeForce RTX 5060 Ti (0x00002D04) Direct3D11 vs_5_0 ps_5_0, D3D11)",
233
+ 7936: "WebKit",
234
+ 7937: "WebKit WebGL",
235
+ 7938: "WebGL 1.0 (OpenGL ES 2.0 Chromium)",
236
+ 35724: "WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium)",
237
+ })[Number(parameter)] ?? 0;
238
+ }, "getParameter", 1);
239
+ element.getContext = env.setFuncNative(function getContext(type) {
240
+ elementDiagnostics.canvasCalls.push(`getContext:${type}`);
241
+ if (type === "2d") return context;
242
+ if (type === "webgl" || type === "experimental-webgl") return webglContext;
243
+ return null;
244
+ }, "getContext", 1);
245
+ element.toDataURL = env.setFuncNative(function toDataURL() {
246
+ elementDiagnostics.canvasCalls.push("toDataURL");
247
+ return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAQCAYAAABQrvyxAAADbklEQVR4AcSWWahNYRSAjzljN2TMrJRIhkxJZAgZywOhW7yZC3kglBdESZIXD5cyZbhI8iZDmTM9GB+QeeiaMg/fd+7Zu/9sm/t07tH67lr/+v/977X+tf591Mz8/a8errUwCupACQwHfQ3QSkP+tIRiSl9eXh4mYHBzcR4E7eno47AcOucYh54Kq8GkaqELIa3Z9CH8TnCKcSOIJUygCd7ncBd+QAXcgBYwAj5D2xwd0Y5/ogshz9i0A9QImIhtUh/RsYQJGPxXZsbCAOgDY+AV3IJIamPoO4OuLvHUl/Cyk2AVrMxl7JIwAcYZx3UxvuSwEuewPenB6CngSVitb9ieECpjm3k6Exg8AvsTlfX7sjIHAc5/YuycGJRB4kqVeXjdfzd6GPjefugKA0bnyXlGO+AI3IZIDNjEbB0TW8SEF9yg12G3B09pJ3oT+KJBaO+KGDTDjP19CGMaGEhjtGKQ6iQejl3hvM+aiEmnVsAgj7LDYfAkvQ+XsE3qAtrEtF9jXwPXd0cbtJUx8HaMlcX8cf0HdCienMn6HitjT59ggUGGVYiCdX8Pw3Xh3XCfvAo0Z5MhMBPcfCnaVtmMHg1dwFNwQ09tFuOmYPC+YCu24ldqL4bV8ZQw8+QYI1/+GL0F0sTEPKiBTJbCPyVsITN8wMr7cBb8ChnoPeyLYCW8uC+w74D3Yhl6BvjFEMyM1VFbak9MO0kbHLbBU3SaGLT7+bytF94Xn5ORPDg5TKA+Dh/yC9MM+xe8AVunB9pWMCE/q86bqGW21ZjOE/v7QJ6ncmCLeGGtcKXn/3+9X96XrizzvkQYhy1XFibwnUW2SSv0S3gPXlgT0ie2jD5P32rZOn6lWBqL/d2JUVr7dMN/E7wvqCrFdpzPKiuBisVu8YPRK0wgns0ZXtC32P3B6qCyYvD+Zng6V/A8gaR4ysmXusbW64lhBbah09bgjsUqep9so9iJYSX9YFxPJmA7GLQ9ZgK2Sm8eMIGr6HdgP3qpPcVyxqF4QS2zPRz5TdKqqD05q+aa9dECtLZ+5xnG4n5DGZ0GY4qwnU2gNEzAh1eycA1sgAWwCmbDHNgFC2Ej+Klcgd4OhRYT9z+PJh1ictlf3mQAYVLRnD9gto6JWIk9TJgIqriSFux4QvLi7kf7Cyv7sPVNQjtv+TCLL38AAAD//0WvmE8AAAAGSURBVAMACkfOk5B1KHEAAAAASUVORK5CYII=";
248
+ }, "toDataURL", 0);
249
+ element.toBlob = env.setFuncNative(function toBlob(callback) {
250
+ if (callback) callback(null);
251
+ }, "toBlob", 1);
252
+ }
253
+ return element;
254
+ }
255
+
256
+ const fakeWindow = makeEventTarget({});
257
+ const [Document, fakeDocument] = env.getNativeProto("HTMLDocument", {});
258
+ const [Navigator, fakeNavigator] = env.getNativeProto("Navigator", {});
259
+ const [Screen, fakeScreen] = env.getNativeProto("Screen", {});
260
+ const fakeLocation = {};
261
+ env.setObjNative(fakeLocation, "Location");
262
+
263
+ const loaderScript = createElement("script");
264
+ loaderScript.src = LOADER_URL;
265
+ loaderScript.defer = true;
266
+ const webmssdkScript = createElement("script");
267
+ webmssdkScript.src = WEBMSSDK_URL;
268
+ webmssdkScript.defer = true;
269
+ let currentScript = loaderScript;
270
+ let coreScheduled = false;
271
+ let webmssdkExScheduled = false;
272
+ const cookiePairs = [];
273
+ const diagnostics = {
274
+ cookieReads: 0,
275
+ elements: elementDiagnostics,
276
+ accessed: {
277
+ document: new Set(), navigator: new Set(),
278
+ location: new Set(), screen: new Set(),
279
+ },
280
+ };
281
+
282
+ function monitorGets(target, label) {
283
+ if (!debugEnvironment) return target;
284
+ return new Proxy(target, {
285
+ get(object, property, receiver) {
286
+ diagnostics.accessed[label].add(String(property));
287
+ return Reflect.get(object, property, receiver);
288
+ },
289
+ });
290
+ }
291
+
292
+ function seedCookies(cookieHeader) {
293
+ cookiePairs.length = 0;
294
+ for (const pair of String(cookieHeader || "").split(";")) {
295
+ const trimmed = pair.trim();
296
+ if (!trimmed) continue;
297
+ const equals = trimmed.indexOf("=");
298
+ if (equals <= 0) continue;
299
+ cookiePairs.push([trimmed.slice(0, equals), trimmed.slice(equals + 1)]);
300
+ }
301
+ }
302
+
303
+ function serializeCookies() {
304
+ return cookiePairs.map(([name, value]) => `${name}=${value}`).join("; ");
305
+ }
306
+
307
+ function currentBsToken() {
308
+ const entry = cookiePairs.find(([name]) => name === "oec_lucifer");
309
+ if (!entry || !entry[1]) return undefined;
310
+ return /^[0-9a-f]{160}$/i.test(entry[1]) ? entry[1] : undefined;
311
+ }
312
+
313
+ function seedSecurityStorage() {
314
+ const msToken = cookiePairs
315
+ .filter(([name, value]) => name === "msToken" && value.length === 144)
316
+ .map(([, value]) => value)[0];
317
+ const bsToken = currentBsToken();
318
+ if (msToken) {
319
+ fakeWindow.localStorage.setItem("msToken", msToken);
320
+ fakeWindow.localStorage.setItem("xmst", msToken);
321
+ fakeWindow.localStorage.setItem("xmstr", JSON.stringify({ sTm: Date.now(), acc: 0 }));
322
+ fakeWindow.localStorage.setItem("xmsi", "0");
323
+ fakeWindow.sessionStorage.setItem("msToken", msToken);
324
+ }
325
+ // Chrome persists the 160-hex OEC value verbatim. Treating it as
326
+ // base64 expands it to 240 hex characters and invalidates every BSID.
327
+ if (bsToken) fakeWindow.localStorage.setItem("_lcf_v", bsToken);
328
+ }
329
+
330
+ function executeVendorScript(scriptElement, source, filename) {
331
+ try {
332
+ currentScript = scriptElement;
333
+ vm.runInThisContext(source, { filename });
334
+ if (typeof scriptElement.onload === "function") scriptElement.onload.call(scriptElement);
335
+ scriptElement.dispatchEvent({ type: "load", target: scriptElement });
336
+ } catch (error) {
337
+ if (typeof scriptElement.onerror === "function") scriptElement.onerror.call(scriptElement, error);
338
+ scriptElement.dispatchEvent({ type: "error", target: scriptElement, error });
339
+ throw error;
340
+ } finally {
341
+ currentScript = loaderScript;
342
+ }
343
+ }
344
+
345
+ const fakeHead = createElement("head");
346
+ const fakeBody = createElement("body");
347
+ const originalHeadAppend = fakeHead.appendChild;
348
+ fakeHead.appendChild = env.setFuncNative(function appendChild(child) {
349
+ const result = originalHeadAppend.call(fakeHead, child);
350
+ if (child && child.tagName === "SCRIPT" && !fakeDocument.scripts.includes(child)) {
351
+ fakeDocument.scripts.push(child);
352
+ }
353
+ const src = String(child && child.src || "");
354
+ if (!coreScheduled && /\/oec\/unisec\/web\/(?!loader\/).*\/index\.js/.test(src)) {
355
+ coreScheduled = true;
356
+ setTimeout(() => executeVendorScript(child, code.core, "core.js"), 0);
357
+ }
358
+ if (!webmssdkExScheduled && /\/ttweb_webmssdk_ex\/.*\/webmssdk_ex\.js/.test(src)) {
359
+ webmssdkExScheduled = true;
360
+ setTimeout(() => executeVendorScript(child, code.webmssdkEx, "webmssdk_ex.js"), 0);
361
+ }
362
+ return result;
363
+ }, "appendChild", 1);
364
+
365
+ Object.defineProperties(fakeDocument, {
366
+ cookie: {
367
+ get() { diagnostics.cookieReads += 1; return serializeCookies(); },
368
+ set(value) {
369
+ const first = String(value || "").split(";", 1)[0];
370
+ const equals = first.indexOf("=");
371
+ if (equals > 0) {
372
+ const name = first.slice(0, equals).trim();
373
+ const pair = [name, first.slice(equals + 1)];
374
+ const index = cookiePairs.findIndex(item => item[0] === name);
375
+ if (index >= 0) cookiePairs[index] = pair;
376
+ else cookiePairs.push(pair);
377
+ }
378
+ },
379
+ enumerable: true,
380
+ },
381
+ domain: { get() { return "shop.tiktok.com"; }, enumerable: true },
382
+ URL: { get() { return PAGE_URL; }, enumerable: true },
383
+ documentURI: { get() { return PAGE_URL; }, enumerable: true },
384
+ referrer: { get() { return ""; }, enumerable: true },
385
+ title: { get() { return ""; }, set() {}, enumerable: true },
386
+ characterSet: { get() { return "UTF-8"; }, enumerable: true },
387
+ readyState: { get() { return "complete"; }, enumerable: true },
388
+ hidden: { get() { return false; }, enumerable: true },
389
+ visibilityState: { get() { return "visible"; }, enumerable: true },
390
+ currentScript: { get() { return currentScript; }, enumerable: true },
391
+ baseURI: { get() { return PAGE_URL; }, enumerable: true },
392
+ defaultView: { get() { return fakeWindow; }, enumerable: true },
393
+ });
394
+ fakeDocument.head = fakeHead;
395
+ fakeDocument.body = fakeBody;
396
+ fakeDocument.documentElement = createElement("html");
397
+ fakeDocument.scripts = [loaderScript, webmssdkScript];
398
+ fakeDocument.createElement = env.setFuncNative(function createElementForDocument(tag) {
399
+ const element = createElement(tag);
400
+ element.ownerDocument = fakeDocument;
401
+ return element;
402
+ }, "createElement", 1);
403
+ fakeDocument.createTextNode = env.setFuncNative(function createTextNode(text) { return { textContent: String(text) }; }, "createTextNode", 1);
404
+ fakeDocument.createEvent = env.setFuncNative(function createEvent(type) {
405
+ return { type, initEvent(value) { this.type = value; }, preventDefault() {}, stopPropagation() {} };
406
+ }, "createEvent", 1);
407
+ fakeDocument.getElementById = env.setFuncNative(function getElementById(id) {
408
+ return fakeDocument.scripts.find(script => script.id === String(id)) || null;
409
+ }, "getElementById", 1);
410
+ fakeDocument.getElementsByTagName = env.setFuncNative(function getElementsByTagName(tag) {
411
+ const lower = String(tag || "").toLowerCase();
412
+ if (lower === "head") return [fakeHead];
413
+ if (lower === "body") return [fakeBody];
414
+ if (lower === "script") return fakeDocument.scripts;
415
+ return [];
416
+ }, "getElementsByTagName", 1);
417
+ fakeDocument.querySelector = env.setFuncNative(function querySelector() { return null; }, "querySelector", 1);
418
+ fakeDocument.querySelectorAll = env.setFuncNative(function querySelectorAll() { return []; }, "querySelectorAll", 1);
419
+ makeEventTarget(fakeDocument);
420
+
421
+ function makeMimeType(type, suffixes, description) {
422
+ const mime = { type, suffixes, description, enabledPlugin: null };
423
+ env.setObjNative(mime, "MimeType");
424
+ return mime;
425
+ }
426
+
427
+ const pdfMime = makeMimeType("application/pdf", "pdf", "Portable Document Format");
428
+ const textPdfMime = makeMimeType("text/pdf", "pdf", "Portable Document Format");
429
+ const pluginNames = [
430
+ "PDF Viewer", "Chrome PDF Viewer", "Chromium PDF Viewer",
431
+ "Microsoft Edge PDF Viewer", "WebKit built-in PDF",
432
+ ];
433
+ const fakePlugins = pluginNames.map(name => {
434
+ const plugin = [pdfMime, textPdfMime];
435
+ Object.assign(plugin, {
436
+ name,
437
+ filename: "internal-pdf-viewer",
438
+ description: "Portable Document Format",
439
+ item: env.setFuncNative(function item(index) { return this[index] || null; }, "item", 1),
440
+ namedItem: env.setFuncNative(function namedItem(type) {
441
+ return this.find(value => value.type === type) || null;
442
+ }, "namedItem", 1),
443
+ });
444
+ env.setObjNative(plugin, "Plugin");
445
+ return plugin;
446
+ });
447
+ pdfMime.enabledPlugin = fakePlugins[0];
448
+ textPdfMime.enabledPlugin = fakePlugins[0];
449
+ fakePlugins.item = env.setFuncNative(function item(index) { return this[index] || null; }, "item", 1);
450
+ fakePlugins.namedItem = env.setFuncNative(function namedItem(name) {
451
+ return this.find(value => value.name === name) || null;
452
+ }, "namedItem", 1);
453
+ fakePlugins.refresh = env.setFuncNative(function refresh() {}, "refresh", 0);
454
+ env.setObjNative(fakePlugins, "PluginArray");
455
+ const fakeMimeTypes = [pdfMime, textPdfMime];
456
+ fakeMimeTypes.item = env.setFuncNative(function item(index) { return this[index] || null; }, "item", 1);
457
+ fakeMimeTypes.namedItem = env.setFuncNative(function namedItem(type) {
458
+ return this.find(value => value.type === type) || null;
459
+ }, "namedItem", 1);
460
+ env.setObjNative(fakeMimeTypes, "MimeTypeArray");
461
+
462
+ Object.defineProperties(fakeNavigator, {
463
+ userAgent: { get() { return "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36"; }, enumerable: true },
464
+ platform: { get() { return "Win32"; }, enumerable: true },
465
+ language: { get() { return "zh-CN"; }, enumerable: true },
466
+ languages: { get() { return ["zh-CN", "zh", "en", "zh-TW", "ja"]; }, enumerable: true },
467
+ cookieEnabled: { get() { return true; }, enumerable: true },
468
+ appName: { get() { return "Netscape"; }, enumerable: true },
469
+ vendor: { get() { return "Google Inc."; }, enumerable: true },
470
+ onLine: { get() { return true; }, enumerable: true },
471
+ hardwareConcurrency: { get() { return 20; }, enumerable: true },
472
+ webdriver: { get() { return false; }, enumerable: true },
473
+ maxTouchPoints: { get() { return 10; }, enumerable: true },
474
+ deviceMemory: { get() { return 32; }, enumerable: true },
475
+ productSub: { get() { return "20030107"; }, enumerable: true },
476
+ plugins: { get() { return fakePlugins; }, enumerable: true },
477
+ mimeTypes: { get() { return fakeMimeTypes; }, enumerable: true },
478
+ });
479
+ const fakeConnection = {};
480
+ env.setObjNative(fakeConnection, "NetworkInformation");
481
+ Object.defineProperties(fakeConnection, {
482
+ effectiveType: { get() { return "3g"; }, enumerable: true },
483
+ rtt: { get() { return 350; }, enumerable: true },
484
+ downlink: { get() { return 1.55; }, enumerable: true },
485
+ saveData: { get() { return false; }, enumerable: true },
486
+ });
487
+ Object.defineProperties(fakeNavigator, {
488
+ connection: { get() { return fakeConnection; }, enumerable: true },
489
+ mozConnection: { get() { return undefined; }, enumerable: true },
490
+ webkitConnection: { get() { return undefined; }, enumerable: true },
491
+ });
492
+ fakeNavigator.sendBeacon = env.setFuncNative(function sendBeacon() { return true; }, "sendBeacon", 2);
493
+
494
+ Object.defineProperties(fakeScreen, {
495
+ width: { get() { return 2560; } }, height: { get() { return 1440; } },
496
+ availWidth: { get() { return 2560; } }, availHeight: { get() { return 1392; } },
497
+ colorDepth: { get() { return 24; } }, pixelDepth: { get() { return 24; } },
498
+ });
499
+
500
+ const pageUrl = new URL(PAGE_URL);
501
+ for (const key of ["href", "protocol", "host", "hostname", "port", "pathname", "search", "hash", "origin"]) {
502
+ Object.defineProperty(fakeLocation, key, { get() { return key === "href" ? PAGE_URL : pageUrl[key]; }, enumerable: true });
503
+ }
504
+ fakeLocation.assign = env.setFuncNative(function assign() {}, "assign", 1);
505
+ fakeLocation.replace = env.setFuncNative(function replace() {}, "replace", 1);
506
+ fakeLocation.reload = env.setFuncNative(function reload() {}, "reload", 0);
507
+ fakeLocation.toString = env.setFuncNative(function toString() { return PAGE_URL; }, "toString", 0);
508
+
509
+ const fakePerformance = {};
510
+ env.setObjNative(fakePerformance, "Performance");
511
+ const startTime = Date.now();
512
+ fakePerformance.now = env.setFuncNative(function now() { return Date.now() - startTime; }, "now", 0);
513
+ fakePerformance.timeOrigin = startTime;
514
+ fakePerformance.timing = { navigationStart: startTime, domLoading: startTime + 100, domComplete: startTime + 500, loadEventEnd: startTime + 600 };
515
+ fakePerformance.getEntries = env.setFuncNative(function getEntries() { return []; }, "getEntries", 0);
516
+ fakePerformance.getEntriesByType = env.setFuncNative(function getEntriesByType() { return []; }, "getEntriesByType", 1);
517
+ fakePerformance.getEntriesByName = env.setFuncNative(function getEntriesByName() { return []; }, "getEntriesByName", 1);
518
+ fakePerformance.mark = env.setFuncNative(function mark() {}, "mark", 1);
519
+ fakePerformance.measure = env.setFuncNative(function measure() {}, "measure", 1);
520
+
521
+ const MOCK_SERVER_CONFIG = {
522
+ js_url: { sg: CORE_URL, eu: CORE_URL, ttp: CORE_URL },
523
+ js_url_v2: { sg: CORE_URL, eu: CORE_URL, ttp: CORE_URL },
524
+ global_config: {
525
+ enable_web_sdk: true,
526
+ enable_web_sign: true,
527
+ enable_web_rt: true,
528
+ enable_web_rt_polling: true,
529
+ sign_apis: [],
530
+ exclude_apis: ["^/api/v[0-9]+/bs/rt.*"],
531
+ },
532
+ biz_config: {
533
+ "1988": {
534
+ enable_web_sdk: true,
535
+ enable_web_sign: true,
536
+ enable_web_rt: true,
537
+ enable_web_rt_polling: true,
538
+ sign_apis: [],
539
+ },
540
+ },
541
+ };
542
+
543
+ function makeJsonResponse(payload, status = 200) {
544
+ const bodyText = JSON.stringify(payload);
545
+ const response = Object.create(NativeResponse.prototype);
546
+ const responseHeaders = new NativeHeaders({ "content-type": "application/json" });
547
+ Object.defineProperties(response, {
548
+ ok: { value: status >= 200 && status < 300, enumerable: true },
549
+ status: { value: status, enumerable: true },
550
+ statusText: { value: status === 200 ? "OK" : "", enumerable: true },
551
+ url: { value: "", enumerable: true },
552
+ redirected: { value: false, enumerable: true },
553
+ type: { value: "basic", enumerable: true },
554
+ headers: { value: responseHeaders, enumerable: true },
555
+ body: { value: null, enumerable: true },
556
+ bodyUsed: { value: false, enumerable: true },
557
+ });
558
+ response.json = env.setFuncNative(async function json() { return JSON.parse(bodyText); }, "json", 0);
559
+ response.text = env.setFuncNative(async function text() { return bodyText; }, "text", 0);
560
+ response.arrayBuffer = env.setFuncNative(async function arrayBuffer() {
561
+ const bytes = new NativeTextEncoder().encode(bodyText);
562
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
563
+ }, "arrayBuffer", 0);
564
+ response.clone = env.setFuncNative(function clone() { return makeJsonResponse(payload, status); }, "clone", 0);
565
+ return response;
566
+ }
567
+
568
+ const capturedRequests = [];
569
+ const transportFetch = env.setFuncNative(async function fetch(input, init) {
570
+ const url = typeof input === "string" || input instanceof URL ? String(input) : input.url;
571
+ const headers = new NativeHeaders((init && init.headers) || (input && input.headers) || undefined);
572
+ capturedRequests.push({ url, headers: Object.fromEntries(headers.entries()), method: (init && init.method) || (input && input.method) || "GET", body: init && init.body });
573
+ if (url.includes("/api/v1/bs/setting")) {
574
+ return makeJsonResponse({
575
+ data: JSON.stringify(MOCK_SERVER_CONFIG),
576
+ });
577
+ }
578
+ if (url.includes("/monitor_web/settings/browser-settings")) {
579
+ return makeJsonResponse({ data: {}, status: 200, ok: true });
580
+ }
581
+ return makeJsonResponse({ code: 0, data: {} });
582
+ }, "fetch", 1);
583
+
584
+ function XMLHttpRequest() {
585
+ this.readyState = 0;
586
+ this.status = 0;
587
+ this.responseText = "";
588
+ this.response = "";
589
+ this.onreadystatechange = null;
590
+ this.onload = null;
591
+ this.onerror = null;
592
+ this._headers = [];
593
+ }
594
+ env.setFuncNative(XMLHttpRequest, "XMLHttpRequest", 0);
595
+ XMLHttpRequest.prototype.open = env.setFuncNative(function open(method, url) { this._method = method; this._url = String(url); this.readyState = 1; }, "open", 2);
596
+ XMLHttpRequest.prototype.setRequestHeader = env.setFuncNative(function setRequestHeader(name, value) { this._headers.push([String(name), String(value)]); }, "setRequestHeader", 2);
597
+ XMLHttpRequest.prototype.getAllResponseHeaders = env.setFuncNative(function getAllResponseHeaders() { return "content-type: application/json\r\n"; }, "getAllResponseHeaders", 0);
598
+ XMLHttpRequest.prototype.getResponseHeader = env.setFuncNative(function getResponseHeader(name) { return String(name).toLowerCase() === "content-type" ? "application/json" : null; }, "getResponseHeader", 1);
599
+ XMLHttpRequest.prototype.send = env.setFuncNative(function send(body) {
600
+ capturedRequests.push({ url: this._url, headers: Object.fromEntries(this._headers), method: this._method || "GET", body });
601
+ this.readyState = 4;
602
+ this.status = 200;
603
+ this.responseText = String(this._url || "").includes("/api/v1/bs/setting")
604
+ ? JSON.stringify({
605
+ data: JSON.stringify(MOCK_SERVER_CONFIG),
606
+ headers: {}, status: 200, ok: true,
607
+ })
608
+ : '{"code":0,"data":{}}';
609
+ this.response = this.responseText;
610
+ if (typeof this.onreadystatechange === "function") this.onreadystatechange();
611
+ if (typeof this.onload === "function") this.onload();
612
+ }, "send", 1);
613
+ XMLHttpRequest.prototype.addEventListener = env.setFuncNative(function addEventListener(type, handler) { this[`on${type}`] = handler; }, "addEventListener", 2);
614
+ XMLHttpRequest.prototype.removeEventListener = env.setFuncNative(function removeEventListener(type, handler) { if (this[`on${type}`] === handler) this[`on${type}`] = null; }, "removeEventListener", 2);
615
+
616
+ Object.assign(fakeWindow, {
617
+ window: fakeWindow, self: fakeWindow, top: fakeWindow, parent: fakeWindow,
618
+ document: fakeDocument, navigator: fakeNavigator, location: fakeLocation, screen: fakeScreen,
619
+ localStorage: createStorage("localStorage"), sessionStorage: createStorage("sessionStorage"),
620
+ performance: fakePerformance, console: sdkConsole, crypto: nativeCrypto,
621
+ fetch: transportFetch, Headers: NativeHeaders, Request: NativeRequest, Response: NativeResponse,
622
+ XMLHttpRequest, URL, URLSearchParams, TextEncoder, TextDecoder, Blob, FormData,
623
+ Event: global.Event, CustomEvent: global.CustomEvent || function CustomEvent(type, init) { this.type = type; this.detail = init && init.detail; },
624
+ setTimeout, setInterval, clearTimeout, clearInterval, queueMicrotask,
625
+ requestAnimationFrame: env.setFuncNative(function requestAnimationFrame(callback) { return setTimeout(callback, 16); }, "requestAnimationFrame", 1),
626
+ cancelAnimationFrame: env.setFuncNative(function cancelAnimationFrame(id) { clearTimeout(id); }, "cancelAnimationFrame", 1),
627
+ getComputedStyle: env.setFuncNative(function getComputedStyle() { return {}; }, "getComputedStyle", 1),
628
+ matchMedia: env.setFuncNative(function matchMedia(query) { return { matches: false, media: String(query), addListener() {}, removeListener() {}, addEventListener() {}, removeEventListener() {} }; }, "matchMedia", 1),
629
+ innerWidth: 1297, innerHeight: 800, outerWidth: 1313, outerHeight: 985, devicePixelRatio: 1,
630
+ screenX: 0, screenY: 0, screenTop: 33, screenLeft: 0, scrollX: 0, scrollY: 0, pageXOffset: 0, pageYOffset: 0,
631
+ });
632
+ for (const value of [Function, Date, RegExp, Array, Object, String, Number, Boolean, Symbol, Error, TypeError, RangeError, Map, Set, WeakMap, WeakSet, Promise, Proxy, Reflect, ArrayBuffer, DataView, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array, BigInt64Array, BigUint64Array]) {
633
+ fakeWindow[value.name] = value;
634
+ }
635
+ Object.assign(fakeWindow, { Math, JSON, Intl, BigInt, eval });
636
+ Object.assign(fakeWindow, {
637
+ EventTarget, Node, Element, HTMLElement, HTMLCanvasElement,
638
+ HTMLAnchorElement, HTMLScriptElement, Document,
639
+ HTMLDocument: Document, Navigator, Screen, CanvasRenderingContext2D,
640
+ WebGLRenderingContext, CanvasGradient, ImageData,
641
+ });
642
+ fakeWindow.parseInt = parseInt;
643
+ fakeWindow.parseFloat = parseFloat;
644
+ fakeWindow.isNaN = isNaN;
645
+ fakeWindow.isFinite = isFinite;
646
+ fakeWindow.atob = global.atob;
647
+ fakeWindow.btoa = global.btoa;
648
+ fakeWindow.encodeURIComponent = encodeURIComponent;
649
+ fakeWindow.decodeURIComponent = decodeURIComponent;
650
+ fakeWindow.encodeURI = encodeURI;
651
+ fakeWindow.decodeURI = decodeURI;
652
+ fakeWindow.chrome = {
653
+ app: { isInstalled: false },
654
+ runtime: { PlatformOs: { MAC: "mac", WIN: "win", ANDROID: "android", CROS: "cros", LINUX: "linux", OPENBSD: "openbsd" } },
655
+ loadTimes: env.setFuncNative(function loadTimes() { return {}; }, "loadTimes", 0),
656
+ csi: env.setFuncNative(function csi() { return {}; }, "csi", 0),
657
+ };
658
+
659
+ const runtimeDocument = debugEnvironment
660
+ ? env.createProxy(monitorGets(fakeDocument, "document"), "document", 2) : fakeDocument;
661
+ const runtimeNavigator = debugEnvironment
662
+ ? env.createProxy(monitorGets(fakeNavigator, "navigator"), "navigator", 2) : fakeNavigator;
663
+ const runtimeLocation = debugEnvironment
664
+ ? env.createProxy(monitorGets(fakeLocation, "location"), "location", 2) : fakeLocation;
665
+ const runtimeScreen = debugEnvironment
666
+ ? env.createProxy(monitorGets(fakeScreen, "screen"), "screen", 2) : fakeScreen;
667
+ if (debugEnvironment) {
668
+ fakeWindow.document = runtimeDocument;
669
+ fakeWindow.navigator = runtimeNavigator;
670
+ fakeWindow.location = runtimeLocation;
671
+ fakeWindow.screen = runtimeScreen;
672
+ }
673
+ env.init({ window: fakeWindow, document: runtimeDocument, navigator: runtimeNavigator, location: runtimeLocation });
674
+ if (quiet) global.console = sdkConsole;
675
+ Object.defineProperties(global, {
676
+ screen: { value: fakeScreen, writable: true, configurable: true },
677
+ localStorage: { value: fakeWindow.localStorage, writable: true, configurable: true },
678
+ sessionStorage: { value: fakeWindow.sessionStorage, writable: true, configurable: true },
679
+ performance: { value: fakePerformance, writable: true, configurable: true },
680
+ fetch: { value: transportFetch, writable: true, configurable: true },
681
+ XMLHttpRequest: { value: XMLHttpRequest, writable: true, configurable: true },
682
+ chrome: { value: fakeWindow.chrome, writable: true, configurable: true },
683
+ });
684
+
685
+ function safeShape(value) {
686
+ if (!value || typeof value !== "object") return value;
687
+ return Object.fromEntries(Object.keys(value).map(key => [key, typeof value[key]]));
688
+ }
689
+
690
+ async function boot(options = {}) {
691
+ seedCookies(options.cookie || "");
692
+ seedSecurityStorage();
693
+ currentScript = loaderScript;
694
+ vm.runInThisContext(code.loader, { filename: "loader.js" });
695
+ currentScript = webmssdkScript;
696
+ vm.runInThisContext(code.webmssdk, { filename: "webmssdk.js" });
697
+ currentScript = loaderScript;
698
+ await new Promise(resolve => setTimeout(resolve, 100));
699
+ if (fakeWindow.lucifer && typeof fakeWindow.lucifer.init === "function") {
700
+ await fakeWindow.lucifer.init({
701
+ aid: 1988,
702
+ ttwid: "",
703
+ region: "sg",
704
+ mode: 516,
705
+ isSDK: false,
706
+ isBoe: false,
707
+ custom: {},
708
+ initialPathList: ["^/captcha/get", "^/captcha/verifyV2", "^/captcha/feedbackV2", "^/.*"],
709
+ excludePathList: [],
710
+ });
711
+ await new Promise(resolve => setTimeout(resolve, 100));
712
+ }
713
+ if (fakeWindow.byted_acrawler && typeof fakeWindow.byted_acrawler.init === "function") {
714
+ const webmssdkInit = fakeWindow.byted_acrawler.init({
715
+ aid: 1988,
716
+ isSDK: false,
717
+ boe: false,
718
+ region: "sg-tiktok",
719
+ mode: 516,
720
+ enablePathList: ["/view/product", "/shop/pdp", "/api/shop/", "/pdp/"],
721
+ });
722
+ if (webmssdkInit && typeof webmssdkInit.catch === "function") {
723
+ webmssdkInit.catch(error => {
724
+ if (!quiet) nativeConsole.error("webmssdk init failed", error && error.message || error);
725
+ });
726
+ }
727
+ await new Promise(resolve => setTimeout(resolve, 500));
728
+ }
729
+ return {
730
+ lucifer: safeShape(fakeWindow.lucifer),
731
+ config: fakeWindow.lucifer && typeof fakeWindow.lucifer.getConfig === "function" ? fakeWindow.lucifer.getConfig() : null,
732
+ capturedRequests,
733
+ nativeFetchAvailable: typeof nativeFetch === "function",
734
+ };
735
+ }
736
+
737
+ if (require.main === module) {
738
+ boot().then(result => {
739
+ const config = result.config;
740
+ nativeConsole.log(JSON.stringify({
741
+ lucifer: result.lucifer,
742
+ config: config && { aid: config.aid, region: config.region, mode: config.mode, initialized: config._isInitialized },
743
+ capturedRequestCount: result.capturedRequests.length,
744
+ capturedUrls: result.capturedRequests.map(item => item.url),
745
+ }, null, 2));
746
+ nativeProcess.exit(0);
747
+ }).catch(error => {
748
+ nativeConsole.error(error && error.stack || error);
749
+ nativeProcess.exitCode = 1;
750
+ });
751
+ }
752
+
753
+ module.exports = { boot, capturedRequests, diagnostics, fakeWindow, seedCookies, transportFetch };