diff --git a/package.json b/package.json index 304a4f0..5e34f06 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ }, "scripts": { "build": "rspack build --mode production", - "rewriter:build": "cd rewriter && bash build.sh && cd ..", + "rewriter:build": "cd rewriter/wasm/ && bash build.sh && cd ../../", "dev": "node server.js", "prepack": "RELEASE=1 npm run rewriter:build && npm run build", "pub": "npm publish --no-git-checks --access public", diff --git a/rewriter/Cargo.lock b/rewriter/Cargo.lock index f29fd16..cdd3346 100644 --- a/rewriter/Cargo.lock +++ b/rewriter/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 4 +version = 3 [[package]] name = "ahash" @@ -16,9 +16,15 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "anyhow" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "arrayvec" @@ -46,13 +52,14 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "boa_ast" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a69ee3a749ea36d4e56d92941e7b25076b493d4917c3d155b6cf369e23547d9" +checksum = "2c340fe0f0b267787095cbe35240c6786ff19da63ec7b69367ba338eace8169b" dependencies = [ "bitflags", "boa_interner", "boa_macros", + "boa_string", "indexmap", "num-bigint", "rustc-hash", @@ -60,9 +67,9 @@ dependencies = [ [[package]] name = "boa_engine" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e4559b35b80ceb2e6328481c0eca9a24506663ea33ee1e279be6b5b618b25c" +checksum = "f620c3f06f51e65c0504ddf04978be1b814ac6586f0b45f6019801ab5efd37f9" dependencies = [ "arrayvec", "bitflags", @@ -75,9 +82,9 @@ dependencies = [ "boa_string", "bytemuck", "cfg-if", - "dashmap 5.5.3", - "fast-float", - "hashbrown 0.14.5", + "dashmap", + "fast-float2", + "hashbrown 0.15.2", "icu_normalizer", "indexmap", "intrusive-collections", @@ -99,32 +106,32 @@ dependencies = [ "static_assertions", "tap", "thin-vec", - "thiserror 1.0.64", + "thiserror 2.0.6", "time", ] [[package]] name = "boa_gc" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716406f57d67bc3ac7fd227d5513b42df401dff14a3be22cbd8ee29817225363" +checksum = "2425c0b7720d42d73eaa6a883fbb77a5c920da8694964a3d79a67597ac55cce2" dependencies = [ "boa_macros", "boa_profiler", "boa_string", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "thin-vec", ] [[package]] name = "boa_interner" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e18df2272616e1ba0322a69333d37dbb78797f1aa0595aad9dc41e8ecd06ad9" +checksum = "42407a3b724cfaecde8f7d4af566df4b56af32a2f11f0956f5570bb974e7f749" dependencies = [ "boa_gc", "boa_macros", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "indexmap", "once_cell", "phf", @@ -134,9 +141,9 @@ dependencies = [ [[package]] name = "boa_macros" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240f4126219a83519bad05c9a40bfc0303921eeb571fc2d7e44c17ffac99d3f1" +checksum = "9fd3f870829131332587f607a7ff909f1af5fc523fd1b192db55fbbdf52e8d3c" dependencies = [ "proc-macro2", "quote", @@ -146,16 +153,16 @@ dependencies = [ [[package]] name = "boa_parser" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b59dc05bf1dc019b11478a92986f590cff43fced4d20e866eefb913493e91c" +checksum = "9cc142dac798cdc6e2dbccfddeb50f36d2523bb977a976e19bdb3ae19b740804" dependencies = [ "bitflags", "boa_ast", "boa_interner", "boa_macros", "boa_profiler", - "fast-float", + "fast-float2", "icu_properties", "num-bigint", "num-traits", @@ -165,17 +172,17 @@ dependencies = [ [[package]] name = "boa_profiler" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00ee0645509b3b91abd724f25072649d9e8e65653a78ff0b6e592788a58dd838" +checksum = "4064908e7cdf9b6317179e9b04dcb27f1510c1c144aeab4d0394014f37a0f922" [[package]] name = "boa_string" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae85205289bab1f2c7c8a30ddf0541cf89ba2ff7dbd144feef50bbfa664288d4" +checksum = "7debc13fbf7997bf38bf8e9b20f1ad5e2a7d27a900e1f6039fe244ce30f589b5" dependencies = [ - "fast-float", + "fast-float2", "paste", "rustc-hash", "sptr", @@ -193,9 +200,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" dependencies = [ "bytemuck_derive", ] @@ -258,19 +265,6 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] - [[package]] name = "dashmap" version = "6.1.0" @@ -318,10 +312,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "fast-float" -version = "0.2.0" +name = "fast-float2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" +checksum = "f8eb564c5c7423d25c886fb561d1e4ee69f72354d16918afa32c08811f6b6a55" + +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" [[package]] name = "form_urlencoded" @@ -332,15 +332,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "ftree" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241f9dd9089e67c0b269989e9f884b12a61f68fc07ea8a4be6af8ee164e1abf7" -dependencies = [ - "serde", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -364,9 +355,14 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] [[package]] name = "icu_collections" @@ -488,31 +484,33 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.15.0", -] - -[[package]] -name = "indexset" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6279c421b4feea3fb8e07ea6bd0934b38b641f6601d5f6677062fad15272ed57" -dependencies = [ - "ftree", + "hashbrown 0.15.2", ] [[package]] @@ -547,30 +545,31 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] name = "libc" -version = "0.2.161" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "lock_api" @@ -603,6 +602,18 @@ dependencies = [ "autocfg", ] +[[package]] +name = "native" +version = "0.1.0" +dependencies = [ + "anyhow", + "boa_engine", + "oxc", + "rewriter", + "url", + "urlencoding", +] + [[package]] name = "nonmax" version = "0.5.5" @@ -688,14 +699,13 @@ checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] name = "oxc" -version = "0.37.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fc2b8d593792ca631b252b043dcaa6e65195432922fde0c4d2397cfba25d02d" +checksum = "49d6a3adf0b9cb2baa889d6e978d792c695a83886bb8e623d27ef0996be8f52b" dependencies = [ "oxc_allocator", "oxc_ast", "oxc_diagnostics", - "oxc_index", "oxc_parser", "oxc_regular_expression", "oxc_span", @@ -712,7 +722,7 @@ dependencies = [ "owo-colors", "oxc-miette-derive", "textwrap", - "thiserror 1.0.64", + "thiserror 1.0.69", "unicode-width 0.2.0", ] @@ -729,9 +739,9 @@ dependencies = [ [[package]] name = "oxc_allocator" -version = "0.37.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3137194d5acbead2fd78db27c03b27faa2dfa53628514b1843ae31b2ba304d28" +checksum = "6b1409be2036cb370daee57ec0942c3aa22949da7e269d583767327b9286493e" dependencies = [ "allocator-api2", "bumpalo", @@ -739,9 +749,9 @@ dependencies = [ [[package]] name = "oxc_ast" -version = "0.37.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a142fb8a722e9eb9bf4c9ef37bc7f37e9cc7fc38acba1889d8fb9f2df8ca85a" +checksum = "9353f8fc2507736ce314763ea7e365e25845f431800f8cba196b8365565a6139" dependencies = [ "bitflags", "cow-utils", @@ -757,9 +767,9 @@ dependencies = [ [[package]] name = "oxc_ast_macros" -version = "0.37.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba3432be9886577f6ea36a3ecba6a9b7f2f0bc16aae8a759a0d43f91e0cb4d5" +checksum = "ffc4de384e05599bb89541ebbff124947e326a02783d66d2c2c534ecf58a66b4" dependencies = [ "proc-macro2", "quote", @@ -768,31 +778,44 @@ dependencies = [ [[package]] name = "oxc_diagnostics" -version = "0.37.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2bc8acd3740a2b2b32e1826d966b65f11b9ef5bebb460ebc7cbadf898d7efec" +checksum = "425d8c272e885c3318878acf0a1e985b7bdb8b8e57d695f4ab72e444ba781432" dependencies = [ "oxc-miette", "rustc-hash", ] [[package]] -name = "oxc_estree" -version = "0.37.0" +name = "oxc_ecmascript" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00fbdfd3e49faee78dada84e8cd79fdcf0bbb9a4c3f77a312b823d867e1894b" +checksum = "754e92029d7deb771b5ae9fb628903d0a8da64ca9e61b2e05eb6e01e7613976c" +dependencies = [ + "num-bigint", + "num-traits", + "oxc_ast", + "oxc_span", + "oxc_syntax", +] + +[[package]] +name = "oxc_estree" +version = "0.40.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89eb8a7cf00b2fd6a8e63f38548ae0f9b4f8e21734ef0ae71424104e8503d667" [[package]] name = "oxc_index" -version = "0.37.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4852baa0de945b11def319a618cb31546f71b0a782f22c2e80f32f0ed356804d" +checksum = "5eca5d9726cd0a6e433debe003b7bc88b2ecad0bb6109f0cef7c55e692139a34" [[package]] name = "oxc_parser" -version = "0.37.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf3395e8cad18ec9cda1bd530720d8e2747c5e4767573ba9bb3f0c798d944a4" +checksum = "56fff5de3a699593b5b7e8fd4b30ffedd6d0a9188580afd28745aaab83961e23" dependencies = [ "assert-unchecked", "bitflags", @@ -803,6 +826,7 @@ dependencies = [ "oxc_allocator", "oxc_ast", "oxc_diagnostics", + "oxc_ecmascript", "oxc_regular_expression", "oxc_span", "oxc_syntax", @@ -812,9 +836,9 @@ dependencies = [ [[package]] name = "oxc_regular_expression" -version = "0.37.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab44622a5b4cb09e12eda5f70d9c033c3a820b26f92a1bc86e596e137dc42089" +checksum = "e420360e2c8e83a3eef7c74bbf3a11b375370fa3656c8cee65e4dfe96e26bb93" dependencies = [ "oxc_allocator", "oxc_ast_macros", @@ -828,9 +852,9 @@ dependencies = [ [[package]] name = "oxc_span" -version = "0.37.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "363c6c4329272836347089768df8c87c298f3bd329668306e1f50fc1f8804b7c" +checksum = "e940a7230413a1a138e04c1cf45fea6014d2e995b9c95857252259f5cec9f844" dependencies = [ "compact_str", "oxc-miette", @@ -841,13 +865,12 @@ dependencies = [ [[package]] name = "oxc_syntax" -version = "0.37.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8697e0c9c99df9f5863196f82cb705685d747b1732733b80f5203cf70d46335a" +checksum = "ef274df7ce9d14a3d4f0b9d8453920b7a4f22bfcc1a4ec394233280cca07ed97" dependencies = [ "assert-unchecked", "bitflags", - "dashmap 6.1.0", "nonmax", "oxc_allocator", "oxc_ast_macros", @@ -856,6 +879,7 @@ dependencies = [ "oxc_span", "phf", "rustc-hash", + "ryu-js", "unicode-id-start", ] @@ -928,15 +952,15 @@ dependencies = [ [[package]] name = "pollster" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "powerfmt" @@ -1012,9 +1036,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags", ] @@ -1033,22 +1057,17 @@ dependencies = [ name = "rewriter" version = "0.1.0" dependencies = [ - "boa_engine", - "indexset", - "instant", - "js-sys", "oxc", - "thiserror 2.0.3", + "smallvec", + "thiserror 2.0.6", "url", - "wasm-bindgen", - "web-sys", ] [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustversion" @@ -1082,18 +1101,18 @@ checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -1102,9 +1121,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -1150,9 +1169,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" -version = "2.0.89" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -1195,27 +1214,27 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl 1.0.64", + "thiserror-impl 1.0.69", ] [[package]] name = "thiserror" -version = "2.0.3" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" dependencies = [ - "thiserror-impl 2.0.3", + "thiserror-impl 2.0.6", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -1224,9 +1243,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.3" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" dependencies = [ "proc-macro2", "quote", @@ -1235,9 +1254,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -1259,9 +1278,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -1277,21 +1296,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "toml_datetime" version = "0.6.8" @@ -1309,12 +1313,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "unicode-bidi" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" - [[package]] name = "unicode-id-start" version = "1.3.1" @@ -1323,9 +1321,9 @@ checksum = "2f322b60f6b9736017344fa0635d64be2f458fbc04eef65f6be22976dd1ffd5b" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-linebreak" @@ -1333,15 +1331,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-width" version = "0.1.14" @@ -1356,15 +1345,21 @@ checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf16_iter" version = "1.0.5" @@ -1389,11 +1384,25 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm" +version = "0.1.0" +dependencies = [ + "instant", + "js-sys", + "oxc", + "rewriter", + "thiserror 2.0.6", + "url", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -1402,13 +1411,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn", @@ -1417,9 +1425,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1427,9 +1435,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", @@ -1440,15 +1448,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -1541,9 +1549,9 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -1553,9 +1561,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", @@ -1586,18 +1594,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", diff --git a/rewriter/Cargo.toml b/rewriter/Cargo.toml index 82ae7fa..6bc3435 100644 --- a/rewriter/Cargo.toml +++ b/rewriter/Cargo.toml @@ -1,14 +1,6 @@ -[package] -name = "rewriter" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib"] - -[features] -default = ["debug"] -debug = [] +[workspace] +members = ["native", "rewriter", "wasm"] +resolver = "2" [profile.release] opt-level = 3 @@ -17,18 +9,6 @@ lto = true codegen-units = 1 panic = "abort" -[dependencies] -indexset = "0.5.0" -instant = { version = "0.1.13", features = ["wasm-bindgen"] } -js-sys = "0.3.69" -oxc = "0.37.0" -thiserror = "2.0.3" -url = "2.5.2" -wasm-bindgen = "0.2.95" -web-sys = { version = "0.3.72", features = ["Url"] } +[workspace.dependencies] +oxc = "0.40.1" -[dev-dependencies] -boa_engine = "0.19.0" - -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(wasm_bindgen_unstable_test_coverage)'] } diff --git a/rewriter/build.ps1 b/rewriter/build.ps1 deleted file mode 100644 index 807d5a7..0000000 --- a/rewriter/build.ps1 +++ /dev/null @@ -1,14 +0,0 @@ -set RUSTFLAGS="-C target-feature=+atomics,+bulk-memory,+simd128" -cargo build --lib --target wasm32-unknown-unknown -Z build-std=panic_abort,std --release -wasm-bindgen --weak-refs --target web --out-dir out/ target/wasm32-unknown-unknown/release/rewriter.wasm - -cd .. - -$WASM = "rewriter/out/rewriter_bg.wasm" - -Measure-Command -Expression { wasm-opt -Oz --vacuum --dce --enable-threads --enable-bulk-memory --enable-simd "$WASM" -o rewriter/out/optimized.wasm } - -Write-Output "self.WASM = '" | Out-File -NoNewline -FilePath static/wasm.js -[System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("rewriter/out/optimized.wasm")) | Out-File -Append -NoNewline -FilePath static/wasm.js -Write-Output "';" | Out-File -Append -NoNewline -FilePath static/wasm.js -Write-Output "Rewriter Build Complete!" \ No newline at end of file diff --git a/rewriter/native/Cargo.toml b/rewriter/native/Cargo.toml new file mode 100644 index 0000000..4f3e701 --- /dev/null +++ b/rewriter/native/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "native" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.94" +oxc = { workspace = true } +rewriter = { version = "0.1.0", path = "../rewriter", features = ["debug"] } +url = "2.5.4" +urlencoding = "2.1.3" + +[dev-dependencies] +boa_engine = "0.20.0" diff --git a/rewriter/native/discord.js b/rewriter/native/discord.js new file mode 100644 index 0000000..fc8461f --- /dev/null +++ b/rewriter/native/discord.js @@ -0,0 +1,2 @@ +(this.webpackChunkdiscord_app=this.webpackChunkdiscord_app||[]).push([["23755"],{500923:function(module,exports){"undefined"!=typeof navigator&&function(t,e){module.exports=e()}(0,function(){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){var i,s,r=t.length;for(i=0;i1?i[1]=1:i[1]<=0&&(i[1]=0),HSVtoRGB(i[0],i[1],i[2])}function addBrightnessToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[2]+=e,i[2]>1?i[2]=1:i[2]<0&&(i[2]=0),HSVtoRGB(i[0],i[1],i[2])}function addHueToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,i[0]>1?i[0]-=1:i[0]<0&&(i[0]+=1),HSVtoRGB(i[0],i[1],i[2])}var rgbToHex=function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1===e.length?"0"+e:e;return function(t,e,s){return t<0&&(t=0),e<0&&(e=0),s<0&&(s=0),"#"+i[t]+i[e]+i[s]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return(_typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var dataManager=function(){var t,e,i=1,s=[],r={onmessage:function(){},postMessage:function(e){t({data:e})}},a={postMessage:function(t){r.onmessage({data:t})}};function n(e){if(window.Worker&&window.Blob&&getWebWorker()){var i=new Blob(["var _workerSelf = self; self.onmessage = ",e.toString()],{type:"text/javascript"});return new Worker(URL.createObjectURL(i))}return t=e,r}function o(){!e&&((e=n(function(t){function e(){function t(e,i){var n,o,h,l,p,f,c=e.length;for(o=0;o=0;e-=1)if("sh"===t[e].ty){if(t[e].ks.k.i)a(t[e].ks.k);else for(i=0,s=t[e].ks.k.length;ii[0])||!(i[0]>t[0])&&(!!(t[1]>i[1])||!(i[1]>t[1])&&(!!(t[2]>i[2])||!(i[2]>t[2])&&null))}var o=function(){var t=[4,4,14];function e(t){var e=t.t.d;t.t.d={k:[{s:e,t:0}]}}function i(t){var i,s=t.length;for(i=0;i=0;i-=1)if("sh"===t[i].ty){if(t[i].ks.k.i)t[i].ks.k.c=t[i].closed;else for(s=0,r=t[i].ks.k.length;s500)&&(this._imageLoaded(),clearInterval(i)),e+=1}).bind(this),50)}function a(e){var i=s(e,this.assetsPath,this.path),r=createNS("image");isSafari?this.testImageLoaded(r):r.addEventListener("load",this._imageLoaded,!1),r.addEventListener("error",(function(){a.img=t,this._imageLoaded()}).bind(this),!1),r.setAttributeNS("http://www.w3.org/1999/xlink","href",i),this._elementHelper.append?this._elementHelper.append(r):this._elementHelper.appendChild(r);var a={img:r,assetData:e};return a}function n(e){var i=s(e,this.assetsPath,this.path),r=createTag("img");r.crossOrigin="anonymous",r.addEventListener("load",this._imageLoaded,!1),r.addEventListener("error",(function(){a.img=t,this._imageLoaded()}).bind(this),!1),r.src=i;var a={img:r,assetData:e};return a}function o(t){var e={assetData:t},i=s(t,this.assetsPath,this.path);return dataManager.loadData(i,(function(t){e.img=t,this._footageLoaded()}).bind(this),(function(){e.img={},this._footageLoaded()}).bind(this)),e}function h(t,e){this.imagesLoadedCb=e;var i,s=t.length;for(i=0;ithis.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,s=this.animationData.layers,r=s.length,a=t.layers,n=a.length;for(i=0;ithis.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&!!this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){if(!t||this.name===t)!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){if(!t||this.name===t)!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){if(!t||this.name===t)!0===this.isPaused?this.play():this.pause()},AnimationItem.prototype.stop=function(t){if(!t||this.name===t)this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0)},AnimationItem.prototype.getMarkerData=function(t){for(var e,i=0;i=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,!this.checkSegments(e%this.totalFrames)&&(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):!this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)&&(i=!0,e=this.totalFrames-1):e<0?!this.checkSegments(e%this.totalFrames)&&(this.loop&&!(this.playCount--<=0&&!0!==this.loop)?(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0):(i=!0,e=0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFramee&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var i,s=t.length;for(i=0;i=0;i-=1)e[i].animation.destroy(t)}function P(t,e,i){var s,r=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=r.length;for(s=0;s0?i=h:e=h;while(Math.abs(o)>a&&++l=r?g(t,p,e,i):0===f?p:d(t,a,a+h,e,i)}},t}(),pooling=function(){return{double:function t(t){return t.concat(createSizedArray(t.length))}}}(),poolFactory=function(){return function(t,e,i){var s=0,r=t,a=createSizedArray(r);return{newElement:function t(){var t;return s?(s-=1,t=a[s]):t=e(),t},release:function t(t){s===r&&(a=pooling.double(a),r*=2),i&&i(t),a[s]=t,s+=1}}}}(),bezierLengthPool=function(){return poolFactory(8,function t(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}})}(),segmentsLengthPool=function(){return poolFactory(8,function t(){return{lengths:[],totalLength:0}},function t(t){var e,i=t.lengths.length;for(e=0;e-.001&&n<.001}function i(i,s,r,a,n,o,h,l,p){if(0===r&&0===o&&0===p)return e(i,s,a,n,h,l);var f,c=t.sqrt(t.pow(a-i,2)+t.pow(n-s,2)+t.pow(o-r,2)),m=t.sqrt(t.pow(h-i,2)+t.pow(l-s,2)+t.pow(p-r,2)),u=t.sqrt(t.pow(h-a,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=c>m?c>u?c-m-u:u-m-c:u>m?u-m-c:m-c-u)>-.0001&&f<1e-4}var s=function(){return function(t,e,i,s){var r,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,c=[],m=[],u=bezierLengthPool.newElement();for(r=0,n=i.length;rn?-1:1,l=!0;l;)if(s[a]<=n&&s[a+1]>n?(o=(n-s[a])/(s[a+1]-s[a]),l=!1):a+=h,a<0||a>=r-1){if(a===r-1)return i[a];l=!1}return i[a]+(i[a+1]-i[a])*o}function l(e,i,s,r,a,n){var o=h(a,n),l=1-o;return[t.round((l*l*l*e[0]+(o*l*l+l*o*l+l*l*o)*s[0]+(o*o*l+l*o*o+o*l*o)*r[0]+o*o*o*i[0])*1e3)/1e3,t.round((l*l*l*e[1]+(o*l*l+l*o*l+l*l*o)*s[1]+(o*o*l+l*o*o+o*l*o)*r[1]+o*o*o*i[1])*1e3)/1e3]}var p=createTypedArray("float32",8);return{getSegmentsLength:r,getNewSegment:function e(e,i,s,r,a,n,o){a<0?a=0:a>1&&(a=1);var l,f=h(a,o),c=h(n=n>1?1:n,o),m=e.length,u=1-f,d=1-c,g=u*u*u,y=f*u*u*3,v=f*f*u*3,b=f*f*f,x=u*u*d,_=f*u*d+u*f*d+u*u*c,k=f*f*d+u*f*c+f*u*c,C=f*f*c,P=u*d*d,A=f*d*d+u*c*d+u*d*c,w=f*c*d+u*c*c+f*d*c,S=f*c*c,D=d*d*d,T=c*d*d+d*c*d+d*d*c,M=c*c*d+d*c*c+c*d*c,E=c*c*c;for(l=0;l=v.t-o){y.h&&(y=v),h=0;break}if(v.t-o>t){h=l;break}l=c||t=c?u.points.length-1:0;for(x=0,_=u.points[d].point.length;x<_;x+=1)g[x]=u.points[d].point[x]}else{b.__fnct?A=b.__fnct:(A=BezierFactory.getBezierEasing(y.o.x,y.o.y,y.i.x,y.i.y,y.n).get,b.__fnct=A),k=A((t-m)/(c-m));var g,y,v,b,x,_,k,C,P,A,w,S,D=u.segmentLength*k,T=e.lastFrame=T&&D=c)g[0]=w[0],g[1]=w[1],g[2]=w[2];else if(t<=m)g[0]=y.s[0],g[1]=y.s[1],g[2]=y.s[2];else{;quaternionToEuler(g,slerp(createQuaternion(y.s),createQuaternion(w),(t-m)/(c-m)))}}else for(l=0;l=c?k=1:t1e-6?(a=Math.sin(s=Math.acos(r)),n=Math.sin((1-i)*s)/a,o=Math.sin(i*s)/a):(n=1-i,o=i),h[0]=n*l+o*m,h[1]=n*p+o*u,h[2]=n*f+o*d,h[3]=n*c+o*g,h}function quaternionToEuler(t,e){var i=e[0],s=e[1],r=e[2],a=e[3],n=Math.atan2(2*s*a-2*i*r,1-2*s*s-2*r*r),o=Math.asin(2*i*s+2*r*a),h=Math.atan2(2*i*a-2*s*r,1-2*i*i-2*r*r);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}function createQuaternion(t){var e=t[0]*degToRads,i=t[1]*degToRads,s=t[2]*degToRads,r=Math.cos(e/2),a=Math.cos(i/2),n=Math.cos(s/2),o=Math.sin(e/2),h=Math.sin(i/2),l=Math.sin(s/2),p=r*a*n-o*h*l;return[o*h*n+r*a*l,o*a*n+r*h*l,r*h*n-o*a*l,p]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=i&&t>=i||this._caching.lastFrame=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var s=this.interpolateValue(t,this._caching);this.pv=s}return this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,mathAbs(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else{for(var i=0,s=this.v.length;i1e-5&&(this.v[i]=e,this._mdf=!0),i+=1}}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&!!this.effectsSequence.length){if(this.lock){this.setVValue(this.pv);return}this.lock=!0,this._mdf=this._isFirstFrame;var t,e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t=this._maxLength&&this.doubleArrayLength(),i){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[s]||a[s]&&!r)&&(a[s]=pointPool.newElement()),a[s][0]=t,a[s][1]=e},ShapePath.prototype.setTripleAt=function(t,e,i,s,r,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,s,"o",n,o),this.setXYAt(r,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t,e=new ShapePath;e.setPathData(this.c,this._length);var i=this.v,s=this.o,r=this.i,a=0;this.c&&(e.setTripleAt(i[0][0],i[0][1],r[0][0],r[0][1],s[0][0],s[0][1],0,!1),a=1);var n=this._length-1,o=this._length;for(t=a;t=r[r.length-1].t-this.offsetTime)a=r[r.length-1].s?r[r.length-1].s[0]:r[r.length-2].e[0],o=!0;else{for(var a,n,o,h,l,p,f,c,m,u,d,g,y,v=s,b=r.length-1,x=!0;x&&(u=r[v],!((d=r[v+1]).t-this.offsetTime>t));){;v=d.t-this.offsetTime?c=1:ts&&e>s))&&(this._caching.lastIndex=r0||t>-.000001&&t<0?s(t*e)/e:t}function I(){var t=this.props;return"matrix("+F(t[0])+","+F(t[1])+","+F(t[4])+","+F(t[5])+","+F(t[12])+","+F(t[13])+")"}return function(){this.reset=r,this.rotate=a,this.rotateX=n,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=c,this.setTransform=m,this.translate=u,this.transform=d,this.multiply=g,this.applyToPoint=_,this.applyToX=k,this.applyToY=C,this.applyToZ=P,this.applyToPointArray=T,this.applyToTriplePoints=D,this.applyToPointStringified=M,this.toCSS=E,this.to2dCSS=I,this.clone=b,this.cloneFromProps=x,this.equals=v,this.inversePoints=S,this.inversePoint=w,this.getInverseMatrix=A,this._t=this.transform,this.isIdentity=y,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return(_typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&t>1&&setDefaultCurveSegments(t);getDefaultCurveSegments()>=50?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),i=0;i=1?l.push({s:t-1,e:e-1}):(l.push({s:t,e:1}),l.push({s:0,e:e-1}));var p=[],f=l.length;for(a=0;as+i)&&(o=n.s*r<=s?0:(n.s*r-s)/i,h=n.e*r>=s+i?1:(n.e*r-s)/i,p.push([o,h]));return!p.length&&p.push([0,0]),p},TrimModifier.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e1?1+e:this.s.v<0?0+e:this.s.v+e,a>(n=this.e.v>1?1+e:this.e.v<0?0+e:this.e.v+e)){var i=a;a=n,n=i}a=1e-4*Math.round(1e4*a),n=1e-4*Math.round(1e4*n),this.sValue=a,this.eValue=n}else a=this.sValue,n=this.eValue;var s=this.shapes.length,r=0;if(n===a)for(h=0;h=0;h-=1)if((u=this.shapes[h]).shape._mdf){for((d=u.localShapeCollection).releaseShapes(),2===this.m&&s>1?(g=this.calculateShapeEdges(a,n,u.totalShapeLength,x,r),x+=u.totalShapeLength):g=[[v,b]],p=g.length,l=0;l=1?y.push({s:u.totalShapeLength*(v-1),e:u.totalShapeLength*(b-1)}):(y.push({s:u.totalShapeLength*v,e:u.totalShapeLength}),y.push({s:0,e:u.totalShapeLength*(b-1)}));var _=this.addShapes(u,y[0]);if(y[0].s!==y[0].e){if(y.length>1){if(u.shape.paths.shapes[u.shape.paths._length-1].c){var k=_.pop();this.addPaths(_,d),_=this.addShapes(u,y[1],k)}else this.addPaths(_,d),_=this.addShapes(u,y[1])}this.addPaths(_,d)}}u.shape.paths=d}}},TrimModifier.prototype.addPaths=function(t,e){var i,s=t.length;for(i=0;ie.e){i.c=!1;break}else e.s<=u&&e.e>=u+n.addedLength?(this.addSegment(c[s].v[r-1],c[s].o[r-1],c[s].i[r],c[s].v[r],i,o,g),g=!1):(l=bez.getNewSegment(c[s].v[r-1],c[s].v[r],c[s].o[r-1],c[s].i[r],(e.s-u)/n.addedLength,(e.e-u)/n.addedLength,h[r-1]),this.addSegmentFromArray(l,i,o,g),g=!1,i.c=!1),u+=n.addedLength,o+=1;if(c[s].c&&h.length){if(n=h[r-1],u<=e.e){var y=h[r-1].addedLength;e.s<=u&&e.e>=u+y?(this.addSegment(c[s].v[r-1],c[s].o[r-1],c[s].i[0],c[s].v[0],i,o,g),g=!1):(l=bez.getNewSegment(c[s].v[r-1],c[s].v[0],c[s].o[r-1],c[s].i[0],(e.s-u)/y,(e.e-u)/y,h[r-1]),this.addSegmentFromArray(l,i,o,g),g=!1,i.c=!1)}else i.c=!1;u+=n.addedLength,o+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),u>e.e)break;s=this.p.keyframes[this.p.keyframes.length-1].t?(s=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),r=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/i,0)):(s=this.p.pv,r=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){s=[],r=[];var s,r,a=this.px,n=this.py;a._caching.lastFrame+a.offsetTime<=a.keyframes[0].t?(s[0]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),s[1]=n.getValueAtTime((n.keyframes[0].t+.01)/i,0),r[0]=a.getValueAtTime(a.keyframes[0].t/i,0),r[1]=n.getValueAtTime(n.keyframes[0].t/i,0)):a._caching.lastFrame+a.offsetTime>=a.keyframes[a.keyframes.length-1].t?(s[0]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),s[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/i,0),r[0]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0),r[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/i,0)):(s=[a.pv,n.pv],r[0]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime),r[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/i,n.offsetTime))}else s=r=t;this.v.rotate(-Math.atan2(s[1]-r[1],s[0]-r[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}}function s(){if(this.appliedTransformations=0,this.pre.reset(),this.a.effectsSequence.length)return;this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1;if(!this.s.effectsSequence.length){this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2;if(this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?!this.r.effectsSequence.length&&(this.pre.rotate(-this.r.v),this.appliedTransformations=4):!this.rz.effectsSequence.length&&!this.ry.effectsSequence.length&&!this.rx.effectsSequence.length&&!this.or.effectsSequence.length&&(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}}function r(){}function a(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0}function n(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var s,r=e.or.k.length;for(s=0;s=Math.abs(t)}function lerp(t,e,i){return t*(1-i)+e*i}function lerpPoint(t,e,i){return[lerp(t[0],e[0],i),lerp(t[1],e[1],i)]}function quadRoots(t,e,i){if(0===t)return[];var s=e*e-4*t*i;if(s<0)return[];var r=-e/(2*t);if(0===s)return[r];var a=Math.sqrt(s)/(2*t);return[r-a,r+a]}function polynomialCoefficients(t,e,i,s){return[-t+3*e-3*i+s,3*t-6*e+3*i,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,i,s,r){r&&pointEqual(t,e)&&(e=lerpPoint(t,s,1/3)),r&&pointEqual(i,s)&&(i=lerpPoint(t,s,2/3));var a=polynomialCoefficients(t[0],e[0],i[0],s[0]),n=polynomialCoefficients(t[1],e[1],i[1],s[1]);this.a=[a[0],n[0]],this.b=[a[1],n[1]],this.c=[a[2],n[2]],this.d=[a[3],n[3]],this.points=[t,e,i,s]}function extrema(t,e){var i=t.points[0][e],s=t.points[t.points.length-1][e];if(i>s){var r=s;s=i,i=r}for(var a=quadRoots(3*t.a[e],2*t.b[e],t.c[e]),n=0;n0&&a[n]<1){var o=t.point(a[n])[e];os&&(s=o)}return{min:i,max:s}}function intersectData(t,e,i){var s=t.boundingBox();return{cx:s.cx,cy:s.cy,width:s.width,height:s.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)=a||t.width<=s&&t.height<=s&&e.width<=s&&e.height<=s){r.push([t.t,e.t]);return}var n=splitData(t),o=splitData(e);intersectsImpl(n[0],o[0],i+1,s,r,a),intersectsImpl(n[0],o[1],i+1,s,r,a),intersectsImpl(n[1],o[0],i+1,s,r,a),intersectsImpl(n[1],o[1],i+1,s,r,a)}}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,i,s){var r=[t[0],t[1],1],a=[e[0],e[1],1],n=[i[0],i[1],1],o=[s[0],s[1],1],h=crossProduct(crossProduct(r,a),crossProduct(n,o));return floatZero(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function polarOffset(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,i,s,r,a,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*s*r,p=e[1]-Math.sin(i)*s*r;t.setTripleAt(l,p,l+Math.cos(o)*a,p-Math.sin(o)*a,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){var i=[e[0]-t[0],e[1]-t[1]],s=-(.5*Math.PI);return[Math.cos(s)*i[0]-Math.sin(s)*i[1],Math.sin(s)*i[0]+Math.cos(s)*i[1]]}function getProjectingAngle(t,e){var i=0===e?t.length()-1:e-1,s=(e+1)%t.length(),r=getPerpendicularVector(t.v[i],t.v[s]);return Math.atan2(0,1)-Math.atan2(r[1],r[0])}function zigZagCorner(t,e,i,s,r,a,n){var o=getProjectingAngle(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,c=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[i%e._length],o,n,s,c/((r+1)*2),f/((r+1)*2),a)}function zigZagSegment(t,e,i,s,r,a){for(var n=0;n1&&e.length>1&&(r=getIntersection(t[0],e[e.length-1])))?[[t[0].split(r[0])[0]],[e[e.length-1].split(r[1])[1]]]:[i,s]}function pruneIntersections(t){for(var e,i=1;i1&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var i,s,r,a,n=t.inflectionPoints();if(0===n.length)return[offsetSegment(t,e)];if(1===n.length||floatEqual(n[1],1))return i=(r=t.split(n[0]))[0],s=r[1],[offsetSegment(i,e),offsetSegment(s,e)];i=(r=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return a=(r=r[1].split(o))[0],s=r[1],[offsetSegment(i,e),offsetSegment(a,e),offsetSegment(s,e)]}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",s="normal",r=e.length,a=0;a0;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e0?Math.floor(u):Math.ceil(u),y=this.pMatrix.props,v=this.rMatrix.props,b=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var x=0;if(u>0){for(;xg;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),x-=1;d&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-d,!0),x-=d)}for(r=1===this.data.m?0:this._currentCopies-1,a=1===this.data.m?1:-1,n=this._currentCopies;n;){if(l=(s=(i=this.elemsData[r].it)[i.length-1].transform.mProps.v.props).length,i[i.length-1].transform.mProps._mdf=!0,i[i.length-1].transform.op._mdf=!0,i[i.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(r/(this._currentCopies-1)),0!==x){for((0!==r&&1===a||r!==this._currentCopies-1&&-1===a)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15]),this.matrix.transform(b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7],b[8],b[9],b[10],b[11],b[12],b[13],b[14],b[15]),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),h=0;h0&&s<1?[e]:[];return[e-s,e+s].filter(function(t){return t>0&&t<1})},PolynomialBezier.prototype.split=function(t){if(t<=0)return[singlePoint(this.points[0]),this];if(t>=1)return[this,singlePoint(this.points[this.points.length-1])];var e=lerpPoint(this.points[0],this.points[1],t),i=lerpPoint(this.points[1],this.points[2],t),s=lerpPoint(this.points[2],this.points[3],t),r=lerpPoint(e,i,t),a=lerpPoint(i,s,t),n=lerpPoint(r,a,t);return[new PolynomialBezier(this.points[0],e,r,n,!0),new PolynomialBezier(n,a,s,this.points[3],!0)]},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var s=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,s,i),s},PolynomialBezier.shapeSegment=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[i],t.v[i],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[i],t.i[i],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,i,s){var r=t._length,a=shapePool.newElement();if(a.c=t.c,!t.c&&(r-=1),0===r)return a;var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,i,s,n);for(var h=0;h=0;r-=1)n=PolynomialBezier.shapeSegmentInverted(t,r),l.push(offsetSegmentSplit(n,e));l=pruneIntersections(l);var p=null,f=null;for(r=0;r0&&(h=!1),h){var l=createTag("style");l.setAttribute("f-forigin",i[a].fOrigin),l.setAttribute("f-origin",i[a].origin),l.setAttribute("f-family",i[a].fFamily),l.type="text/css",l.innerText="@font-face {font-family: "+i[a].fFamily+"; font-style: normal; src: url('"+i[a].fPath+"');}",e.appendChild(l)}}else if("g"===i[a].fOrigin||1===i[a].origin){for(o=0,n=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');o=55296&&i<=56319){var s=t.charCodeAt(1);s>=56320&&s<=57343&&(e=(i-55296)*1024+s-56320+65536)}return e}function k(t,e){var i=t.toString(16)+e.toString(16);return -1!==f.indexOf(i)}function C(t){return t===h}function P(t){return t===o}function A(t){var e=_(t);return!!(e>=l)&&!!(e<=p)||!1}function w(t){return A(t.substr(0,2))&&A(t.substr(2,2))}function S(t){return -1!==i.indexOf(t)}function D(t,e){var i=_(t.substr(e,2));if(i!==s)return!1;var o=0;for(e+=2;o<5;){if((i=_(t.substr(e,2)))n)return!1;o+=1,e+=2}return _(t.substr(e,2))===r}function T(){this.isLoaded=!0}var M=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};M.isModifier=k,M.isZeroWidthJoiner=C,M.isFlagEmoji=w,M.isRegionalCode=A,M.isCombinedCharacter=S,M.isRegionalFlag=D,M.isVariationSelector=P,M.BLACK_FLAG_CODE_POINT=s;var E={addChars:y,addFonts:g,getCharData:v,getFontByName:x,measureText:b,checkLoadedFonts:u,setIsLoaded:T};return M.prototype=E,M}();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,i,s=this.layers.length;for(this.completeLayers=!0,e=s-1;e>=0;e-=1)!this.elements[e]&&(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},BaseRenderer.prototype.createCamera=function(){throw Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t0&&(this.maskElement.setAttribute("id",h),this.element.maskedElement.setAttribute(p,"url("+getLocationHref()+"#"+h+")"),s.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,s=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i1&&(a+=" C"+e.o[s-1][0]+","+e.o[s-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==a){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),i.elem.setAttribute("d",n)),i.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=function(){var t={};function e(t,e){var i=createNS("filter");return i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%")),i}function i(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1"),t}return t.createFilter=e,t.createAlphaToLuminanceFilter=i,t}(),featureSupport=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),registeredEffects$1={},idPrefix="filter_result_";function SVGEffects(t){var e,i,s="SourceGraphic",r=t.data.ef?t.data.ef.length:0,a=createElementID(),n=filtersFactory.createFilter(a,!0),o=0;for(e=0,this.filters=[];e=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,s=e.length;i.01)return!1;i+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s){for(var t=0,e=this.data.k.k.length;t0;)h=s.transformers[u].mProps._mdf||h,m-=1,u-=1;if(h)for(m=g-s.styles[p].lvl,u=s.transformers.length-1;m>0;)c.multiply(s.transformers[u].mProps.v),m-=1,u-=1}else c=t;if(n=(f=s.sh.paths)._length,h){for(a=0,o="";a=1?v=.99:v<=-1&&(v=-.99);var b=o*v,x=Math.cos(y+e.a.v)*b+p[0],_=Math.sin(y+e.a.v)*b+p[1];h.setAttribute("fx",x),h.setAttribute("fy",_),l&&!e.g._collapsable&&(e.of.setAttribute("fx",x),e.of.setAttribute("fy",_))}}function h(t,e,i){var s=e.style,r=e.d;r&&(r._mdf||i)&&r.dashStr&&(s.pElem.setAttribute("stroke-dasharray",r.dashStr),s.pElem.setAttribute("stroke-dashoffset",r.dashoffset[0])),e.c&&(e.c._mdf||i)&&s.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&s.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(s.pElem.setAttribute("stroke-width",e.w.v),s.msElem&&s.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function t(t){switch(t.ty){case"fl":return a;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return r;case"tr":return i;case"no":return s;default:return null}}}}();function SVGShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function LetterProps(t,e,i,s,r,a){this.o=t,this.sw=e,this.sc=i,this.fc=s,this.m=r,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!s,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),!this.searchProperty()&&this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,i,s,r=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(i=0;i1&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e=0;o-=1){if((c=this.searchProcessedElement(t[o]))?e[o]=i[c-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)c?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],r),t[o]._render&&e[o].style.pElem.parentNode!==s&&s.appendChild(e[o].style.pElem),d.push(e[o].style);else if("gr"===t[o].ty){if(c)for(h=0,l=e[o].it.length;h1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&!!this.effectsSequence.length||!!t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e,i=this.currentData,s=this.keysIndex;if(this.lock){this.setCurrentData(this.currentData);return}this.lock=!0,this._mdf=!1;var r=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(e=0;ee);){;i+=1}return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,i,s=[],r=0,a=t.length,n=!1,o=!1,h="";r=55296&&e<=56319?FontManager.isRegionalFlag(t,r)?h=t.substr(r,14):(i=t.charCodeAt(r+1))>=56320&&i<=57343&&(FontManager.isModifier(e,i)?(h=t.substr(r,2),n=!0):h=FontManager.isFlagEmoji(t.substr(r,4))?t.substr(r,4):t.substr(r,2)):e>56319?(i=t.charCodeAt(r+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(s[s.length-1]+=h,n=!1):s.push(h),r+=h.length;return s},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e=this.elem.globalData.fontManager,i=this.data,s=[],r=0,a=i.m.g,n=0,o=0,h=0,l=[],p=0,f=0,c=e.getFontByName(t.f),m=0,u=getFontProperties(c);t.fWeight=u.weight,t.fStyle=u.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),y=t.finalText.length,t.finalLineHeight=t.lh;var d=t.tr/1e3*t.finalSize;if(t.sz){for(var g,y,v,b,x,_,k,C,P,A,w=!0,S=t.sz[0],D=t.sz[1];w;){A=this.buildFinalText(t.t),P=0,p=0,y=A.length,d=t.tr/1e3*t.finalSize;var T=-1;for(g=0;gS&&" "!==A[g]?(-1===T?y+=1:g=T,P+=t.finalLineHeight||1.2*t.finalSize,A.splice(g,T===g?1:0,"\r"),T=-1,p=0):p+=m+d;P+=c.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&Df?p:f,p=-2*d,b="",v=!0,h+=1):b=I,e.chars?(k=e.getCharData(I,c.fStyle,e.getFontByName(t.f).fFamily),m=v?0:k.w*t.finalSize/100):m=e.measureText(b,t.f,t.finalSize)," "===I?M+=m+d:(p+=m+d+M,M=0),s.push({l:m,an:m,add:n,n:v,anIndexes:[],val:b,line:h,animatorJustifyOffset:0}),2==a){if(n+=m,""===b||" "===b||g===y-1){for((""===b||" "===b)&&(n-=m);o<=g;)s[o].an=n,s[o].ind=r,s[o].extra=m,o+=1;r+=1,n=0}}else if(3==a){if(n+=m,""===b||g===y-1){for(""===b&&(n-=m);o<=g;)s[o].an=n,s[o].ind=r,s[o].extra=m,o+=1;n=0,r+=1}}else s[r].ind=r,s[r].extra=0,r+=1;if(t.l=s,f=p>f?p:f,l.push(p),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=f,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=l;var E=i.a;_=E.length;var F=[];for(x=0;x<_;x+=1){for((L=E[x]).a.sc&&(t.strokeColorAnim=!0),L.a.sw&&(t.strokeWidthAnim=!0),(L.a.fc||L.a.fh||L.a.fs||L.a.fb)&&(t.fillColorAnim=!0),V=0,R=L.s.b,g=0;g0?r=this.ne.v/100:a=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=BezierFactory.getBezierEasing(r,a,n,o).get,l=0,p=this.finalS,f=this.finalE,c=this.data.sh;if(2===c)l=h(l=f===p?s>=f?1:0:t(0,e(.5/(f-p)+(s-p)/(f-p),1)));else if(3===c)l=h(l=f===p?s>=f?0:1:1-t(0,e(.5/(f-p)+(s-p)/(f-p),1)));else if(4===c)f===p?l=0:(l=t(0,e(.5/(f-p)+(s-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===c){if(f===p)l=0;else{var m=f-p,u=-m/2+(s=e(t(0,s+.5-p),f-p)),d=m/2;l=Math.sqrt(1-u*u/(d*d))}l=h(l)}else 6===c?l=h(l=f===p?0:(1+Math.cos(Math.PI+2*Math.PI*(s=e(t(0,s+.5-p),f-p))/(f-p)))/2):(s>=i(p)&&(l=s-p<0?t(0,e(e(f,1)-(p-s),1)):t(0,e(f-s,1))),l=h(l));if(100!==this.sm.v){var g=.01*this.sm.v;0===g&&(g=1e-8);var y=.5-.5*g;l1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,s=this.s.v/e+i,r=this.e.v/e+i;if(s>r){var a=s;s=r,r=a}this.finalS=s,this.finalE=r}},extendPrototype([DynamicPropertyContainer],s),{getTextSelectorProp:function t(t,e,i){return new s(t,e,i)}}}();function TextAnimatorDataProperty(t,e,i){var s={propType:!1},r=PropertyFactory.getProp,a=e.a;this.a={r:a.r?r(t,a.r,0,degToRads,i):s,rx:a.rx?r(t,a.rx,0,degToRads,i):s,ry:a.ry?r(t,a.ry,0,degToRads,i):s,sk:a.sk?r(t,a.sk,0,degToRads,i):s,sa:a.sa?r(t,a.sa,0,degToRads,i):s,s:a.s?r(t,a.s,1,.01,i):s,a:a.a?r(t,a.a,1,0,i):s,o:a.o?r(t,a.o,0,.01,i):s,p:a.p?r(t,a.p,1,0,i):s,sw:a.sw?r(t,a.sw,0,0,i):s,sc:a.sc?r(t,a.sc,1,0,i):s,fc:a.fc?r(t,a.fc,1,0,i):s,fh:a.fh?r(t,a.fh,0,0,i):s,fs:a.fs?r(t,a.fs,0,.01,i):s,fb:a.fb?r(t,a.fb,0,.01,i):s,t:a.t?r(t,a.t,0,0,i):s},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function TextAnimatorProperty(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,s=PropertyFactory.getProp;for(t=0;t=F+to||!O?(q=(F+to-L)/I.partialLength,l=z.point[0]+(I.point[0]-z.point[0])*q,p=z.point[1]+(I.point[1]-z.point[1])*q,C.translate(-x[0]*w[T].an*.005,-(.01*(x[1]*X))),B=!1):O&&(L+=I.partialLength,(R+=1)>=O.length&&(R=0,N[V+=1]?O=N[V].points:W.v.c?(R=0,O=N[V=0].points):(L-=I.partialLength,O=null)),O&&(z=I,G=(I=O[R]).partialLength));h=w[T].an/2-w[T].add,C.translate(-h,0,0)}else h=w[T].an/2-w[T].add,C.translate(-h,0,0),C.translate(-x[0]*w[T].an*.005,-x[1]*X*.01,0);for(r=0;rd?this.textSpans[d].span:createNS(a?"g":"text"),m<=d){if(y.setAttribute("stroke-linecap","butt"),y.setAttribute("stroke-linejoin","round"),y.setAttribute("stroke-miterlimit","4"),this.textSpans[d].span=y,a){var u=createNS("g");y.appendChild(u),this.textSpans[d].childSpan=u}this.textSpans[d].span=y,this.layerElement.appendChild(y)}y.style.display="inherit"}if(n.reset(),h&&(r[d].n&&(l=-c,p+=t.yOffset+(f?1:0),f=!1),this.applyTextPropertiesToMatrix(t,n,r[d].line,l,p),l+=(r[d].l||0)+c),a){if(1===(v=this.globalData.fontManager.getCharData(t.finalText[d],e.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily)).t)b=new SVGCompElement(v.data,this.globalData,this);else{var d,g,y,v,b,x=emptyShapeData;v.data&&v.data.shapes&&(x=this.buildShapeData(v.data,t.finalSize)),b=new SVGShapeElement(x,this.globalData,this)}if(this.textSpans[d].glyph){var _=this.textSpans[d].glyph;this.textSpans[d].childSpan.removeChild(_.layerElement),_.destroy()}this.textSpans[d].glyph=b,b._debug=!0,b.prepareFrame(0),b.renderFrame(),this.textSpans[d].childSpan.appendChild(b.layerElement),1===v.t&&this.textSpans[d].childSpan.setAttribute("transform","scale("+t.finalSize/100+","+t.finalSize/100+")")}else h&&y.setAttribute("transform","translate("+n.props[12]+","+n.props[13]+")"),y.textContent=r[d].val,y.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}h&&y&&y.setAttribute("d",o)}else{var k=this.textContainer,C="start";switch(t.j){case 1:C="end";break;case 2:C="middle";break;default:C="start"}k.setAttribute("text-anchor",C),k.setAttribute("letter-spacing",c);var P=this.buildTextContents(t.finalText);for(d=0,g=P.length,p=t.ps?t.ps[1]+t.ascent:0;d=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e=0;e-=1)(this.completeLayers||this.elements[e])&&(this.elements[e].prepareFrame(this.renderedFrame-this.layers[e].st),this.elements[e]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t=0;i-=1)t.finalTransform.multiply(t.transforms[i].transform.mProps.v);t._mdf=r},processSequences:function(t){var e,i=this.sequenceList.length;for(e=0;e=1){this.buffers=[];var t=this.globalData.canvasContext,e=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(e);var i=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(i),this.data.tt>=3&&!document._isProxy&&assetLoader.loadLumaCanvas()}this.canvasContext=this.globalData.canvasContext,this.transformCanvas=this.globalData.transformCanvas,this.renderableEffectsManager=new CVEffects(this),this.searchEffectTransforms()},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=getBlendMode(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this),this.transformEffects=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT)},hideElement:function(){!this.hidden&&(!this.isInRange||this.isTransparent)&&(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},clearCanvas:function(t){t.clearRect(this.transformCanvas.tx,this.transformCanvas.ty,this.transformCanvas.w*this.transformCanvas.sx,this.transformCanvas.h*this.transformCanvas.sy)},prepareLayer:function(){if(this.data.tt>=1){var t=this.buffers[0].getContext("2d");this.clearCanvas(t),t.drawImage(this.canvasContext.canvas,0,0),this.currentTransform=this.canvasContext.getTransform(),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform)}},exitLayer:function(){if(this.data.tt>=1){var t=this.buffers[1],e=t.getContext("2d");if(this.clearCanvas(e),e.drawImage(this.canvasContext.canvas,0,0),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform),this.comp.getElementById("tp"in this.data?this.data.tp:this.data.ind-1).renderFrame(!0),this.canvasContext.setTransform(1,0,0,1,0,0),this.data.tt>=3&&!document._isProxy){var i=assetLoader.getLumaCanvas(this.canvasContext.canvas);i.getContext("2d").drawImage(this.canvasContext.canvas,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.drawImage(i,0,0)}this.canvasContext.globalCompositeOperation=operationsMap[this.data.tt],this.canvasContext.drawImage(t,0,0),this.canvasContext.globalCompositeOperation="destination-over",this.canvasContext.drawImage(this.buffers[0],0,0),this.canvasContext.setTransform(this.currentTransform),this.canvasContext.globalCompositeOperation="source-over"}},renderFrame:function(t){if(!this.hidden&&!this.data.hd&&(1!==this.data.td||!!t)){this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.setBlendMode();var e=0===this.data.ty;this.prepareLayer(),this.globalData.renderer.save(e),this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity),this.renderInnerContent(),this.globalData.renderer.restore(e),this.exitLayer(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1)}},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var i={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},s={};if("fl"===t.ty||"st"===t.ty?(s.c=PropertyFactory.getProp(this,t.c,1,255,this),!s.c.k&&(i.co="rgb("+bmFloor(s.c.v[0])+","+bmFloor(s.c.v[1])+","+bmFloor(s.c.v[2])+")")):("gf"===t.ty||"gs"===t.ty)&&(s.s=PropertyFactory.getProp(this,t.s,1,null,this),s.e=PropertyFactory.getProp(this,t.e,1,null,this),s.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),s.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),s.g=new GradientProperty(this,t.g,this)),s.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"===t.ty||"gs"===t.ty){if(i.lc=lineCapEnum[t.lc||2],i.lj=lineJoinEnum[t.lj||2],1==t.lj&&(i.ml=t.ml),s.w=PropertyFactory.getProp(this,t.w,0,null,this),!s.w.k&&(i.wi=s.w.v),t.d){var r=new DashProperty(this,t.d,"canvas",this);s.d=r,!s.d.k&&(i.da=s.d.dashArray,i.do=s.d.dashoffset[0])}}else i.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(i),s.style=i,s},CVShapeElement.prototype.createGroupElement=function(){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){var e=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},CVShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;var t,e=this.itemsData.length;for(t=0;t=0;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=i[h-1]:t[a]._shouldRender=s,"fl"===t[a].ty||"st"===t[a].ty||"gf"===t[a].ty||"gs"===t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],u),c.push(e[a].style);else if("gr"===t[a].ty){if(h)for(n=0,o=e[a].it.length;n=0;r-=1)"tr"===e[r].ty?(a=i[r].transform,this.renderShapeTransform(t,a)):"sh"===e[r].ty||"el"===e[r].ty||"rc"===e[r].ty||"sr"===e[r].ty?this.renderPath(e[r],i[r]):"fl"===e[r].ty?this.renderFill(e[r],i[r],a):"st"===e[r].ty?this.renderStroke(e[r],i[r],a):"gf"===e[r].ty||"gs"===e[r].ty?this.renderGradientFill(e[r],i[r],a):"gr"===e[r].ty?this.renderShape(a,e[r].it,i[r].it):e[r].ty;s&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var i,s,r,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(r=0;r=1?f=.99:f<=-1&&(f=-.99);var c=l*f,m=Math.cos(p+e.a.v)*c+o[0],u=Math.sin(p+e.a.v)*c+o[1];r=n.createRadialGradient(m,u,0,o[0],o[1],l)}var d=t.g.p,g=e.g.c,y=1;for(a=0;ao&&"xMidYMid slice"===h||nr&&"meet"===o||ar&&"slice"===o)?this.transformCanvas.tx=(i-this.transformCanvas.w*(s/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===l&&(ar&&"slice"===o)?this.transformCanvas.tx=(i-this.transformCanvas.w*(s/this.transformCanvas.h))*this.renderConfig.dpr:this.transformCanvas.tx=0,"YMid"===p&&(a>r&&"meet"===o||ar&&"meet"===o||a=0;t-=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRendererBase.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||!!e)&&!this.destroyed&&-1!==t){this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var i,s=this.layers.length;for(!this.completeLayers&&this.checkLayers(t),i=s-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].prepareFrame(t-this.layers[i].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),i=s-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){var i=this.createItem(this.layers[t],this,this.globalData);e[t]=i,i.initExpressions()}},CanvasRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;)this.pendingElements.pop().checkParenting()},CanvasRendererBase.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRendererBase.prototype.show=function(){this.animationItem.container.style.display="block"},CVContextData.prototype.duplicate=function(){var t=2*this._length,e=0;for(e=this._length;e=0;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVCompElement.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},extendPrototype([CanvasRendererBase],CanvasRenderer),CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},HBaseElement.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=createTag(this.data.tg||"div"),this.data.hasMask?(this.svgElement=createNS("svg"),this.layerElement=createNS("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,styleDiv(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new CVEffects(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t=this.transformedElement?this.transformedElement.style:{};if(this.finalTransform._matMdf){var e=this.finalTransform.mat.toCSS();t.transform=e,t.webkitTransform=e}this.finalTransform._opMdf&&(t.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){if(!this.data.hd&&!this.hidden)this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1)},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},HBaseElement.prototype.getBaseElement=SVGBaseElement.prototype.getBaseElement,HBaseElement.prototype.destroyBaseElement=HBaseElement.prototype.destroy,HBaseElement.prototype.buildElementParenting=BaseRenderer.prototype.buildElementParenting,extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],HSolidElement),HSolidElement.prototype.createContent=function(){var t;this.data.hasMask?((t=createNS("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=createTag("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,HSolidElement,SVGShapeElement,HBaseElement,HierarchyElement,FrameElement,RenderableElement],HShapeElement),HShapeElement.prototype._renderShapeFrame=HShapeElement.prototype.renderInnerContent,HShapeElement.prototype.createContent=function(){var t;if(this.baseElement.style.fontSize=0,this.data.hasMask)this.layerElement.appendChild(this.shapesContainer),t=this.svgElement;else{t=createNS("svg");var e=this.comp.data?this.comp.data:this.globalData.compSize;t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)}this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},HShapeElement.prototype.getTransformedPoint=function(t,e){var i,s=t.length;for(i=0;i0&&h<1&&r[c].push(this.calculateF(h,t,e,i,s,c)):(l=n*n-4*o*a)>=0&&((p=(-n+bmSqrt(l))/(2*a))>0&&p<1&&r[c].push(this.calculateF(p,t,e,i,s,c)),(f=(-n-bmSqrt(l))/(2*a))>0&&f<1&&r[c].push(this.calculateF(f,t,e,i,s,c))));this.shapeBoundingBox.left=bmMin.apply(null,r[0]),this.shapeBoundingBox.top=bmMin.apply(null,r[1]),this.shapeBoundingBox.right=bmMax.apply(null,r[0]),this.shapeBoundingBox.bottom=bmMax.apply(null,r[1])},HShapeElement.prototype.calculateF=function(t,e,i,s,r,a){return bmPow(1-t,3)*e[a]+3*bmPow(1-t,2)*t*i[a]+3*(1-t)*bmPow(t,2)*s[a]+bmPow(t,3)*r[a]},HShapeElement.prototype.calculateBoundingBox=function(t,e){var i,s=t.length;for(i=0;ii&&(i=r)}i*=t.mult}else i=t.v*t.mult;e.x-=i,e.xMax+=i,e.y-=i,e.yMax+=i},HShapeElement.prototype.currentBoxContains=function(t){return this.currentBBox.x<=t.x&&this.currentBBox.y<=t.y&&this.currentBBox.width+this.currentBBox.x>=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},HShapeElement.prototype.renderInnerContent=function(){if(this._renderShapeFrame(),!this.hidden&&(this._isFirstFrame||this._mdf)){var t=this.tempBoundingBox,e=999999;if(t.x=e,t.xMax=-e,t.y=e,t.yMax=-e,this.calculateBoundingBox(this.itemsData,t),t.width=t.xMax=0;i-=1){var e=this.hierarchy[i].finalTransform.mProp;this.mat.translate(-e.p.v[0],-e.p.v[1],e.p.v[2]),this.mat.rotateX(-e.or.v[0]).rotateY(-e.or.v[1]).rotateZ(e.or.v[2]),this.mat.rotateX(-e.rx.v).rotateY(-e.ry.v).rotateZ(e.rz.v),this.mat.scale(1/e.s.v[0],1/e.s.v[1],1/e.s.v[2]),this.mat.translate(e.a.v[0],e.a.v[1],e.a.v[2])}if(this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a){var i,s,r,a=Math.sqrt(Math.pow((r=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]])[0],2)+Math.pow(r[1],2)+Math.pow(r[2],2)),n=[r[0]/a,r[1]/a,r[2]/a],o=Math.sqrt(n[2]*n[2]+n[0]*n[0]),h=Math.atan2(n[1],o),l=Math.atan2(n[0],-n[2]);this.mat.rotateY(l).rotateX(-h)}this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var p=!this._prevMat.equals(this.mat);if((p||this.pe._mdf)&&this.comp.threeDElements){for(i=0,s=this.comp.threeDElements.length;i=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},HybridRendererBase.prototype.createThreeDContainer=function(t,e){var i,s,r=createTag("div");styleDiv(r);var a=createTag("div");if(styleDiv(a),"3d"===e){(i=r.style).width=this.globalData.compSize.w+"px",i.height=this.globalData.compSize.h+"px";var n="50% 50%";i.webkitTransformOrigin=n,i.mozTransformOrigin=n,i.transformOrigin=n,s=a.style;var o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";s.transform=o,s.webkitTransform=o}r.appendChild(a);var h={container:a,perspectiveElem:r,startPos:t,endPos:t,type:e};return this.threeDElements.push(h),h},HybridRendererBase.prototype.build3dContainers=function(){var t,e,i=this.layers.length,s="";for(t=0;t=0;t-=1)this.resizerElem.appendChild(this.threeDElements[t].perspectiveElem)},HybridRendererBase.prototype.addTo3dContainer=function(t,e){for(var i=0,s=this.threeDElements.length;in?(t=r/this.globalData.compSize.w,e=r/this.globalData.compSize.w,i=0,s=(a-this.globalData.compSize.h*(r/this.globalData.compSize.w))/2):(t=a/this.globalData.compSize.h,e=a/this.globalData.compSize.h,i=(r-this.globalData.compSize.w*(a/this.globalData.compSize.h))/2,s=0);var o=this.resizerElem.style;o.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+i+","+s+",0,1)",o.transform=o.webkitTransform},HybridRendererBase.prototype.renderFrame=SVGRenderer.prototype.renderFrame,HybridRendererBase.prototype.hide=function(){this.resizerElem.style.display="none"},HybridRendererBase.prototype.show=function(){this.resizerElem.style.display="block"},HybridRendererBase.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else{var t,e=this.globalData.compSize.w,i=this.globalData.compSize.h,s=this.threeDElements.length;for(t=0;t=p;)t/=2,e/=2,i>>>=1;return(t+i)/e};return x.int32=function(){return 0|b.g(4)},x.quick=function(){return b.g(4)/4294967296},x.double=x,g(v(b.S),t),(s.pass||n||function(t,i,s,r){return(r&&(r.S&&u(r,b),t.state=function(){return u(b,{})}),s)?(e[o]=t,i):t})(x,c,"global"in s?s.global:this==e,s.state)}function m(t){var e,i=t.length,s=this,a=0,n=s.i=s.j=0,o=s.S=[];for(!i&&(t=[i++]);ai){var s=i;i=e,e=s}return Math.min(Math.max(t,e),i)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);!e&&(e=helperLengthArray);var i,s=Math.min(t.length,e.length),r=0;for(i=0;i.5?l/(2-n-o):l/(n+o),n){case s:e=(r-a)/l+(r1&&(i-=1),i<1/6)?t+(e-t)*6*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function hslToRgb(t){var e,i,s,r=t[0],a=t[1],n=t[2];if(0===a)e=n,s=n,i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,r+1/3),i=hue2rgb(h,o,r),s=hue2rgb(h,o,r-1/3)}return[e,i,s,t[3]]}function linear(t,e,i,s,r){if((void 0===s||void 0===r)&&(s=e,r=i,e=0,i=1),i=i)return r;var o=i===e?0:(t-e)/(i-e);if(!s.length)return s+(r-s)*o;var h=s.length,l=createTypedArray("float32",h);for(a=0;a1){for(s=0;s1?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(r)){var o,h=r.length,l=createTypedArray("float32",h);for(o=0;odata.k[e].t&&tdata.k[e+1].t-t?(i=e+2,s=data.k[e+1].t):(i=e+1,s=data.k[e].t);break}}-1===i&&(i=e+1,s=data.k[e].t)}}else i=0,s=0;var a={};return a.index=i,a.time=s/elem.comp.globalData.frameRate,a}function key(t){if(!data.k.length||"number"==typeof data.k[0])throw Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var e,i,s,r=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(i=0,s=r.length;il.length-1)&&(e=l.length-1),s=p-(r=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-r)/s)%2!=0)return this.getValueAtTime((s-(h-r)%s+r)/this.comp.globalData.frameRate,0)}else if("offset"===t){var f=this.getValueAtTime(r/this.comp.globalData.frameRate,0),c=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(((h-r)%s+r)/this.comp.globalData.frameRate,0),u=Math.floor((h-r)/s);if(this.pv.length){for(a=0,n=(o=Array(f.length)).length;a=p)return this.pv;if(i?(s=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p),r=p+s):((!e||e>l.length-1)&&(e=l.length-1),s=(r=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/s)%2==0)return this.getValueAtTime(((p-h)%s+p)/this.comp.globalData.frameRate,0)}else if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(r/this.comp.globalData.frameRate,0),m=this.getValueAtTime((s-(p-h)%s+p)/this.comp.globalData.frameRate,0),u=Math.floor((p-h)/s)+1;if(this.pv.length){for(a=0,n=(o=Array(f.length)).length;a1?(n-a)/(e-1):1,h=0,l=0;for(i=this.pv.length?createTypedArray("float32",this.pv.length):0;hn){var p=o,f=s.c&&o===h-1?0:o+1,c=(n-l)/a[o].addedLength;i=bez.getPointInSegment(s.v[p],s.v[f],s.o[p],s.i[f],c,a[o]);break}l+=a[o].addedLength;o+=1}return!i&&(i=s.c?[s.v[0][0],s.v[0][1]]:[s.v[s._length-1][0],s.v[s._length-1][1]]),i},vectorOnPath:function(t,e,i){1==t?t=this.v.c:0==t&&(t=.999);var s=this.pointOnPath(t,e),r=this.pointOnPath(t+.001,e),a=r[0]-s[0],n=r[1]-s[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===i?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([p],h),extendPrototype([p],l),l.prototype.getValueAtTime=o,l.prototype.initiateExpression=ExpressionManager.initiateExpression;var f=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,i,s,r){var a=f(t,e,i,s,r);return a.propertyIndex=e.ix,a.lock=!1,3===i?expressionHelpers.searchExpressions(t,e.pt,a):4===i&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}function initialize$1(){addPropertyDecorator()}function addDecorator(){function t(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}TextProperty.prototype.getExpressionValue=function(t,e){var i=this.calculateExpression(e);if(t.t!==i){var s={};return this.copyData(s,t),s.t=i.toString(),s.__complete=!1,s}return t},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=t}function initialize(){addDecorator()}function SVGComposableEffect(){}SVGComposableEffect.prototype={createMergeNode:function(t,e){var i,s,r=createNS("feMerge");for(r.setAttribute("result",t),s=0;s=p?u<0?s:r:s+m*Math.pow((a-t)/u,1/i),f[c]=n,c+=1,o+=256/(h-1);return f.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e,i=this.filterManager.effectElements;this.feFuncRComposed&&(t||i[3].p._mdf||i[4].p._mdf||i[5].p._mdf||i[6].p._mdf||i[7].p._mdf)&&(e=this.getTableValue(i[3].p.v,i[4].p.v,i[5].p.v,i[6].p.v,i[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||i[10].p._mdf||i[11].p._mdf||i[12].p._mdf||i[13].p._mdf||i[14].p._mdf)&&(e=this.getTableValue(i[10].p.v,i[11].p.v,i[12].p.v,i[13].p.v,i[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||i[17].p._mdf||i[18].p._mdf||i[19].p._mdf||i[20].p._mdf||i[21].p._mdf)&&(e=this.getTableValue(i[17].p.v,i[18].p.v,i[19].p.v,i[20].p.v,i[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||i[24].p._mdf||i[25].p._mdf||i[26].p._mdf||i[27].p._mdf||i[28].p._mdf)&&(e=this.getTableValue(i[24].p.v,i[25].p.v,i[26].p.v,i[27].p.v,i[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA&&(t||i[31].p._mdf||i[32].p._mdf||i[33].p._mdf||i[34].p._mdf||i[35].p._mdf)&&(e=this.getTableValue(i[31].p.v,i[32].p.v,i[33].p.v,i[34].p.v,i[35].p.v),this.feFuncA.setAttribute("tableValues",e))}},extendPrototype([SVGComposableEffect],SVGDropShadowEffect),SVGDropShadowEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){if((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),t||this.filterManager.effectElements[0].p._mdf){var e=this.filterManager.effectElements[0].p.v;this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])))}if((t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf){var i=this.filterManager.effectElements[3].p.v,s=(this.filterManager.effectElements[2].p.v-90)*degToRads,r=i*Math.cos(s),a=i*Math.sin(s);this.feOffset.setAttribute("dx",r),this.feOffset.setAttribute("dy",a)}}};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,i){this.initialized=!1,this.filterManager=e,this.filterElem=t,this.elem=i,i.matteElement=createNS("g"),i.matteElement.appendChild(i.layerElement),i.matteElement.appendChild(i.transformedElement),i.baseElement=i.matteElement}function SVGGaussianBlurEffect(t,e,i,s){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;var r=createNS("feGaussianBlur");r.setAttribute("result",s),t.appendChild(r),this.feGaussianBlur=r}function TransformEffect(){}function SVGTransformEffect(t,e){this.init(e)}function CVTransformEffect(t){this.init(t)}return SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,i=_svgMatteSymbols.length;e String { + encode(&str).to_string() +} + +fn dorewrite(data: &str) -> Result { + rewrite( + data, + Config { + prefix: "/scrammedjet/".to_string(), + encoder: Box::new(encode_string), + + base: Url::from_str("https://google.com/glorngle/si.js").context("invalid base")?, + sourcetag: "glongle1".to_string(), + + wrapfn: "$wrap".to_string(), + wrapthisfn: "$gwrap".to_string(), + importfn: "$import".to_string(), + rewritefn: "$rewrite".to_string(), + metafn: "$meta".to_string(), + setrealmfn: "$setrealm".to_string(), + pushsourcemapfn: "$pushsourcemap".to_string(), + + capture_errors: true, + do_sourcemaps: true, + scramitize: false, + strict_rewrites: true, + }, + ) + .context("failed to rewrite file") +} + +fn main() -> Result<()> { + let file = env::args().nth(1).unwrap_or_else(|| "test.js".to_string()); + let data = fs::read_to_string(file).context("failed to read file")?; + + let res = dorewrite(&data)?; + + let source = Arc::new( + NamedSource::new(data, "https://google.com/glorngle/si.js").with_language("javascript"), + ); + eprintln!("errors:"); + for err in res.errors { + eprintln!("{}", err.with_source_code(source.clone())); + } + + println!("changes: {:#?}", res.changes); + + println!( + "rewritten:\n{}", + String::from_utf8(res.js).context("failed to parse rewritten js")? + ); + + Ok(()) +} + +#[cfg(test)] +mod test { + use std::fs; + + use boa_engine::{ + js_str, js_string, + object::ObjectInitializer, + property::{Attribute, PropertyDescriptorBuilder}, + Context, NativeFunction, Source, + }; + + use crate::dorewrite; + + #[test] + fn google() { + let source_text = include_str!("../sample/google.js"); + dorewrite(source_text).unwrap(); + } + + #[test] + fn test() { + let files = fs::read_dir("./tests").unwrap(); + + for file in files { + if !file + .as_ref() + .unwrap() + .file_name() + .to_str() + .unwrap() + .ends_with(".js") + { + continue; + } + + let content = fs::read_to_string(file.unwrap().path()).unwrap(); + + let mut context = Context::default(); + + let window = ObjectInitializer::new(&mut context).build(); + context + .register_global_property(js_str!("window"), window, Attribute::READONLY) + .unwrap(); + context + .global_object() + .define_property_or_throw( + js_str!("location"), + PropertyDescriptorBuilder::new() + .get( + NativeFunction::from_copy_closure(|_, _, _| { + Ok(js_str!("location").into()) + }) + .to_js_function(context.realm()), + ) + .set( + NativeFunction::from_copy_closure(|_, _, _| { + panic!("fail: window.location got set") + }) + .to_js_function(context.realm()), + ) + .build(), + &mut context, + ) + .unwrap(); + + context + .register_global_callable( + js_string!("fail"), + 0, + NativeFunction::from_copy_closure(|_, _, _| { + panic!("fail"); + }), + ) + .unwrap(); + + let result = context + .eval(Source::from_bytes( + br#" +function $wrap(val) { + if (val === window || val === "location" || val === globalThis) return ""; + + return val; +} + +function assert(val) { + if (!val) fail(); +} + +function check(val) { + if (val === window || val === "location") fail(); +} + "#, + )) + .unwrap(); + + let rewritten = dorewrite(&content).unwrap(); + println!("{:?}", rewritten); + + context.eval(Source::from_bytes(&rewritten.js)).unwrap(); + println!("PASS"); + } + } +} diff --git a/rewriter/test.js b/rewriter/native/test.js similarity index 99% rename from rewriter/test.js rename to rewriter/native/test.js index 65aeee8..633f544 100644 --- a/rewriter/test.js +++ b/rewriter/native/test.js @@ -25,5 +25,3 @@ function f() { return import("x") } let window = (1, window); - - diff --git a/rewriter/rewriter/Cargo.toml b/rewriter/rewriter/Cargo.toml new file mode 100644 index 0000000..94a64e7 --- /dev/null +++ b/rewriter/rewriter/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "rewriter" +version = "0.1.0" +edition = "2021" + +[dependencies] +oxc = { workspace = true } +smallvec = "1.13.2" +thiserror = "2.0.6" +url = "2.5.4" + +[features] +debug = [] diff --git a/rewriter/rewriter/src/cfg.rs b/rewriter/rewriter/src/cfg.rs new file mode 100644 index 0000000..41af644 --- /dev/null +++ b/rewriter/rewriter/src/cfg.rs @@ -0,0 +1,24 @@ +use url::Url; + +pub struct Config { + pub prefix: String, + pub sourcetag: String, + pub base: Url, + + pub wrapfn: String, + pub wrapthisfn: String, + pub importfn: String, + pub rewritefn: String, + pub setrealmfn: String, + pub metafn: String, + pub pushsourcemapfn: String, + + pub encoder: EncodeFn, + + pub capture_errors: bool, + pub scramitize: bool, + pub do_sourcemaps: bool, + pub strict_rewrites: bool, +} + +pub type EncodeFn = Box String>; diff --git a/rewriter/rewriter/src/changes.rs b/rewriter/rewriter/src/changes.rs new file mode 100644 index 0000000..cf25308 --- /dev/null +++ b/rewriter/rewriter/src/changes.rs @@ -0,0 +1,277 @@ +use oxc::{ + ast::ast::AssignmentOperator, + span::{CompactStr, Span}, +}; +use smallvec::{smallvec, SmallVec}; + +use crate::cfg::Config; + +#[derive(Debug, PartialEq, Eq)] +pub enum JsChange { + /// `(cfg.wrapfn(ident))` | `cfg.wrapfn(ident)` + WrapFn { + span: Span, + ident: CompactStr, + wrapped: bool, + }, + /// `cfg.setrealmfn({}).ident` + SetRealmFn { + span: Span, + ident: CompactStr, + }, + /// `cfg.wrapthis(this)` + WrapThisFn { + span: Span, + }, + /// `(cfg.importfn("cfg.base"))` + ImportFn { + span: Span, + }, + /// `cfg.metafn("cfg.base")` + MetaFn { + span: Span, + }, + + /// `$scramerr(name)` + ScramErr { + span: Span, + name: CompactStr, + }, + /// `$scramitize(span)` + Scramitize { + span: Span, + }, + + /// `eval(cfg.rewritefn(inner))` + Eval { + span: Span, + inner: Span, + }, + /// `((t)=>$scramjet$tryset(name,"op",t)||(name op t))(rhsspan)` + Assignment { + name: CompactStr, + entirespan: Span, + rhsspan: Span, + op: AssignmentOperator, + }, + /// `ident,` -> `ident: cfg.wrapfn(ident)` + ShorthandObj { + span: Span, + name: CompactStr, + }, + SourceTag { + span: Span, + tagname: String, + }, + + // don't use for anything static, only use for stuff like rewriteurl + Replace { + span: Span, + text: String, + }, + Delete { + span: Span, + }, +} + +type Changes<'a> = SmallVec<[&'a str; 8]>; + +enum JsChangeInner<'a> { + Wrap { + /// Changes to add before span + before: Changes<'a>, + /// Span to add in between + span: &'a Span, + /// Changes to add after span + after: Changes<'a>, + }, + Replace(Changes<'a>), +} + +impl JsChange { + pub fn get_span(&self) -> &Span { + match self { + Self::WrapFn { span, .. } => span, + Self::SetRealmFn { span, .. } => span, + Self::WrapThisFn { span } => span, + Self::ImportFn { span } => span, + Self::MetaFn { span } => span, + + Self::ScramErr { span, .. } => span, + Self::Scramitize { span } => span, + + Self::Eval { span, .. } => span, + Self::Assignment { entirespan, .. } => entirespan, + Self::ShorthandObj { span, .. } => span, + Self::SourceTag { span, .. } => span, + + Self::Replace { span, .. } => span, + Self::Delete { span } => span, + } + } + + // returns (bunch of stuff to add before, option) + // bunch of stuff to add after should only be some if it's not a replace op + fn to_inner<'a>(&'a self, cfg: &'a Config) -> JsChangeInner<'a> { + match self { + Self::WrapFn { ident, wrapped, .. } => JsChangeInner::Replace(if *wrapped { + smallvec!["(", cfg.wrapfn.as_str(), "(", ident.as_str(), ")", ")"] + } else { + smallvec![cfg.wrapfn.as_str(), "(", ident.as_str(), ")"] + }), + Self::SetRealmFn { ident, .. } => { + JsChangeInner::Replace(smallvec![cfg.setrealmfn.as_str(), "({}).", ident.as_str()]) + } + Self::WrapThisFn { .. } => { + JsChangeInner::Replace(smallvec![cfg.wrapthisfn.as_str(), "(this)"]) + } + Self::ImportFn { .. } => JsChangeInner::Replace(smallvec![ + "(", + cfg.importfn.as_str(), + "(\"", + cfg.base.as_str(), + "\"))" + ]), + Self::MetaFn { .. } => JsChangeInner::Replace(smallvec![ + cfg.metafn.as_str(), + "(\"", + cfg.base.as_str(), + "\")" + ]), + + Self::ScramErr { name, .. } => { + JsChangeInner::Replace(smallvec!["$scramerr(", name.as_str(), ");"]) + } + Self::Scramitize { span } => JsChangeInner::Wrap { + before: smallvec!["$scramitize("], + span, + after: smallvec![")"], + }, + + Self::Eval { inner, .. } => JsChangeInner::Wrap { + before: smallvec!["eval(", cfg.rewritefn.as_str(), "("], + span: inner, + after: smallvec![")"], + }, + Self::Assignment { + name, rhsspan, op, .. + } => JsChangeInner::Wrap { + before: smallvec![ + "((t)=>$scramjet$tryset(", + name.as_str(), + ",\"", + op.as_str(), + "\",t)||(", + name.as_str(), + op.as_str(), + "t))(" + ], + span: rhsspan, + after: smallvec![")"], + }, + Self::ShorthandObj { name, .. } => JsChangeInner::Replace(smallvec![ + name.as_str(), + ":", + cfg.wrapfn.as_str(), + "(", + name.as_str(), + ")" + ]), + Self::SourceTag { tagname, .. } => JsChangeInner::Replace(smallvec![ + "/*scramtag ", + tagname.as_str(), + " ", + cfg.sourcetag.as_str(), + "*/" + ]), + Self::Replace { text, .. } => JsChangeInner::Replace(smallvec![text.as_str()]), + Self::Delete { .. } => JsChangeInner::Replace(smallvec![]), + } + } +} + +impl PartialOrd for JsChange { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for JsChange { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.get_span().start.cmp(&other.get_span().start) + } +} + +pub(crate) struct JsChangeResult { + pub js: Vec, + pub sourcemap: Vec, +} + +pub(crate) struct JsChanges { + pub inner: Vec, +} + +impl JsChanges { + pub fn new() -> Self { + Self { inner: Vec::new() } + } + + pub fn add(&mut self, change: JsChange) { + self.inner.push(change); + } + + pub fn perform(&mut self, js: &str, cfg: &Config) -> JsChangeResult { + let mut offset = 0; + let mut buffer = Vec::with_capacity(((js.len() as u64 * 120) / 100) as usize); + + // TODO: add sourcemaps + let map = Vec::with_capacity(js.len() * 2); + + self.inner.sort(); + + for change in &self.inner { + println!("{:?}", change); + let span = change.get_span(); + let start = span.start as usize; + let end = span.end as usize; + + buffer.extend_from_slice(js[offset..start].as_bytes()); + + let change = change.to_inner(cfg); + match change { + JsChangeInner::Wrap { + before, + span: wrapspan, + after, + } => { + // wrap op + for str in before { + buffer.extend_from_slice(str.as_bytes()); + } + + let wrapstart = wrapspan.start as usize; + let wrapend = wrapspan.end as usize; + buffer.extend_from_slice(js[wrapstart..wrapend].as_bytes()); + + for str in after { + buffer.extend_from_slice(str.as_bytes()); + } + } + JsChangeInner::Replace(list) => { + for str in list { + buffer.extend_from_slice(str.as_bytes()); + } + } + } + + offset = end; + } + + buffer.extend_from_slice(js[offset..].as_bytes()); + + JsChangeResult { + js: buffer, + sourcemap: map, + } + } +} diff --git a/rewriter/rewriter/src/lib.rs b/rewriter/rewriter/src/lib.rs new file mode 100644 index 0000000..ec2d7b8 --- /dev/null +++ b/rewriter/rewriter/src/lib.rs @@ -0,0 +1,65 @@ +use cfg::Config; +use changes::{JsChange, JsChangeResult, JsChanges}; +use oxc::{ + allocator::Allocator, + ast::Visit, + diagnostics::OxcDiagnostic, + parser::{ParseOptions, Parser}, + span::SourceType, +}; +use thiserror::Error; +use visitor::Visitor; + +pub mod cfg; +pub mod changes; +mod visitor; + +#[derive(Error, Debug)] +pub enum RewriterError { + #[error("oxc panicked in parser")] + OxcPanicked, +} + +#[derive(Debug)] +pub struct RewriteResult { + pub js: Vec, + pub sourcemap: Vec, + pub errors: Vec, + pub changes: Vec, +} + +pub fn rewrite(js: &str, config: Config) -> Result { + let allocator = Allocator::default(); + let source_type = SourceType::default(); + let ret = Parser::new(&allocator, js, source_type) + .with_options(ParseOptions { + parse_regular_expression: false, // default + allow_return_outside_function: true, + preserve_parens: true, // default + }) + .parse(); + + if ret.panicked { + return Err(RewriterError::OxcPanicked); + } + + let mut visitor = Visitor { + jschanges: JsChanges::new(), + config, + }; + visitor.visit_program(&ret.program); + let Visitor { + mut jschanges, + config, + } = visitor; + + let JsChangeResult { js, sourcemap } = jschanges.perform(js, &config); + let JsChanges { inner: changes } = jschanges; + + Ok(RewriteResult { + js, + sourcemap, + errors: ret.errors, + changes, + }) +} diff --git a/rewriter/rewriter/src/visitor.rs b/rewriter/rewriter/src/visitor.rs new file mode 100644 index 0000000..8df5008 --- /dev/null +++ b/rewriter/rewriter/src/visitor.rs @@ -0,0 +1,340 @@ +use oxc::{ + ast::{ + ast::{ + AssignmentExpression, AssignmentTarget, CallExpression, DebuggerStatement, + ExportAllDeclaration, ExportNamedDeclaration, Expression, ForInStatement, + ForOfStatement, FunctionBody, IdentifierReference, ImportDeclaration, ImportExpression, + MemberExpression, MetaProperty, NewExpression, ObjectExpression, ObjectPropertyKind, + ReturnStatement, ThisExpression, UnaryExpression, UnaryOperator, UpdateExpression, + }, + visit::walk, + Visit, + }, + span::{Atom, GetSpan, Span}, +}; + +use crate::{ + cfg::Config, + changes::{JsChange, JsChanges}, +}; + +// js MUST not be able to get a reference to any of these because sbx +// +// maybe move this out of this lib? +const UNSAFE_GLOBALS: &[&str] = &[ + "window", + "self", + "globalThis", + "this", + "parent", + "top", + "location", + "document", + "eval", + "frames", +]; + +pub struct Visitor { + pub jschanges: JsChanges, + pub config: Config, +} + +impl Visitor { + fn rewrite_url(&mut self, url: String) -> String { + let url = self.config.base.join(&url).unwrap(); + + let urlencoded = (self.config.encoder)(url.to_string()); + + format!("\"{}{}\"", self.config.prefix, urlencoded) + } + + fn rewrite_ident(&mut self, name: &Atom, span: Span) { + if UNSAFE_GLOBALS.contains(&name.as_str()) { + self.jschanges.add(JsChange::WrapFn { + span, + ident: name.to_compact_str(), + wrapped: true, + }); + } + } + + fn walk_member_expression(&mut self, it: &Expression) -> bool { + if match it { + Expression::Identifier(s) => { + self.rewrite_ident(&s.name, s.span); + true + } + Expression::StaticMemberExpression(s) => self.walk_member_expression(&s.object), + Expression::ComputedMemberExpression(s) => self.walk_member_expression(&s.object), + _ => false, + } { + return true; + } + // TODO: WE SHOULD PROBABLY WALK THE REST OF THE TREE + // walk::walk_expression(self, it); + false + } + + fn scramitize(&mut self, span: Span) { + self.jschanges.add(JsChange::Scramitize { span }); + } +} + +impl<'a> Visit<'a> for Visitor { + fn visit_identifier_reference(&mut self, it: &IdentifierReference) { + // if self.config.capture_errors { + // self.jschanges.insert(JsChange::GenericChange { + // span: it.span, + // text: format!( + // "{}({}, typeof arguments != 'undefined' && arguments)", + // self.config.wrapfn, it.name + // ), + // }); + // } else { + // + if UNSAFE_GLOBALS.contains(&it.name.as_str()) { + self.jschanges.add(JsChange::WrapFn { + span: it.span, + ident: it.name.to_compact_str(), + wrapped: false, + }); + } + // } + } + + // we need to rewrite `new Something` to `new (wrapfn(Something))` instead of `new wrapfn(Something)`, that's why there's weird extra code here + fn visit_new_expression(&mut self, it: &NewExpression) { + self.walk_member_expression(&it.callee); + walk::walk_arguments(self, &it.arguments); + } + + fn visit_member_expression(&mut self, it: &MemberExpression) { + match it { + MemberExpression::StaticMemberExpression(s) => { + if s.property.name == "postMessage" { + self.jschanges.add(JsChange::SetRealmFn { + span: s.property.span, + ident: s.property.name.to_compact_str(), + }); + + walk::walk_expression(self, &s.object); + return; // unwise to walk the rest of the tree + } + + if !self.config.strict_rewrites + && !UNSAFE_GLOBALS.contains(&s.property.name.as_str()) + { + if let Expression::Identifier(_) = &s.object { + // cull tree - this should be safe + return; + } + if let Expression::ThisExpression(_) = &s.object { + return; + } + } + + if self.config.scramitize + && !matches!(s.object, Expression::MetaProperty(_) | Expression::Super(_)) + { + self.scramitize(s.object.span()); + } + } + _ => { + // TODO + // you could break this with ["postMessage"] etc + // however this code only exists because of recaptcha whatever + // and it would slow down js execution a lot + } + } + + walk::walk_member_expression(self, it); + } + fn visit_this_expression(&mut self, it: &ThisExpression) { + self.jschanges.add(JsChange::WrapThisFn { span: it.span }); + } + + fn visit_debugger_statement(&mut self, it: &DebuggerStatement) { + // delete debugger statements entirely. some sites will spam debugger as an anti-debugging measure, and we don't want that! + self.jschanges.add(JsChange::Delete { span: it.span }); + } + + // we can't overwrite window.eval in the normal way because that would make everything an + // indirect eval, which could break things. we handle that edge case here + fn visit_call_expression(&mut self, it: &CallExpression<'a>) { + if let Expression::Identifier(s) = &it.callee { + // if it's optional that actually makes it an indirect eval which is handled separately + if s.name == "eval" && !it.optional { + self.jschanges.add(JsChange::Eval { + span: Span::new(it.span.start, it.span.end), + inner: Span::new(s.span.end + 1, it.span.end), + }); + + // then we walk the arguments, but not the callee, since we want it to resolve to + // the real eval + walk::walk_arguments(self, &it.arguments); + return; + } + } + if self.config.scramitize { + self.scramitize(it.span); + } + walk::walk_call_expression(self, it); + } + + fn visit_import_declaration(&mut self, it: &ImportDeclaration<'a>) { + let name = it.source.value.to_string(); + let text = self.rewrite_url(name); + self.jschanges.add(JsChange::Replace { + span: it.source.span, + text, + }); + walk::walk_import_declaration(self, it); + } + fn visit_import_expression(&mut self, it: &ImportExpression<'a>) { + self.jschanges.add(JsChange::ImportFn { + span: Span::new(it.span.start, it.span.start + 6), + }); + walk::walk_import_expression(self, it); + } + + fn visit_export_all_declaration(&mut self, it: &ExportAllDeclaration<'a>) { + let name = it.source.value.to_string(); + let text = self.rewrite_url(name); + self.jschanges.add(JsChange::Replace { + span: it.source.span, + text, + }); + } + fn visit_export_named_declaration(&mut self, it: &ExportNamedDeclaration<'a>) { + if let Some(source) = &it.source { + let name = source.value.to_string(); + let text = self.rewrite_url(name); + self.jschanges.add(JsChange::Replace { + span: source.span, + text, + }); + } + // do not walk further, we don't want to rewrite the identifiers + } + + #[cfg(feature = "debug")] + fn visit_try_statement(&mut self, it: &oxc::ast::ast::TryStatement<'a>) { + // for debugging we need to know what the error was + + if self.config.capture_errors { + if let Some(h) = &it.handler { + if let Some(name) = &h.param { + if let Some(name) = name.pattern.get_identifier() { + self.jschanges.add(JsChange::ScramErr { + span: Span::new(h.body.span.start + 1, h.body.span.start + 1), + name: name.to_compact_str(), + }); + } + } + } + } + walk::walk_try_statement(self, it); + } + + fn visit_object_expression(&mut self, it: &ObjectExpression<'a>) { + for prop in &it.properties { + if let ObjectPropertyKind::ObjectProperty(p) = prop { + match &p.value { + Expression::Identifier(s) => { + if UNSAFE_GLOBALS.contains(&s.name.to_string().as_str()) && p.shorthand { + self.jschanges.add(JsChange::ShorthandObj { + span: s.span, + name: s.name.to_compact_str(), + }); + return; + } + } + _ => {} + } + } + } + + walk::walk_object_expression(self, it); + } + + fn visit_function_body(&mut self, it: &FunctionBody<'a>) { + // tag function for use in sourcemaps + if self.config.do_sourcemaps { + self.jschanges.add(JsChange::SourceTag { + span: Span::new(it.span.start, it.span.start), + tagname: it.span.start.to_string(), + }); + } + walk::walk_function_body(self, it); + } + + fn visit_return_statement(&mut self, it: &ReturnStatement<'a>) { + // if let Some(arg) = &it.argument { + // self.jschanges.insert(JsChange::GenericChange { + // span: Span::new(it.span.start + 6, it.span.start + 6), + // text: format!(" $scramdbg((()=>{{ try {{return arguments}} catch(_){{}} }})(),("), + // }); + // self.jschanges.insert(JsChange::GenericChange { + // span: Span::new(expression_span(arg).end, expression_span(arg).end), + // text: format!("))"), + // }); + // } + walk::walk_return_statement(self, it); + } + + fn visit_unary_expression(&mut self, it: &UnaryExpression<'a>) { + if matches!(it.operator, UnaryOperator::Typeof) { + // don't walk to identifier rewrites since it won't matter + return; + } + walk::walk_unary_expression(self, it); + } + + // we don't want to rewrite the identifiers here because of a very specific edge case + fn visit_for_in_statement(&mut self, it: &ForInStatement<'a>) { + walk::walk_statement(self, &it.body); + } + fn visit_for_of_statement(&mut self, it: &ForOfStatement<'a>) { + walk::walk_statement(self, &it.body); + } + + fn visit_update_expression(&mut self, _it: &UpdateExpression<'a>) { + // then no, don't walk it, we don't care + } + + fn visit_meta_property(&mut self, it: &MetaProperty<'a>) { + if it.meta.name == "import" { + self.jschanges.add(JsChange::MetaFn { span: it.span }); + } + } + + fn visit_assignment_expression(&mut self, it: &AssignmentExpression<'a>) { + match &it.left { + AssignmentTarget::AssignmentTargetIdentifier(s) => { + if ["location"].contains(&s.name.to_string().as_str()) { + self.jschanges.add(JsChange::Assignment { + name: s.name.to_compact_str(), + entirespan: it.span, + rhsspan: it.right.span(), + op: it.operator, + }); + + // avoid walking rest of tree, i would need to figure out nested rewrites + // somehow + return; + } + } + AssignmentTarget::ArrayAssignmentTarget(_) => { + // [location] = ["https://example.com"] + // this is such a ridiculously specific edge case. just ignore it + return; + } + _ => { + // only walk the left side if it isn't an identifier, we can't replace the + // identifier with a function obviously + walk::walk_assignment_target(self, &it.left); + } + } + walk::walk_expression(self, &it.right); + } +} diff --git a/rewriter/rust-toolchain.toml b/rewriter/rust-toolchain.toml index abe29a0..5155a79 100644 --- a/rewriter/rust-toolchain.toml +++ b/rewriter/rust-toolchain.toml @@ -2,3 +2,4 @@ channel = "nightly" targets = [ "wasm32-unknown-unknown" ] components = [ "rust-src" ] + diff --git a/rewriter/src/error.rs b/rewriter/src/error.rs deleted file mode 100644 index 1b7a65f..0000000 --- a/rewriter/src/error.rs +++ /dev/null @@ -1,48 +0,0 @@ -use js_sys::Error; -use thiserror::Error; -use wasm_bindgen::{JsError, JsValue}; - -#[derive(Debug, Error)] -pub enum RewriterError { - #[error("JS: {0}")] - Js(String), - #[error("URL parse error: {0}")] - Url(#[from] url::ParseError), - #[error("str fromutf8 error: {0}")] - Str(#[from] std::str::Utf8Error), - #[error("reflect set failed: {0}")] - ReflectSetFail(String), - - #[error("{0} was not {1}")] - Not(String, &'static str), - #[error("❗❗❗ ❗❗❗ REWRITER OFFSET OOB FAIL ❗❗❗ ❗❗❗")] - Oob, -} - -impl From for RewriterError { - fn from(value: JsValue) -> Self { - Self::Js(Error::from(value).to_string().into()) - } -} - -impl From for JsValue { - fn from(value: RewriterError) -> Self { - JsError::from(value).into() - } -} - -impl RewriterError { - pub fn not_str(x: &str) -> Self { - Self::Not(x.to_string(), "string") - } - - pub fn not_fn(x: &str) -> Self { - Self::Not(x.to_string(), "function") - } - - pub fn not_bool(x: &str) -> Self { - Self::Not(x.to_string(), "bool") - } -} - -pub type Result = std::result::Result; diff --git a/rewriter/src/lib.rs b/rewriter/src/lib.rs deleted file mode 100644 index c88d054..0000000 --- a/rewriter/src/lib.rs +++ /dev/null @@ -1,179 +0,0 @@ -pub mod error; -pub mod rewrite; - -use std::{str::FromStr, sync::Arc, time::Duration}; - -use error::{Result, RewriterError}; -use instant::Instant; -use js_sys::{Function, Object, Reflect}; -use oxc::diagnostics::{NamedSource, OxcDiagnostic}; -use rewrite::{rewrite, Config, EncodeFn}; -use url::Url; -use wasm_bindgen::prelude::*; - -#[wasm_bindgen(typescript_custom_section)] -const REWRITER_OUTPUT: &'static str = r#" -type RewriterOutput = { js: Uint8Array, errors: string[], duration: bigint }; -"#; - -#[wasm_bindgen(inline_js = r#" -// slightly modified https://github.com/ungap/random-uuid/blob/main/index.js -export function scramtag() { - return (""+1e10).replace(/[018]/g, - c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) - ); -} -"#)] -extern "C" { - pub fn scramtag() -> String; -} - -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(typescript_type = "RewriterOutput")] - pub type RewriterOutput; -} - -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(js_namespace = console)] - fn error(s: &str); -} - -fn create_encode_function(encode: JsValue) -> Result { - let encode = encode.dyn_into::()?; - - Ok(Box::new(move |str| { - encode - .call1(&JsValue::NULL, &str.into()) - .unwrap() - .as_string() - .unwrap() - .to_string() - })) -} - -fn get_obj(obj: &JsValue, k: &str) -> Result { - Ok(Reflect::get(obj, &k.into())?) -} - -fn get_str(obj: &JsValue, k: &str) -> Result { - Reflect::get(obj, &k.into())? - .as_string() - .ok_or_else(|| RewriterError::not_str(k)) -} - -fn set_obj(obj: &Object, k: &str, v: &JsValue) -> Result<()> { - if !Reflect::set(&obj.into(), &k.into(), v)? { - Err(RewriterError::ReflectSetFail(k.to_string())) - } else { - Ok(()) - } -} - -fn get_flag(scramjet: &Object, url: &str, flag: &str) -> Result { - let fenabled = get_obj(scramjet, "flagEnabled")? - .dyn_into::() - .map_err(|_| RewriterError::not_fn("scramjet.flagEnabled"))?; - let ret = fenabled.call2( - &JsValue::NULL, - &flag.into(), - &web_sys::Url::new(url)?.into(), - )?; - - ret.as_bool().ok_or_else(|| RewriterError::not_bool("scramjet.flagEnabled return value")) -} - -fn get_config(scramjet: &Object, url: &str) -> Result { - let codec = &get_obj(scramjet, "codec")?; - let config = &get_obj(scramjet, "config")?; - let globals = &get_obj(config, "globals")?; - - Ok(Config { - prefix: get_str(config, "prefix")?, - encode: create_encode_function(get_obj(codec, "encode")?)?, - - wrapfn: get_str(globals, "wrapfn")?, - wrapthisfn: get_str(globals, "wrapthisfn")?, - importfn: get_str(globals, "importfn")?, - rewritefn: get_str(globals, "rewritefn")?, - metafn: get_str(globals, "metafn")?, - setrealmfn: get_str(globals, "setrealmfn")?, - pushsourcemapfn: get_str(globals, "pushsourcemapfn")?, - - do_sourcemaps: get_flag(scramjet, url, "sourcemaps")?, - capture_errors: get_flag(scramjet, url, "captureErrors")?, - scramitize: get_flag(scramjet, url, "scramitize")?, - strict_rewrites: get_flag(scramjet, url, "strictRewrites")?, - }) -} - -fn duration_to_millis_f64(duration: Duration) -> f64 { - (duration.as_secs() as f64) * 1_000f64 + (duration.subsec_nanos() as f64) / 1_000_000f64 -} - -fn create_rewriter_output( - out: (Vec, Vec), - url: String, - src: String, - duration: Duration, -) -> Result { - let src = Arc::new(NamedSource::new(url, src).with_language("javascript")); - #[cfg(feature = "debug")] - let errs: Vec<_> = out - .1 - .into_iter() - .map(|x| format!("{}", x.with_source_code(src.clone()))) - .collect(); - - let obj = Object::new(); - set_obj(&obj, "js", &out.0.into())?; - #[cfg(feature = "debug")] - set_obj(&obj, "errors", &errs.into())?; - #[cfg(not(feature = "debug"))] - set_obj(&obj, "errors", &js_sys::Array::new())?; - set_obj(&obj, "duration", &duration_to_millis_f64(duration).into())?; - - Ok(RewriterOutput::from(JsValue::from(obj))) -} - -#[wasm_bindgen] -pub fn rewrite_js( - js: String, - url: &str, - script_url: String, - scramjet: &Object, -) -> Result { - let before = Instant::now(); - let out = rewrite( - &js, - Url::from_str(url)?, - scramtag(), - get_config(scramjet, url)?, - )?; - let after = Instant::now(); - - create_rewriter_output(out, script_url, js, after - before) -} - -#[wasm_bindgen] -pub fn rewrite_js_from_arraybuffer( - js: Vec, - url: &str, - script_url: String, - scramjet: &Object, -) -> Result { - // we know that this is a valid utf-8 string - let js = unsafe { String::from_utf8_unchecked(js) }; - - let before = Instant::now(); - let out = rewrite( - &js, - Url::from_str(url)?, - scramtag(), - get_config(scramjet, url)?, - )?; - let after = Instant::now(); - - create_rewriter_output(out, script_url, js, after - before) -} diff --git a/rewriter/src/main.rs b/rewriter/src/main.rs deleted file mode 100644 index 564a350..0000000 --- a/rewriter/src/main.rs +++ /dev/null @@ -1,255 +0,0 @@ -#![allow(clippy::print_stdout)] -use std::{ - borrow::Cow, - env, - path::Path, - str::{from_utf8, FromStr}, -}; - -pub mod error; -pub mod rewrite; - -use error::Result; -use rewrite::rewrite; -use url::Url; - -use crate::rewrite::Config; - -// Instruction: -// create a `test.js`, -// run `cargo run -p oxc_parser --example visitor` -// or `cargo watch -x "run -p oxc_parser --example visitor"` - -/// Percent-encodes every byte except alphanumerics and `-`, `_`, `.`, `~`. Assumes UTF-8 encoding. -/// -/// Call `.into_owned()` if you need a `String` -#[inline(always)] -#[must_use] -pub fn encode(data: &str) -> Cow<'_, str> { - encode_binary(data.as_bytes()) -} - -/// Percent-encodes every byte except alphanumerics and `-`, `_`, `.`, `~`. -#[inline] -#[must_use] -pub fn encode_binary(data: &[u8]) -> Cow<'_, str> { - // add maybe extra capacity, but try not to exceed allocator's bucket size - let mut escaped = String::new(); - let _ = escaped.try_reserve(data.len() | 15); - let unmodified = append_string(data, &mut escaped, true); - if unmodified { - return Cow::Borrowed(unsafe { - // encode_into has checked it's ASCII - std::str::from_utf8_unchecked(data) - }); - } - Cow::Owned(escaped) -} - -fn append_string(data: &[u8], escaped: &mut String, may_skip: bool) -> bool { - encode_into(data, may_skip, |s| { - escaped.push_str(s); - Ok::<_, std::convert::Infallible>(()) - }) - .unwrap() -} - -fn encode_into( - mut data: &[u8], - may_skip_write: bool, - mut push_str: impl FnMut(&str) -> std::result::Result<(), E>, -) -> std::result::Result { - let mut pushed = false; - loop { - // Fast path to skip over safe chars at the beginning of the remaining string - let ascii_len = data - .iter() - .take_while( - |&&c| matches!(c, b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z' | b'-' | b'.' | b'_' | b'~'), - ) - .count(); - - let (safe, rest) = if ascii_len >= data.len() { - if !pushed && may_skip_write { - return Ok(true); - } - (data, &[][..]) // redundatnt to optimize out a panic in split_at - } else { - data.split_at(ascii_len) - }; - pushed = true; - if !safe.is_empty() { - push_str(unsafe { std::str::from_utf8_unchecked(safe) })?; - } - if rest.is_empty() { - break; - } - - match rest.split_first() { - Some((byte, rest)) => { - let enc = &[b'%', to_hex_digit(byte >> 4), to_hex_digit(byte & 15)]; - push_str(unsafe { std::str::from_utf8_unchecked(enc) })?; - data = rest; - } - None => break, - }; - } - Ok(false) -} - -#[inline] -fn to_hex_digit(digit: u8) -> u8 { - match digit { - 0..=9 => b'0' + digit, - 10..=255 => b'A' - 10 + digit, - } -} - -fn encode_string(s: String) -> String { - encode(&s).to_string() -} - -fn dorewrite(source_text: &str) -> Result { - Ok(from_utf8( - rewrite( - source_text, - Url::from_str("https://google.com/glorngle/si.js").unwrap(), - "glongle1".to_string(), - Config { - prefix: "/scrammedjet/".to_string(), - encode: Box::new(encode_string), - wrapfn: "$wrap".to_string(), - wrapthisfn: "$gwrap".to_string(), - importfn: "$import".to_string(), - rewritefn: "$rewrite".to_string(), - metafn: "$meta".to_string(), - setrealmfn: "$setrealm".to_string(), - pushsourcemapfn: "$pushsourcemap".to_string(), - capture_errors: true, - do_sourcemaps: true, - scramitize: false, - strict_rewrites: true, - }, - )? - .0 - .as_slice(), - )? - .to_string()) -} - -fn main() -> std::io::Result<()> { - let name = env::args().nth(1).unwrap_or_else(|| "test.js".to_string()); - let path = Path::new(&name); - let source_text = std::fs::read_to_string(path)?; - - println!("{}", dorewrite(&source_text).unwrap()); - - Ok(()) -} - -#[cfg(test)] -mod tests { - use std::fs; - - use boa_engine::{ - js_str, js_string, - object::ObjectInitializer, - property::{Attribute, PropertyDescriptorBuilder}, - Context, NativeFunction, Source, - }; - - use crate::dorewrite; - - #[test] - fn google() { - // sanity check- just making sure it won't crash - let source_text = include_str!("../sample/google.js"); - dorewrite(source_text).unwrap(); - } - - #[test] - fn test() { - let files = fs::read_dir("./tests").unwrap(); - - for file in files { - if !file - .as_ref() - .unwrap() - .file_name() - .to_str() - .unwrap() - .ends_with(".js") - { - continue; - } - - let content = fs::read_to_string(file.unwrap().path()).unwrap(); - - let mut context = Context::default(); - - let window = ObjectInitializer::new(&mut context).build(); - context - .register_global_property(js_str!("window"), window, Attribute::READONLY) - .unwrap(); - context - .global_object() - .define_property_or_throw( - js_str!("location"), - PropertyDescriptorBuilder::new() - .get( - NativeFunction::from_copy_closure(|_, _, _| { - Ok(js_str!("location").into()) - }) - .to_js_function(context.realm()), - ) - .set( - NativeFunction::from_copy_closure(|_, _, _| { - panic!("fail: window.location got set") - }) - .to_js_function(context.realm()), - ) - .build(), - &mut context, - ) - .unwrap(); - - context - .register_global_callable( - js_string!("fail"), - 0, - NativeFunction::from_copy_closure(|_, _, _| { - panic!("fail"); - }), - ) - .unwrap(); - - let result = context - .eval(Source::from_bytes( - br#" -function $wrap(val) { - if (val === window || val === "location" || val === globalThis) return ""; - - return val; -} - -function assert(val) { - if (!val) fail(); -} - -function check(val) { - if (val === window || val === "location") fail(); -} - "#, - )) - .unwrap(); - - let rewritten = dorewrite(&content).unwrap(); - println!("{}", rewritten); - - context - .eval(Source::from_bytes(rewritten.as_bytes())) - .unwrap(); - println!("PASS"); - } - } -} diff --git a/rewriter/src/rewrite.rs b/rewriter/src/rewrite.rs deleted file mode 100644 index 8f486d3..0000000 --- a/rewriter/src/rewrite.rs +++ /dev/null @@ -1,591 +0,0 @@ -use std::str; - -use indexset::BTreeSet; -use oxc::{ - allocator::Allocator, - ast::{ - ast::{ - AssignmentExpression, AssignmentTarget, CallExpression, DebuggerStatement, - ExportAllDeclaration, ExportNamedDeclaration, Expression, ForInStatement, - ForOfStatement, FunctionBody, IdentifierReference, ImportDeclaration, ImportExpression, - MemberExpression, MetaProperty, NewExpression, ObjectExpression, ObjectPropertyKind, - ReturnStatement, ThisExpression, UnaryExpression, UpdateExpression, - }, - visit::walk, - Visit, - }, - diagnostics::OxcDiagnostic, - parser::{ParseOptions, Parser}, - span::{Atom, GetSpan, SourceType, Span}, - syntax::operator::{AssignmentOperator, UnaryOperator}, -}; -use url::Url; - -use crate::error::{Result, RewriterError}; - -#[derive(Debug, PartialEq, Eq)] -enum JsChange { - GenericChange { - span: Span, - text: String, - }, - SourceTag { - tagstart: u32, - }, - Assignment { - name: String, - entirespan: Span, - rhsspan: Span, - op: AssignmentOperator, - }, -} - -impl JsChange { - fn inner_cmp(&self, other: &Self) -> std::cmp::Ordering { - let a = match self { - JsChange::GenericChange { span, text: _ } => span.start, - JsChange::Assignment { - name: _, - entirespan, - rhsspan: _, - op: _, - } => entirespan.start, - JsChange::SourceTag { tagstart } => *tagstart, - }; - let b = match other { - JsChange::GenericChange { span, text: _ } => span.start, - JsChange::Assignment { - name: _, - entirespan, - rhsspan: _, - op: _, - } => entirespan.start, - JsChange::SourceTag { tagstart } => *tagstart, - }; - a.cmp(&b) - } -} - -impl PartialOrd for JsChange { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.inner_cmp(other)) - } -} - -impl Ord for JsChange { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.inner_cmp(other) - } -} - -pub type EncodeFn = Box String>; -struct Rewriter { - jschanges: BTreeSet, - base: Url, - config: Config, -} - -pub struct Config { - pub prefix: String, - - pub wrapfn: String, - pub wrapthisfn: String, - pub importfn: String, - pub rewritefn: String, - pub setrealmfn: String, - pub metafn: String, - pub pushsourcemapfn: String, - - pub encode: EncodeFn, - pub capture_errors: bool, - pub scramitize: bool, - pub do_sourcemaps: bool, - pub strict_rewrites: bool, -} - -impl Rewriter { - fn rewrite_url(&mut self, url: String) -> String { - let url = self.base.join(&url).unwrap(); - - let urlencoded = (self.config.encode)(url.to_string()); - - format!("\"{}{}\"", self.config.prefix, urlencoded) - } - - fn rewrite_ident(&mut self, name: &Atom, span: Span) { - if UNSAFE_GLOBALS.contains(&name.to_string().as_str()) { - self.jschanges.insert(JsChange::GenericChange { - span, - text: format!("({}({}))", self.config.wrapfn, name), - }); - } - } - - fn walk_member_expression(&mut self, it: &Expression) -> bool { - if match it { - Expression::Identifier(s) => { - self.rewrite_ident(&s.name, s.span); - true - } - Expression::StaticMemberExpression(s) => self.walk_member_expression(&s.object), - Expression::ComputedMemberExpression(s) => self.walk_member_expression(&s.object), - _ => false, - } { - return true; - } - // TODO: WE SHOULD PROBABLY WALK THE REST OF THE TREE - // walk::walk_expression(self, it); - false - } -} - -impl<'a> Visit<'a> for Rewriter { - fn visit_identifier_reference(&mut self, it: &IdentifierReference<'a>) { - // if self.config.capture_errors { - // self.jschanges.insert(JsChange::GenericChange { - // span: it.span, - // text: format!( - // "{}({}, typeof arguments != 'undefined' && arguments)", - // self.config.wrapfn, it.name - // ), - // }); - // } else { - if UNSAFE_GLOBALS.contains(&it.name.to_string().as_str()) { - self.jschanges.insert(JsChange::GenericChange { - span: it.span, - text: format!("{}({})", self.config.wrapfn, it.name), - }); - } - // } - } - - // we need to rewrite `new Something` to `new (wrapfn(Something))` instead of `new wrapfn(Something)`, that's why there's weird extra code here - fn visit_new_expression(&mut self, it: &NewExpression<'a>) { - self.walk_member_expression(&it.callee); - walk::walk_arguments(self, &it.arguments); - } - fn visit_member_expression(&mut self, it: &MemberExpression<'a>) { - match it { - MemberExpression::StaticMemberExpression(s) => { - if s.property.name == "postMessage" { - self.jschanges.insert(JsChange::GenericChange { - span: s.property.span, - // an empty object will let us safely reconstruct the realm later - text: format!("{}({{}}).{}", self.config.setrealmfn, s.property.name), - }); - - walk::walk_expression(self, &s.object); - return; // unwise to walk the rest of the tree - } - - if !self.config.strict_rewrites - && !UNSAFE_GLOBALS.contains(&s.property.name.as_str()) - { - if let Expression::Identifier(_) = &s.object { - // cull tree - this should be safe - return; - } - if let Expression::ThisExpression(_) = &s.object { - return; - } - } - - if self.config.scramitize - && !matches!(s.object, Expression::MetaProperty(_)) - && !matches!(s.object, Expression::Super(_)) - { - let span = s.object.span(); - self.jschanges.insert(JsChange::GenericChange { - span: Span::new(span.start, span.start), - text: " $scramitize(".to_string(), - }); - self.jschanges.insert(JsChange::GenericChange { - span: Span::new(span.end, span.end), - text: ")".to_string(), - }); - } - } - _ => { - // TODO - // you could break this with ["postMessage"] etc - // however this code only exists because of recaptcha whatever - // and it would slow down js execution a lot - } - } - - walk::walk_member_expression(self, it); - } - fn visit_this_expression(&mut self, it: &ThisExpression) { - self.jschanges.insert(JsChange::GenericChange { - span: it.span, - text: format!("{}(this)", self.config.wrapthisfn), - }); - } - - fn visit_debugger_statement(&mut self, it: &DebuggerStatement) { - // delete debugger statements entirely. some sites will spam debugger as an anti-debugging measure, and we don't want that! - self.jschanges.insert(JsChange::GenericChange { - span: it.span, - text: "".to_string(), - }); - } - - // we can't overwrite window.eval in the normal way because that would make everything an - // indirect eval, which could break things. we handle that edge case here - fn visit_call_expression(&mut self, it: &CallExpression<'a>) { - if let Expression::Identifier(s) = &it.callee { - // if it's optional that actually makes it an indirect eval which is handled separately - if s.name == "eval" && !it.optional { - self.jschanges.insert(JsChange::GenericChange { - span: Span::new(s.span.start, s.span.end + 1), - text: format!("eval({}(", self.config.rewritefn), - }); - self.jschanges.insert(JsChange::GenericChange { - span: Span::new(it.span.end, it.span.end), - text: ")".to_string(), - }); - - // then we walk the arguments, but not the callee, since we want it to resolve to - // the real eval - walk::walk_arguments(self, &it.arguments); - return; - } - } - if self.config.scramitize { - self.jschanges.insert(JsChange::GenericChange { - span: Span::new(it.span.start, it.span.start), - text: " $scramitize(".to_string(), - }); - self.jschanges.insert(JsChange::GenericChange { - span: Span::new(it.span.end, it.span.end), - text: ")".to_string(), - }); - } - walk::walk_call_expression(self, it); - } - - fn visit_import_declaration(&mut self, it: &ImportDeclaration<'a>) { - let name = it.source.value.to_string(); - let text = self.rewrite_url(name); - self.jschanges.insert(JsChange::GenericChange { - span: it.source.span, - text, - }); - walk::walk_import_declaration(self, it); - } - fn visit_import_expression(&mut self, it: &ImportExpression<'a>) { - self.jschanges.insert(JsChange::GenericChange { - span: Span::new(it.span.start, it.span.start + 6), - text: format!("({}(\"{}\"))", self.config.importfn, self.base), - }); - walk::walk_import_expression(self, it); - } - - fn visit_export_all_declaration(&mut self, it: &ExportAllDeclaration<'a>) { - let name = it.source.value.to_string(); - let text = self.rewrite_url(name); - self.jschanges.insert(JsChange::GenericChange { - span: it.source.span, - text, - }); - } - - fn visit_export_named_declaration(&mut self, it: &ExportNamedDeclaration<'a>) { - if let Some(source) = &it.source { - let name = source.value.to_string(); - let text = self.rewrite_url(name); - self.jschanges.insert(JsChange::GenericChange { - span: source.span, - text, - }); - } - // do not walk further, we don't want to rewrite the identifiers - } - - #[cfg(feature = "debug")] - fn visit_try_statement(&mut self, it: &oxc::ast::ast::TryStatement<'a>) { - // for debugging we need to know what the error was - - if self.config.capture_errors { - if let Some(h) = &it.handler { - if let Some(name) = &h.param { - if let Some(name) = name.pattern.get_identifier() { - self.jschanges.insert(JsChange::GenericChange { - span: Span::new(h.body.span.start + 1, h.body.span.start + 1), - text: format!("$scramerr({});", name), - }); - } - } - } - } - walk::walk_try_statement(self, it); - } - - fn visit_object_expression(&mut self, it: &ObjectExpression<'a>) { - for prop in &it.properties { - #[allow(clippy::single_match)] - match prop { - ObjectPropertyKind::ObjectProperty(p) => match &p.value { - Expression::Identifier(s) => { - if UNSAFE_GLOBALS.contains(&s.name.to_string().as_str()) && p.shorthand { - self.jschanges.insert(JsChange::GenericChange { - span: s.span, - text: format!("{}: ({}({}))", s.name, self.config.wrapfn, s.name), - }); - return; - } - } - _ => {} - }, - _ => {} - } - } - - walk::walk_object_expression(self, it); - } - - fn visit_function_body(&mut self, it: &FunctionBody<'a>) { - // tag function for use in sourcemaps - if self.config.do_sourcemaps { - self.jschanges.insert(JsChange::SourceTag { - tagstart: it.span.start, - }); - } - walk::walk_function_body(self, it); - } - - fn visit_return_statement(&mut self, it: &ReturnStatement<'a>) { - // if let Some(arg) = &it.argument { - // self.jschanges.insert(JsChange::GenericChange { - // span: Span::new(it.span.start + 6, it.span.start + 6), - // text: format!(" $scramdbg((()=>{{ try {{return arguments}} catch(_){{}} }})(),("), - // }); - // self.jschanges.insert(JsChange::GenericChange { - // span: Span::new(expression_span(arg).end, expression_span(arg).end), - // text: format!("))"), - // }); - // } - walk::walk_return_statement(self, it); - } - - fn visit_unary_expression(&mut self, it: &UnaryExpression<'a>) { - if matches!(it.operator, UnaryOperator::Typeof) { - // don't walk to identifier rewrites since it won't matter - return; - } - walk::walk_unary_expression(self, it); - } - - // we don't want to rewrite the identifiers here because of a very specific edge case - fn visit_for_in_statement(&mut self, it: &ForInStatement<'a>) { - walk::walk_statement(self, &it.body); - } - fn visit_for_of_statement(&mut self, it: &ForOfStatement<'a>) { - walk::walk_statement(self, &it.body); - } - - fn visit_update_expression(&mut self, _it: &UpdateExpression<'a>) { - // then no, don't walk it, we don't care - } - - fn visit_meta_property(&mut self, it: &MetaProperty<'a>) { - if it.meta.name == "import" { - self.jschanges.insert(JsChange::GenericChange { - span: it.span, - text: format!("{}(\"{}\")", self.config.metafn, self.base), - }); - } - } - - fn visit_assignment_expression(&mut self, it: &AssignmentExpression<'a>) { - #[allow(clippy::single_match)] - match &it.left { - AssignmentTarget::AssignmentTargetIdentifier(s) => { - if ["location"].contains(&s.name.to_string().as_str()) { - self.jschanges.insert(JsChange::Assignment { - name: s.name.to_string(), - entirespan: it.span, - rhsspan: it.right.span(), - op: it.operator, - }); - - // avoid walking rest of tree, i would need to figure out nested rewrites - // somehow - return; - } - } - AssignmentTarget::ArrayAssignmentTarget(_) => { - // [location] = ["https://example.com"] - // this is such a ridiculously specific edge case. just ignore it - return; - } - _ => { - // only walk the left side if it isn't an identifier, we can't replace the - // identifier with a function obviously - walk::walk_assignment_target(self, &it.left); - } - } - walk::walk_expression(self, &it.right); - } -} - -// js MUST not be able to get a reference to any of these because sbx -const UNSAFE_GLOBALS: &[&str] = &[ - "window", - "self", - "globalThis", - "this", - "parent", - "top", - "location", - "document", - "eval", - "frames", -]; - -pub fn rewrite( - js: &str, - url: Url, - sourcetag: String, - config: Config, -) -> Result<(Vec, Vec)> { - let allocator = Allocator::default(); - let source_type = SourceType::default(); - let ret = Parser::new(&allocator, js, source_type) - .with_options(ParseOptions { - parse_regular_expression: false, // default - allow_return_outside_function: true, - preserve_parens: true, // default - }) - .parse(); - - let program = ret.program; - - let mut ast_pass = Rewriter { - jschanges: BTreeSet::new(), - base: url, - config, - }; - - ast_pass.visit_program(&program); - - let original_len = js.len(); - let mut difference = 0i32; - - for change in &ast_pass.jschanges { - match &change { - JsChange::GenericChange { span, text } => { - difference += text.len() as i32 - (span.end - span.start) as i32; - } - JsChange::Assignment { - name, - entirespan, - rhsspan: _, - op: _, - } => difference += entirespan.size() as i32 + name.len() as i32 + 10, - _ => {} - } - } - - let size_estimate = (original_len as i32 + difference) as usize; - let mut buffer: Vec = Vec::with_capacity(size_estimate); - - let mut sourcemap: Vec = Vec::new(); - if ast_pass.config.do_sourcemaps { - sourcemap.reserve(size_estimate * 2); - sourcemap.extend_from_slice(format!("{}([", ast_pass.config.pushsourcemapfn).as_bytes()); - } - - let mut offset = 0; - for change in ast_pass.jschanges { - match &change { - JsChange::GenericChange { span, text } => { - let start = span.start as usize; - let end = span.end as usize; - - if ast_pass.config.do_sourcemaps { - let spliced = &js[start..end]; - sourcemap.extend_from_slice( - format!( - "[\"{}\",{},{}],", - json_escape_string(spliced), - start, - start + text.len() - ) - .as_bytes(), - ); - } - - buffer - .extend_from_slice(js.get(offset..start).ok_or(RewriterError::Oob)?.as_bytes()); - - buffer.extend_from_slice(text.as_bytes()); - offset = end; - } - JsChange::Assignment { - name, - entirespan, - rhsspan, - op, - } => { - let start = entirespan.start as usize; - buffer.extend_from_slice(js[offset..start].as_bytes()); - - buffer.extend_from_slice( - format!( - "((t)=>$scramjet$tryset({},\"{}\",t)||({}{}t))({})", - name, - op.as_str(), - name, - op.as_str(), - &js[rhsspan.start as usize..rhsspan.end as usize] - ) - .as_bytes(), - ); - - offset = entirespan.end as usize; - } - JsChange::SourceTag { tagstart } => { - let start = *tagstart as usize; - buffer - .extend_from_slice(js.get(offset..start).ok_or(RewriterError::Oob)?.as_bytes()); - - let inject = format!("/*scramtag {} {}*/", start, sourcetag); - buffer.extend_from_slice(inject.as_bytes()); - - offset = start; - } - } - } - buffer.extend_from_slice(js[offset..].as_bytes()); - - if ast_pass.config.do_sourcemaps { - sourcemap.extend_from_slice(b"],"); - sourcemap.extend_from_slice(b"\""); - sourcemap.extend_from_slice(sourcetag.as_bytes()); - sourcemap.extend_from_slice(b"\");\n"); - - sourcemap.extend_from_slice(&buffer); - - return Ok((sourcemap, ret.errors)); - } - - Ok((buffer, ret.errors)) -} - -fn json_escape_string(s: &str) -> String { - let mut out = String::with_capacity(s.len()); - for c in s.chars() { - match c { - '"' => out.push_str("\\\""), - '\\' => out.push_str("\\\\"), - '\x08' => out.push_str("\\b"), - '\x0C' => out.push_str("\\f"), - '\n' => out.push_str("\\n"), - '\r' => out.push_str("\\r"), - '\t' => out.push_str("\\t"), - _ => out.push(c), - } - } - out -} diff --git a/rewriter/tests/0-sanity.js b/rewriter/tests/0-sanity.js deleted file mode 100644 index c4bb536..0000000 --- a/rewriter/tests/0-sanity.js +++ /dev/null @@ -1,5 +0,0 @@ -check(window); -check(this); -check(globalThis); -check(location); -check(globalThis["win" + "dow"]) diff --git a/rewriter/tests/1-destructure.js b/rewriter/tests/1-destructure.js deleted file mode 100644 index 7c236b6..0000000 --- a/rewriter/tests/1-destructure.js +++ /dev/null @@ -1,3 +0,0 @@ -const { location: x } = globalThis; - -check(x); diff --git a/rewriter/tests/2-function-default.js b/rewriter/tests/2-function-default.js deleted file mode 100644 index 7ad7532..0000000 --- a/rewriter/tests/2-function-default.js +++ /dev/null @@ -1,6 +0,0 @@ -function f(g = globalThis, l = location) { - check(g); - check(l); -} - -f(); diff --git a/rewriter/tests/3-shadow-globals.js b/rewriter/tests/3-shadow-globals.js deleted file mode 100644 index e1fd8c0..0000000 --- a/rewriter/tests/3-shadow-globals.js +++ /dev/null @@ -1,7 +0,0 @@ - -function f(location, globalThis) { - assert(location === 1) - assert(globalThis === 2) -} - -f(1, 2); diff --git a/rewriter/tests/eval-overridden-locals.js.disabled b/rewriter/tests/eval-overridden-locals.js.disabled deleted file mode 100644 index 700890e..0000000 --- a/rewriter/tests/eval-overridden-locals.js.disabled +++ /dev/null @@ -1,8 +0,0 @@ - -let reached = false -let eval = (t) => t === "location = 1" && (reached = true) - -// testing to make sure this doesn't get rewritten -eval("location = 1") - -if (!reached) fail(); diff --git a/rewriter/tests/for-assignment.js.disabled b/rewriter/tests/for-assignment.js.disabled deleted file mode 100644 index 78e1e21..0000000 --- a/rewriter/tests/for-assignment.js.disabled +++ /dev/null @@ -1,3 +0,0 @@ -for (location of ["https://google.com"]) { - // -} diff --git a/rewriter/wasm/Cargo.toml b/rewriter/wasm/Cargo.toml new file mode 100644 index 0000000..177078e --- /dev/null +++ b/rewriter/wasm/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "wasm" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +instant = { version = "0.1.13", features = ["wasm-bindgen"] } +js-sys = "0.3.76" +oxc = { workspace = true } +rewriter = { version = "0.1.0", path = "../rewriter" } +thiserror = "2.0.6" +url = "2.5.4" +wasm-bindgen = "0.2.99" +web-sys = { version = "0.3.76", features = ["Url"] } + +[features] +default = ["debug"] +debug = ["rewriter/debug"] diff --git a/rewriter/build.sh b/rewriter/wasm/build.sh old mode 100755 new mode 100644 similarity index 76% rename from rewriter/build.sh rename to rewriter/wasm/build.sh index 9554e65..26b0a9a --- a/rewriter/build.sh +++ b/rewriter/wasm/build.sh @@ -8,7 +8,7 @@ which cargo wasm-bindgen wasm-opt &> /dev/null || { exit 1 } -WBG="wasm-bindgen 0.2.95" +WBG="wasm-bindgen 0.2.99" if ! [[ "$(wasm-bindgen -V)" =~ ^"$WBG" ]]; then echo "Incorrect wasm-bindgen-cli version: '$(wasm-bindgen -V)' != '$WBG'" exit 1 @@ -23,16 +23,14 @@ else fi RUSTFLAGS='-C target-feature=+atomics,+bulk-memory,+simd128 -Zlocation-detail=none -Zfmt-debug=none' cargo build --lib --target wasm32-unknown-unknown -Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort --no-default-features --features "$FEATURES" --release -wasm-bindgen --target web --out-dir out/ target/wasm32-unknown-unknown/release/rewriter.wasm +wasm-bindgen --target web --out-dir out/ ../target/wasm32-unknown-unknown/release/wasm.wasm -sed -i 's/import.meta.url/""/g' out/rewriter.js +sed -i 's/import.meta.url/""/g' out/wasm.js -cd .. - -WASM=rewriter/out/rewriter_bg.wasm +cd ../../ # shellcheck disable=SC2086 -time wasm-opt $WASMOPTFLAGS --converge -tnh -O4 --vacuum --dce --enable-threads --enable-bulk-memory --enable-simd "$WASM" -o rewriter/out/optimized.wasm +time wasm-opt $WASMOPTFLAGS --converge -tnh -O4 --vacuum --dce --enable-threads --enable-bulk-memory --enable-simd rewriter/wasm/out/wasm_bg.wasm -o rewriter/wasm/out/optimized.wasm mkdir dist/ || true @@ -44,7 +42,7 @@ if ("document" in self && document?.currentScript) { } EOF echo -n "self.WASM = '" -base64 -w0 < "rewriter/out/optimized.wasm" +base64 -w0 < "rewriter/wasm/out/optimized.wasm" echo -n "';" } > dist/scramjet.wasm.js diff --git a/rewriter/wasm/out/optimized.wasm b/rewriter/wasm/out/optimized.wasm new file mode 100644 index 0000000..a5f8072 Binary files /dev/null and b/rewriter/wasm/out/optimized.wasm differ diff --git a/rewriter/wasm/out/snippets/wasm-4b0f351a8e6eeb46/inline0.js b/rewriter/wasm/out/snippets/wasm-4b0f351a8e6eeb46/inline0.js new file mode 100644 index 0000000..72a52d9 --- /dev/null +++ b/rewriter/wasm/out/snippets/wasm-4b0f351a8e6eeb46/inline0.js @@ -0,0 +1,7 @@ + +// slightly modified https://github.com/ungap/random-uuid/blob/main/index.js +export function scramtag() { + return (""+1e10).replace(/[018]/g, + c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) + ); +} diff --git a/rewriter/wasm/out/wasm.d.ts b/rewriter/wasm/out/wasm.d.ts new file mode 100644 index 0000000..449fb4f --- /dev/null +++ b/rewriter/wasm/out/wasm.d.ts @@ -0,0 +1,48 @@ +/* tslint:disable */ +/* eslint-disable */ +export function rewrite_js(js: string, url: string, script_url: string, scramjet: object): RewriterOutput; +export function rewrite_js_from_arraybuffer(js: Uint8Array, url: string, script_url: string, scramjet: object): RewriterOutput; + +type RewriterOutput = { js: Uint8Array, errors: string[], duration: bigint }; + + + +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; + +export interface InitOutput { + readonly rewrite_js: (a: number, b: number, c: number, d: number, e: number, f: number, g: any) => [number, number, number]; + readonly rewrite_js_from_arraybuffer: (a: number, b: number, c: number, d: number, e: number, f: number, g: any) => [number, number, number]; + readonly __wbindgen_exn_store: (a: number) => void; + readonly __externref_table_alloc: () => number; + readonly __wbindgen_export_2: WebAssembly.Table; + readonly memory: WebAssembly.Memory; + readonly __wbindgen_malloc: (a: number, b: number) => number; + readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; + readonly __wbindgen_free: (a: number, b: number, c: number) => void; + readonly __externref_table_dealloc: (a: number) => void; + readonly __wbindgen_thread_destroy: (a?: number, b?: number, c?: number) => void; + readonly __wbindgen_start: (a: number) => void; +} + +export type SyncInitInput = BufferSource | WebAssembly.Module; +/** +* Instantiates the given `module`, which can either be bytes or +* a precompiled `WebAssembly.Module`. +* +* @param {{ module: SyncInitInput, memory?: WebAssembly.Memory, thread_stack_size?: number }} module - Passing `SyncInitInput` directly is deprecated. +* @param {WebAssembly.Memory} memory - Deprecated. +* +* @returns {InitOutput} +*/ +export function initSync(module: { module: SyncInitInput, memory?: WebAssembly.Memory, thread_stack_size?: number } | SyncInitInput, memory?: WebAssembly.Memory): InitOutput; + +/** +* If `module_or_path` is {RequestInfo} or {URL}, makes a request and +* for everything else, calls `WebAssembly.instantiate` directly. +* +* @param {{ module_or_path: InitInput | Promise, memory?: WebAssembly.Memory, thread_stack_size?: number }} module_or_path - Passing `InitInput` directly is deprecated. +* @param {WebAssembly.Memory} memory - Deprecated. +* +* @returns {Promise} +*/ +export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise, memory?: WebAssembly.Memory, thread_stack_size?: number } | InitInput | Promise, memory?: WebAssembly.Memory): Promise; diff --git a/rewriter/wasm/out/wasm.js b/rewriter/wasm/out/wasm.js new file mode 100644 index 0000000..2bbc855 --- /dev/null +++ b/rewriter/wasm/out/wasm.js @@ -0,0 +1,390 @@ +import { scramtag } from './snippets/wasm-4b0f351a8e6eeb46/inline0.js'; + +let wasm; + +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc(); + wasm.__wbindgen_export_2.set(idx, obj); + return idx; +} + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + const idx = addToExternrefTable0(e); + wasm.__wbindgen_exn_store(idx); + } +} + +const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); + +if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; + +let cachedUint8ArrayMemory0 = null; + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.buffer !== wasm.memory.buffer) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8ArrayMemory0().slice(ptr, ptr + len)); +} + +let WASM_VECTOR_LEN = 0; + +const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } ); + +const encodeString = function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}; + +function passStringToWasm0(arg, malloc, realloc) { + + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +let cachedDataViewMemory0 = null; + +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer !== wasm.memory.buffer) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); + } + return cachedDataViewMemory0; +} + +function isLikeNone(x) { + return x === undefined || x === null; +} + +function getArrayU8FromWasm0(ptr, len) { + ptr = ptr >>> 0; + return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len); +} + +function takeFromExternrefTable0(idx) { + const value = wasm.__wbindgen_export_2.get(idx); + wasm.__externref_table_dealloc(idx); + return value; +} +/** + * @param {string} js + * @param {string} url + * @param {string} script_url + * @param {object} scramjet + * @returns {RewriterOutput} + */ +export function rewrite_js(js, url, script_url, scramjet) { + const ptr0 = passStringToWasm0(js, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(url, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passStringToWasm0(script_url, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len2 = WASM_VECTOR_LEN; + const ret = wasm.rewrite_js(ptr0, len0, ptr1, len1, ptr2, len2, scramjet); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); + } + return takeFromExternrefTable0(ret[0]); +} + +function passArray8ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 1, 1) >>> 0; + getUint8ArrayMemory0().set(arg, ptr / 1); + WASM_VECTOR_LEN = arg.length; + return ptr; +} +/** + * @param {Uint8Array} js + * @param {string} url + * @param {string} script_url + * @param {object} scramjet + * @returns {RewriterOutput} + */ +export function rewrite_js_from_arraybuffer(js, url, script_url, scramjet) { + const ptr0 = passArray8ToWasm0(js, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(url, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passStringToWasm0(script_url, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len2 = WASM_VECTOR_LEN; + const ret = wasm.rewrite_js_from_arraybuffer(ptr0, len0, ptr1, len1, ptr2, len2, scramjet); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); + } + return takeFromExternrefTable0(ret[0]); +} + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + + } catch (e) { + if (module.headers.get('Content-Type') != 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { + throw e; + } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + + } else { + return instance; + } + } +} + +function __wbg_get_imports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbg_call_3b770f0d6eb4720e = function() { return handleError(function (arg0, arg1, arg2, arg3) { + const ret = arg0.call(arg1, arg2, arg3); + return ret; + }, arguments) }; + imports.wbg.__wbg_call_500db948e69c7330 = function() { return handleError(function (arg0, arg1, arg2) { + const ret = arg0.call(arg1, arg2); + return ret; + }, arguments) }; + imports.wbg.__wbg_call_b0d8e36992d9900d = function() { return handleError(function (arg0, arg1) { + const ret = arg0.call(arg1); + return ret; + }, arguments) }; + imports.wbg.__wbg_get_bbccf8970793c087 = function() { return handleError(function (arg0, arg1) { + const ret = Reflect.get(arg0, arg1); + return ret; + }, arguments) }; + imports.wbg.__wbg_new_17f755666e48d1d8 = function() { return handleError(function (arg0, arg1) { + const ret = new URL(getStringFromWasm0(arg0, arg1)); + return ret; + }, arguments) }; + imports.wbg.__wbg_new_688846f374351c92 = function() { + const ret = new Object(); + return ret; + }; + imports.wbg.__wbg_newnoargs_fd9e4bf8be2bc16d = function(arg0, arg1) { + const ret = new Function(getStringFromWasm0(arg0, arg1)); + return ret; + }; + imports.wbg.__wbg_now_62a101fe35b60230 = function(arg0) { + const ret = arg0.now(); + return ret; + }; + imports.wbg.__wbg_scramtag_bd98edaa0eaec45e = function(arg0) { + const ret = scramtag(); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbg_set_4e647025551483bd = function() { return handleError(function (arg0, arg1, arg2) { + const ret = Reflect.set(arg0, arg1, arg2); + return ret; + }, arguments) }; + imports.wbg.__wbg_static_accessor_GLOBAL_0be7472e492ad3e3 = function() { + const ret = typeof global === 'undefined' ? null : global; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }; + imports.wbg.__wbg_static_accessor_GLOBAL_THIS_1a6eb482d12c9bfb = function() { + const ret = typeof globalThis === 'undefined' ? null : globalThis; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }; + imports.wbg.__wbg_static_accessor_SELF_1dc398a895c82351 = function() { + const ret = typeof self === 'undefined' ? null : self; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }; + imports.wbg.__wbg_static_accessor_WINDOW_ae1c80c7eea8d64a = function() { + const ret = typeof window === 'undefined' ? null : window; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }; + imports.wbg.__wbg_toString_cbcf95f260c441ae = function(arg0) { + const ret = arg0.toString(); + return ret; + }; + imports.wbg.__wbindgen_array_new = function() { + const ret = []; + return ret; + }; + imports.wbg.__wbindgen_array_push = function(arg0, arg1) { + arg0.push(arg1); + }; + imports.wbg.__wbindgen_boolean_get = function(arg0) { + const v = arg0; + const ret = typeof(v) === 'boolean' ? (v ? 1 : 0) : 2; + return ret; + }; + imports.wbg.__wbindgen_error_new = function(arg0, arg1) { + const ret = new Error(getStringFromWasm0(arg0, arg1)); + return ret; + }; + imports.wbg.__wbindgen_init_externref_table = function() { + const table = wasm.__wbindgen_export_2; + const offset = table.grow(4); + table.set(0, undefined); + table.set(offset + 0, undefined); + table.set(offset + 1, null); + table.set(offset + 2, true); + table.set(offset + 3, false); + ; + }; + imports.wbg.__wbindgen_is_function = function(arg0) { + const ret = typeof(arg0) === 'function'; + return ret; + }; + imports.wbg.__wbindgen_is_undefined = function(arg0) { + const ret = arg0 === undefined; + return ret; + }; + imports.wbg.__wbindgen_number_new = function(arg0) { + const ret = arg0; + return ret; + }; + imports.wbg.__wbindgen_string_get = function(arg0, arg1) { + const obj = arg1; + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbindgen_string_new = function(arg0, arg1) { + const ret = getStringFromWasm0(arg0, arg1); + return ret; + }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + imports.wbg.__wbindgen_uint8_array_new = function(arg0, arg1) { + var v0 = getArrayU8FromWasm0(arg0, arg1).slice(); + wasm.__wbindgen_free(arg0, arg1 * 1, 1); + const ret = v0; + return ret; + }; + + return imports; +} + +function __wbg_init_memory(imports, memory) { + imports.wbg.memory = memory || new WebAssembly.Memory({initial:21,maximum:16384,shared:true}); +} + +function __wbg_finalize_init(instance, module, thread_stack_size) { + wasm = instance.exports; + __wbg_init.__wbindgen_wasm_module = module; + cachedDataViewMemory0 = null; + cachedUint8ArrayMemory0 = null; + + if (typeof thread_stack_size !== 'undefined' && (typeof thread_stack_size !== 'number' || thread_stack_size === 0 || thread_stack_size % 65536 !== 0)) { throw 'invalid stack size' } + wasm.__wbindgen_start(thread_stack_size); + return wasm; +} + +function initSync(module, memory) { + if (wasm !== undefined) return wasm; + + let thread_stack_size + if (typeof module !== 'undefined') { + if (Object.getPrototypeOf(module) === Object.prototype) { + ({module, memory, thread_stack_size} = module) + } else { + console.warn('using deprecated parameters for `initSync()`; pass a single object instead') + } + } + + const imports = __wbg_get_imports(); + + __wbg_init_memory(imports, memory); + + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + + const instance = new WebAssembly.Instance(module, imports); + + return __wbg_finalize_init(instance, module, thread_stack_size); +} + +async function __wbg_init(module_or_path, memory) { + if (wasm !== undefined) return wasm; + + let thread_stack_size + if (typeof module_or_path !== 'undefined') { + if (Object.getPrototypeOf(module_or_path) === Object.prototype) { + ({module_or_path, memory, thread_stack_size} = module_or_path) + } else { + console.warn('using deprecated parameters for the initialization function; pass a single object instead') + } + } + + if (typeof module_or_path === 'undefined') { + module_or_path = new URL('wasm_bg.wasm', ""); + } + const imports = __wbg_get_imports(); + + if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) { + module_or_path = fetch(module_or_path); + } + + __wbg_init_memory(imports, memory); + + const { instance, module } = await __wbg_load(await module_or_path, imports); + + return __wbg_finalize_init(instance, module, thread_stack_size); +} + +export { initSync }; +export default __wbg_init; diff --git a/rewriter/wasm/out/wasm_bg.wasm b/rewriter/wasm/out/wasm_bg.wasm new file mode 100644 index 0000000..b167e28 Binary files /dev/null and b/rewriter/wasm/out/wasm_bg.wasm differ diff --git a/rewriter/wasm/out/wasm_bg.wasm.d.ts b/rewriter/wasm/out/wasm_bg.wasm.d.ts new file mode 100644 index 0000000..626d2dd --- /dev/null +++ b/rewriter/wasm/out/wasm_bg.wasm.d.ts @@ -0,0 +1,14 @@ +/* tslint:disable */ +/* eslint-disable */ +export const rewrite_js: (a: number, b: number, c: number, d: number, e: number, f: number, g: any) => [number, number, number]; +export const rewrite_js_from_arraybuffer: (a: number, b: number, c: number, d: number, e: number, f: number, g: any) => [number, number, number]; +export const __wbindgen_exn_store: (a: number) => void; +export const __externref_table_alloc: () => number; +export const __wbindgen_export_2: WebAssembly.Table; +export const memory: WebAssembly.Memory; +export const __wbindgen_malloc: (a: number, b: number) => number; +export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; +export const __wbindgen_free: (a: number, b: number, c: number) => void; +export const __externref_table_dealloc: (a: number) => void; +export const __wbindgen_thread_destroy: (a?: number, b?: number, c?: number) => void; +export const __wbindgen_start: (a: number) => void; diff --git a/rewriter/wasm/src/error.rs b/rewriter/wasm/src/error.rs new file mode 100644 index 0000000..33fafc7 --- /dev/null +++ b/rewriter/wasm/src/error.rs @@ -0,0 +1,49 @@ +use js_sys::Error; +use rewriter::RewriterError as InnerRewriterError; +use thiserror::Error; +use wasm_bindgen::{JsError, JsValue}; + +#[derive(Debug, Error)] +pub enum RewriterError { + #[error("JS: {0}")] + Js(String), + #[error("URL parse error: {0}")] + Url(#[from] url::ParseError), + #[error("str fromutf8 error: {0}")] + Str(#[from] std::str::Utf8Error), + #[error("Rewriter: {0}")] + Rewriter(#[from] InnerRewriterError), + #[error("reflect set failed: {0}")] + ReflectSetFail(String), + + #[error("{0} was not {1}")] + Not(String, &'static str), +} + +impl From for RewriterError { + fn from(value: JsValue) -> Self { + Self::Js(Error::from(value).to_string().into()) + } +} + +impl From for JsValue { + fn from(value: RewriterError) -> Self { + JsError::from(value).into() + } +} + +impl RewriterError { + pub fn not_str(x: &str) -> Self { + Self::Not(x.to_string(), "string") + } + + pub fn not_fn(x: &str) -> Self { + Self::Not(x.to_string(), "function") + } + + pub fn not_bool(x: &str) -> Self { + Self::Not(x.to_string(), "bool") + } +} + +pub type Result = std::result::Result; diff --git a/rewriter/wasm/src/lib.rs b/rewriter/wasm/src/lib.rs new file mode 100644 index 0000000..f85571d --- /dev/null +++ b/rewriter/wasm/src/lib.rs @@ -0,0 +1,174 @@ +pub mod error; + +use std::{str::FromStr, sync::Arc, time::Duration}; + +use error::{Result, RewriterError}; +use instant::Instant; +use js_sys::{Function, Object, Reflect}; +use oxc::diagnostics::NamedSource; +use rewriter::{ + cfg::{Config, EncodeFn}, + rewrite, RewriteResult, +}; +use url::Url; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(typescript_custom_section)] +const REWRITER_OUTPUT: &'static str = r#" +type RewriterOutput = { js: Uint8Array, errors: string[], duration: bigint }; +"#; + +#[wasm_bindgen(inline_js = r#" +// slightly modified https://github.com/ungap/random-uuid/blob/main/index.js +export function scramtag() { + return (""+1e10).replace(/[018]/g, + c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) + ); +} +"#)] +extern "C" { + pub fn scramtag() -> String; +} + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(typescript_type = "RewriterOutput")] + pub type JsRewriterOutput; +} + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console)] + fn error(s: &str); +} + +fn create_encode_function(encode: JsValue) -> Result { + let encode = encode.dyn_into::()?; + + Ok(Box::new(move |str| { + encode + .call1(&JsValue::NULL, &str.into()) + .unwrap() + .as_string() + .unwrap() + .to_string() + })) +} + +fn get_obj(obj: &JsValue, k: &str) -> Result { + Ok(Reflect::get(obj, &k.into())?) +} + +fn get_str(obj: &JsValue, k: &str) -> Result { + Reflect::get(obj, &k.into())? + .as_string() + .ok_or_else(|| RewriterError::not_str(k)) +} + +fn set_obj(obj: &Object, k: &str, v: &JsValue) -> Result<()> { + if !Reflect::set(&obj.into(), &k.into(), v)? { + Err(RewriterError::ReflectSetFail(k.to_string())) + } else { + Ok(()) + } +} + +fn get_flag(scramjet: &Object, url: &str, flag: &str) -> Result { + let fenabled = get_obj(scramjet, "flagEnabled")? + .dyn_into::() + .map_err(|_| RewriterError::not_fn("scramjet.flagEnabled"))?; + let ret = fenabled.call2( + &JsValue::NULL, + &flag.into(), + &web_sys::Url::new(url)?.into(), + )?; + + ret.as_bool() + .ok_or_else(|| RewriterError::not_bool("scramjet.flagEnabled return value")) +} + +fn get_config(scramjet: &Object, url: &str) -> Result { + let codec = &get_obj(scramjet, "codec")?; + let config = &get_obj(scramjet, "config")?; + let globals = &get_obj(config, "globals")?; + + Ok(Config { + prefix: get_str(config, "prefix")?, + encoder: create_encode_function(get_obj(codec, "encode")?)?, + base: Url::from_str(url)?, + sourcetag: scramtag(), + + wrapfn: get_str(globals, "wrapfn")?, + wrapthisfn: get_str(globals, "wrapthisfn")?, + importfn: get_str(globals, "importfn")?, + rewritefn: get_str(globals, "rewritefn")?, + metafn: get_str(globals, "metafn")?, + setrealmfn: get_str(globals, "setrealmfn")?, + pushsourcemapfn: get_str(globals, "pushsourcemapfn")?, + + do_sourcemaps: get_flag(scramjet, url, "sourcemaps")?, + capture_errors: get_flag(scramjet, url, "captureErrors")?, + scramitize: get_flag(scramjet, url, "scramitize")?, + strict_rewrites: get_flag(scramjet, url, "strictRewrites")?, + }) +} + +fn duration_to_millis_f64(duration: Duration) -> f64 { + (duration.as_secs() as f64) * 1_000f64 + (duration.subsec_nanos() as f64) / 1_000_000f64 +} + +fn create_rewriter_output( + out: RewriteResult, + url: String, + src: String, + duration: Duration, +) -> Result { + let src = Arc::new(NamedSource::new(url, src).with_language("javascript")); + #[cfg(feature = "debug")] + let errs: Vec<_> = out + .errors + .into_iter() + .map(|x| format!("{}", x.with_source_code(src.clone()))) + .collect(); + + let obj = Object::new(); + set_obj(&obj, "js", &out.js.into())?; + #[cfg(feature = "debug")] + set_obj(&obj, "errors", &errs.into())?; + #[cfg(not(feature = "debug"))] + set_obj(&obj, "errors", &js_sys::Array::new())?; + set_obj(&obj, "duration", &duration_to_millis_f64(duration).into())?; + + Ok(JsRewriterOutput::from(JsValue::from(obj))) +} + +#[wasm_bindgen] +pub fn rewrite_js( + js: String, + url: &str, + script_url: String, + scramjet: &Object, +) -> Result { + let before = Instant::now(); + let out = rewrite(&js, get_config(scramjet, url)?)?; + let after = Instant::now(); + + create_rewriter_output(out, script_url, js, after - before) +} + +#[wasm_bindgen] +pub fn rewrite_js_from_arraybuffer( + js: Vec, + url: &str, + script_url: String, + scramjet: &Object, +) -> Result { + // we know that this is a valid utf-8 string + let js = unsafe { String::from_utf8_unchecked(js) }; + + let before = Instant::now(); + let out = rewrite(&js, get_config(scramjet, url)?)?; + let after = Instant::now(); + + create_rewriter_output(out, script_url, js, after - before) +} diff --git a/src/shared/rewriters/js.ts b/src/shared/rewriters/js.ts index 8928588..2b0e0da 100644 --- a/src/shared/rewriters/js.ts +++ b/src/shared/rewriters/js.ts @@ -6,7 +6,7 @@ import { rewrite_js, rewrite_js_from_arraybuffer, RewriterOutput, -} from "../../../rewriter/out/rewriter.js"; +} from "../../../rewriter/wasm/out/wasm.js"; import { $scramjet, flagEnabled } from "../../scramjet"; initSync({