소스 검색

now use underscore for various operations.
control flow flattening continues refactoring

sanex3339 8 년 전
부모
커밋
90021e251c

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 255 - 246
dist/index.js


+ 5 - 4
package.json

@@ -28,11 +28,11 @@
     "esprima": "3.1.2",
     "estraverse": "4.2.0",
     "inversify": "^3.0.0-rc.2",
-    "is-equal": "^1.5.3",
     "mkdirp": "0.5.1",
     "reflect-metadata": "^0.1.8",
     "source-map-support": "0.4.6",
-    "string-template": "^1.0.0"
+    "string-template": "^1.0.0",
+    "underscore": "^1.8.3"
   },
   "devDependencies": {
     "@types/chai": "3.4.34",
@@ -45,10 +45,11 @@
     "@types/joi": "9.0.33",
     "@types/mkdirp": "0.3.29",
     "@types/mocha": "2.2.33",
-    "@types/node": "6.0.51",
+    "@types/node": "6.0.52",
     "@types/sinon": "1.16.33",
     "@types/string-template": "1.0.2",
-    "awesome-typescript-loader": "3.0.0-beta.14",
+    "@types/underscore": "^1.7.36",
+    "awesome-typescript-loader": "3.0.0-beta.17",
     "babel-cli": "6.18.0",
     "babel-loader": "6.2.9",
     "babel-preset-es2015": "6.18.0",

+ 1 - 3
src/cli/CLIUtils.ts

@@ -4,8 +4,6 @@ import * as path from 'path';
 
 import { IPackageConfig } from '../interfaces/IPackageConfig';
 
-import { Utils } from '../utils/Utils';
-
 export class CLIUtils {
     /**
      * @type {string[]}
@@ -102,7 +100,7 @@ export class CLIUtils {
             throw new ReferenceError(`Given input path must be a valid file path`);
         }
 
-        if (!Utils.arrayContains(CLIUtils.availableInputExtensions, path.extname(inputPath))) {
+        if (!CLIUtils.availableInputExtensions.includes(path.extname(inputPath))) {
             throw new ReferenceError(`Input file must have .js extension`);
         }
     }

+ 2 - 3
src/cli/JavaScriptObfuscatorCLI.ts

@@ -13,7 +13,6 @@ import { DEFAULT_PRESET } from '../preset-options/DefaultPreset';
 
 import { CLIUtils } from './CLIUtils';
 import { JavaScriptObfuscator } from '../JavaScriptObfuscator';
-import { Utils } from '../utils/Utils';
 
 export class JavaScriptObfuscatorCLI {
     /**
@@ -104,7 +103,7 @@ export class JavaScriptObfuscatorCLI {
     public run (): void {
         this.configureCommands();
 
-        if (!this.arguments.length || Utils.arrayContains(this.arguments, '--help')) {
+        if (!this.arguments.length || this.arguments.includes('--help')) {
             this.commands.outputHelp();
 
             return;
@@ -129,7 +128,7 @@ export class JavaScriptObfuscatorCLI {
                 continue;
             }
 
-            if (!Utils.arrayContains(availableOptions, option)) {
+            if (!availableOptions.includes(option)) {
                 continue;
             }
 

+ 1 - 1
src/interfaces/node-transformers/IControlFlowData.d.ts → src/interfaces/node-transformers/IControlFlowNodeMetadata.d.ts

@@ -1,7 +1,7 @@
 import { ICustomNode } from '../custom-nodes/ICustomNode';
 import { IStorage } from '../storages/IStorage';
 
-export interface IControlFlowData {
+export interface IControlFlowNodeMetadata {
     controlFlowStorage: IStorage<ICustomNode>;
     controlFlowStorageNodeName: string;
 }

+ 5 - 0
src/interfaces/storages/IStorage.d.ts

@@ -28,6 +28,11 @@ export interface IStorage <T> extends IInitializable {
      */
     initialize (...args: any[]): void;
 
+    /**
+     * @param storage
+     */
+    mergeWith (storage: this): void;
+
     /**
      * @param key
      * @param value

+ 29 - 22
src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts

@@ -3,6 +3,7 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
 
 import * as estraverse from 'estraverse';
 import * as ESTree from 'estree';
+import * as _ from 'underscore';
 
 import { TControlFlowReplacerFactory } from '../../types/container/TControlFlowReplacerFactory';
 import { TControlFlowStorageFactory } from '../../types/container/TControlFlowStorageFactory';
@@ -10,7 +11,7 @@ import { TCustomNodeFactory } from '../../types/container/TCustomNodeFactory';
 import { TNodeWithBlockStatement } from '../../types/node/TNodeWithBlockStatement';
 import { TStatement } from '../../types/node/TStatement';
 
-import { IControlFlowData } from '../../interfaces/node-transformers/IControlFlowData';
+import { IControlFlowNodeMetadata } from '../../interfaces/node-transformers/IControlFlowNodeMetadata';
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/options/IOptions';
 import { IStorage } from '../../interfaces/storages/IStorage';
@@ -35,9 +36,9 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
     ]);
 
     /**
-     * @type {Map<ESTree.Node, IControlFlowData>}
+     * @type {Map<ESTree.Node, IControlFlowNodeMetadata>}
      */
-    private controlFlowData: Map <ESTree.Node, IControlFlowData> = new Map <ESTree.Node, IControlFlowData> ();
+    private controlFlowData: Map <ESTree.Node, IControlFlowNodeMetadata> = new Map <ESTree.Node, IControlFlowNodeMetadata> ();
 
     /**
      * @type {TStatement[][]}
@@ -78,6 +79,27 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
         this.customNodeFactory = customNodeFactory;
     }
 
+    /**
+     * @param hostNodeBody
+     * @param controlFlowNodesList
+     */
+    private static removeOldControlFlowNodeFromHostNodeBody (
+        hostNodeBody: TStatement[],
+        controlFlowNodesList: TStatement[][]
+    ): TStatement[] {
+        for (let controlFlowNode of controlFlowNodesList) {
+            const firstIndexOfNode: number = hostNodeBody.indexOf(controlFlowNode[0]);
+
+            if (firstIndexOfNode === -1) {
+                continue;
+            }
+
+            return _.difference(hostNodeBody, controlFlowNode);
+        }
+
+        return hostNodeBody;
+    }
+
     /**
      * @param functionNode
      */
@@ -107,30 +129,15 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
                 controlFlowStorageNodeName
             });
         } else {
-            for (let controlFlowNode of this.controlFlowNodesList) {
-                const firstIndexOfNode: number = (<TStatement[]>hostNode.body).indexOf(controlFlowNode[0]);
-
-                if (firstIndexOfNode === -1) {
-                    continue;
-                }
-
-                const statementLength: number = controlFlowNode.length;
-
-                (<TStatement[]>hostNode.body).splice(firstIndexOfNode, statementLength);
-                break;
-            }
+            hostNode.body = FunctionControlFlowTransformer
+                .removeOldControlFlowNodeFromHostNodeBody(hostNode.body, this.controlFlowNodesList);
 
             const {
                 controlFlowStorage: hostControlFlowStorage,
                 controlFlowStorageNodeName: hostControlFlowStorageNodeName
-            } = <IControlFlowData>this.controlFlowData.get(hostNode);
-
-            hostControlFlowStorage
-                .getStorage()
-                .forEach((customNode: ICustomNode, key: string) => {
-                    controlFlowStorage.set(key, customNode);
-                });
+            } = <IControlFlowNodeMetadata>this.controlFlowData.get(hostNode);
 
+            controlFlowStorage.mergeWith(hostControlFlowStorage);
             controlFlowStorageNodeName = hostControlFlowStorageNodeName;
 
             this.controlFlowData.set(hostNode, {

+ 1 - 2
src/node-transformers/node-obfuscators/MethodDefinitionObfuscator.ts

@@ -11,7 +11,6 @@ import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscatorsR
 
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { Node } from '../../node/Node';
-import { Utils } from '../../utils/Utils';
 
 /**
  * replaces:
@@ -61,7 +60,7 @@ export class MethodDefinitionObfuscator extends AbstractNodeTransformer {
             enter: (node: ESTree.Node): any => {
                 if (
                     Node.isIdentifierNode(node) &&
-                    !Utils.arrayContains(MethodDefinitionObfuscator.ignoredNames, node.name) &&
+                    !MethodDefinitionObfuscator.ignoredNames.includes(node.name) &&
                     methodDefinitionNode.computed === false
                 ) {
                     methodDefinitionNode.computed = true;

+ 1 - 1
src/node-transformers/node-obfuscators/replacers/NumberLiteralReplacer.ts

@@ -22,7 +22,7 @@ export class NumberLiteralReplacer extends AbstractReplacer {
      * @returns {string}
      */
     public replace (nodeValue: number): string {
-        if (!Utils.isInteger(nodeValue)) {
+        if (!Utils.isCeilNumber(nodeValue)) {
             return String(nodeValue);
         }
 

+ 2 - 3
src/node/NodeUtils.ts

@@ -9,7 +9,6 @@ import { TStatement } from '../types/node/TStatement';
 import { NodeType } from '../enums/NodeType';
 
 import { Node } from './Node';
-import { Utils } from '../utils/Utils';
 
 export class NodeUtils {
     /**
@@ -100,7 +99,7 @@ export class NodeUtils {
                 throw new ReferenceError('`parentNode` property of `parentNode` of given node is `undefined`');
             }
 
-            if (!Utils.arrayContains(NodeUtils.nodesWithBlockScope, parentNode.parentNode.type)) {
+            if (!NodeUtils.nodesWithBlockScope.includes(parentNode.parentNode.type)) {
                 return NodeUtils.getBlockScopeOfNode(parentNode, depth);
             } else if (depth > 0) {
                 return NodeUtils.getBlockScopeOfNode(parentNode, --depth);
@@ -132,7 +131,7 @@ export class NodeUtils {
             return depth;
         }
 
-        if (Node.isBlockStatementNode(node) && Utils.arrayContains(NodeUtils.nodesWithBlockScope, parentNode.type)) {
+        if (Node.isBlockStatementNode(node) && NodeUtils.nodesWithBlockScope.includes(parentNode.type)) {
             return NodeUtils.getNodeBlockScopeDepth(parentNode, ++depth);
         }
 

+ 7 - 0
src/storages/ArrayStorage.ts

@@ -55,6 +55,13 @@ export abstract class ArrayStorage <T> implements IStorage <T> {
         this.storage = [];
     }
 
+    /**
+     * @param storage
+     */
+    public mergeWith (storage: this): void {
+        this.storage = [...this.storage, ...storage.getStorage()];
+    }
+
     /**
      * @param key
      * @param value

+ 8 - 1
src/storages/MapStorage.ts

@@ -33,7 +33,7 @@ export abstract class MapStorage <T> implements IStorage <T> {
      * @returns {string | number | null}
      */
     public getKeyOf (value: T): string | number | null {
-        return Utils.mapGetFirstKeyOf(this.storage, value);
+        return Utils.mapGetFirstKeyOf <string | number, T> (this.storage, value);
     }
 
     /**
@@ -57,6 +57,13 @@ export abstract class MapStorage <T> implements IStorage <T> {
         this.storage = new Map <string | number, T> ();
     }
 
+    /**
+     * @param storage
+     */
+    public mergeWith (storage: this): void {
+        this.storage = new Map <string | number, T> ([...this.storage, ...storage.getStorage()]);
+    }
+
     /**
      * @param key
      * @param value

+ 5 - 15
src/utils/Utils.ts

@@ -1,22 +1,12 @@
+import * as _ from 'underscore';
 import { JSFuck } from '../enums/JSFuck';
 
-const isEqual: any = require('is-equal');
-
 export class Utils {
     /**
      * @type {string}
      */
     public static readonly hexadecimalPrefix: string = '0x';
 
-    /**
-     * @param array
-     * @param searchElement
-     * @returns {boolean}
-     */
-    public static arrayContains (array: any[], searchElement: any): boolean {
-        return array.indexOf(searchElement) >= 0;
-    }
-
     /**
      * @param array
      * @param times
@@ -74,18 +64,18 @@ export class Utils {
      * @param number
      * @returns {boolean}
      */
-    public static isInteger (number: number): boolean {
+    public static isCeilNumber (number: number): boolean {
         return number % 1 === 0;
     }
 
     /**
      * @param map
      * @param value
-     * @returns {any}
+     * @returns {T | null}
      */
-    public static mapGetFirstKeyOf(map: Map <any, any>, value: any): any {
+    public static mapGetFirstKeyOf <T, U> (map: Map <T, U>, value: U): T | null {
         for (let [key, storageValue] of map) {
-            if (isEqual(value, storageValue)) {
+            if (_.isEqual(value, storageValue)) {
                 return key;
             }
         }

+ 18 - 18
test/fixtures/compile-performance.js

@@ -19813,8 +19813,8 @@
                 else {
                     mergedOutputs = outputs;
                 }
-                var mergedHost = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_2__facade_lang__["a" /* isPresent */])(dm.host) ? __WEBPACK_IMPORTED_MODULE_1__facade_collection__["b" /* StringMapWrapper */].merge(dm.host, host) : host;
-                var mergedQueries = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_2__facade_lang__["a" /* isPresent */])(dm.queries) ? __WEBPACK_IMPORTED_MODULE_1__facade_collection__["b" /* StringMapWrapper */].merge(dm.queries, queries) : queries;
+                var mergedHost = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_2__facade_lang__["a" /* isPresent */])(dm.host) ? __WEBPACK_IMPORTED_MODULE_1__facade_collection__["b" /* StringMapWrapper */].mergeWith(dm.host, host) : host;
+                var mergedQueries = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_2__facade_lang__["a" /* isPresent */])(dm.queries) ? __WEBPACK_IMPORTED_MODULE_1__facade_collection__["b" /* StringMapWrapper */].mergeWith(dm.queries, queries) : queries;
                 if (dm instanceof __WEBPACK_IMPORTED_MODULE_0__angular_core__["Component"]) {
                     return new __WEBPACK_IMPORTED_MODULE_0__angular_core__["Component"]({
                         selector: dm.selector,
@@ -25918,7 +25918,7 @@
         }
         function _createRootRenderer(rootRenderer /** TODO #9100 */, extraTokens) {
             __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__dom_adapter__["a" /* getDOM */])().setGlobalVar(INSPECT_GLOBAL_NAME, inspectNativeElement);
-            __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__dom_adapter__["a" /* getDOM */])().setGlobalVar(CORE_TOKENS_GLOBAL_NAME, __WEBPACK_IMPORTED_MODULE_1__facade_collection__["a" /* StringMapWrapper */].merge(CORE_TOKENS, _ngProbeTokensToMap(extraTokens || [])));
+            __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__dom_adapter__["a" /* getDOM */])().setGlobalVar(CORE_TOKENS_GLOBAL_NAME, __WEBPACK_IMPORTED_MODULE_1__facade_collection__["a" /* StringMapWrapper */].mergeWith(CORE_TOKENS, _ngProbeTokensToMap(extraTokens || [])));
             return new __WEBPACK_IMPORTED_MODULE_2__private_import_core__["b" /* DebugDomRootRenderer */](rootRenderer);
         }
         function _ngProbeTokensToMap(tokens) {
@@ -38913,14 +38913,14 @@
                         if (!_this._finished) {
                             var responseOptions_1 = new __WEBPACK_IMPORTED_MODULE_2__base_response_options__["a" /* ResponseOptions */]({ body: JSONP_ERR_NO_CALLBACK, type: __WEBPACK_IMPORTED_MODULE_3__enums__["a" /* ResponseType */].Error, url: url });
                             if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_4__facade_lang__["a" /* isPresent */])(baseResponseOptions)) {
-                                responseOptions_1 = baseResponseOptions.merge(responseOptions_1);
+                                responseOptions_1 = baseResponseOptions.mergeWith(responseOptions_1);
                             }
                             responseObserver.error(new __WEBPACK_IMPORTED_MODULE_6__static_response__["a" /* Response */](responseOptions_1));
                             return;
                         }
                         var responseOptions = new __WEBPACK_IMPORTED_MODULE_2__base_response_options__["a" /* ResponseOptions */]({ body: _this._responseData, url: url });
                         if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_4__facade_lang__["a" /* isPresent */])(_this.baseResponseOptions)) {
-                            responseOptions = _this.baseResponseOptions.merge(responseOptions);
+                            responseOptions = _this.baseResponseOptions.mergeWith(responseOptions);
                         }
                         responseObserver.next(new __WEBPACK_IMPORTED_MODULE_6__static_response__["a" /* Response */](responseOptions));
                         responseObserver.complete();
@@ -38932,7 +38932,7 @@
                         _dom.cleanup(script);
                         var responseOptions = new __WEBPACK_IMPORTED_MODULE_2__base_response_options__["a" /* ResponseOptions */]({ body: error.message, type: __WEBPACK_IMPORTED_MODULE_3__enums__["a" /* ResponseType */].Error });
                         if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_4__facade_lang__["a" /* isPresent */])(baseResponseOptions)) {
-                            responseOptions = baseResponseOptions.merge(responseOptions);
+                            responseOptions = baseResponseOptions.mergeWith(responseOptions);
                         }
                         responseObserver.error(new __WEBPACK_IMPORTED_MODULE_6__static_response__["a" /* Response */](responseOptions));
                     };
@@ -39075,7 +39075,7 @@
                         var statusText = _xhr.statusText || 'OK';
                         var responseOptions = new __WEBPACK_IMPORTED_MODULE_3__base_response_options__["a" /* ResponseOptions */]({ body: body, status: status, headers: headers, statusText: statusText, url: url });
                         if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_5__facade_lang__["a" /* isPresent */])(baseResponseOptions)) {
-                            responseOptions = baseResponseOptions.merge(responseOptions);
+                            responseOptions = baseResponseOptions.mergeWith(responseOptions);
                         }
                         var response = new __WEBPACK_IMPORTED_MODULE_9__static_response__["a" /* Response */](responseOptions);
                         response.ok = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_7__http_utils__["d" /* isSuccess */])(status);
@@ -39096,7 +39096,7 @@
                             statusText: _xhr.statusText,
                         });
                         if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_5__facade_lang__["a" /* isPresent */])(baseResponseOptions)) {
-                            responseOptions = baseResponseOptions.merge(responseOptions);
+                            responseOptions = baseResponseOptions.mergeWith(responseOptions);
                         }
                         responseObserver.error(new __WEBPACK_IMPORTED_MODULE_9__static_response__["a" /* Response */](responseOptions));
                     };
@@ -39355,7 +39355,7 @@
             var newOptions = defaultOpts;
             if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__src_facade_lang__["a" /* isPresent */])(providedOpts)) {
                 // Hack so Dart can used named parameters
-                return newOptions.merge(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({
+                return newOptions.mergeWith(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({
                     method: providedOpts.method || method,
                     url: providedOpts.url || url,
                     search: providedOpts.search,
@@ -39366,10 +39366,10 @@
                 }));
             }
             if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__src_facade_lang__["a" /* isPresent */])(method)) {
-                return newOptions.merge(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({ method: method, url: url }));
+                return newOptions.mergeWith(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({ method: method, url: url }));
             }
             else {
-                return newOptions.merge(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({ url: url }));
+                return newOptions.mergeWith(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({ url: url }));
             }
         }
         /**
@@ -39466,13 +39466,13 @@
              * Performs a request with `post` http method.
              */
             Http.prototype.post = function (url, body, options) {
-                return httpRequest(this._backend, new __WEBPACK_IMPORTED_MODULE_5__static_request__["a" /* Request */](mergeOptions(this._defaultOptions.merge(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({ body: body })), options, __WEBPACK_IMPORTED_MODULE_3__enums__["b" /* RequestMethod */].Post, url)));
+                return httpRequest(this._backend, new __WEBPACK_IMPORTED_MODULE_5__static_request__["a" /* Request */](mergeOptions(this._defaultOptions.mergeWith(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({ body: body })), options, __WEBPACK_IMPORTED_MODULE_3__enums__["b" /* RequestMethod */].Post, url)));
             };
             /**
              * Performs a request with `put` http method.
              */
             Http.prototype.put = function (url, body, options) {
-                return httpRequest(this._backend, new __WEBPACK_IMPORTED_MODULE_5__static_request__["a" /* Request */](mergeOptions(this._defaultOptions.merge(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({ body: body })), options, __WEBPACK_IMPORTED_MODULE_3__enums__["b" /* RequestMethod */].Put, url)));
+                return httpRequest(this._backend, new __WEBPACK_IMPORTED_MODULE_5__static_request__["a" /* Request */](mergeOptions(this._defaultOptions.mergeWith(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({ body: body })), options, __WEBPACK_IMPORTED_MODULE_3__enums__["b" /* RequestMethod */].Put, url)));
             };
             /**
              * Performs a request with `delete` http method.
@@ -39484,7 +39484,7 @@
              * Performs a request with `patch` http method.
              */
             Http.prototype.patch = function (url, body, options) {
-                return httpRequest(this._backend, new __WEBPACK_IMPORTED_MODULE_5__static_request__["a" /* Request */](mergeOptions(this._defaultOptions.merge(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({ body: body })), options, __WEBPACK_IMPORTED_MODULE_3__enums__["b" /* RequestMethod */].Patch, url)));
+                return httpRequest(this._backend, new __WEBPACK_IMPORTED_MODULE_5__static_request__["a" /* Request */](mergeOptions(this._defaultOptions.mergeWith(new __WEBPACK_IMPORTED_MODULE_2__base_request_options__["a" /* RequestOptions */]({ body: body })), options, __WEBPACK_IMPORTED_MODULE_3__enums__["b" /* RequestMethod */].Patch, url)));
             };
             /**
              * Performs a request with `head` http method.
@@ -49300,7 +49300,7 @@
                 var lastIndex = stylesList.length - 1;
                 var lastItem = stylesList[lastIndex];
                 if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_2__facade_lang__["l" /* isStringMap */])(lastItem)) {
-                    stylesList[lastIndex] = __WEBPACK_IMPORTED_MODULE_1__facade_collection__["b" /* StringMapWrapper */].merge(lastItem, newItem);
+                    stylesList[lastIndex] = __WEBPACK_IMPORTED_MODULE_1__facade_collection__["b" /* StringMapWrapper */].mergeWith(lastItem, newItem);
                     return;
                 }
             }
@@ -53616,7 +53616,7 @@
                     hasExtraFirstStyles = true;
                 }
             });
-            var keyframeCollectedStyles = __WEBPACK_IMPORTED_MODULE_0__facade_collection__["d" /* StringMapWrapper */].merge({}, flatenedFirstKeyframeStyles);
+            var keyframeCollectedStyles = __WEBPACK_IMPORTED_MODULE_0__facade_collection__["d" /* StringMapWrapper */].mergeWith({}, flatenedFirstKeyframeStyles);
             // phase 2: normalize the final keyframe
             var finalKeyframe = keyframes[limit];
             __WEBPACK_IMPORTED_MODULE_0__facade_collection__["a" /* ListWrapper */].insert(finalKeyframe.styles.styles, 0, finalStateStyles);
@@ -64367,7 +64367,7 @@
         "use strict";
         var Observable_1 = __webpack_require__(0);
         var merge_1 = __webpack_require__(857);
-        Observable_1.Observable.merge = merge_1.merge;
+        Observable_1.Observable.merge = merge_1.mergeWith;
 //# sourceMappingURL=merge.js.map
 
         /***/ },
@@ -64975,7 +64975,7 @@
         "use strict";
         var Observable_1 = __webpack_require__(0);
         var merge_1 = __webpack_require__(404);
-        Observable_1.Observable.prototype.merge = merge_1.merge;
+        Observable_1.Observable.prototype.merge = merge_1.mergeWith;
 //# sourceMappingURL=merge.js.map
 
         /***/ },

+ 4 - 13
test/unit-tests/utils/Utils.spec.ts

@@ -5,14 +5,6 @@ import { Utils } from '../../../src/utils/Utils';
 import { JSFuck } from '../../../src/enums/JSFuck';
 
 describe('Utils', () => {
-    describe('arrayContains (array: any[], searchElement: any): boolean', () => {
-        it('should return boolean depends on condition if array is contains given value or not', () => {
-            assert.equal(Utils.arrayContains(['1', '2', '3'], '2'), true);
-            assert.equal(Utils.arrayContains([1, 2, 3], 2), true);
-            assert.equal(Utils.arrayContains([1, 2, 3], 4), false);
-        });
-    });
-
     describe('arrayRotate <T> (array: T[], times: number): T[]', () => {
         let array: number[];
 
@@ -54,11 +46,10 @@ describe('Utils', () => {
         });
     });
 
-    describe('isInteger (number: number): boolean', () => {
-        it('should return true if given number or string is integer', () => {
-            assert.equal(Utils.isInteger(4), true);
-            assert.equal(Utils.isInteger(<any>'4'), true);
-            assert.equal(Utils.isInteger(<any>'a'), false);
+    describe('isCeilNumber (number: number): boolean', () => {
+        it('should return true if given number is a ceil', () => {
+            assert.equal(Utils.isCeilNumber(4), true);
+            assert.equal(Utils.isCeilNumber(4.5), false);
         });
     });
 

+ 4 - 0
tsconfig.json

@@ -1,6 +1,10 @@
 {
   "compilerOptions": {
     "target": "ES6",
+    "lib": [
+      "es2017",
+      "DOM"
+    ],
     "module": "commonjs",
     "sourceMap": true,
     "emitDecoratorMetadata": true,

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.