js-confuser 1.2.2 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/README.md +4 -1
  3. package/dist/parser.js +1 -2
  4. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +482 -91
  5. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -0
  6. package/dist/transforms/controlFlowFlattening/{switchCaseObfucation.js → switchCaseObfuscation.js} +2 -2
  7. package/dist/transforms/deadCode.js +1 -1
  8. package/dist/transforms/dispatcher.js +7 -6
  9. package/dist/transforms/eval.js +1 -1
  10. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +4 -2
  11. package/dist/transforms/hideInitializingCode.js +4 -1
  12. package/dist/transforms/identifier/globalConcealing.js +18 -8
  13. package/dist/transforms/identifier/variableAnalysis.js +1 -1
  14. package/dist/transforms/label.js +11 -2
  15. package/dist/transforms/lock/antiDebug.js +32 -13
  16. package/dist/transforms/lock/lock.js +3 -3
  17. package/dist/transforms/minify.js +2 -2
  18. package/dist/transforms/opaquePredicates.js +4 -2
  19. package/dist/transforms/preparation/preparation.js +8 -0
  20. package/dist/transforms/renameLabels.js +17 -3
  21. package/dist/transforms/rgf.js +8 -3
  22. package/dist/transforms/stack.js +1 -1
  23. package/dist/transforms/string/encoding.js +74 -0
  24. package/dist/transforms/string/stringCompression.js +6 -2
  25. package/dist/transforms/string/stringConcealing.js +1 -1
  26. package/dist/transforms/string/stringSplitting.js +6 -0
  27. package/dist/traverse.js +0 -34
  28. package/dist/util/gen.js +3 -1
  29. package/dist/util/identifiers.js +8 -18
  30. package/dist/util/insert.js +4 -38
  31. package/package.json +2 -2
  32. package/src/options.ts +3 -3
  33. package/src/parser.ts +1 -2
  34. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +735 -134
  35. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +6 -0
  36. package/src/transforms/controlFlowFlattening/{switchCaseObfucation.ts → switchCaseObfuscation.ts} +6 -2
  37. package/src/transforms/deadCode.ts +8 -0
  38. package/src/transforms/dispatcher.ts +16 -6
  39. package/src/transforms/eval.ts +2 -1
  40. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +40 -5
  41. package/src/transforms/hideInitializingCode.ts +432 -425
  42. package/src/transforms/identifier/globalConcealing.ts +102 -38
  43. package/src/transforms/identifier/variableAnalysis.ts +1 -1
  44. package/src/transforms/label.ts +20 -2
  45. package/src/transforms/lock/antiDebug.ts +69 -33
  46. package/src/transforms/lock/lock.ts +4 -5
  47. package/src/transforms/minify.ts +2 -1
  48. package/src/transforms/opaquePredicates.ts +25 -3
  49. package/src/transforms/preparation/preparation.ts +8 -1
  50. package/src/transforms/renameLabels.ts +26 -3
  51. package/src/transforms/rgf.ts +6 -1
  52. package/src/transforms/stack.ts +2 -1
  53. package/src/transforms/string/encoding.ts +107 -1
  54. package/src/transforms/string/stringCompression.ts +28 -3
  55. package/src/transforms/string/stringConcealing.ts +2 -0
  56. package/src/transforms/string/stringSplitting.ts +11 -0
  57. package/src/transforms/transform.ts +1 -2
  58. package/src/traverse.ts +0 -30
  59. package/src/util/gen.ts +5 -3
  60. package/src/util/identifiers.ts +18 -19
  61. package/src/util/insert.ts +10 -76
  62. package/src/util/scope.ts +9 -9
  63. package/test/{transforms/compare.test.ts → compare.test.ts} +2 -2
  64. package/test/index.test.ts +109 -1
  65. package/test/templates/template.test.ts +14 -0
  66. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +392 -10
  67. package/test/transforms/dispatcher.test.ts +30 -0
  68. package/test/transforms/eval.test.ts +28 -0
  69. package/test/transforms/flatten.test.ts +28 -0
  70. package/test/transforms/hideInitializingCode.test.ts +336 -336
  71. package/test/transforms/identifier/renameVariables.test.ts +31 -0
  72. package/test/transforms/lock/antiDebug.test.ts +43 -0
  73. package/test/transforms/renameLabels.test.ts +33 -0
  74. package/test/transforms/rgf.test.ts +29 -0
  75. package/test/transforms/string/stringSplitting.test.ts +33 -0
  76. package/test/util/identifiers.test.ts +105 -17
  77. package/dist/util/expr.js +0 -60
  78. package/src/util/expr.ts +0 -56
@@ -80,6 +80,10 @@ class ExpressionObfuscation extends _transform.default {
80
80
  stmt.argument = (0, _gen.SequenceExpression)([...exprs, { ...stmt.argument
81
81
  }]);
82
82
  deleteExprs.push(...exprs);
83
+ } else if (stmt.type == "ReturnStatement") {
84
+ stmt.argument = (0, _gen.SequenceExpression)([...exprs, { ...(stmt.argument || (0, _gen.Identifier)("undefined"))
85
+ }]);
86
+ deleteExprs.push(...exprs);
83
87
  }
84
88
  }
85
89
 
@@ -35,7 +35,7 @@ class SwitchCaseObfuscation extends _transform.default {
35
35
  var types = new Set();
36
36
  (0, _traverse.walk)(object.discriminant, [object, ...parents], (o, p) => {
37
37
  if (o.type) {
38
- if (o.type == "BinaryExpression" && o.operator === "+") {} else {
38
+ if (object.$controlFlowFlattening && o.type == "BinaryExpression" && o.operator === "+") {} else {
39
39
  types.add(o.type);
40
40
  }
41
41
  }
@@ -64,7 +64,7 @@ class SwitchCaseObfuscation extends _transform.default {
64
64
  return;
65
65
  }
66
66
 
67
- var factor = (0, _random.getRandomInteger)(-250, 250);
67
+ var factor = (0, _random.getRandomInteger)(-150, 150);
68
68
 
69
69
  if (factor == 0) {
70
70
  factor = 2;
@@ -25,7 +25,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
25
25
 
26
26
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
27
27
 
28
- const templates = [(0, _template.default)("\n function curCSS( elem, name, computed ) {\n var ret;\n \n computed = computed || getStyles( elem );\n \n if ( computed ) {\n ret = computed.getPropertyValue( name ) || computed[ name ];\n \n if ( ret === \"\" && !isAttached( elem ) ) {\n ret = redacted.style( elem, name );\n }\n }\n \n return ret !== undefined ?\n \n // Support: IE <=9 - 11+\n // IE returns zIndex value as an integer.\n ret + \"\" :\n ret;\n }"), (0, _template.default)("\n function Example() {\n var state = redacted.useState(false);\n return x(\n ErrorBoundary,\n null,\n x(\n DisplayName,\n null,\n )\n );\n }"), (0, _template.default)("\n const path = require('path');\nconst { version } = require('../../package');\nconst { version: dashboardPluginVersion } = require('@redacted/enterprise-plugin/package');\nconst { version: componentsVersion } = require('@redacted/components/package');\nconst { sdkVersion } = require('@redacted/enterprise-plugin');\nconst isStandaloneExecutable = require('../utils/isStandaloneExecutable');\nconst resolveLocalRedactedPath = require('./resolve-local-redacted-path');\n\nconst redactedPath = path.resolve(__dirname, '../redacted.js');"), (0, _template.default)("\nmodule.exports = async (resolveLocalRedactedPath = ()=>{throw new Error(\"No redacted path provided\")}) => {\n const cliParams = new Set(process.argv.slice(2));\n if (!cliParams.has('--version')) {\n if (cliParams.size !== 1) return false;\n if (!cliParams.has('-v')) return false;\n }\n\n const installationModePostfix = await (async (isStandaloneExecutable, redactedPath) => {\n if (isStandaloneExecutable) return ' (standalone)';\n if (redactedPath === (await resolveLocalRedactedPath())) return ' (local)';\n return '';\n })();\n\n return true;\n};"), (0, _template.default)("\nfunction setCookie(cname, cvalue, exdays) {\n var d = new Date();\n d.setTime(d.getTime() + (exdays*24*60*60*1000));\n var expires = \"expires=\"+ d.toUTCString();\n document.cookie = cname + \"=\" + cvalue + \";\" + expires + \";path=/\";\n}"), (0, _template.default)("function getCookie(cname) {\n var name = cname + \"=\";\n var decodedCookie = decodeURIComponent(document.cookie);\n var ca = decodedCookie.split(';');\n for(var i = 0; i <ca.length; i++) {\n var c = ca[i];\n while (c.charAt(0) == ' ') {\n c = c.substring(1);\n }\n if (c.indexOf(name) == 0) {\n return c.substring(name.length, c.length);\n }\n }\n return \"\";\n}"), (0, _template.default)("function getLocalStorageValue(key, cb){\n if ( typeof key !== \"string\" ) {\n throw new Error(\"Invalid data key provided (not type string)\")\n }\n if ( !key ) {\n throw new Error(\"Invalid data key provided (empty string)\")\n }\n var value = window.localStorage.getItem(key)\n try {\n value = JSON.parse(value)\n } catch ( e ) {\n cb(new Error(\"Serialization error for data '\" + key + \"': \" + e.message))\n }\n\n cb(null, value)\n }")];
28
+ const templates = [(0, _template.default)("\n function curCSS( elem, name, computed ) {\n var ret;\n \n computed = computed || getStyles( elem );\n \n if ( computed ) {\n ret = computed.getPropertyValue( name ) || computed[ name ];\n \n if ( ret === \"\" && !isAttached( elem ) ) {\n ret = redacted.style( elem, name );\n }\n }\n \n return ret !== undefined ?\n \n // Support: IE <=9 - 11+\n // IE returns zIndex value as an integer.\n ret + \"\" :\n ret;\n }"), (0, _template.default)("\n function Example() {\n var state = redacted.useState(false);\n return x(\n ErrorBoundary,\n null,\n x(\n DisplayName,\n null,\n )\n );\n }"), (0, _template.default)("\n const path = require('path');\nconst { version } = require('../../package');\nconst { version: dashboardPluginVersion } = require('@redacted/enterprise-plugin/package');\nconst { version: componentsVersion } = require('@redacted/components/package');\nconst { sdkVersion } = require('@redacted/enterprise-plugin');\nconst isStandaloneExecutable = require('../utils/isStandaloneExecutable');\nconst resolveLocalRedactedPath = require('./resolve-local-redacted-path');\n\nconst redactedPath = path.resolve(__dirname, '../redacted.js');"), (0, _template.default)("\nmodule.exports = async (resolveLocalRedactedPath = ()=>{throw new Error(\"No redacted path provided\")}) => {\n const cliParams = new Set(process.argv.slice(2));\n if (!cliParams.has('--version')) {\n if (cliParams.size !== 1) return false;\n if (!cliParams.has('-v')) return false;\n }\n\n const installationModePostfix = await (async (isStandaloneExecutable, redactedPath) => {\n if (isStandaloneExecutable) return ' (standalone)';\n if (redactedPath === (await resolveLocalRedactedPath())) return ' (local)';\n return '';\n })();\n\n return true;\n};"), (0, _template.default)("\nfunction setCookie(cname, cvalue, exdays) {\n var d = new Date();\n d.setTime(d.getTime() + (exdays*24*60*60*1000));\n var expires = \"expires=\"+ d.toUTCString();\n document.cookie = cname + \"=\" + cvalue + \";\" + expires + \";path=/\";\n}"), (0, _template.default)("function getCookie(cname) {\n var name = cname + \"=\";\n var decodedCookie = decodeURIComponent(document.cookie);\n var ca = decodedCookie.split(';');\n for(var i = 0; i <ca.length; i++) {\n var c = ca[i];\n while (c.charAt(0) == ' ') {\n c = c.substring(1);\n }\n if (c.indexOf(name) == 0) {\n return c.substring(name.length, c.length);\n }\n }\n return \"\";\n}"), (0, _template.default)("function getLocalStorageValue(key, cb){\n if ( typeof key !== \"string\" ) {\n throw new Error(\"Invalid data key provided (not type string)\")\n }\n if ( !key ) {\n throw new Error(\"Invalid data key provided (empty string)\")\n }\n var value = window.localStorage.getItem(key)\n try {\n value = JSON.parse(value)\n } catch ( e ) {\n cb(new Error(\"Serialization error for data '\" + key + \"': \" + e.message))\n }\n\n cb(null, value)\n }"), (0, _template.default)("\n \n var __ = \"(c=ak(<~F$VU'9f)~><&85dBPL-module/from\";\n var s = \"q:function(){var ad=ad=>b(ad-29);if(!T.r[(typeof ab==ad(123)?\";\n var g = \"return U[c[c[d(-199)]-b(205)]]||V[ae(b(166))];case T.o[c[c[c[d(-199)]+d(-174)]-(c[b(119)]-(c[d(-199)]-163))]+ae(b(146))](0)==b(167)?d(-130):-d(-144)\";\n\n __.match(s + g);\n ")];
29
29
  /**
30
30
  * Adds dead code to blocks.
31
31
  *
@@ -87,7 +87,7 @@ class Dispatcher extends _transform.default {
87
87
 
88
88
  var newFnNames = {}; // [old name]: randomized name
89
89
 
90
- var context = (0, _insert.getVarContext)(object, parents);
90
+ var context = (0, _insert.isVarContext)(object) ? object : (0, _insert.getVarContext)(object, parents);
91
91
  (0, _traverse.walk)(object, parents, (o, p) => {
92
92
  if (object == o) {
93
93
  // Fix 1
@@ -102,7 +102,7 @@ class Dispatcher extends _transform.default {
102
102
 
103
103
  if (context === c) {
104
104
  if (o.type == "FunctionDeclaration" && o.id.name) {
105
- if (p.find(x => x.$dispatcherSkip || x.type == "MethodDefinition") || o.body.type != "BlockStatement") {
105
+ if (o.$requiresEval || o.async || o.generator || p.find(x => x.$dispatcherSkip || x.type == "MethodDefinition") || o.body.type != "BlockStatement") {
106
106
  illegalFnNames.add(name);
107
107
  }
108
108
 
@@ -114,10 +114,11 @@ class Dispatcher extends _transform.default {
114
114
  }
115
115
 
116
116
  (0, _traverse.walk)(o, p, (oo, pp) => {
117
- if (oo.type == "Identifier" && oo.name == "arguments") {
118
- illegalFnNames.add(name);
119
- } else if (oo.type == "ThisExpression") {
120
- illegalFnNames.add(name);
117
+ if (oo.type == "Identifier" && oo.name == "arguments" || oo.type == "ThisExpression" || oo.type == "Super") {
118
+ if ((0, _insert.getVarContext)(oo, pp) === o) {
119
+ illegalFnNames.add(name);
120
+ return "EXIT";
121
+ }
121
122
  }
122
123
  });
123
124
  functionDeclarations[name] = [o, p];
@@ -27,7 +27,7 @@ class Eval extends _transform.default {
27
27
  }
28
28
 
29
29
  match(object, parents) {
30
- return (0, _insert.isFunction)(object) && object.type != "ArrowFunctionExpression" && !object.$eval;
30
+ return (0, _insert.isFunction)(object) && object.type != "ArrowFunctionExpression" && !object.$eval && !object.$dispatcherSkip;
31
31
  }
32
32
 
33
33
  transform(object, parents) {
@@ -78,7 +78,9 @@ class DuplicateLiteralsRemoval extends _transform.default {
78
78
  super.apply(tree);
79
79
 
80
80
  if (this.arrayName && this.arrayExpression.elements.length) {
81
- (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.arrayName, this.arrayExpression)));
81
+ var getArrayFn = this.getPlaceholder();
82
+ (0, _insert.append)(tree, (0, _gen.FunctionDeclaration)(getArrayFn, [], [(0, _gen.ReturnStatement)(this.arrayExpression)]));
83
+ (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.arrayName, (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(getArrayFn), (0, _gen.Identifier)("call"), false), [(0, _gen.ThisExpression)()]))));
82
84
  }
83
85
  }
84
86
 
@@ -125,7 +127,7 @@ class DuplicateLiteralsRemoval extends _transform.default {
125
127
  }
126
128
 
127
129
  this.fnGetters.set(lexContext, getterName);
128
- (0, _insert.prepend)(lexContext, (0, _gen.FunctionDeclaration)(getterName, [(0, _gen.Identifier)("index")], body));
130
+ (0, _insert.prepend)(lexContext, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(getterName, (0, _gen.CallExpression)((0, _gen.FunctionExpression)([], [(0, _gen.ReturnStatement)((0, _gen.FunctionExpression)([(0, _gen.Identifier)("index")], body))]), []))));
129
131
  }
130
132
 
131
133
  var theShift = this.fnShifts.get(getterName);
@@ -129,12 +129,15 @@ class HideInitializingCode extends _transform.default {
129
129
  });
130
130
  var map = new Map();
131
131
  var fnsToMake = (0, _random.getRandomInteger)(1, 5);
132
+ var numberLiteralsMade = 1;
132
133
 
133
134
  function numberLiteral(num, depth = 1) {
134
- if (depth > 6 || Math.random() > 0.8 / depth) {
135
+ if (depth > 6 || Math.random() > 0.8 / depth || Math.random() > 80 / numberLiteralsMade) {
135
136
  return (0, _gen.Literal)(num);
136
137
  }
137
138
 
139
+ numberLiteralsMade++;
140
+
138
141
  function ternaryCall(name, param = (0, _random.getRandomInteger)(-250, 250)) {
139
142
  return (0, _gen.ConditionalExpression)((0, _gen.BinaryExpression)("==", (0, _gen.UnaryExpression)("typeof", (0, _gen.Identifier)(name)), (0, _gen.Literal)("function")), (0, _gen.CallExpression)((0, _gen.Identifier)(name), [numberLiteral(param, depth + 1)]), (0, _gen.Identifier)(name));
140
143
  }
@@ -140,8 +140,8 @@ class GlobalConcealing extends _transform.default {
140
140
  var getGlobalVariableFnName = this.getPlaceholder();
141
141
  var getThisVariableFnName = this.getPlaceholder(); // Returns global variable or fall backs to `this`
142
142
 
143
- var getGlobalVariableFn = (0, _template.default)("\n function ".concat(getGlobalVariableFnName, "(){\n try {\n return ").concat(global, ";\n } catch (e){\n return ").concat(getThisVariableFnName, "();\n }\n }")).single();
144
- var getThisVariableFn = (0, _template.default)("\n function ".concat(getThisVariableFnName, "(){\n try {\n return this;\n } catch (e){\n return null;\n }\n }")).single(); // 2. Replace old accessors
143
+ var getGlobalVariableFn = (0, _template.default)("\n var ".concat(getGlobalVariableFnName, " = function(){\n try {\n return ").concat(global, ";\n } catch (e){\n return ").concat(getThisVariableFnName, "[\"call\"](this);\n }\n }")).single();
144
+ var getThisVariableFn = (0, _template.default)("\n var ".concat(getThisVariableFnName, " = function(){\n try {\n return this;\n } catch (e){\n return null;\n }\n }")).single(); // 2. Replace old accessors
145
145
 
146
146
  var globalFn = this.getPlaceholder();
147
147
  var newNames = Object.create(null);
@@ -183,13 +183,23 @@ class GlobalConcealing extends _transform.default {
183
183
  newNames[name] = state;
184
184
  }
185
185
  });
186
- (0, _insert.prepend)(object, (0, _gen.FunctionDeclaration)(globalFn, [(0, _gen.Identifier)("index")], [(0, _gen.SwitchStatement)((0, _gen.Identifier)("index"), Object.keys(newNames).map(name => {
186
+ var indexParamName = this.getPlaceholder();
187
+ var returnName = this.getPlaceholder();
188
+ var functionDeclaration = (0, _gen.FunctionDeclaration)(globalFn, [(0, _gen.Identifier)(indexParamName)], [(0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(returnName)), (0, _gen.SwitchStatement)((0, _gen.Identifier)(indexParamName), Object.keys(newNames).map(name => {
187
189
  var code = newNames[name];
188
- return (0, _gen.SwitchCase)((0, _gen.Literal)(code), [(0, _gen.ReturnStatement)((0, _gen.LogicalExpression)("||", (0, _gen.MemberExpression)((0, _gen.Identifier)(globalVar), (0, _gen.Literal)(name), true), (0, _gen.MemberExpression)((0, _gen.Identifier)(thisVar), (0, _gen.Literal)(name), true)))]);
189
- }))]));
190
- (0, _insert.prepend)(object, (0, _template.default)("\n var ".concat(globalVar, " = ").concat(getGlobalVariableFnName, ".call(this), ").concat(thisVar, " = ").concat(getGlobalVariableFnName, ".call(this);\n ")).single());
191
- (0, _insert.prepend)(object, getGlobalVariableFn);
192
- (0, _insert.prepend)(object, getThisVariableFn);
190
+ var body = [(0, _gen.ReturnStatement)((0, _gen.LogicalExpression)("||", (0, _gen.MemberExpression)((0, _gen.Identifier)(globalVar), (0, _gen.Literal)(name), true), (0, _gen.MemberExpression)((0, _gen.Identifier)(thisVar), (0, _gen.Literal)(name), true)))];
191
+
192
+ if (Math.random() > 0.5 && name) {
193
+ body = [(0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(returnName), (0, _gen.LogicalExpression)("||", (0, _gen.Literal)(name), (0, _gen.MemberExpression)((0, _gen.Identifier)(thisVar), (0, _gen.Literal)(name), true)))), (0, _gen.BreakStatement)()];
194
+ }
195
+
196
+ return (0, _gen.SwitchCase)((0, _gen.Literal)(code), body);
197
+ })), (0, _gen.ReturnStatement)((0, _gen.LogicalExpression)("||", (0, _gen.MemberExpression)((0, _gen.Identifier)(globalVar), (0, _gen.Identifier)(returnName), true), (0, _gen.MemberExpression)((0, _gen.Identifier)(thisVar), (0, _gen.Identifier)(returnName), true)))]);
198
+ var tempVar = this.getPlaceholder();
199
+ var variableDeclaration = (0, _template.default)("\n var ".concat(globalVar, ", ").concat(thisVar, ";\n ")).single();
200
+ variableDeclaration.declarations.push((0, _gen.VariableDeclarator)(tempVar, (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.FunctionExpression)([], [getGlobalVariableFn, getThisVariableFn, (0, _template.default)("return ".concat(thisVar, " = ").concat(getThisVariableFnName, "[\"call\"](this, ").concat(globalFn, "), ").concat(globalVar, " = ").concat(getGlobalVariableFnName, "[\"call\"](this)")).single()]), (0, _gen.Literal)("call"), true), [])));
201
+ (0, _insert.prepend)(object, variableDeclaration);
202
+ (0, _insert.append)(object, functionDeclaration);
193
203
  }
194
204
  };
195
205
  }
@@ -100,7 +100,7 @@ class VariableAnalysis extends _transform.default {
100
100
  this.globals.add(o.name);
101
101
  }
102
102
 
103
- var definingContexts = info.spec.isDefined ? [(0, _insert.getDefiningContext)(o, p)] : (0, _insert.getReferencingContexts)(o, p);
103
+ var definingContexts = info.spec.isDefined ? [(0, _insert.getDefiningContext)(o, p)] : (0, _insert.getReferencingContexts)(o, p, info);
104
104
  (0, _assert.ok)(definingContexts.length);
105
105
  definingContexts.forEach(definingContext => {
106
106
  (0, _assert.ok)((0, _insert.isContext)(definingContext), "".concat(definingContext.type, " is not a context"));
@@ -27,7 +27,7 @@ class Label extends _transform.default {
27
27
  }
28
28
 
29
29
  match(object, parents) {
30
- return (0, _compare.isLoop)(object);
30
+ return (0, _compare.isLoop)(object) || object.type == "BlockStatement" && parents[0] && parents[0].type == "LabeledStatement" && parents[0].body === object;
31
31
  }
32
32
 
33
33
  transform(object, parents) {
@@ -36,7 +36,16 @@ class Label extends _transform.default {
36
36
  var label = currentLabel || this.getPlaceholder();
37
37
  (0, _traverse.walk)(object, parents, (o, p) => {
38
38
  if (o.type == "BreakStatement" || o.type == "ContinueStatement") {
39
- var loop = p.find(x => (0, _compare.isLoop)(x));
39
+ function isContinuableStatement(x) {
40
+ return (0, _compare.isLoop)(x) && x.type !== "SwitchStatement";
41
+ }
42
+
43
+ function isBreakableStatement(x) {
44
+ return (0, _compare.isLoop)(x) || o.label && x.type == "BlockStatement";
45
+ }
46
+
47
+ var fn = o.type == "ContinueStatement" ? isContinuableStatement : isBreakableStatement;
48
+ var loop = p.find(fn);
40
49
 
41
50
  if (object == loop) {
42
51
  if (!o.label) {
@@ -23,20 +23,31 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
23
23
 
24
24
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
25
25
 
26
- var DevToolsDetection = (0, _template.default)("\n function $jsc_debug(){\n\n var isDev1 = !(\"\" + function() {/* Hello world */}).includes(\"/*\");\n var s = \"s\";\n while (isDev1) {\n s = s + s;\n }\n\n var startTime = new Date();\n debugger;\n var endTime = new Date();\n var isDev2 = endTime-startTime > 600;\n \n var a = \"a\";\n while (isDev2) {\n a = a + a;\n }\n \n }\n try {\n if ( setInterval ) {\n setInterval(()=>{\n $jsc_debug();\n }, 4000);\n }\n } catch ( e ) {\n\n }\n \n");
26
+ var DevToolsDetection = (0, _template.default)("\n try {\n if ( setInterval ) {\n setInterval(()=>{\n {functionName}();\n }, 4000);\n }\n } catch ( e ) {\n\n }\n");
27
27
 
28
28
  class AntiDebug extends _transform.default {
29
- constructor(o) {
29
+ constructor(o, lock) {
30
30
  super(o, _order.ObfuscateOrder.Lock);
31
31
 
32
32
  _defineProperty(this, "made", void 0);
33
33
 
34
+ _defineProperty(this, "lock", void 0);
35
+
36
+ this.lock = lock;
34
37
  this.made = 0;
35
38
  }
36
39
 
37
40
  apply(tree) {
38
41
  super.apply(tree);
39
- tree.body.unshift(...DevToolsDetection.compile());
42
+ var fnName = this.getPlaceholder();
43
+ var startTimeName = this.getPlaceholder();
44
+ var endTimeName = this.getPlaceholder();
45
+ var isDevName = this.getPlaceholder();
46
+ var functionDeclaration = (0, _gen.FunctionDeclaration)(fnName, [], [...(0, _template.default)("\n var ".concat(startTimeName, " = new Date();\n debugger;\n var ").concat(endTimeName, " = new Date();\n var ").concat(isDevName, " = ").concat(endTimeName, "-").concat(startTimeName, " > 1000;\n ")).compile(), (0, _gen.IfStatement)((0, _gen.Identifier)(isDevName), this.options.lock.countermeasures ? this.lock.getCounterMeasuresCode() : [(0, _gen.WhileStatement)((0, _gen.Identifier)(isDevName), [(0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(startTimeName), (0, _gen.Identifier)(endTimeName)))])], null)]);
47
+ tree.body.unshift(...DevToolsDetection.compile({
48
+ functionName: fnName
49
+ }));
50
+ tree.body.push(functionDeclaration);
40
51
  }
41
52
 
42
53
  match(object, parents) {
@@ -44,17 +55,25 @@ class AntiDebug extends _transform.default {
44
55
  }
45
56
 
46
57
  transform(object, parents) {
47
- var body = (0, _insert.getBlockBody)(object.body);
48
- [...body].forEach(stmt => {
49
- if (Math.random() < 0.1 / (this.made || 1)) {
50
- var index = (0, _random.getRandomInteger)(0, body.length);
51
-
52
- if (body[index].type != "DebuggerStatement") {
53
- body.splice(index, 0, (0, _gen.DebuggerStatement)());
54
- this.made++;
58
+ return () => {
59
+ var body = (0, _insert.getBlockBody)(object.body);
60
+ [...body].forEach((stmt, i) => {
61
+ var addDebugger = Math.random() < 0.1 / (this.made || 1);
62
+
63
+ if (object.type == "Program" && i == 0) {
64
+ addDebugger = true;
65
+ }
66
+
67
+ if (addDebugger) {
68
+ var index = (0, _random.getRandomInteger)(0, body.length);
69
+
70
+ if (body[index].type != "DebuggerStatement") {
71
+ body.splice(index, 0, (0, _gen.DebuggerStatement)());
72
+ this.made++;
73
+ }
55
74
  }
56
- }
57
- });
75
+ });
76
+ };
58
77
  }
59
78
 
60
79
  }
@@ -62,7 +62,7 @@ class Lock extends _transform.default {
62
62
  }
63
63
 
64
64
  if (this.options.lock.antiDebug) {
65
- this.before.push(new _antiDebug.default(o));
65
+ this.before.push(new _antiDebug.default(o, this));
66
66
  }
67
67
 
68
68
  this.made = 0;
@@ -104,7 +104,7 @@ class Lock extends _transform.default {
104
104
  });
105
105
 
106
106
  if (!this.counterMeasuresNode) {
107
- throw new Error("Countermeasures function named '" + this.options.lock.countermeasures + "' was not found. Names found: " + Array.from(defined).slice(0, 100).join(", "));
107
+ throw new Error("Countermeasures function named '" + this.options.lock.countermeasures + "' was not found.");
108
108
  }
109
109
  }
110
110
 
@@ -238,7 +238,7 @@ class Lock extends _transform.default {
238
238
  case "selfDefending":
239
239
  // A very simple mechanism inspired from https://github.com/javascript-obfuscator/javascript-obfuscator/blob/master/src/custom-code-helpers/self-defending/templates/SelfDefendingNoEvalTemplate.ts
240
240
  // regExp checks for a newline, formatters add these
241
- var callExpression = (0, _template.default)("\n (\n function(){\n\n var namedFunction = function(){\n const test= function(){\n const regExp=new RegExp('\\n');\n return regExp['test'](namedFunction)\n };\n return test()\n }\n\n return namedFunction();\n }\n )()\n ").single().expression;
241
+ var callExpression = (0, _template.default)("\n (\n function(){\n // Breaks JSNice.org, beautifier.io\n var namedFunction = function(){\n const test = function(){\n const regExp=new RegExp('\\n');\n return regExp['test'](namedFunction)\n };\n return test()\n }\n\n return namedFunction();\n }\n )()\n ").single().expression;
242
242
  nodes.push((0, _gen.IfStatement)(callExpression, this.getCounterMeasuresCode() || [], null));
243
243
  break;
244
244
 
@@ -314,7 +314,7 @@ class Minify extends _transform.default {
314
314
  if (last) {
315
315
  var lastStatement = last.consequent[last.consequent.length - 1];
316
316
 
317
- if (lastStatement.type == "BreakStatement" && lastStatement.label == null) {
317
+ if (lastStatement && lastStatement.type == "BreakStatement" && lastStatement.label == null) {
318
318
  last.consequent.pop();
319
319
  }
320
320
  } else {
@@ -410,7 +410,7 @@ class Minify extends _transform.default {
410
410
  var key = object.callee.computed ? object.callee.property.value : object.callee.property.name;
411
411
 
412
412
  if (key == "toString" && object.arguments.length == 0) {
413
- this.replace(object, (0, _gen.BinaryExpression)("+", (0, _insert.clone)(object.callee.object), (0, _gen.Literal)("")));
413
+ this.replace(object, (0, _gen.BinaryExpression)("+", (0, _gen.Literal)(""), (0, _insert.clone)(object.callee.object)));
414
414
  }
415
415
  }
416
416
  } // { "x": 1 } -> {x: 1}
@@ -89,7 +89,8 @@ class OpaquePredicates extends _transform.default {
89
89
  if (!this.predicate) {
90
90
  this.predicateName = this.getPlaceholder();
91
91
  this.predicate = (0, _gen.ObjectExpression)([]);
92
- (0, _insert.prepend)(parents[parents.length - 1] || object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.predicateName, this.predicate)));
92
+ var tempName = this.getPlaceholder();
93
+ (0, _insert.prepend)(parents[parents.length - 1] || object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(this.predicateName, (0, _gen.CallExpression)((0, _gen.FunctionExpression)([], [(0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(tempName, this.predicate)), (0, _gen.ReturnStatement)((0, _gen.Identifier)(tempName))]), []))));
93
94
  }
94
95
 
95
96
  var expr = (0, _random.choice)(Object.values(this.predicates));
@@ -102,7 +103,8 @@ class OpaquePredicates extends _transform.default {
102
103
  case "array":
103
104
  var arrayProp = this.gen.generate();
104
105
  this.predicate.properties.push((0, _gen.Property)((0, _gen.Identifier)(arrayProp), (0, _gen.ArrayExpression)([])));
105
- this.predicate.properties.push((0, _gen.Property)((0, _gen.Identifier)(prop), (0, _gen.FunctionExpression)([], (0, _template.default)("\n if ( !".concat(this.predicateName, ".").concat(arrayProp, "[0] ) {\n ").concat(this.predicateName, ".").concat(arrayProp, ".push(").concat((0, _random.getRandomInteger)(-100, 100), ");\n }\n return ").concat(this.predicateName, ".").concat(arrayProp, ".length;\n ")).compile())));
106
+ var paramName = this.getPlaceholder();
107
+ this.predicate.properties.push((0, _gen.Property)((0, _gen.Identifier)(prop), (0, _gen.FunctionExpression)([(0, _gen.AssignmentPattern)((0, _gen.Identifier)(paramName), (0, _gen.Literal)("length"))], (0, _template.default)("\n if ( !".concat(this.predicateName, ".").concat(arrayProp, "[0] ) {\n ").concat(this.predicateName, ".").concat(arrayProp, ".push(").concat((0, _random.getRandomInteger)(-100, 100), ");\n }\n return ").concat(this.predicateName, ".").concat(arrayProp, "[").concat(paramName, "];\n ")).compile())));
106
108
  expr = (0, _gen.CallExpression)(accessor, []);
107
109
  break;
108
110
 
@@ -88,6 +88,14 @@ class ExplicitIdentifiers extends _transform.default {
88
88
  }
89
89
 
90
90
  transform(object, parents) {
91
+ if (object.name === "eval") {
92
+ var fn = (0, _insert.getFunction)(object, parents);
93
+
94
+ if (fn) {
95
+ fn.$requiresEval = true;
96
+ }
97
+ }
98
+
91
99
  var info = (0, _identifiers.getIdentifierInfo)(object, parents);
92
100
 
93
101
  if (info.isPropertyKey || info.isAccessor) {
@@ -40,12 +40,25 @@ class RenameLabels extends _transform.default {
40
40
  transform(object, parents) {
41
41
  return () => {
42
42
  var newName = null;
43
+ var isRemovable = object.body.type !== "BlockStatement";
44
+ var labelNeverUsed = true;
43
45
  (0, _traverse.walk)(object, parents, (o, p) => {
44
46
  if (o.type == "BreakStatement" || o.type == "ContinueStatement") {
45
- var labelStatement = p.find(x => (0, _compare.isLoop)(x));
47
+ function isContinuableStatement(x, stmtParents) {
48
+ return (0, _compare.isLoop)(x) && x.type !== "SwitchStatement";
49
+ }
50
+
51
+ function isBreakableStatement(x, stmtParents) {
52
+ return (0, _compare.isLoop)(x) || x.type == "BlockStatement" && o.label && stmtParents[0] && stmtParents[0].type == "LabeledStatement";
53
+ }
54
+
55
+ var fn = o.type == "ContinueStatement" ? isContinuableStatement : isBreakableStatement;
56
+ var labelStatement = p.find((node, i) => {
57
+ return fn(node, p.slice(i + 1));
58
+ });
46
59
 
47
60
  if (o.label && o.label.name == object.label.name) {
48
- if (object.body == labelStatement) {
61
+ if (object.body == labelStatement && isRemovable) {
49
62
  // In same loop
50
63
  o.label = null;
51
64
  } else {
@@ -54,6 +67,7 @@ class RenameLabels extends _transform.default {
54
67
  }
55
68
 
56
69
  o.label = (0, _gen.Identifier)(newName);
70
+ labelNeverUsed = false;
57
71
  }
58
72
  }
59
73
  }
@@ -61,7 +75,7 @@ class RenameLabels extends _transform.default {
61
75
 
62
76
  if (newName) {
63
77
  object.label = (0, _gen.Identifier)(newName);
64
- } else {
78
+ } else if (isRemovable || labelNeverUsed) {
65
79
  this.replace(object, (0, _insert.clone)(object.body));
66
80
  }
67
81
  };
@@ -71,7 +71,7 @@ class RGF extends _transform.default {
71
71
  var names = new Map();
72
72
  var definingNodes = new Map();
73
73
  (0, _traverse.walk)(contextObject, contextParents, (object, parents) => {
74
- if (object !== contextObject && (0, _insert.isFunction)(object) && !object.async && !object.generator && (0, _insert.getVarContext)(parents[0], parents.slice(1)) === contextObject) {
74
+ if (object !== contextObject && (0, _insert.isFunction)(object) && !object.$requiresEval && !object.async && !object.generator && (0, _insert.getVarContext)(parents[0], parents.slice(1)) === contextObject) {
75
75
  var defined = new Set(),
76
76
  referenced = new Set();
77
77
  var isBound = false;
@@ -79,9 +79,13 @@ class RGF extends _transform.default {
79
79
  if (o.type == "Identifier" && !_constants.reservedIdentifiers.has(o.name) && !this.options.globalVariables.has(o.name)) {
80
80
  var info = (0, _identifiers.getIdentifierInfo)(o, p);
81
81
 
82
+ if (!info.spec.isReferenced) {
83
+ return;
84
+ }
85
+
82
86
  if (info.spec.isDefined) {
83
87
  defined.add(o.name);
84
- } else if (info.spec.isReferenced || info.spec.isModified) {
88
+ } else {
85
89
  referenced.add(o.name);
86
90
  }
87
91
  }
@@ -205,7 +209,8 @@ class RGF extends _transform.default {
205
209
  lock: {
206
210
  integrity: false
207
211
  },
208
- eval: false
212
+ eval: false,
213
+ hideInitializingCode: false
209
214
  });
210
215
  var transforms = Object.values(obfuscator.transforms).filter(x => x.priority > this.priority);
211
216
  var embeddedFunction = { ...object,
@@ -37,7 +37,7 @@ class Stack extends _transform.default {
37
37
  }
38
38
 
39
39
  match(object, parents) {
40
- return (0, _insert.isFunction)(object) && !object.params.find(x => x.type !== "Identifier") && object.body.type === "BlockStatement" && !parents.find(x => x.$dispatcherSkip);
40
+ return (0, _insert.isFunction)(object) && !object.params.find(x => x.type !== "Identifier") && object.body.type === "BlockStatement" && !parents.find(x => x.$dispatcherSkip) && !object.$requiresEval;
41
41
  }
42
42
 
43
43
  transform(object, parents) {
@@ -129,6 +129,80 @@ const Encoding = {
129
129
  return o;
130
130
  },
131
131
  template: (0, _template.default)("\n function {name}(s) {\n var v,\n x,\n b = 0,\n o = \"\",\n len = s.length,\n d = String,\n e = \"charCodeAt\",\n f = \"fromCharCode\", i;\n \n for (i = 0; i < len; i += 1) {\n (v = s[e](i) - 33),\n v >= 0 && v < 32\n ? ((b += ((x = (x << 5) | v), 5)),\n b >= 8\n ? (b -= ((o += d[f]((x >> (b - 8)) & 0xff)), 8))\n : 0)\n : 0;\n }\n return o;\n }\n ")
132
+ },
133
+ hexTable: {
134
+ encode: function (str) {
135
+ var output = "";
136
+
137
+ for (var j = 0; j < str.length; j += 3) {
138
+ var chunk = str.substring(j, j + 3);
139
+
140
+ if (!chunk) {
141
+ continue;
142
+ }
143
+
144
+ chunk = chunk + "~";
145
+ var uniqueChars = new Set([]);
146
+
147
+ for (var char of chunk) {
148
+ uniqueChars.add(char);
149
+ }
150
+
151
+ var keys = Array.from(uniqueChars).sort();
152
+ var table = {},
153
+ i = 0;
154
+
155
+ for (var key of keys) {
156
+ table[key] = i++;
157
+ }
158
+
159
+ var idx = [];
160
+
161
+ for (var char of chunk) {
162
+ idx.push(table[char]);
163
+ }
164
+
165
+ var table64 = "0x";
166
+
167
+ for (var i = keys.length - 1; i >= 0; i--) {
168
+ table64 += keys[i].charCodeAt(0).toString(16).toUpperCase();
169
+ }
170
+
171
+ var idxInt = 0;
172
+
173
+ for (var i = idx.length - 1; i >= 0; i--) {
174
+ idxInt = idxInt << 3 | idx[i];
175
+ }
176
+
177
+ var idx64 = "0x" + idxInt.toString(16).toUpperCase(); // console.log(chunk, table, idx, table64, idx64);
178
+
179
+ output += table64 + "," + idx64 + ",";
180
+ }
181
+
182
+ if (output.endsWith(",")) {
183
+ output = output.substring(0, output.length - 1);
184
+ }
185
+
186
+ return "{" + output + "}";
187
+ },
188
+ decode: function (str) {
189
+ var output = "";
190
+ str = str.substring(1, str.length - 1);
191
+ var chunks = str.split(",");
192
+
193
+ for (var i = 0; i < chunks.length; i += 2) {
194
+ var arr = [chunks[i], chunks[i + 1]];
195
+ var [table, idx] = arr.map(Number); // console.log(table, idx);
196
+
197
+ while (idx) {
198
+ output += String.fromCharCode(table >> 8 * (idx & 7) & 0xff);
199
+ idx >>= 3;
200
+ }
201
+ }
202
+
203
+ return output.replace(/~/g, "");
204
+ },
205
+ template: (0, _template.default)("\n function {name}(str){\n var output = \"\";\n \n str = str.substring(1, str.length - 1);\n var chunks = str.split(\",\");\n \n for (var i = 0; i < chunks.length; i += 2) {\n var arr = [chunks[i], chunks[i + 1]];\n \n var [table, idx] = arr.map(Number);\n \n // console.log(table, idx);\n while (idx) {\n output += String.fromCharCode((table >> (8 * (idx & 7))) & 0xff);\n idx >>= 3;\n }\n }\n \n return output.replace(/~/g, \"\");\n }\n \n ")
132
206
  }
133
207
  };
134
208
  var _default = Encoding;
@@ -94,14 +94,18 @@ class StringCompression extends _transform.default {
94
94
 
95
95
  var split = this.getPlaceholder();
96
96
  var decoder = this.getPlaceholder();
97
+ var getStringName = this.getPlaceholder();
97
98
  var encoded = LZ_encode(this.string);
98
99
 
99
100
  if (LZ_decode(encoded) !== this.string) {
100
101
  this.error(new Error("String failed to be decoded"));
101
102
  }
102
103
 
103
- var callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(decoder), [(0, _gen.Literal)(encoded)]);
104
- (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(split, callExpression)));
104
+ var getStringParamName = this.getPlaceholder();
105
+ var decoderParamName = this.getPlaceholder();
106
+ var callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(decoderParamName), [(0, _gen.CallExpression)((0, _gen.Identifier)(getStringParamName), [])]);
107
+ (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(split, (0, _gen.CallExpression)((0, _gen.FunctionExpression)([(0, _gen.Identifier)(getStringParamName), (0, _gen.Identifier)(decoderParamName)], [(0, _gen.ReturnStatement)(callExpression)]), [(0, _gen.Identifier)(getStringName), (0, _gen.Identifier)(decoder)]))));
108
+ (0, _insert.append)(tree, (0, _gen.FunctionDeclaration)(getStringName, [], [(0, _gen.ReturnStatement)((0, _gen.Literal)(encoded))]));
105
109
  (0, _insert.append)(tree, (0, _gen.FunctionDeclaration)(this.fnName, [(0, _gen.Identifier)("index")], [(0, _gen.ReturnStatement)((0, _gen.MemberExpression)((0, _gen.Identifier)(split), (0, _gen.Identifier)("index"), true))]));
106
110
  (0, _insert.append)(tree, DecodeTemplate.single({
107
111
  name: decoder,
@@ -101,7 +101,7 @@ class StringConcealing extends _transform.default {
101
101
  (0, _insert.append)(tree, template.single({
102
102
  name: decodeFn
103
103
  }));
104
- (0, _insert.append)(tree, (0, _template.default)("\n \n function ".concat(getterFn, "(x, y, z, a = ").concat(decodeFn, ", b = ").concat(cacheName, "){\n if ( z ) {\n return y[").concat(cacheName, "[z]] = ").concat(getterFn, "(x, y);\n }\n \n return y ? x[b[y]] : ").concat(cacheName, "[x] || (z=(b[x], a), ").concat(cacheName, "[x] = z(").concat(this.arrayName, "[x]))\n }\n \n ")).single());
104
+ (0, _insert.append)(tree, (0, _template.default)("\n \n function ".concat(getterFn, "(x, y, z, a = ").concat(decodeFn, ", b = ").concat(cacheName, "){\n if ( z ) {\n return y[").concat(cacheName, "[z]] = ").concat(getterFn, "(x, y);\n } else if ( y ) {\n [b, y] = [a(b), x || z]\n }\n \n return y ? x[b[y]] : ").concat(cacheName, "[x] || (z=(b[x], a), ").concat(cacheName, "[x] = z(").concat(this.arrayName, "[x]))\n }\n \n ")).single());
105
105
  });
106
106
  var flowIntegrity = this.getPlaceholder();
107
107
  (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)(cacheName, (0, _gen.ArrayExpression)([])), (0, _gen.VariableDeclarator)(flowIntegrity, (0, _gen.Literal)(0)), (0, _gen.VariableDeclarator)(this.arrayName, (0, _gen.CallExpression)((0, _gen.FunctionExpression)([], [(0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)("a", this.arrayExpression)), (0, _template.default)("return (".concat(flowIntegrity, " ? a.pop() : ").concat(flowIntegrity, "++, a)")).single()]), []))]));
@@ -21,6 +21,8 @@ var _compare = require("../../util/compare");
21
21
 
22
22
  var _assert = require("assert");
23
23
 
24
+ var _probability = require("../../probability");
25
+
24
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
27
 
26
28
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -81,6 +83,10 @@ class StringSplitting extends _transform.default {
81
83
  return;
82
84
  }
83
85
 
86
+ if (!(0, _probability.ComputeProbabilityMap)(this.options.stringSplitting, x => x, object.value)) {
87
+ return;
88
+ }
89
+
84
90
  var binaryExpression;
85
91
  var parent;
86
92
  var last = chunks.pop();