├── .gitattributes ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── input.js ├── output.js └── src ├── lib.rs ├── main.rs └── transform ├── mod.rs └── visit ├── functions.rs ├── mod.rs └── strings.rs /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "allocator-api2" 7 | version = "0.2.18" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" 10 | 11 | [[package]] 12 | name = "assert-unchecked" 13 | version = "0.1.2" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "7330592adf847ee2e3513587b4db2db410a0d751378654e7e993d9adcbe5c795" 16 | 17 | [[package]] 18 | name = "autocfg" 19 | version = "1.4.0" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 22 | 23 | [[package]] 24 | name = "base64-simd" 25 | version = "0.8.0" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" 28 | dependencies = [ 29 | "outref", 30 | "vsimd", 31 | ] 32 | 33 | [[package]] 34 | name = "bitflags" 35 | version = "2.6.0" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 38 | 39 | [[package]] 40 | name = "bumpalo" 41 | version = "3.16.0" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 44 | dependencies = [ 45 | "allocator-api2", 46 | ] 47 | 48 | [[package]] 49 | name = "castaway" 50 | version = "0.2.3" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" 53 | dependencies = [ 54 | "rustversion", 55 | ] 56 | 57 | [[package]] 58 | name = "cfg-if" 59 | version = "1.0.0" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 62 | 63 | [[package]] 64 | name = "compact_str" 65 | version = "0.8.0" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "6050c3a16ddab2e412160b31f2c871015704239bca62f72f6e5f0be631d3f644" 68 | dependencies = [ 69 | "castaway", 70 | "cfg-if", 71 | "itoa", 72 | "rustversion", 73 | "ryu", 74 | "static_assertions", 75 | ] 76 | 77 | [[package]] 78 | name = "cow-utils" 79 | version = "0.1.3" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "417bef24afe1460300965a25ff4a24b8b45ad011948302ec221e8a0a81eb2c79" 82 | 83 | [[package]] 84 | name = "crossbeam-utils" 85 | version = "0.8.20" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 88 | 89 | [[package]] 90 | name = "daachorse" 91 | version = "1.0.0" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "63b7ef7a4be509357f4804d0a22e830daddb48f19fd604e4ad32ddce04a94c36" 94 | 95 | [[package]] 96 | name = "dashmap" 97 | version = "6.1.0" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" 100 | dependencies = [ 101 | "cfg-if", 102 | "crossbeam-utils", 103 | "hashbrown 0.14.5", 104 | "lock_api", 105 | "once_cell", 106 | "parking_lot_core", 107 | ] 108 | 109 | [[package]] 110 | name = "either" 111 | version = "1.13.0" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 114 | 115 | [[package]] 116 | name = "equivalent" 117 | version = "1.0.1" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 120 | 121 | [[package]] 122 | name = "fixedbitset" 123 | version = "0.4.2" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" 126 | 127 | [[package]] 128 | name = "hashbrown" 129 | version = "0.14.5" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 132 | 133 | [[package]] 134 | name = "hashbrown" 135 | version = "0.15.0" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" 138 | 139 | [[package]] 140 | name = "indexmap" 141 | version = "2.6.0" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" 144 | dependencies = [ 145 | "equivalent", 146 | "hashbrown 0.15.0", 147 | ] 148 | 149 | [[package]] 150 | name = "itertools" 151 | version = "0.13.0" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" 154 | dependencies = [ 155 | "either", 156 | ] 157 | 158 | [[package]] 159 | name = "itoa" 160 | version = "1.0.11" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 163 | 164 | [[package]] 165 | name = "libc" 166 | version = "0.2.161" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" 169 | 170 | [[package]] 171 | name = "lock_api" 172 | version = "0.4.12" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 175 | dependencies = [ 176 | "autocfg", 177 | "scopeguard", 178 | ] 179 | 180 | [[package]] 181 | name = "memchr" 182 | version = "2.7.4" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 185 | 186 | [[package]] 187 | name = "miette" 188 | version = "7.2.0" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" 191 | dependencies = [ 192 | "cfg-if", 193 | "miette-derive", 194 | "owo-colors", 195 | "textwrap", 196 | "thiserror", 197 | "unicode-width 0.1.14", 198 | ] 199 | 200 | [[package]] 201 | name = "miette-derive" 202 | version = "7.2.0" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" 205 | dependencies = [ 206 | "proc-macro2", 207 | "quote", 208 | "syn", 209 | ] 210 | 211 | [[package]] 212 | name = "nonmax" 213 | version = "0.5.5" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" 216 | 217 | [[package]] 218 | name = "num-bigint" 219 | version = "0.4.6" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" 222 | dependencies = [ 223 | "num-integer", 224 | "num-traits", 225 | ] 226 | 227 | [[package]] 228 | name = "num-integer" 229 | version = "0.1.46" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 232 | dependencies = [ 233 | "num-traits", 234 | ] 235 | 236 | [[package]] 237 | name = "num-traits" 238 | version = "0.2.19" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 241 | dependencies = [ 242 | "autocfg", 243 | ] 244 | 245 | [[package]] 246 | name = "once_cell" 247 | version = "1.20.2" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 250 | 251 | [[package]] 252 | name = "outref" 253 | version = "0.5.1" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" 256 | 257 | [[package]] 258 | name = "owo-colors" 259 | version = "4.1.0" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" 262 | 263 | [[package]] 264 | name = "oxc_allocator" 265 | version = "0.34.0" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "b5c86018e4c158687698514494cb02b48b0367fd63e463c7b3846e565df53f46" 268 | dependencies = [ 269 | "allocator-api2", 270 | "bumpalo", 271 | ] 272 | 273 | [[package]] 274 | name = "oxc_ast" 275 | version = "0.34.0" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "761ab257d19f07de7f91bab40fd7b232e6e0c68164b9086434f416e960f28149" 278 | dependencies = [ 279 | "bitflags", 280 | "num-bigint", 281 | "oxc_allocator", 282 | "oxc_ast_macros", 283 | "oxc_estree", 284 | "oxc_regular_expression", 285 | "oxc_span", 286 | "oxc_syntax", 287 | ] 288 | 289 | [[package]] 290 | name = "oxc_ast_macros" 291 | version = "0.34.0" 292 | source = "registry+https://github.com/rust-lang/crates.io-index" 293 | checksum = "a58d52ec144ec10c6c890a5356f7859510aa37e3e2839abd91e419969628302e" 294 | dependencies = [ 295 | "proc-macro2", 296 | "quote", 297 | "syn", 298 | ] 299 | 300 | [[package]] 301 | name = "oxc_cfg" 302 | version = "0.34.0" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "ef63e4a5b26bbc51cae765e1ee2d882f9f8e1e70c1675d28ac264575962b4eb5" 305 | dependencies = [ 306 | "bitflags", 307 | "itertools", 308 | "nonmax", 309 | "oxc_index", 310 | "oxc_syntax", 311 | "petgraph", 312 | "rustc-hash", 313 | ] 314 | 315 | [[package]] 316 | name = "oxc_codegen" 317 | version = "0.34.0" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | checksum = "56b92d5e14118de64196e8e8557aad2bf5ff6fca36e8cd723409fcbaf1d40710" 320 | dependencies = [ 321 | "assert-unchecked", 322 | "bitflags", 323 | "cow-utils", 324 | "daachorse", 325 | "nonmax", 326 | "once_cell", 327 | "oxc_allocator", 328 | "oxc_ast", 329 | "oxc_index", 330 | "oxc_mangler", 331 | "oxc_sourcemap", 332 | "oxc_span", 333 | "oxc_syntax", 334 | "rustc-hash", 335 | ] 336 | 337 | [[package]] 338 | name = "oxc_diagnostics" 339 | version = "0.34.0" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "980c673834c9b2fa15eb2692d418df45c84294771fd364ab53f9abdf4d3e874b" 342 | dependencies = [ 343 | "miette", 344 | "owo-colors", 345 | "rustc-hash", 346 | "textwrap", 347 | "unicode-width 0.2.0", 348 | ] 349 | 350 | [[package]] 351 | name = "oxc_ecmascript" 352 | version = "0.34.0" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "20243d6de6301a5265c85d9d8007bf3044be5311906ba1686570de67743904a3" 355 | dependencies = [ 356 | "num-bigint", 357 | "num-traits", 358 | "oxc_ast", 359 | "oxc_span", 360 | "oxc_syntax", 361 | ] 362 | 363 | [[package]] 364 | name = "oxc_estree" 365 | version = "0.34.0" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "7c30428989d3af8c8d868ec5fdd3e227865bbf7bc875e47785de368968282234" 368 | 369 | [[package]] 370 | name = "oxc_index" 371 | version = "0.34.0" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "2c33b9c780ed9ea47548248450b04da65b1e4e8023157403c37407a3210b675a" 374 | 375 | [[package]] 376 | name = "oxc_mangler" 377 | version = "0.34.0" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "a175f7b6873f7fd9df0de6fe11e5769622f8b8dacc31f9a92339208a0b804934" 380 | dependencies = [ 381 | "itertools", 382 | "oxc_ast", 383 | "oxc_index", 384 | "oxc_semantic", 385 | "oxc_span", 386 | ] 387 | 388 | [[package]] 389 | name = "oxc_parser" 390 | version = "0.34.0" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "22251ed2d64a743481450f64e5d279193165b637dc3dce6f5eaa3eeb494d470b" 393 | dependencies = [ 394 | "assert-unchecked", 395 | "bitflags", 396 | "cow-utils", 397 | "memchr", 398 | "num-bigint", 399 | "num-traits", 400 | "oxc_allocator", 401 | "oxc_ast", 402 | "oxc_diagnostics", 403 | "oxc_ecmascript", 404 | "oxc_regular_expression", 405 | "oxc_span", 406 | "oxc_syntax", 407 | "rustc-hash", 408 | "seq-macro", 409 | ] 410 | 411 | [[package]] 412 | name = "oxc_regular_expression" 413 | version = "0.34.0" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "fbd944dbd4a2b479bda4e29472e1489bb3abd9efbf8a84397fbe3259944b39b4" 416 | dependencies = [ 417 | "oxc_allocator", 418 | "oxc_ast_macros", 419 | "oxc_diagnostics", 420 | "oxc_estree", 421 | "oxc_span", 422 | "phf", 423 | "rustc-hash", 424 | "unicode-id-start", 425 | ] 426 | 427 | [[package]] 428 | name = "oxc_semantic" 429 | version = "0.34.0" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "7693d8e4f47f3b9346dc828fc0ac2f2cc0c795efc633d3c9516981e689c8c655" 432 | dependencies = [ 433 | "assert-unchecked", 434 | "indexmap", 435 | "itertools", 436 | "oxc_allocator", 437 | "oxc_ast", 438 | "oxc_cfg", 439 | "oxc_diagnostics", 440 | "oxc_ecmascript", 441 | "oxc_index", 442 | "oxc_span", 443 | "oxc_syntax", 444 | "phf", 445 | "rustc-hash", 446 | ] 447 | 448 | [[package]] 449 | name = "oxc_sourcemap" 450 | version = "0.34.0" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "6e5eac041bff0e4392790431f54fc9bf8f0d37de68c22cac52f05219dd466d70" 453 | dependencies = [ 454 | "base64-simd", 455 | "cfg-if", 456 | "cow-utils", 457 | "rustc-hash", 458 | "serde", 459 | "serde_json", 460 | ] 461 | 462 | [[package]] 463 | name = "oxc_span" 464 | version = "0.34.0" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "74ea8734bdf818608fe5b92322ef1ad56c56896d83052b5d477f0197d09e7f15" 467 | dependencies = [ 468 | "compact_str", 469 | "miette", 470 | "oxc_allocator", 471 | "oxc_ast_macros", 472 | "oxc_estree", 473 | ] 474 | 475 | [[package]] 476 | name = "oxc_syntax" 477 | version = "0.34.0" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "14ecf5a5134b738088f1a56fbae78aa4e478b07f27b5f4db3c07734e0c9e005a" 480 | dependencies = [ 481 | "assert-unchecked", 482 | "bitflags", 483 | "dashmap", 484 | "nonmax", 485 | "oxc_allocator", 486 | "oxc_ast_macros", 487 | "oxc_estree", 488 | "oxc_index", 489 | "oxc_span", 490 | "phf", 491 | "rustc-hash", 492 | "ryu-js", 493 | "unicode-id-start", 494 | ] 495 | 496 | [[package]] 497 | name = "parking_lot_core" 498 | version = "0.9.10" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 501 | dependencies = [ 502 | "cfg-if", 503 | "libc", 504 | "redox_syscall", 505 | "smallvec", 506 | "windows-targets", 507 | ] 508 | 509 | [[package]] 510 | name = "petgraph" 511 | version = "0.6.5" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" 514 | dependencies = [ 515 | "fixedbitset", 516 | "indexmap", 517 | ] 518 | 519 | [[package]] 520 | name = "phf" 521 | version = "0.11.2" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" 524 | dependencies = [ 525 | "phf_macros", 526 | "phf_shared", 527 | ] 528 | 529 | [[package]] 530 | name = "phf_generator" 531 | version = "0.11.2" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" 534 | dependencies = [ 535 | "phf_shared", 536 | "rand", 537 | ] 538 | 539 | [[package]] 540 | name = "phf_macros" 541 | version = "0.11.2" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" 544 | dependencies = [ 545 | "phf_generator", 546 | "phf_shared", 547 | "proc-macro2", 548 | "quote", 549 | "syn", 550 | ] 551 | 552 | [[package]] 553 | name = "phf_shared" 554 | version = "0.11.2" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" 557 | dependencies = [ 558 | "siphasher", 559 | ] 560 | 561 | [[package]] 562 | name = "proc-macro2" 563 | version = "1.0.89" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" 566 | dependencies = [ 567 | "unicode-ident", 568 | ] 569 | 570 | [[package]] 571 | name = "px-deobfuscator" 572 | version = "0.1.0" 573 | dependencies = [ 574 | "oxc_allocator", 575 | "oxc_ast", 576 | "oxc_codegen", 577 | "oxc_parser", 578 | "oxc_semantic", 579 | "oxc_span", 580 | "oxc_syntax", 581 | "rustc-hash", 582 | ] 583 | 584 | [[package]] 585 | name = "quote" 586 | version = "1.0.37" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 589 | dependencies = [ 590 | "proc-macro2", 591 | ] 592 | 593 | [[package]] 594 | name = "rand" 595 | version = "0.8.5" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 598 | dependencies = [ 599 | "rand_core", 600 | ] 601 | 602 | [[package]] 603 | name = "rand_core" 604 | version = "0.6.4" 605 | source = "registry+https://github.com/rust-lang/crates.io-index" 606 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 607 | 608 | [[package]] 609 | name = "redox_syscall" 610 | version = "0.5.7" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" 613 | dependencies = [ 614 | "bitflags", 615 | ] 616 | 617 | [[package]] 618 | name = "rustc-hash" 619 | version = "2.0.0" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" 622 | 623 | [[package]] 624 | name = "rustversion" 625 | version = "1.0.18" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" 628 | 629 | [[package]] 630 | name = "ryu" 631 | version = "1.0.18" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 634 | 635 | [[package]] 636 | name = "ryu-js" 637 | version = "1.0.1" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "ad97d4ce1560a5e27cec89519dc8300d1aa6035b099821261c651486a19e44d5" 640 | 641 | [[package]] 642 | name = "scopeguard" 643 | version = "1.2.0" 644 | source = "registry+https://github.com/rust-lang/crates.io-index" 645 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 646 | 647 | [[package]] 648 | name = "seq-macro" 649 | version = "0.3.5" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" 652 | 653 | [[package]] 654 | name = "serde" 655 | version = "1.0.214" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" 658 | dependencies = [ 659 | "serde_derive", 660 | ] 661 | 662 | [[package]] 663 | name = "serde_derive" 664 | version = "1.0.214" 665 | source = "registry+https://github.com/rust-lang/crates.io-index" 666 | checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" 667 | dependencies = [ 668 | "proc-macro2", 669 | "quote", 670 | "syn", 671 | ] 672 | 673 | [[package]] 674 | name = "serde_json" 675 | version = "1.0.132" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" 678 | dependencies = [ 679 | "itoa", 680 | "memchr", 681 | "ryu", 682 | "serde", 683 | ] 684 | 685 | [[package]] 686 | name = "siphasher" 687 | version = "0.3.11" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" 690 | 691 | [[package]] 692 | name = "smallvec" 693 | version = "1.13.2" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 696 | 697 | [[package]] 698 | name = "smawk" 699 | version = "0.3.2" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" 702 | 703 | [[package]] 704 | name = "static_assertions" 705 | version = "1.1.0" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 708 | 709 | [[package]] 710 | name = "syn" 711 | version = "2.0.85" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" 714 | dependencies = [ 715 | "proc-macro2", 716 | "quote", 717 | "unicode-ident", 718 | ] 719 | 720 | [[package]] 721 | name = "textwrap" 722 | version = "0.16.1" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" 725 | dependencies = [ 726 | "smawk", 727 | "unicode-linebreak", 728 | "unicode-width 0.1.14", 729 | ] 730 | 731 | [[package]] 732 | name = "thiserror" 733 | version = "1.0.65" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" 736 | dependencies = [ 737 | "thiserror-impl", 738 | ] 739 | 740 | [[package]] 741 | name = "thiserror-impl" 742 | version = "1.0.65" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" 745 | dependencies = [ 746 | "proc-macro2", 747 | "quote", 748 | "syn", 749 | ] 750 | 751 | [[package]] 752 | name = "unicode-id-start" 753 | version = "1.3.1" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | checksum = "2f322b60f6b9736017344fa0635d64be2f458fbc04eef65f6be22976dd1ffd5b" 756 | 757 | [[package]] 758 | name = "unicode-ident" 759 | version = "1.0.13" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 762 | 763 | [[package]] 764 | name = "unicode-linebreak" 765 | version = "0.1.5" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" 768 | 769 | [[package]] 770 | name = "unicode-width" 771 | version = "0.1.14" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 774 | 775 | [[package]] 776 | name = "unicode-width" 777 | version = "0.2.0" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" 780 | 781 | [[package]] 782 | name = "vsimd" 783 | version = "0.8.0" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" 786 | 787 | [[package]] 788 | name = "windows-targets" 789 | version = "0.52.6" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 792 | dependencies = [ 793 | "windows_aarch64_gnullvm", 794 | "windows_aarch64_msvc", 795 | "windows_i686_gnu", 796 | "windows_i686_gnullvm", 797 | "windows_i686_msvc", 798 | "windows_x86_64_gnu", 799 | "windows_x86_64_gnullvm", 800 | "windows_x86_64_msvc", 801 | ] 802 | 803 | [[package]] 804 | name = "windows_aarch64_gnullvm" 805 | version = "0.52.6" 806 | source = "registry+https://github.com/rust-lang/crates.io-index" 807 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 808 | 809 | [[package]] 810 | name = "windows_aarch64_msvc" 811 | version = "0.52.6" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 814 | 815 | [[package]] 816 | name = "windows_i686_gnu" 817 | version = "0.52.6" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 820 | 821 | [[package]] 822 | name = "windows_i686_gnullvm" 823 | version = "0.52.6" 824 | source = "registry+https://github.com/rust-lang/crates.io-index" 825 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 826 | 827 | [[package]] 828 | name = "windows_i686_msvc" 829 | version = "0.52.6" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 832 | 833 | [[package]] 834 | name = "windows_x86_64_gnu" 835 | version = "0.52.6" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 838 | 839 | [[package]] 840 | name = "windows_x86_64_gnullvm" 841 | version = "0.52.6" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 844 | 845 | [[package]] 846 | name = "windows_x86_64_msvc" 847 | version = "0.52.6" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 850 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "px-deobfuscator" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | oxc_allocator = "0.34.0" 8 | oxc_ast = "0.34.0" 9 | oxc_codegen = "0.34.0" 10 | oxc_parser = "0.34.0" 11 | oxc_semantic = "0.34.0" 12 | oxc_span = "0.34.0" 13 | oxc_syntax = "0.34.0" 14 | rustc-hash = "2.0.0" 15 | 16 | [profile.release] 17 | lto = true 18 | codegen-units = 1 19 | opt-level = 3 20 | panic = "abort" 21 | incremental = true 22 | debug = "none" 23 | strip = "symbols" 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

PerimeterX Deobfuscator

3 |

4 | 📜 ChangeLog 5 | · 6 | ⚠️ Report Bug 7 | · 8 | 💡 Request Feature 9 |

10 |
11 | 12 | --- 13 | 14 | ### 📞 Contact 15 | 16 | - Discord: `mciemmmmmmmmmm` 17 | - Telegram: `t.me/sddasdasdas` 18 | 19 | ### ⚙️ Installation 20 | 21 | - Requires: `rust` 22 | 23 | --- 24 | 25 | ### 📝 Description 26 | 27 | Really simple deobfuscator for PerimeterX init.js script. 28 | Right now only deobfuscates strings, might add more features in the future. 29 | 30 | To get the best performance, use the `--release` flag when building. 31 | 32 | --- 33 | 34 | ### 🤷 How to use 35 | 36 | - Build project: 37 | ```bash 38 | cargo build --release 39 | ``` 40 | 41 | - Navigate to the target folder: 42 | ```bash 43 | cd target/release 44 | ``` 45 | 46 | - Run: 47 | ```bash 48 | ./px-deobfuscator 49 | ``` 50 | 51 | --- 52 | 53 | ### 🔥 Features 54 | 55 | - very fast, bcs its rust and oxc 56 | - deobfuscates strings 57 | 58 | --- 59 | 60 | ### 🚀 Milestones 61 | 62 | - [ ] Delete unused variables 63 | - [ ] Handle ints that are stored in objects 64 | - [ ] ... 65 | 66 | --- 67 | 68 | ### 📜 ChangeLog 69 | 70 | ```diff 71 | v1.0.0 ⋮ 04/02/2024 72 | ! Initial Release (alpha version) 73 | ``` 74 | 75 | --- 76 | -------------------------------------------------------------------------------- /input.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mciem/px-deobfuscator/451e172b95bdbbfd51f6194c74e9266a943adcbb/input.js -------------------------------------------------------------------------------- /output.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mciem/px-deobfuscator/451e172b95bdbbfd51f6194c74e9266a943adcbb/output.js -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod transform; 2 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use oxc_allocator::Allocator; 2 | use oxc_codegen::{Codegen, CodegenOptions}; 3 | use oxc_parser::Parser; 4 | use oxc_span::SourceType; 5 | 6 | use std::env::args; 7 | 8 | use px_deobfuscator::transform::Transform; 9 | 10 | pub fn parse(js_code: &str) -> () { 11 | let source_type: SourceType = SourceType::default().with_module(true); 12 | let allocator = Allocator::default(); 13 | 14 | let parsed = Parser::new(&allocator, js_code, source_type).parse(); 15 | 16 | let program = allocator.alloc(parsed.program); 17 | let mut transform = Transform::new(&allocator); 18 | 19 | transform.transform(program); 20 | 21 | let source_text = Codegen::new() 22 | .with_options(CodegenOptions::default()) 23 | .build(program) 24 | .code; 25 | 26 | std::fs::write("output.js", source_text).unwrap(); 27 | } 28 | 29 | fn main() { 30 | let start = std::time::Instant::now(); 31 | 32 | let args = args().collect::>(); 33 | let mut file = &args[1]; // ./px-deobfuscator 34 | if file == "." { 35 | // cargo run . 36 | file = &args[2]; 37 | } 38 | 39 | let js_code = std::fs::read_to_string(file).unwrap(); 40 | 41 | parse(js_code.as_str()); 42 | 43 | println!("Elapsed: {:?}", start.elapsed()); 44 | } 45 | -------------------------------------------------------------------------------- /src/transform/mod.rs: -------------------------------------------------------------------------------- 1 | use oxc_allocator::Allocator; 2 | use oxc_ast::ast::*; 3 | use oxc_ast::AstBuilder; 4 | use oxc_ast::VisitMut; 5 | use std::collections::HashMap; 6 | 7 | mod visit; 8 | 9 | use visit::{functions::FunctionVisitor, strings::StringsVisitor}; 10 | 11 | pub struct Transform<'a> { 12 | pub allocator: &'a Allocator, 13 | pub ast: AstBuilder<'a>, 14 | pub imports: HashMap, 15 | } 16 | 17 | impl<'a> Transform<'a> { 18 | pub fn new(allocator: &'a Allocator) -> Self { 19 | Self { 20 | allocator, 21 | ast: AstBuilder::new(allocator), 22 | imports: HashMap::new(), 23 | } 24 | } 25 | 26 | pub fn get_imports(&self) -> &HashMap { 27 | &self.imports 28 | } 29 | 30 | pub fn transform(&mut self, program: &mut Program<'a>) { 31 | let mut func_visitor = FunctionVisitor::new(self.allocator); 32 | func_visitor.visit_program(program); 33 | 34 | StringsVisitor::new(self.allocator, func_visitor.functions).visit_program(program); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/transform/visit/functions.rs: -------------------------------------------------------------------------------- 1 | use oxc_allocator::Allocator; 2 | use oxc_ast::ast::*; 3 | use oxc_ast::{visit::walk_mut, AstBuilder, VisitMut}; 4 | 5 | use rustc_hash::FxHashMap; 6 | 7 | #[derive(Debug, Default, Clone)] 8 | pub struct Function { 9 | pub offset: usize, 10 | pub list: Vec, 11 | } 12 | 13 | #[derive(Debug)] 14 | pub struct PendingFunction { 15 | pub name: String, 16 | pub offset: usize, 17 | } 18 | 19 | #[derive(Debug)] 20 | pub struct Values { 21 | pub objects: FxHashMap>, 22 | pub ints: FxHashMap, 23 | 24 | pub function: Function, 25 | pub function_name: String, 26 | } 27 | 28 | pub struct FunctionVisitor<'a> { 29 | ast: AstBuilder<'a>, 30 | 31 | pub functions: FxHashMap, 32 | pending_functions: FxHashMap, 33 | anon_function_counter: usize, 34 | lists: FxHashMap>, 35 | } 36 | 37 | impl<'a> FunctionVisitor<'a> { 38 | pub fn new(allocator: &'a Allocator) -> Self { 39 | Self { 40 | ast: AstBuilder::new(allocator), 41 | functions: FxHashMap::default(), 42 | pending_functions: FxHashMap::default(), 43 | anon_function_counter: 0, 44 | lists: FxHashMap::default(), 45 | } 46 | } 47 | } 48 | 49 | impl<'a> VisitMut<'a> for FunctionVisitor<'a> { 50 | fn visit_function(&mut self, it: &mut oxc_ast::ast::Function<'a>, _: oxc_semantic::ScopeFlags) { 51 | let name = if let Some(id) = &it.id { 52 | id.name.to_string() 53 | } else { 54 | // Anonymous function handling 55 | let anon_name = format!("anon_function_{}", self.anon_function_counter); 56 | self.anon_function_counter += 1; 57 | anon_name 58 | }; 59 | 60 | if let Some(body) = &mut it.body { 61 | let mut func_name = ""; 62 | 63 | let mut indices_to_remove = Vec::new(); 64 | let mut i = 0; 65 | for stmt in &body.statements { 66 | match stmt { 67 | Statement::VariableDeclaration(var_decl) => { 68 | for decl in &var_decl.declarations { 69 | if let Some(init) = &decl.init { 70 | match init { 71 | Expression::ArrayExpression(array) => { 72 | let mut list = Vec::new(); 73 | for elem in &array.elements { 74 | if let ArrayExpressionElement::StringLiteral(lit) = elem 75 | { 76 | list.push(lit.value.to_string()); 77 | } 78 | } 79 | 80 | if list.len() > 0 { 81 | self.lists.insert(name.to_string(), list.clone()); 82 | } 83 | 84 | if let Some(func) = 85 | self.pending_functions.get(name.as_str()) 86 | { 87 | self.functions.insert( 88 | func.name.to_string(), 89 | Function { 90 | offset: func.offset, 91 | list, 92 | }, 93 | ); 94 | } 95 | 96 | indices_to_remove.push(i); 97 | } 98 | 99 | Expression::CallExpression(call) => { 100 | if let Expression::Identifier(ident) = &call.callee { 101 | func_name = ident.name.as_str(); 102 | } 103 | } 104 | 105 | _ => {} 106 | } 107 | } 108 | } 109 | } 110 | 111 | Statement::ReturnStatement(retrn) => { 112 | if let Some(arg) = &retrn.argument { 113 | if let Expression::CallExpression(call) = arg { 114 | if let Expression::ParenthesizedExpression(parenth) = &call.callee { 115 | if let Expression::AssignmentExpression(assign) = 116 | &parenth.expression 117 | { 118 | if let Expression::FunctionExpression(func) = &assign.right 119 | { 120 | if let Some(body) = &mut &func.body { 121 | for stmt in &body.statements { 122 | if let Statement::ReturnStatement(retrn) = stmt 123 | { 124 | if let Some(arg) = &retrn.argument { 125 | if let Expression::ComputedMemberExpression(computed) = arg { 126 | if let Expression::AssignmentExpression(assign) = 127 | &computed.expression 128 | { 129 | if let Expression::NumericLiteral(lit) = &assign.right { 130 | if let Some(list) = self.lists.get(func_name) { 131 | self.functions.insert(name.to_string(), Function{ 132 | offset: lit.value as usize, 133 | list: list.to_vec(), 134 | }); 135 | } else { 136 | self.pending_functions.insert(func_name.to_string(), PendingFunction{ 137 | name: name.to_string(), 138 | offset: lit.value as usize, 139 | }); 140 | } 141 | 142 | indices_to_remove.push(i); 143 | } 144 | } 145 | } 146 | } 147 | } 148 | } 149 | } 150 | } 151 | } 152 | } 153 | } 154 | } 155 | } 156 | 157 | _ => {} 158 | } 159 | 160 | i += 1; 161 | } 162 | 163 | for index in indices_to_remove.iter().rev() { 164 | body.statements.remove(*index); 165 | } 166 | } 167 | 168 | walk_mut::walk_function(self, it, oxc_semantic::ScopeFlags::all()); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/transform/visit/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod functions; 2 | pub mod strings; 3 | -------------------------------------------------------------------------------- /src/transform/visit/strings.rs: -------------------------------------------------------------------------------- 1 | use oxc_allocator::Allocator; 2 | use oxc_ast::ast::*; 3 | use oxc_ast::{visit::walk_mut, AstBuilder, VisitMut}; 4 | use oxc_span::SPAN; 5 | 6 | use rustc_hash::FxHashMap; 7 | 8 | use super::functions::{Function, Values}; 9 | 10 | pub struct StringsVisitor<'a> { 11 | ast: AstBuilder<'a>, 12 | 13 | functions: FxHashMap, 14 | anon_function_counter: usize, 15 | proxies: FxHashMap, 16 | 17 | values: FxHashMap, 18 | current_function: Option, 19 | } 20 | 21 | impl<'a> StringsVisitor<'a> { 22 | pub fn new(allocator: &'a Allocator, functions: FxHashMap) -> Self { 23 | Self { 24 | ast: AstBuilder::new(allocator), 25 | functions, 26 | anon_function_counter: 0, 27 | proxies: FxHashMap::default(), 28 | values: FxHashMap::default(), 29 | current_function: None, 30 | } 31 | } 32 | } 33 | 34 | impl<'a> VisitMut<'a> for StringsVisitor<'a> { 35 | fn visit_function(&mut self, it: &mut oxc_ast::ast::Function<'a>, _: oxc_semantic::ScopeFlags) { 36 | let name = if let Some(id) = &it.id { 37 | id.name.to_string() 38 | } else { 39 | // Anonymous function handling 40 | let anon_name = format!("anon_function_{}", self.anon_function_counter); 41 | self.anon_function_counter += 1; 42 | anon_name 43 | }; 44 | 45 | let previous_function = self.current_function.take(); 46 | self.current_function = Some(name.to_string()); 47 | 48 | if let Some(body) = &mut it.body { 49 | let mut ints: FxHashMap = FxHashMap::default(); 50 | let mut objects: FxHashMap> = FxHashMap::default(); 51 | 52 | let mut function = Function::default(); 53 | let mut function_name = String::new(); 54 | 55 | let mut indices_to_remove = Vec::new(); 56 | let mut i = 0; 57 | for stmt in &body.statements { 58 | let mut remove = true; 59 | 60 | if let Statement::VariableDeclaration(var_decl) = stmt { 61 | for decl in var_decl.declarations.iter() { 62 | if let Some(init) = &decl.init { 63 | match init { 64 | Expression::NumericLiteral(lit) => { 65 | if let BindingPatternKind::BindingIdentifier(binding_ident) = 66 | &decl.id.kind 67 | { 68 | ints.insert( 69 | binding_ident.name.to_string(), 70 | lit.value as i64, 71 | ); 72 | } 73 | } 74 | Expression::ObjectExpression(obj) => { 75 | let mut properties: FxHashMap = 76 | FxHashMap::default(); 77 | 78 | for prop in &obj.properties { 79 | if let ObjectPropertyKind::ObjectProperty(obj_prop) = prop { 80 | if let PropertyKey::StaticIdentifier(ident) = 81 | &obj_prop.key 82 | { 83 | if let Expression::NumericLiteral(lit) = 84 | &obj_prop.value 85 | { 86 | properties.insert( 87 | ident.name.to_string(), 88 | lit.value as i64, 89 | ); 90 | } 91 | } 92 | } 93 | } 94 | 95 | if !properties.is_empty() { 96 | if let BindingPatternKind::BindingIdentifier( 97 | binding_ident, 98 | ) = &decl.id.kind 99 | { 100 | objects 101 | .insert(binding_ident.name.to_string(), properties); 102 | } 103 | } 104 | } 105 | Expression::Identifier(ident) => { 106 | if let BindingPatternKind::BindingIdentifier(binding_ident) = 107 | &decl.id.kind 108 | { 109 | function_name = binding_ident.name.to_string(); 110 | } 111 | 112 | if let Some(proxy) = self.proxies.get(ident.name.as_str()) { 113 | if let Some(func) = self.functions.get(proxy) { 114 | function = func.clone(); 115 | } 116 | } else if let Some(func) = 117 | self.functions.get(ident.name.as_str()) 118 | { 119 | function = func.clone(); 120 | } 121 | } 122 | _ => { 123 | remove = false; 124 | } 125 | } 126 | } 127 | } 128 | 129 | if remove { 130 | indices_to_remove.push(i); 131 | } 132 | } 133 | 134 | i += 1; 135 | } 136 | 137 | if !ints.is_empty() || !objects.is_empty() { 138 | self.values.insert( 139 | name.to_string(), 140 | Values { 141 | objects, 142 | ints, 143 | function, 144 | function_name, 145 | }, 146 | ); 147 | } 148 | 149 | for i in indices_to_remove.iter().rev() { 150 | //body.statements.remove(*i); 151 | } 152 | } 153 | 154 | walk_mut::walk_function(self, it, oxc_semantic::ScopeFlags::all()); 155 | self.current_function = previous_function; 156 | } 157 | 158 | fn visit_expression(&mut self, it: &mut Expression<'a>) { 159 | match it { 160 | Expression::CallExpression(call_expr) => { 161 | if let Expression::Identifier(ident) = &call_expr.callee { 162 | if let Some(current_fn) = &self.current_function { 163 | if let Some(values) = self.values.get(current_fn) { 164 | for arg in &call_expr.arguments { 165 | match arg { 166 | Argument::Identifier(ident_2) => { 167 | if let Some(value) = values.ints.get(ident_2.name.as_str()) 168 | { 169 | let index = *value as usize - values.function.offset; 170 | if index < values.function.list.len() { 171 | *it = Expression::StringLiteral(self.ast.alloc( 172 | StringLiteral { 173 | span: SPAN, 174 | value: self.ast.atom( 175 | values.function.list[index].as_str(), 176 | ), 177 | }, 178 | )); 179 | 180 | return; 181 | } 182 | } 183 | } 184 | 185 | Argument::NumericLiteral(lit) => { 186 | if ident.name == values.function_name { 187 | let index = lit.value as usize - values.function.offset; 188 | if index < values.function.list.len() { 189 | *it = Expression::StringLiteral(self.ast.alloc( 190 | StringLiteral { 191 | span: SPAN, 192 | value: self.ast.atom( 193 | values.function.list[index].as_str(), 194 | ), 195 | }, 196 | )); 197 | 198 | return; 199 | } 200 | } 201 | } 202 | 203 | Argument::StaticMemberExpression(member_expr) => { 204 | if let Expression::Identifier(ident_2) = &member_expr.object 205 | { 206 | if let Some(value) = 207 | values.objects.get(ident_2.name.as_str()) 208 | { 209 | if let Some(int) = 210 | value.get(member_expr.property.name.as_str()) 211 | { 212 | let index = 213 | *int as usize - values.function.offset; 214 | if index < values.function.list.len() { 215 | *it = Expression::StringLiteral( 216 | self.ast.alloc(StringLiteral { 217 | span: SPAN, 218 | value: self.ast.atom( 219 | values.function.list[index] 220 | .as_str(), 221 | ), 222 | }), 223 | ); 224 | 225 | return; 226 | } 227 | } 228 | } 229 | } 230 | } 231 | 232 | _ => {} 233 | } 234 | } 235 | } 236 | } 237 | } 238 | } 239 | 240 | _ => {} 241 | } 242 | 243 | walk_mut::walk_expression(self, it); 244 | } 245 | 246 | fn visit_variable_declarator(&mut self, it: &mut VariableDeclarator<'a>) { 247 | if let Some(init) = &it.init { 248 | match init { 249 | Expression::Identifier(ident) => { 250 | if let BindingPatternKind::BindingIdentifier(binding_ident) = &it.id.kind { 251 | if ident.name.len() == 2 && binding_ident.name.len() == 2 { 252 | self.proxies 253 | .insert(binding_ident.name.to_string(), ident.name.to_string()); 254 | 255 | it.init = None; 256 | } 257 | } 258 | } 259 | 260 | _ => {} 261 | } 262 | } 263 | 264 | walk_mut::walk_variable_declarator(self, it); 265 | } 266 | } 267 | --------------------------------------------------------------------------------