├── .nvmrc ├── App ├── styles │ ├── site │ │ ├── modules │ │ │ ├── embed.variables │ │ │ ├── nag.overrides │ │ │ ├── tab.overrides │ │ │ ├── chatroom.overrides │ │ │ ├── dimmer.overrides │ │ │ ├── dropdown.overrides │ │ │ ├── embed.overrides │ │ │ ├── modal.overrides │ │ │ ├── modal.variables │ │ │ ├── nag.variables │ │ │ ├── popup.overrides │ │ │ ├── rating.overrides │ │ │ ├── rating.variables │ │ │ ├── search.overrides │ │ │ ├── search.variables │ │ │ ├── shape.overrides │ │ │ ├── sidebar.overrides │ │ │ ├── sidebar.variables │ │ │ ├── sticky.overrides │ │ │ ├── sticky.variables │ │ │ ├── tab.variables │ │ │ ├── accordion.overrides │ │ │ ├── chatroom.variables │ │ │ ├── checkbox.overrides │ │ │ ├── checkbox.variables │ │ │ ├── dimmer.variables │ │ │ ├── dropdown.variables │ │ │ ├── popup.variables │ │ │ ├── progress.overrides │ │ │ ├── progress.variables │ │ │ ├── shape.variables │ │ │ ├── transition.overrides │ │ │ ├── accordion.variables │ │ │ └── transition.variables │ │ ├── elements │ │ │ ├── flag.variables │ │ │ ├── button.overrides │ │ │ ├── flag.overrides │ │ │ ├── header.overrides │ │ │ ├── icon.overrides │ │ │ ├── image.overrides │ │ │ ├── input.overrides │ │ │ ├── label.overrides │ │ │ ├── loader.overrides │ │ │ ├── rail.overrides │ │ │ ├── reveal.overrides │ │ │ ├── step.overrides │ │ │ ├── button.variables │ │ │ ├── container.overrides │ │ │ ├── divider.overrides │ │ │ ├── divider.variables │ │ │ ├── header.variables │ │ │ ├── icon.variables │ │ │ ├── image.variables │ │ │ ├── input.variables │ │ │ ├── label.variables │ │ │ ├── list.overrides │ │ │ ├── list.variables │ │ │ ├── loader.variables │ │ │ ├── rail.variables │ │ │ ├── reveal.variables │ │ │ ├── segment.overrides │ │ │ ├── segment.variables │ │ │ ├── step.variables │ │ │ └── container.variables │ │ ├── globals │ │ │ ├── reset.overrides │ │ │ ├── site.overrides │ │ │ ├── reset.variables │ │ │ └── site.variables │ │ ├── views │ │ │ ├── ad.overrides │ │ │ ├── ad.variables │ │ │ ├── card.overrides │ │ │ ├── card.variables │ │ │ ├── feed.overrides │ │ │ ├── feed.variables │ │ │ ├── item.overrides │ │ │ ├── item.variables │ │ │ ├── comment.overrides │ │ │ ├── comment.variables │ │ │ ├── statistic.overrides │ │ │ └── statistic.variables │ │ └── collections │ │ │ ├── form.overrides │ │ │ ├── form.variables │ │ │ ├── grid.overrides │ │ │ ├── grid.variables │ │ │ ├── menu.overrides │ │ │ ├── menu.variables │ │ │ ├── message.overrides │ │ │ ├── table.overrides │ │ │ ├── breadcrumb.overrides │ │ │ ├── breadcrumb.variables │ │ │ ├── message.variables │ │ │ └── table.variables │ ├── theme.config │ ├── main.less │ └── semantic.less ├── reducers │ ├── index.js │ ├── code.js │ └── options.js ├── util │ ├── get-options-markdown.js │ ├── get-emoji-support-renderer.js │ ├── get-heading-renderer.js │ └── downloadFile.js ├── localStorage.js ├── constants │ ├── EuropeTimezones.js │ └── ActionTypes.js ├── workers │ └── obfuscation-worker.js ├── index.js ├── containers │ ├── EditorContainer.js │ ├── ConsentHandler.js │ ├── EntryInputContainer.js │ ├── App.js │ ├── CodeContainer.js │ └── OptionsContainer.js └── actions │ └── index.js ├── public ├── ads.txt ├── images │ └── logo.png ├── docs │ ├── cookie-policy.docx │ └── privacy-policy.docx └── semantic │ └── assets │ └── fonts │ ├── icons.eot │ ├── icons.ttf │ ├── icons.woff │ └── icons.woff2 ├── .gitignore ├── jsconfig.json ├── .babelrc ├── .eslintrc.json ├── LICENSE.BSD ├── README.md ├── webpack.conf.js ├── package.json └── templates └── index.html /.nvmrc: -------------------------------------------------------------------------------- 1 | 12.13.1 2 | -------------------------------------------------------------------------------- /App/styles/site/modules/embed.variables: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/ads.txt: -------------------------------------------------------------------------------- 1 | google.com, pub-5000712498982649, DIRECT, f08c47fec0942fa0 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | /node_modules/ 4 | /dist/ 5 | /semantic/dist/ 6 | -------------------------------------------------------------------------------- /App/styles/site/elements/flag.variables: -------------------------------------------------------------------------------- 1 | /*------------------- 2 | Flag Variables 3 | --------------------*/ 4 | -------------------------------------------------------------------------------- /public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javascript-obfuscator/javascript-obfuscator-ui/HEAD/public/images/logo.png -------------------------------------------------------------------------------- /App/styles/site/modules/nag.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/tab.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/button.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/flag.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/header.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/icon.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/image.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/input.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/label.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/loader.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/rail.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/reveal.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/step.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/globals/reset.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/globals/site.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/chatroom.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/dimmer.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/dropdown.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/embed.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/modal.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/modal.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/nag.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/popup.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/rating.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/rating.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/search.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/search.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/shape.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/sidebar.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/sidebar.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/sticky.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/sticky.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/tab.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/ad.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/ad.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/card.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/card.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/feed.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/feed.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/item.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/item.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /public/docs/cookie-policy.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javascript-obfuscator/javascript-obfuscator-ui/HEAD/public/docs/cookie-policy.docx -------------------------------------------------------------------------------- /App/styles/site/collections/form.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/collections/form.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/collections/grid.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/collections/grid.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/collections/menu.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/collections/menu.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/collections/message.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/collections/table.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/button.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/container.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/divider.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/divider.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/header.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/icon.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/image.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/input.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/label.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/list.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/list.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/loader.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/rail.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/reveal.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/segment.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/segment.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/step.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/globals/reset.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Global Variables 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/accordion.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/chatroom.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/checkbox.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/checkbox.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/dimmer.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/dropdown.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/popup.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/progress.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/progress.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/shape.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/transition.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/comment.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/comment.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/statistic.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/views/statistic.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /public/docs/privacy-policy.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javascript-obfuscator/javascript-obfuscator-ui/HEAD/public/docs/privacy-policy.docx -------------------------------------------------------------------------------- /App/styles/site/collections/breadcrumb.overrides: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/collections/breadcrumb.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | Site Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/collections/message.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/collections/table.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/elements/container.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/accordion.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /App/styles/site/modules/transition.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Variable Overrides 3 | *******************************/ 4 | -------------------------------------------------------------------------------- /public/semantic/assets/fonts/icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javascript-obfuscator/javascript-obfuscator-ui/HEAD/public/semantic/assets/fonts/icons.eot -------------------------------------------------------------------------------- /public/semantic/assets/fonts/icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javascript-obfuscator/javascript-obfuscator-ui/HEAD/public/semantic/assets/fonts/icons.ttf -------------------------------------------------------------------------------- /public/semantic/assets/fonts/icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javascript-obfuscator/javascript-obfuscator-ui/HEAD/public/semantic/assets/fonts/icons.woff -------------------------------------------------------------------------------- /public/semantic/assets/fonts/icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javascript-obfuscator/javascript-obfuscator-ui/HEAD/public/semantic/assets/fonts/icons.woff2 -------------------------------------------------------------------------------- /App/reducers/index.js: -------------------------------------------------------------------------------- 1 | import {combineReducers} from 'redux' 2 | 3 | import {code} from './code'; 4 | import {options} from './options'; 5 | 6 | export default combineReducers({ 7 | code, 8 | options, 9 | }); -------------------------------------------------------------------------------- /App/util/get-options-markdown.js: -------------------------------------------------------------------------------- 1 | const fullReadmeMarkdown = require('javascript-obfuscator/README.md').default; 2 | 3 | export function getOptionsMarkdown() { 4 | return fullReadmeMarkdown 5 | .split('')[1] 6 | .split('\n')[0]; 7 | } -------------------------------------------------------------------------------- /App/util/get-emoji-support-renderer.js: -------------------------------------------------------------------------------- 1 | const emojiDictionary = require('emoji-dictionary'); 2 | 3 | export const getEmojiSupportRenderer = (text) => { 4 | return text 5 | .value 6 | .replace( 7 | /:\w+:/gi, 8 | (name) => emojiDictionary.getUnicode(name) 9 | ); 10 | }; -------------------------------------------------------------------------------- /App/styles/site/globals/site.variables: -------------------------------------------------------------------------------- 1 | /******************************* 2 | User Global Variables 3 | *******************************/ 4 | 5 | /* This is the single variable that controls them all */ 6 | @emSize : 16px; 7 | 8 | /* The size of page text */ 9 | @fontSize : 16px; 10 | 11 | 12 | @imagePath : '../assets/images'; 13 | @fontPath : '../assets/fonts'; -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=759670 3 | // for the documentation about the jsconfig.json format 4 | "compilerOptions": { 5 | "target": "es6", 6 | "module": "commonjs", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "exclude": [ 10 | "node_modules", 11 | "bower_components", 12 | "jspm_packages", 13 | "tmp", 14 | "temp" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-react" 4 | ], 5 | "plugins": [ 6 | "@babel/plugin-proposal-class-properties", 7 | [ 8 | "@babel/plugin-proposal-decorators", 9 | { 10 | "legacy": true 11 | } 12 | ], 13 | "@babel/plugin-proposal-numeric-separator", 14 | "@babel/plugin-proposal-optional-chaining", 15 | "@babel/plugin-proposal-nullish-coalescing-operator", 16 | "@babel/plugin-proposal-function-bind" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true 7 | }, 8 | "parser": "babel-eslint", 9 | "parserOptions": { 10 | "ecmaVersion": 8, 11 | "ecmaFeatures": { 12 | "jsx": true, 13 | "experimentalObjectRestSpread": true 14 | }, 15 | "sourceType": "module" 16 | }, 17 | "plugins": [ 18 | "react" 19 | ], 20 | "rules": { 21 | "no-case-declarations": 0 22 | }, 23 | "extends": [ 24 | "eslint:recommended", 25 | "plugin:react/recommended" 26 | ] 27 | } -------------------------------------------------------------------------------- /App/localStorage.js: -------------------------------------------------------------------------------- 1 | // from https://egghead.io/lessons/javascript-redux-persisting-the-state-to-the-local-storage 2 | 3 | export const loadState = () => { 4 | try { 5 | const serializedState = localStorage.getItem('state'); 6 | if (serializedState === null) { 7 | return undefined; 8 | } 9 | return JSON.parse(serializedState); 10 | } catch (err) { 11 | return undefined; 12 | } 13 | }; 14 | 15 | export const saveState = (state) => { 16 | try { 17 | const serializedState = JSON.stringify(state); 18 | localStorage.setItem('state', serializedState); 19 | } catch (err) { 20 | // ignore 21 | } 22 | }; -------------------------------------------------------------------------------- /App/util/get-heading-renderer.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/prop-types */ 2 | import React from "react"; 3 | 4 | const flatten = (text, child) => { 5 | return typeof child === 'string' 6 | ? text + child 7 | : React.Children.toArray(child.props.children).reduce(flatten, text) 8 | }; 9 | 10 | export const getHeadingRenderer = (props) => { 11 | const children = React.Children.toArray(props.children) 12 | const text = children.reduce(flatten, '') 13 | const slug = text.toLowerCase().replace(/\W/g, '-') 14 | 15 | const Element = 'h' + props.level 16 | 17 | return ( 18 | 19 | {props.children} 20 | 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /App/util/downloadFile.js: -------------------------------------------------------------------------------- 1 | // from http://stackoverflow.com/questions/283956/ 2 | const saveAs = (URI, filename) => { 3 | var link = document.createElement('a'); 4 | if (typeof link.download === 'string') { 5 | document.body.appendChild(link); //Firefox requires the link to be in the body 6 | link.download = filename; 7 | link.href = URI; 8 | link.click(); 9 | document.body.removeChild(link); //remove the link when done 10 | } else { 11 | location.replace(URI); 12 | } 13 | }; 14 | 15 | export const downloadFile = (fileData) => { 16 | const blob = new Blob([fileData.contents], {type: fileData.mime}); 17 | const url = URL.createObjectURL(blob); 18 | saveAs(url, fileData.filename); 19 | }; 20 | -------------------------------------------------------------------------------- /App/constants/EuropeTimezones.js: -------------------------------------------------------------------------------- 1 | export const EUROPE_TIMEZONES = [ 2 | 'Europe/Vienna', 3 | 'Europe/Brussels', 4 | 'Europe/Sofia', 5 | 'Europe/Zagreb', 6 | 'Asia/Famagusta', 7 | 'Asia/Nicosia', 8 | 'Europe/Prague', 9 | 'Europe/Copenhagen', 10 | 'Europe/Tallinn', 11 | 'Europe/Helsinki', 12 | 'Europe/Paris', 13 | 'Europe/Berlin', 14 | 'Europe/Busingen', 15 | 'Europe/Athens', 16 | 'Europe/Budapest', 17 | 'Europe/Dublin', 18 | 'Europe/Rome', 19 | 'Europe/Riga', 20 | 'Europe/Vilnius', 21 | 'Europe/Luxembourg', 22 | 'Europe/Malta', 23 | 'Europe/Amsterdam', 24 | 'Europe/Warsaw', 25 | 'Atlantic/Azores', 26 | 'Atlantic/Madeira', 27 | 'Europe/Lisbon', 28 | 'Europe/Bucharest', 29 | 'Europe/Bratislava', 30 | 'Europe/Ljubljana', 31 | 'Africa/Ceuta', 32 | 'Atlantic/Canary', 33 | 'Europe/Madrid', 34 | 'Europe/Stockholm' 35 | ]; -------------------------------------------------------------------------------- /LICENSE.BSD: -------------------------------------------------------------------------------- 1 | 2 | Redistribution and use in source and binary forms, with or without 3 | modification, are permitted provided that the following conditions are met: 4 | 5 | * Redistributions of source code must retain the above copyright 6 | notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright 8 | notice, this list of conditions and the following disclaimer in the 9 | documentation and/or other materials provided with the distribution. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 12 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 13 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 14 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 15 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 16 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 17 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 18 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 19 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 20 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /App/workers/obfuscation-worker.js: -------------------------------------------------------------------------------- 1 | self.window = self; 2 | 3 | const JavaScriptObfuscator = require('javascript-obfuscator'); 4 | 5 | onmessage = function(event) { 6 | const {type, payload} = event.data; 7 | 8 | switch (type) { 9 | case 'OBFUSCATOR_WORKER_OBFUSCATE_EVENT': 10 | onObfuscateEvent(payload); 11 | 12 | break; 13 | 14 | case 'OBFUSCATOR_WORKER_GET_OPTIONS_BY_PRESET_EVENT': 15 | onGetOptionsByPresetEvent(payload); 16 | 17 | break; 18 | 19 | default: 20 | throw new Error('Unknown obfuscator worker event'); 21 | } 22 | }; 23 | 24 | /** 25 | * @param payload 26 | */ 27 | function onObfuscateEvent(payload) { 28 | const {code, options} = payload; 29 | 30 | let result; 31 | 32 | try { 33 | const obfuscationResult = JavaScriptObfuscator.obfuscate(code, options); 34 | 35 | result = { 36 | code: obfuscationResult.getObfuscatedCode(), 37 | sourceMap: obfuscationResult.getSourceMap(), 38 | } 39 | } catch (error) { 40 | result = { 41 | code: error.toString(), 42 | sourceMap: '', 43 | } 44 | } 45 | 46 | postMessage(JSON.stringify(result)); 47 | } 48 | 49 | /** 50 | * @param payload 51 | */ 52 | function onGetOptionsByPresetEvent(payload) { 53 | const {optionsPreset} = payload; 54 | 55 | const options = JavaScriptObfuscator.getOptionsByPreset(optionsPreset); 56 | 57 | postMessage(JSON.stringify(options)); 58 | } 59 | -------------------------------------------------------------------------------- /App/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {createStore, applyMiddleware} from 'redux' 4 | import {render} from 'react-dom'; 5 | import {Provider} from 'react-redux'; 6 | 7 | import {createLogger} from 'redux-logger' 8 | import thunk from 'redux-thunk' 9 | import promise from 'redux-promise-middleware'; 10 | 11 | import {loadState, saveState} from './localStorage'; 12 | 13 | import reducer from './reducers' 14 | 15 | import App from './containers/App' 16 | 17 | import "./styles/main.less"; 18 | import {sanitizePersistedOptions} from "./reducers/options"; 19 | 20 | 21 | const middleware = [thunk, promise]; 22 | if (process.env.NODE_ENV !== 'production') { 23 | middleware.push(createLogger()); 24 | } 25 | 26 | const persistedState = loadState(); 27 | 28 | /* 29 | `options.hydrated` should not be in the localStorage, but was saved there previously. Now we need to delete it here because some users will have it on 30 | their localStorage. 31 | */ 32 | if (persistedState !== undefined) { 33 | delete persistedState.options.hydrated; 34 | 35 | sanitizePersistedOptions(persistedState.options); 36 | } 37 | 38 | const store = createStore( 39 | reducer, 40 | persistedState, 41 | applyMiddleware(...middleware) 42 | ); 43 | 44 | // There's no need to throttle the saveState function because 45 | // we don't change the state very often 46 | store.subscribe(() => { 47 | const options = store.getState().options; 48 | delete options.hydrated; 49 | saveState({ 50 | options, 51 | }); 52 | }); 53 | 54 | render( 55 | 56 | 57 | 58 | , 59 | document.getElementById('root') 60 | ); -------------------------------------------------------------------------------- /App/containers/EditorContainer.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import {Controlled as CodeMirror} from 'react-codemirror2' 5 | 6 | require('codemirror/mode/javascript/javascript'); 7 | 8 | export default class EditorContainer extends Component { 9 | editor = null; 10 | 11 | constructor(props) { 12 | super(props); 13 | 14 | this.state = { 15 | code: props.value 16 | } 17 | } 18 | 19 | static propTypes = { 20 | value: PropTypes.string.isRequired, 21 | onBlur: PropTypes.func.isRequired, 22 | }; 23 | 24 | componentWillReceiveProps(nextProps) { 25 | this.setState({ 26 | code: nextProps.value 27 | }); 28 | 29 | setTimeout(() => { 30 | this.editor && this.editor.refresh(); 31 | }, 1); 32 | } 33 | 34 | handleEditorMount(editor) { 35 | editor.execCommand('selectAll'); 36 | this.editor = editor; 37 | } 38 | 39 | handleOnChange(editor, data, value) { 40 | this.setState({ 41 | code: value 42 | }); 43 | } 44 | 45 | handleFocusChange(editor) { 46 | this.props.onBlur(editor.getValue()); 47 | } 48 | 49 | render() { 50 | const options = { 51 | autofocus: false, 52 | lineNumbers: true, 53 | mode: 'javascript', 54 | }; 55 | 56 | return ( 57 | 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Web UI for JavaScript Obfuscator 8 | 9 | This project is a web interface to the [javascript obufscator](https://github.com/javascript-obfuscator/javascript-obfuscator) project. 10 | 11 | You can see it running here: [obfuscator.io](https://obfuscator.io) 12 | 13 | ## Running it 14 | 15 | Building the react project: 16 | ```sh 17 | $ yarn # or npm install 18 | $ npm run updatesemantic 19 | $ npm run webpack:dev 20 | ``` 21 | 22 | Running the express server: 23 | ```sh 24 | $ node server.js 25 | ``` 26 | The server runs on http://localhost:3000/ 27 | 28 | ## License 29 | 30 | Copyright (C) 2016-2018 Tiago Serafim 31 | 32 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 33 | 34 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 35 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 36 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | -------------------------------------------------------------------------------- /App/containers/ConsentHandler.js: -------------------------------------------------------------------------------- 1 | import React, { useCallback, useEffect, useRef } from "react"; 2 | import { ConsentBanner, ConsentProvider } from "react-hook-consent"; 3 | import 'react-hook-consent/dist/styles/style.css'; 4 | const dayjs = require('dayjs') 5 | const timezone = require('dayjs/plugin/timezone') 6 | import { EUROPE_TIMEZONES } from "../constants/EuropeTimezones"; 7 | 8 | export const ConsentHandler = () => { 9 | const isConsentRequired = useCallback( 10 | () => { 11 | dayjs.extend(timezone); 12 | 13 | return EUROPE_TIMEZONES.includes(dayjs.tz.guess()); 14 | }, 15 | [] 16 | ) 17 | 18 | const consentRequiredRef = useRef(isConsentRequired()); 19 | 20 | const enableCookies = useCallback( 21 | () => { 22 | (adsbygoogle=window.adsbygoogle||[]).pauseAdRequests=0; 23 | }, 24 | [] 25 | ) 26 | 27 | useEffect(() => { 28 | window.enableCookies = enableCookies 29 | 30 | if (!consentRequiredRef.current) { 31 | // enableCookies() 32 | } 33 | }, [enableCookies]); 34 | 35 | // if (!consentRequiredRef.current) { 36 | if (true) { 37 | return null; 38 | } 39 | 40 | return ( 41 | 57 | 62 | obfuscator.io uses cookies according to the cookie policy 63 | 64 | 65 | ); 66 | } 67 | -------------------------------------------------------------------------------- /App/reducers/code.js: -------------------------------------------------------------------------------- 1 | import * as types from '../constants/ActionTypes'; 2 | 3 | 4 | const DEFAULT_CODE = [ 5 | '// Paste your JavaScript code here', 6 | 'function hi() {', 7 | ' console.log("Hello World!");', 8 | '}', 9 | 'hi();', 10 | ].join('\n'); 11 | 12 | export const DEFAULT_OUTPUT_FILE_NAME = 'obfuscated.js'; 13 | 14 | const initialState = { 15 | code: DEFAULT_CODE, 16 | outputFileName: DEFAULT_OUTPUT_FILE_NAME, 17 | obfuscatedCode: '', 18 | sourceMap: '', 19 | obfuscating: false, 20 | obfuscated: false, 21 | error: false 22 | }; 23 | 24 | 25 | export const code = (state = initialState, action) => { 26 | 27 | switch (action.type) { 28 | case types.UPDATE_CODE: 29 | return { 30 | ...state, 31 | obfuscated: false, 32 | error: false, 33 | obfuscatedCode: '', 34 | sourceMap: '', 35 | code: action.code 36 | }; 37 | 38 | case types.OBFUSCATE_PENDING: 39 | return { 40 | ...state, 41 | obfuscating: true, 42 | obfuscated: false, 43 | error: false, 44 | obfuscatedCode: '', 45 | sourceMap: '', 46 | }; 47 | 48 | case types.OBFUSCATE_REJECTED: 49 | return { 50 | ...state, 51 | obfuscating: false, 52 | obfuscated: false, 53 | error: true, 54 | obfuscatedCode: '', 55 | sourceMap: '', 56 | }; 57 | 58 | case types.OBFUSCATE_FULFILLED: 59 | return { 60 | ...state, 61 | obfuscating: false, 62 | obfuscated: true, 63 | error: false, 64 | obfuscatedCode: action.payload.code, 65 | sourceMap: action.payload.sourceMap, 66 | }; 67 | 68 | case types.UPDATE_OUTPUT_FILE_NAME: 69 | return { 70 | ...state, 71 | outputFileName: action.outputFileName 72 | }; 73 | 74 | default: 75 | return state 76 | } 77 | 78 | }; 79 | -------------------------------------------------------------------------------- /App/styles/theme.config: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | ████████╗██╗ ██╗███████╗███╗ ███╗███████╗███████╗ 4 | ╚══██╔══╝██║ ██║██╔════╝████╗ ████║██╔════╝██╔════╝ 5 | ██║ ███████║█████╗ ██╔████╔██║█████╗ ███████╗ 6 | ██║ ██╔══██║██╔══╝ ██║╚██╔╝██║██╔══╝ ╚════██║ 7 | ██║ ██║ ██║███████╗██║ ╚═╝ ██║███████╗███████║ 8 | ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝ 9 | 10 | */ 11 | 12 | /******************************* 13 | Theme Selection 14 | *******************************/ 15 | 16 | /* To override a theme for an individual element 17 | specify theme name below 18 | */ 19 | 20 | /* Global */ 21 | @site : 'default'; 22 | @reset : 'default'; 23 | 24 | /* Elements */ 25 | @button : 'default'; 26 | @container : 'default'; 27 | @divider : 'default'; 28 | @flag : 'default'; 29 | @header : 'default'; 30 | @icon : 'default'; 31 | @image : 'default'; 32 | @input : 'default'; 33 | @label : 'default'; 34 | @list : 'default'; 35 | @loader : 'default'; 36 | @rail : 'default'; 37 | @reveal : 'default'; 38 | @segment : 'default'; 39 | @step : 'default'; 40 | 41 | /* Collections */ 42 | @breadcrumb : 'default'; 43 | @form : 'default'; 44 | @grid : 'default'; 45 | @menu : 'default'; 46 | @message : 'default'; 47 | @table : 'default'; 48 | 49 | /* Modules */ 50 | @accordion : 'default'; 51 | @checkbox : 'default'; 52 | @dimmer : 'default'; 53 | @dropdown : 'default'; 54 | @embed : 'default'; 55 | @modal : 'default'; 56 | @nag : 'default'; 57 | @popup : 'default'; 58 | @progress : 'default'; 59 | @rating : 'default'; 60 | @search : 'default'; 61 | @shape : 'default'; 62 | @sidebar : 'default'; 63 | @sticky : 'default'; 64 | @tab : 'default'; 65 | @transition : 'default'; 66 | 67 | /* Views */ 68 | @ad : 'default'; 69 | @card : 'default'; 70 | @comment : 'default'; 71 | @feed : 'default'; 72 | @item : 'default'; 73 | @statistic : 'default'; 74 | 75 | /******************************* 76 | Folders 77 | *******************************/ 78 | 79 | /* Path to theme packages */ 80 | @themesFolder : 'themes'; 81 | 82 | /* Path to site override folder */ 83 | @siteFolder : 'site'; 84 | 85 | 86 | /******************************* 87 | Import Theme 88 | *******************************/ 89 | 90 | @import "theme.less"; 91 | 92 | /* End Config */ -------------------------------------------------------------------------------- /webpack.conf.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 3 | const webpack = require('webpack'); 4 | const CopyPlugin = require("copy-webpack-plugin"); 5 | 6 | module.exports = { 7 | context: __dirname, 8 | devtool: 'source-map', 9 | entry: { 10 | 'bundle': './App/index.js', 11 | 'workers/obfuscation-worker': './App/workers/obfuscation-worker.js' 12 | }, 13 | output: { 14 | path: __dirname + '/dist', 15 | filename: '[name].js', 16 | globalObject: 'this' 17 | }, 18 | module: { 19 | rules: [ 20 | { 21 | test: /\.js$/, 22 | exclude: /node_modules/, 23 | loader: 'babel-loader' 24 | }, 25 | { 26 | test: /\.css$/, 27 | use: ['style-loader', 'css-loader'], 28 | }, 29 | { 30 | test: /\.less$/, 31 | use: [ 32 | { 33 | loader: MiniCssExtractPlugin.loader, 34 | options : { 35 | publicPath : '.' 36 | } 37 | }, 38 | 'css-loader', 39 | 'less-loader' 40 | ] 41 | }, 42 | { 43 | test: /\.woff(2)?$/, 44 | loader: 'url-loader', 45 | options: { 46 | limit: 10000, 47 | mimetype: 'application/font-woff' 48 | } 49 | }, 50 | { 51 | test: /\.(ttf|eot|svg)$/, 52 | loader: 'file-loader' 53 | }, 54 | { 55 | test: /\.md$/i, 56 | use: 'raw-loader' 57 | } 58 | ] 59 | }, 60 | resolve: { 61 | alias: { 62 | process: "process/browser" 63 | } 64 | }, 65 | plugins: [ 66 | new webpack.ProvidePlugin({ 67 | process: ['process'] 68 | }), 69 | new HtmlWebpackPlugin({ 70 | inject: false, 71 | template: './templates/index.html', 72 | hash: true 73 | }), 74 | new MiniCssExtractPlugin(), 75 | new CopyPlugin({ 76 | patterns: [ 77 | { from: "public", to: "." }, 78 | ], 79 | }), 80 | ] 81 | }; 82 | -------------------------------------------------------------------------------- /App/containers/EntryInputContainer.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {Form} from 'semantic-ui-react'; 4 | 5 | export default class EntryInputContainer extends Component { 6 | static propTypes = { 7 | label: PropTypes.string, 8 | actionAddEntryToState: PropTypes.func.isRequired, 9 | actionRemoveEntryFromState: PropTypes.func.isRequired, 10 | entries: PropTypes.array.isRequired, 11 | placeholder: PropTypes.string, 12 | buttonIcon: PropTypes.string, 13 | disabled: PropTypes.bool, 14 | }; 15 | 16 | constructor(props) { 17 | super(props); 18 | 19 | this.state = { 20 | value: '', 21 | }; 22 | 23 | this.handleAdd = this.handleAdd.bind(this); 24 | 25 | } 26 | 27 | handleAdd(event) { 28 | event.preventDefault(); 29 | 30 | if (this.state.value.trim() === '') { 31 | return; 32 | } 33 | 34 | this.props.actionAddEntryToState(this.state.value); 35 | this.setState({ 36 | value: '', 37 | }) 38 | } 39 | 40 | handleRemove(entry) { 41 | this.props.actionRemoveEntryFromState(entry) 42 | } 43 | 44 | handleOnChange(value) { 45 | this.setState({ 46 | value: value, 47 | }) 48 | } 49 | 50 | render() { 51 | const {entries, label, buttonIcon, placeholder, disabled} = this.props; 52 | 53 | return ( 54 |
55 | this.handleOnChange(event.target.value)} 58 | value={this.state.value} 59 | action={{icon: buttonIcon, onClick: this.handleAdd}} 60 | placeholder={placeholder} 61 | disabled={disabled} 62 | /> 63 | 64 |
65 | ); 66 | 67 | } 68 | 69 | } 70 | 71 | 72 | const Labels = ({entries, onCloseClick}) => 73 |
74 | {entries.map(entry => 75 | 76 | {entry} 77 | onCloseClick(entry)} className="icon close"/> 78 | 79 | )} 80 |
; 81 | 82 | Labels.propTypes = { 83 | entries: PropTypes.array, 84 | onCloseClick: PropTypes.func.isRequired, 85 | }; 86 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript-obfuscator-web", 3 | "version": "4.1.2", 4 | "description": "", 5 | "engines": { 6 | "node": ">=12.13.1", 7 | "yarn": "^1.22.4" 8 | }, 9 | "scripts": { 10 | "start": "node server.js", 11 | "webpack:dev": "NODE_OPTIONS=--openssl-legacy-provide webpack --mode development --config webpack.conf.js --watch --color --progress", 12 | "webpack:prod": "NODE_ENV=production NODE_OPTIONS=--openssl-legacy-provider webpack --mode production --config webpack.conf.js --progress", 13 | "postinstall": "npm run updatesemantic && npm run webpack:prod", 14 | "updatesemantic": "cp App/styles/theme.config ./node_modules/semantic-ui-less/theme.config; rm -Rf ./node_modules/semantic-ui-less/site; cp -R App/styles/site ./node_modules/semantic-ui-less/" 15 | }, 16 | "author": "", 17 | "license": "ISC", 18 | "dependencies": { 19 | "@babel/core": "^7.12.10", 20 | "@babel/eslint-parser": "^7.12.1", 21 | "@babel/plugin-proposal-class-properties": "^7.0.0", 22 | "@babel/plugin-proposal-decorators": "^7.0.0", 23 | "@babel/plugin-proposal-function-bind": "^7.0.0", 24 | "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", 25 | "@babel/plugin-proposal-optional-chaining": "^7.0.0", 26 | "@babel/preset-env": "^7.12.11", 27 | "@babel/preset-es2015": "^7.0.0-beta.53", 28 | "@babel/preset-react": "^7.12.10", 29 | "@ctrl/react-adsense": "1.7.0", 30 | "babel-loader": "8.2.2", 31 | "body-parser": "1.19.0", 32 | "classnames": "2.2.6", 33 | "codemirror": "5.59.2", 34 | "css-loader": "5.2.7", 35 | "dayjs": "1.11.9", 36 | "emoji-dictionary": "^1.0.11", 37 | "eslint": "7.18.0", 38 | "eslint-plugin-react": "7.22.0", 39 | "express": "4.17.1", 40 | "file-loader": "^6.2.0", 41 | "graceful-fs": "4.2.4", 42 | "html-webpack-plugin": "^4.5.2", 43 | "javascript-obfuscator": "4.0.0", 44 | "less": "2.7.1", 45 | "less-loader": "7.3.0", 46 | "mini-css-extract-plugin": "^1.3.4", 47 | "pm2": "3.5.1", 48 | "process": "^0.11.10", 49 | "prop-types": "15.7.2", 50 | "raw-loader": "^4.0.2", 51 | "react": "17.0.1", 52 | "react-codemirror2": "7.2.1", 53 | "react-dom": "17.0.1", 54 | "react-dropzone": "11.2.4", 55 | "react-helmet": "6.1.0", 56 | "react-hook-consent": "3.3.0", 57 | "react-markdown": "^5.0.3", 58 | "react-redux": "7.2.2", 59 | "redux": "4.0.5", 60 | "redux-logger": "3.0.6", 61 | "redux-promise-middleware": "6.1.2", 62 | "redux-thunk": "2.3.0", 63 | "semantic-ui-less": "2.4.1", 64 | "semantic-ui-react": "2.0.3", 65 | "style-loader": "2.0.0", 66 | "threads": "^1.6.3", 67 | "url-loader": "4.1.1", 68 | "webpack": "5.69.1", 69 | "webpack-cli": "4.4.0" 70 | }, 71 | "devDependencies": { 72 | "copy-webpack-plugin": "^13.0.0" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /App/styles/main.less: -------------------------------------------------------------------------------- 1 | @import "semantic.less"; 2 | @import (inline) "~codemirror/lib/codemirror.css"; 3 | @import url('~semantic-ui-less/themes/default/globals/site.variables'); 4 | 5 | .title { 6 | display: flex; 7 | flex-wrap: wrap; 8 | align-items: center; 9 | 10 | & > h1 { 11 | margin-right: 1rem; 12 | } 13 | } 14 | 15 | #GithubBadges, #DonateBadges { 16 | display: flex; 17 | margin-bottom: 1rem; 18 | 19 | & #donate { 20 | position: relative; 21 | display: inline-block; 22 | margin-left: 10px; 23 | padding: 3px 10px; 24 | font-size: 14px; 25 | line-height: 22px; 26 | font-weight: 600; 27 | color: #24292e; 28 | background-color: #eee; 29 | background-image: linear-gradient(to bottom,#fcfcfc 0,#eee 100%); 30 | white-space: nowrap; 31 | vertical-align: middle; 32 | cursor: pointer; 33 | user-select: none; 34 | background-repeat: repeat-x; 35 | background-position: -1px -1px; 36 | background-size: 110% 110%; 37 | border: 1px solid rgba(27,31,35,.2); 38 | border-radius: .25em; 39 | 40 | &:hover { 41 | background-color: #ddd; 42 | background-image: linear-gradient(to bottom,#eee 0,#ddd 100%); 43 | border-color: #ccc; 44 | } 45 | 46 | &:active { 47 | background-image: none; 48 | background-color: #dcdcdc; 49 | border-color: #b5b5b5; 50 | box-shadow: inset 0 2px 4px rgba(0,0,0,.15); 51 | } 52 | 53 | & #donate-heart { 54 | display: inline-block; 55 | vertical-align: middle; 56 | color: #ea4aaa; 57 | fill: currentColor; 58 | margin-right: 2px; 59 | margin-bottom: 2px; 60 | } 61 | } 62 | 63 | @media only screen and (max-width: @largestMobileScreen) { 64 | & { 65 | justify-content: center; 66 | } 67 | } 68 | } 69 | 70 | #DonateWallets { 71 | word-break: break-all; 72 | } 73 | 74 | .donate-badge { 75 | margin-right: 4px; 76 | } 77 | 78 | .CodeMirror { 79 | height: 200px; 80 | } 81 | 82 | .DropZone { 83 | padding: 1em; 84 | height: 200px; 85 | border-width: 2px; 86 | border-color: #ccc; 87 | border-style: dashed; 88 | border-radius: 5px; 89 | } 90 | 91 | .OptionsForm.ui.form { 92 | label { 93 | font-size: 0.8em; 94 | } 95 | } 96 | 97 | .ui.labels > .label { 98 | font-family: monospace; 99 | } 100 | 101 | code { 102 | padding: 0.2em; 103 | background-color: rgba(0, 0, 0, 0.04); 104 | border-radius: 3px; 105 | } 106 | 107 | .evaluatedCode { 108 | white-space: pre; 109 | padding: 0.2em; 110 | background-color: rgba(0, 0, 0, 0.04); 111 | overflow: auto; 112 | max-height: 200px; 113 | } 114 | 115 | table#Options { 116 | display: inline-block; 117 | word-wrap: break-word; 118 | } 119 | 120 | img#Logo { 121 | width: 100%; 122 | max-width: 300px; 123 | } 124 | 125 | .table code { 126 | word-break: break-word; 127 | } 128 | 129 | pre#Html { 130 | display: flex; 131 | margin: 0; 132 | padding: 0; 133 | 134 | & code { 135 | width: 100%; 136 | } 137 | } 138 | 139 | pre code { 140 | display: block; 141 | padding: 16px; 142 | overflow: auto; 143 | font-size: 85%; 144 | line-height: 1.45; 145 | border-radius: 5px; 146 | } 147 | 148 | h3 code { 149 | white-space: pre-wrap; 150 | word-wrap: break-word; 151 | } 152 | 153 | code { 154 | max-width: 100%; 155 | overflow-y: hidden; 156 | overflow-x: auto; 157 | background-color: #e1e1e4; 158 | padding: .2em .4em; 159 | margin: 0; 160 | font-size: 85%; 161 | border-radius: 5px; 162 | white-space: pre; 163 | } 164 | 165 | .policies { 166 | margin-bottom: 8px; 167 | } 168 | 169 | ins:has(> div:empty) { 170 | height: 0!important; 171 | } 172 | -------------------------------------------------------------------------------- /App/containers/App.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {Adsense} from '@ctrl/react-adsense'; 4 | 5 | import {connect} from 'react-redux'; 6 | 7 | import {downloadFile} from '../util/downloadFile'; 8 | 9 | import * as actions from '../actions'; 10 | 11 | import CodeContainer from './CodeContainer'; 12 | import OptionsContainer from './OptionsContainer'; 13 | import { ConsentHandler } from "./ConsentHandler"; 14 | 15 | class App extends Component { 16 | 17 | static propTypes = { 18 | dispatch: PropTypes.func, 19 | code: PropTypes.string, 20 | obfuscatedCode: PropTypes.string, 21 | outputFileName: PropTypes.string, 22 | sourceMap: PropTypes.string, 23 | obfuscating: PropTypes.bool, 24 | obfuscated: PropTypes.bool, 25 | error: PropTypes.bool, 26 | options: PropTypes.object, 27 | }; 28 | 29 | obfuscate() { 30 | const {dispatch} = this.props; 31 | const {code, options} = this.props; 32 | 33 | dispatch(actions.obfuscateCode(code, {...options})); 34 | } 35 | 36 | downloadCode() { 37 | const data = { 38 | mime: 'application/javascript', 39 | filename: this.props.outputFileName, 40 | contents: this.props.obfuscatedCode, 41 | }; 42 | 43 | downloadFile(data); 44 | } 45 | 46 | downloadSourceMap() { 47 | const data = { 48 | mime: 'application/octet-stream', 49 | filename: `${this.props.outputFileName}.map`, 50 | contents: this.props.sourceMap, 51 | }; 52 | 53 | downloadFile(data); 54 | } 55 | 56 | render() { 57 | 58 | const {dispatch} = this.props; 59 | 60 | const { 61 | code, 62 | obfuscatedCode, 63 | obfuscating, 64 | obfuscated, 65 | error, 66 | } = this.props; 67 | 68 | const hasSourceMap = this.props.sourceMap.length > 0; 69 | const hasObfuscatedCode = obfuscatedCode.length !== 0; 70 | 71 | return ( 72 | 73 | dispatch(actions.updateCode(code))} 79 | onOutputFileNameChange={(fileName) => dispatch(actions.updateOutputFileName(fileName))} 80 | onObfuscateClick={::this.obfuscate} 81 | onDownloadCodeClick={::this.downloadCode} 82 | onDownloadSourceMapClick={::this.downloadSourceMap} 83 | hasSourceMap={hasSourceMap} 84 | hasObfuscatedCode={hasObfuscatedCode} 85 | /> 86 | 87 |
88 | 93 |
94 | 95 | 96 | 97 | 98 |
99 | ); 100 | } 101 | 102 | } 103 | 104 | const mapStateToProps = (state) => { 105 | const code = state.code; 106 | return { 107 | code: code.code, 108 | obfuscatedCode: code.obfuscatedCode, 109 | outputFileName: code.outputFileName, 110 | sourceMap: code.sourceMap, 111 | obfuscating: code.obfuscating, 112 | obfuscated: code.obfuscated, 113 | error: code.error, 114 | options: state.options, 115 | } 116 | }; 117 | 118 | export default connect(mapStateToProps)(App); -------------------------------------------------------------------------------- /App/styles/semantic.less: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | ███████╗███████╗███╗ ███╗ █████╗ ███╗ ██╗████████╗██╗ ██████╗ ██╗ ██╗██╗ 4 | ██╔════╝██╔════╝████╗ ████║██╔══██╗████╗ ██║╚══██╔══╝██║██╔════╝ ██║ ██║██║ 5 | ███████╗█████╗ ██╔████╔██║███████║██╔██╗ ██║ ██║ ██║██║ ██║ ██║██║ 6 | ╚════██║██╔══╝ ██║╚██╔╝██║██╔══██║██║╚██╗██║ ██║ ██║██║ ██║ ██║██║ 7 | ███████║███████╗██║ ╚═╝ ██║██║ ██║██║ ╚████║ ██║ ██║╚██████╗ ╚██████╔╝██║ 8 | ╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ 9 | 10 | Import this file into your LESS project to use Semantic UI without build tools 11 | */ 12 | 13 | /* Global */ 14 | & { 15 | @import "~semantic-ui-less/definitions/globals/reset"; 16 | } 17 | 18 | & { 19 | @import "~semantic-ui-less/definitions/globals/site"; 20 | } 21 | 22 | /* Elements */ 23 | & { 24 | @import "~semantic-ui-less/definitions/elements/button"; 25 | } 26 | 27 | & { 28 | @import "~semantic-ui-less/definitions/elements/container"; 29 | } 30 | 31 | & { 32 | @import "~semantic-ui-less/definitions/elements/divider"; 33 | } 34 | 35 | // & { @import "~semantic-ui-less/definitions/elements/flag"; } 36 | & { 37 | @import "~semantic-ui-less/definitions/elements/header"; 38 | } 39 | 40 | & { 41 | @import "~semantic-ui-less/definitions/elements/icon"; 42 | } 43 | 44 | & { 45 | @import "~semantic-ui-less/definitions/elements/image"; 46 | } 47 | 48 | & { 49 | @import "~semantic-ui-less/definitions/elements/input"; 50 | } 51 | 52 | & { 53 | @import "~semantic-ui-less/definitions/elements/label"; 54 | } 55 | 56 | & { 57 | @import "~semantic-ui-less/definitions/elements/list"; 58 | } 59 | 60 | & { 61 | @import "~semantic-ui-less/definitions/elements/loader"; 62 | } 63 | 64 | // & { @import "~semantic-ui-less/definitions/elements/rail"; } 65 | // & { @import "~semantic-ui-less/definitions/elements/reveal"; } 66 | & { 67 | @import "~semantic-ui-less/definitions/elements/segment"; 68 | } 69 | 70 | // & { @import "~semantic-ui-less/definitions/elements/step"; } 71 | 72 | /* Collections */ 73 | & { 74 | @import "~semantic-ui-less/definitions/collections/breadcrumb"; 75 | } 76 | 77 | & { 78 | @import "~semantic-ui-less/definitions/collections/form"; 79 | } 80 | 81 | & { 82 | @import "~semantic-ui-less/definitions/collections/grid"; 83 | } 84 | 85 | & { 86 | @import "~semantic-ui-less/definitions/collections/menu"; 87 | } 88 | 89 | & { 90 | @import "~semantic-ui-less/definitions/collections/message"; 91 | } 92 | 93 | & { 94 | @import "~semantic-ui-less/definitions/collections/table"; 95 | } 96 | 97 | /* Views */ 98 | // & { @import "~semantic-ui-less/definitions/views/ad"; } 99 | // & { @import "~semantic-ui-less/definitions/views/card"; } 100 | // & { @import "~semantic-ui-less/definitions/views/comment"; } 101 | // & { @import "~semantic-ui-less/definitions/views/feed"; } 102 | // & { @import "~semantic-ui-less/definitions/views/item"; } 103 | // & { @import "~semantic-ui-less/definitions/views/statistic"; } 104 | 105 | /* Modules */ 106 | // & { @import "~semantic-ui-less/definitions/modules/accordion"; } 107 | & { 108 | @import "~semantic-ui-less/definitions/modules/checkbox"; 109 | } 110 | 111 | // & { @import "~semantic-ui-less/definitions/modules/dimmer"; } 112 | & { 113 | @import "~semantic-ui-less/definitions/modules/dropdown"; 114 | } 115 | 116 | // & { @import "~semantic-ui-less/definitions/modules/embed"; } 117 | // & { @import "~semantic-ui-less/definitions/modules/modal"; } 118 | // & { @import "~semantic-ui-less/definitions/modules/nag"; } 119 | // & { @import "~semantic-ui-less/definitions/modules/popup"; } 120 | // & { @import "~semantic-ui-less/definitions/modules/progress"; } 121 | // & { @import "~semantic-ui-less/definitions/modules/rating"; } 122 | // & { @import "~semantic-ui-less/definitions/modules/search"; } 123 | // & { @import "~semantic-ui-less/definitions/modules/shape"; } 124 | // & { @import "~semantic-ui-less/definitions/modules/sidebar"; } 125 | // & { @import "~semantic-ui-less/definitions/modules/sticky"; } 126 | & { 127 | @import "~semantic-ui-less/definitions/modules/tab"; 128 | } 129 | 130 | & { 131 | @import "~semantic-ui-less/definitions/modules/transition"; 132 | } 133 | -------------------------------------------------------------------------------- /App/constants/ActionTypes.js: -------------------------------------------------------------------------------- 1 | export const UPDATE_CODE = 'UPDATE_CODE'; 2 | export const UPDATE_OUTPUT_FILE_NAME = 'UPDATE_OUTPUT_FILE_NAME'; 3 | 4 | export const OBFUSCATE = 'OBFUSCATE'; 5 | export const OBFUSCATE_PENDING = 'OBFUSCATE_PENDING'; 6 | export const OBFUSCATE_FULFILLED = 'OBFUSCATE_FULFILLED'; 7 | export const OBFUSCATE_REJECTED = 'OBFUSCATE_REJECTED'; 8 | 9 | export const RESET_OPTIONS = 'RESET_OPTIONS'; 10 | 11 | export const SET_OPTIONS_PRESET = 'SET_OPTIONS_PRESET'; 12 | 13 | export const TOGGLE_COMPACT_CODE = 'TOGGLE_COMPACT_CODE'; 14 | export const TOGGLE_SIMPLIFY = 'TOGGLE_SIMPLIFY'; 15 | 16 | export const TOGGLE_SELF_DEFENDING = 'TOGGLE_SELF_DEFENDING'; 17 | export const TOGGLE_DISABLE_CONSOLE_OUTPUT = 'TOGGLE_DISABLE_CONSOLE_OUTPUT'; 18 | 19 | export const TOGGLE_DEBUG_PROTECTION = 'TOGGLE_DEBUG_PROTECTION'; 20 | export const TOGGLE_DEBUG_PROTECTION_INTERVAL = 'TOGGLE_DEBUG_PROTECTION_INTERVAL'; 21 | 22 | export const TOGGLE_SOURCEMAP = 'TOGGLE_SOURCEMAP'; 23 | export const SET_SOURCEMAP_MODE = 'SET_SOURCEMAP_MODE'; 24 | export const SET_SOURCEMAP_BASE_URL = 'SET_SOURCEMAP_BASE_URL'; 25 | export const SET_SOURCEMAP_FILE_NAME = 'SET_SOURCEMAP_FILE_NAME'; 26 | 27 | export const TOGGLE_SPLIT_STRINGS = 'TOGGLE_SPLIT_STRINGS'; 28 | export const SET_SPLIT_STRINGS_CHUNK_LENGTH = 'SET_SPLIT_STRINGS_CHUNK_LENGTH'; 29 | 30 | export const SET_STRING_ARRAY_THRESHOLD = 'SET_STRING_ARRAY_THRESHOLD'; 31 | export const SET_STRING_ARRAY_INDEXES_TYPE = 'SET_STRING_ARRAY_INDEXES_TYPE'; 32 | export const TOGGLE_STRING_ARRAY = 'TOGGLE_STRING_ARRAY'; 33 | export const TOGGLE_STRING_ARRAY_INDEX_SHIFT = 'TOGGLE_STRING_ARRAY_INDEX_SHIFT'; 34 | export const TOGGLE_STRING_ARRAY_ROTATE = 'TOGGLE_STRING_ARRAY_ROTATE'; 35 | export const TOGGLE_STRING_ARRAY_SHUFFLE = 'TOGGLE_STRING_ARRAY_SHUFFLE'; 36 | export const SET_STRING_ARRAY_ENCODING = 'SET_STRING_ARRAY_ENCODING'; 37 | 38 | export const TOGGLE_STRING_ARRAY_CALLS_TRANSFORM = 'TOGGLE_STRING_ARRAY_CALLS_TRANSFORM'; 39 | export const SET_STRING_ARRAY_CALLS_TRANSFORM_THRESHOLD = 'SET_STRING_ARRAY_CALLS_TRANSFORM_THRESHOLD'; 40 | 41 | export const SET_STRING_ARRAY_WRAPPERS_COUNT = 'SET_STRING_ARRAY_WRAPPERS_COUNT'; 42 | export const SET_STRING_ARRAY_WRAPPERS_PARAMETERS_MAX_COUNT = 'SET_STRING_ARRAY_WRAPPERS_PARAMETERS_MAX_COUNT'; 43 | export const TOGGLE_STRING_ARRAY_WRAPPERS_CHAINED_CALLS = 'TOGGLE_STRING_ARRAY_WRAPPERS_CHAINED_CALLS'; 44 | export const SET_STRING_ARRAY_WRAPPERS_TYPE = 'SET_STRING_ARRAY_WRAPPERS_TYPE'; 45 | 46 | export const ADD_DOMAIN_LOCK = 'ADD_DOMAIN_LOCK'; 47 | export const REMOVE_DOMAIN_LOCK = 'REMOVE_DOMAIN_LOCK'; 48 | export const SET_DOMAIN_LOCK_REDIRECT_URL = 'SET_DOMAIN_LOCK_REDIRECT_URL'; 49 | 50 | export const ADD_RESERVED_NAME = 'ADD_RESERVED_NAME'; 51 | export const REMOVE_RESERVED_NAME = 'REMOVE_RESERVED_NAME'; 52 | 53 | export const ADD_FORCE_TRANSFORM_STRING = 'ADD_FORCE_TRANSFORM_STRING'; 54 | export const REMOVE_FORCE_TRANSFORM_STRING = 'REMOVE_FORCE_TRANSFORM_STRING'; 55 | 56 | export const ADD_RESERVED_STRING = 'ADD_RESERVED_STRING'; 57 | export const REMOVE_RESERVED_STRING = 'REMOVE_RESERVED_STRING'; 58 | 59 | export const ADD_DICTIONARY_IDENTIFIER = 'ADD_DICTIONARY_IDENTIFIER'; 60 | export const REMOVE_DICTIONARY_IDENTIFIER = 'REMOVE_DICTIONARY_IDENTIFIER'; 61 | 62 | export const SET_SEED = 'SET_SEED'; 63 | 64 | export const SET_CONTROL_FLOW_FLATTENING_THRESHOLD = 'SET_CONTROL_FLOW_FLATTENING_THRESHOLD'; 65 | export const TOGGLE_CONTROL_FLOW_FLATTENING = 'TOGGLE_CONTROL_FLOW_FLATTENING'; 66 | 67 | export const SET_DEAD_CODE_INJECTION_THRESHOLD = 'SET_DEAD_CODE_INJECTION_THRESHOLD'; 68 | export const TOGGLE_DEAD_CODE_INJECTION = 'TOGGLE_DEAD_CODE_INJECTION'; 69 | 70 | export const TOGGLE_NUMBERS_TO_EXPRESSIONS = 'TOGGLE_NUMBERS_TO_EXPRESSIONS'; 71 | 72 | export const TOGGLE_UNICODE_ESCAPE_SEQUENCE = 'TOGGLE_UNICODE_ESCAPE_SEQUENCE'; 73 | 74 | export const TOGGLE_RENAME_GLOBALS = 'TOGGLE_RENAME_GLOBALS'; 75 | 76 | export const TOGGLE_RENAME_PROPERTIES = 'TOGGLE_RENAME_PROPERTIES'; 77 | export const SET_RENAME_PROPERTIES_MODE = 'SET_RENAME_PROPERTIES_MODE'; 78 | 79 | export const SET_TARGET = 'SET_TARGET'; 80 | 81 | export const SET_IDENTIFIER_NAMES_GENERATOR = 'SET_IDENTIFER_NAMES_GENERATOR'; 82 | 83 | export const SET_IDENTIFIERS_PREFIX = 'SET_IDENTIFIERS_PREFIX'; 84 | 85 | export const TOGGLE_TRANSFORM_OBJECT_KEYS = 'TOGGLE_TRANSFORM_OBJECT_KEYS'; 86 | 87 | export const TOGGLE_IGNORE_IMPORTS = 'TOGGLE_IGNORE_IMPORTS'; 88 | 89 | export const SET_DEBUG_PROTECTION_INTERVAL = 'SET_DEBUG_PROTECTION_INTERVAL'; -------------------------------------------------------------------------------- /App/actions/index.js: -------------------------------------------------------------------------------- 1 | import * as types from '../constants/ActionTypes'; 2 | import {OPTIONS_PRESET_DEFAULT} from "../containers/OptionsContainer"; 3 | 4 | const obfuscationWorker = new Worker('../workers/obfuscation-worker.js?v=' + new Date().getTime()); 5 | 6 | export const OBFUSCATOR_WORKER_OBFUSCATE_EVENT = 'OBFUSCATOR_WORKER_OBFUSCATE_EVENT'; 7 | export const OBFUSCATOR_WORKER_GET_OPTIONS_BY_PRESET_EVENT = 'OBFUSCATOR_WORKER_GET_OPTIONS_BY_PRESET_EVENT'; 8 | 9 | export const updateCode = (code) => ({ 10 | 'type': types.UPDATE_CODE, 11 | code 12 | }); 13 | 14 | export const updateOutputFileName = (outputFileName) => ({ 15 | 'type': types.UPDATE_OUTPUT_FILE_NAME, 16 | outputFileName 17 | }); 18 | 19 | export const obfuscateCode = (code, options) => { 20 | return (dispatch) => { 21 | if (!options.sourceMap) { 22 | delete options.sourceMapMode 23 | } 24 | 25 | // options.stringArrayEncoding come from the client as strings, but the 26 | // obfuscator expects it to be a boolean or a string if 'base64'/'rc4' 27 | if (['false', 'true'].indexOf(options.stringArrayEncoding) !== -1) { 28 | options.stringArrayEncoding = options.stringArrayEncoding === 'true'; 29 | } 30 | 31 | const message = { 32 | type: OBFUSCATOR_WORKER_OBFUSCATE_EVENT, 33 | payload: { 34 | code, 35 | options 36 | } 37 | }; 38 | 39 | obfuscationWorker.postMessage(message); 40 | 41 | dispatch({ 42 | type: types.OBFUSCATE, 43 | payload: new Promise((resolve) => { 44 | obfuscationWorker.onmessage = function (event) { 45 | const result = JSON.parse(event.data); 46 | 47 | resolve(result); 48 | }; 49 | }) 50 | }); 51 | }; 52 | }; 53 | 54 | export const resetOptions = () => { 55 | return (dispatch) => { 56 | dispatch({ 57 | 'type': types.RESET_OPTIONS, 58 | }); 59 | dispatch(setOptionsPreset(OPTIONS_PRESET_DEFAULT)); 60 | }; 61 | }; 62 | 63 | export const setOptionsPreset = (optionsPreset) => { 64 | return (dispatch) => { 65 | const message = { 66 | type: OBFUSCATOR_WORKER_GET_OPTIONS_BY_PRESET_EVENT, 67 | payload: { optionsPreset } 68 | }; 69 | 70 | obfuscationWorker.postMessage(message); 71 | obfuscationWorker.onmessage = function (event) { 72 | const options = JSON.parse(event.data); 73 | 74 | dispatch({ 75 | type: types.SET_OPTIONS_PRESET, 76 | optionsPreset, 77 | options 78 | }); 79 | }; 80 | }; 81 | }; 82 | 83 | export const toggleOption = (optionType) => ({ 84 | 'type': optionType 85 | }); 86 | 87 | export const addDomainLock = (domain) => ({ 88 | 'type': types.ADD_DOMAIN_LOCK, 89 | domain 90 | }); 91 | 92 | export const removeDomainLock = (domain) => ({ 93 | 'type': types.REMOVE_DOMAIN_LOCK, 94 | domain 95 | }); 96 | 97 | export const setDomainLockRedirectUrl = (domainLockRedirectUrl) => ({ 98 | 'type': types.SET_DOMAIN_LOCK_REDIRECT_URL, 99 | domainLockRedirectUrl 100 | }); 101 | export const addReservedName = (name) => ({ 102 | 'type': types.ADD_RESERVED_NAME, 103 | name 104 | }); 105 | 106 | export const removeReservedName = (name) => ({ 107 | 'type': types.REMOVE_RESERVED_NAME, 108 | name 109 | }); 110 | 111 | export const addForceTransformString = (string) => ({ 112 | 'type': types.ADD_FORCE_TRANSFORM_STRING, 113 | string 114 | }); 115 | 116 | export const removeForceTransformString = (string) => ({ 117 | 'type': types.REMOVE_FORCE_TRANSFORM_STRING, 118 | string 119 | }); 120 | 121 | export const addReservedString = (string) => ({ 122 | 'type': types.ADD_RESERVED_STRING, 123 | string 124 | }); 125 | 126 | export const removeReservedString = (string) => ({ 127 | 'type': types.REMOVE_RESERVED_STRING, 128 | string 129 | }); 130 | 131 | export const addDictionaryIdentifier = (name) => ({ 132 | 'type': types.ADD_DICTIONARY_IDENTIFIER, 133 | name 134 | }); 135 | 136 | export const removeDictionaryIdentifier = (name) => ({ 137 | 'type': types.REMOVE_DICTIONARY_IDENTIFIER, 138 | name 139 | }); 140 | 141 | export const setRenamePropertiesMode = (renamePropertiesMode) => ({ 142 | 'type': types.SET_RENAME_PROPERTIES_MODE, 143 | renamePropertiesMode 144 | }); 145 | 146 | export const setSplitStringsChunkLength = (chunkLength) => ({ 147 | 'type': types.SET_SPLIT_STRINGS_CHUNK_LENGTH, 148 | chunkLength 149 | }); 150 | 151 | export const setStringArrayThreshold = (threshold) => ({ 152 | 'type': types.SET_STRING_ARRAY_THRESHOLD, 153 | threshold 154 | }); 155 | 156 | export const setStringArrayIndexesType = (indexesType) => ({ 157 | 'type': types.SET_STRING_ARRAY_INDEXES_TYPE, 158 | indexesType 159 | }); 160 | 161 | export const setStringArrayCallsTransformThreshold = (threshold) => ({ 162 | 'type': types.SET_STRING_ARRAY_CALLS_TRANSFORM_THRESHOLD, 163 | threshold 164 | }); 165 | 166 | export const setStringArrayEncoding = (encoding) => ({ 167 | 'type': types.SET_STRING_ARRAY_ENCODING, 168 | encoding 169 | }); 170 | 171 | export const setStringArrayWrappersCount = (stringArrayWrappersCount) => ({ 172 | 'type': types.SET_STRING_ARRAY_WRAPPERS_COUNT, 173 | stringArrayWrappersCount 174 | }); 175 | 176 | export const setStringArrayWrappersParametersMaxCount = (stringArrayWrappersParametersMaxCount) => ({ 177 | 'type': types.SET_STRING_ARRAY_WRAPPERS_PARAMETERS_MAX_COUNT, 178 | stringArrayWrappersParametersMaxCount 179 | }); 180 | 181 | export const setStringArrayWrappersType = (stringArrayWrappersType) => ({ 182 | 'type': types.SET_STRING_ARRAY_WRAPPERS_TYPE, 183 | stringArrayWrappersType 184 | }); 185 | 186 | export const setSourceMapMode = (mode) => ({ 187 | 'type': types.SET_SOURCEMAP_MODE, 188 | mode 189 | }); 190 | 191 | export const setSourceMapBaseUrl = (baseUrl) => ({ 192 | 'type': types.SET_SOURCEMAP_BASE_URL, 193 | baseUrl 194 | }); 195 | 196 | export const setSourceMapFileName = (fileName) => ({ 197 | 'type': types.SET_SOURCEMAP_FILE_NAME, 198 | fileName 199 | }); 200 | 201 | export const setSeed = (seed) => ({ 202 | 'type': types.SET_SEED, 203 | seed 204 | }); 205 | 206 | export const setControlFlowFlatteningThreshold = (threshold) => ({ 207 | 'type': types.SET_CONTROL_FLOW_FLATTENING_THRESHOLD, 208 | threshold 209 | }); 210 | 211 | export const setDeadCodeInjectionThreshold = (threshold) => ({ 212 | 'type': types.SET_DEAD_CODE_INJECTION_THRESHOLD, 213 | threshold 214 | }); 215 | 216 | export const setTarget = (target) => ({ 217 | 'type': types.SET_TARGET, 218 | target 219 | }); 220 | 221 | export const setIdentifierNamesGenerator = (identifierNamesGenerator) => ({ 222 | 'type': types.SET_IDENTIFIER_NAMES_GENERATOR, 223 | identifierNamesGenerator 224 | }); 225 | 226 | export const setIdentifiersPrefix = (identifiersPrefix) => ({ 227 | 'type': types.SET_IDENTIFIERS_PREFIX, 228 | identifiersPrefix 229 | }); 230 | 231 | export const setDebugProtectionInterval = (debugProtectionInterval) => ({ 232 | 'type': types.SET_DEBUG_PROTECTION_INTERVAL, 233 | debugProtectionInterval 234 | }); 235 | -------------------------------------------------------------------------------- /App/containers/CodeContainer.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import {connect} from 'react-redux'; 5 | 6 | import {Form, Grid, Segment, Button, Icon, Tab} from 'semantic-ui-react'; 7 | 8 | import Dropzone from 'react-dropzone'; 9 | 10 | import EditorContainer from '../containers/EditorContainer'; 11 | import {DEFAULT_OUTPUT_FILE_NAME} from '../reducers/code'; 12 | 13 | const TAB_CODE = 0; 14 | const TAB_RESULTS = 2; 15 | 16 | class CodeContainer extends Component { 17 | 18 | static propTypes = { 19 | code: PropTypes.string, 20 | obfuscatedCode: PropTypes.string, 21 | pending: PropTypes.bool, 22 | hasResults: PropTypes.bool, 23 | onCodeChange: PropTypes.func, 24 | onOutputFileNameChange: PropTypes.func, 25 | onObfuscateClick: PropTypes.func, 26 | onDownloadCodeClick: PropTypes.func, 27 | onDownloadSourceMapClick: PropTypes.func, 28 | hasSourceMap: PropTypes.bool, 29 | hasObfuscatedCode: PropTypes.bool, 30 | }; 31 | 32 | constructor(props) { 33 | super(props); 34 | 35 | this.state = { 36 | selectedTabIndex: TAB_CODE, 37 | evaluate: false, 38 | evaluatedResult: '', 39 | }; 40 | 41 | this.capturingConsole = null; 42 | } 43 | 44 | componentWillReceiveProps(nextProps) { 45 | if (this.props.pending && nextProps.hasResults) { 46 | this.setState({ 47 | selectedTabIndex: TAB_RESULTS, 48 | }) 49 | } 50 | 51 | if (this.state.evaluate) { 52 | this.evaluate(nextProps.obfuscatedCode); 53 | } 54 | } 55 | 56 | onTabClick(index) { 57 | this.setState({ 58 | selectedTabIndex: index, 59 | }); 60 | } 61 | 62 | onCodeChange(code) { 63 | const {code: prevCode, onCodeChange, onOutputFileNameChange} = this.props; 64 | 65 | onCodeChange(code); 66 | 67 | if (code !== prevCode) { 68 | onOutputFileNameChange(DEFAULT_OUTPUT_FILE_NAME); 69 | } 70 | } 71 | 72 | onDrop(files) { 73 | const {onCodeChange, onOutputFileNameChange} = this.props; 74 | 75 | if (!window.File || !window.FileReader) { 76 | alert('Your browser does not support File API'); 77 | } 78 | 79 | const file = files[0]; 80 | const reader = new FileReader(); 81 | 82 | reader.onload = (event) => { 83 | onCodeChange(event.target.result); 84 | onOutputFileNameChange(file.name); 85 | this.onTabClick(TAB_CODE); 86 | }; 87 | 88 | reader.readAsText(file); 89 | } 90 | 91 | toggleEvaluate = () => { 92 | const nextEvaluate = !this.state.evaluate; 93 | 94 | this.setState({ 95 | evaluate: nextEvaluate, 96 | }); 97 | 98 | if (nextEvaluate) { 99 | this.evaluate(this.props.obfuscatedCode); 100 | } 101 | 102 | }; 103 | 104 | // from https://github.com/babel/babel.github.io/blob/e7d082e4d545a75d7aa29b1df580c86114ab1586/scripts/7.js#L361 105 | evaluate(code) { 106 | this.capturingConsole = Object.create(console); 107 | 108 | const capturingConsole = this.capturingConsole; 109 | let done = false; 110 | 111 | let buffer = []; 112 | 113 | const self = this; 114 | 115 | function flush() { 116 | self.setState({ 117 | evaluatedResult: buffer.join('\n'), 118 | }) 119 | } 120 | 121 | function write(data) { 122 | buffer.push(data); 123 | if (done) flush(); 124 | } 125 | 126 | // TODO: replace this function with a proper one 127 | // right now the `pretty-format` npm package doesn't work with the uglify 128 | function prettyFormat(str) { 129 | return str; 130 | } 131 | 132 | function capture() { 133 | const logs = [].map.call(arguments, (log) => { 134 | return prettyFormat(log); 135 | }); 136 | 137 | write(logs.join('\n')); 138 | } 139 | 140 | ['error', 'log', 'info', 'debug'].forEach(function (key) { 141 | capturingConsole[key] = function () { 142 | Function.prototype.apply.call(console[key], console, arguments); 143 | capture.apply(this, arguments); 144 | }; 145 | }); 146 | 147 | try { 148 | new Function('console', code)(capturingConsole); 149 | } catch (err) { 150 | buffer.push(err.message); 151 | } 152 | 153 | done = true; 154 | flush(); 155 | } 156 | 157 | buildPanes() { 158 | const { 159 | code, 160 | obfuscatedCode, 161 | pending, 162 | onObfuscateClick, 163 | onDownloadCodeClick, 164 | onDownloadSourceMapClick, 165 | hasSourceMap, 166 | hasObfuscatedCode, 167 | } = this.props; 168 | 169 | return [ 170 | { 171 | menuItem: { 172 | as: 'a', 173 | content: 'Copy & Paste JavaScript Code', 174 | href: "#code", 175 | }, 176 | render: () => ( 177 | 178 | 179 | 180 | 188 | 189 | 190 | ) 191 | }, 192 | { 193 | menuItem: { 194 | as: 'a', 195 | content: 'Upload JavaScript File', 196 | href: "#upload", 197 | }, 198 | render: () => ( 199 | 200 | 204 | {({getRootProps, getInputProps}) => ( 205 |
206 |
207 | 208 |
Try dropping some file here, or click to select file to upload.
209 |
210 |
211 | )} 212 |
213 |
214 | ) 215 | }, 216 | { 217 | menuItem: { 218 | as: 'a', 219 | content: 'Output', 220 | href: "#output", 221 | }, 222 | render: () => ( 223 | 224 | 225 | 226 |
227 | event.target.select()} 231 | /> 232 | 233 |
234 | 235 | 236 | 242 | 243 | {hasSourceMap && 244 | 249 | } 250 | 251 | 252 | 253 | 258 | 259 | 260 | {this.state.evaluate && 261 | 262 |
263 | {this.state.evaluatedResult} 264 |
265 |
266 | } 267 |
268 |
269 | ) 270 | } 271 | ]; 272 | } 273 | 274 | render() { 275 | const tabIndex = this.state.selectedTabIndex; 276 | 277 | return ( 278 | this.onTabClick(data.activeIndex)} 283 | /> 284 | ); 285 | } 286 | } 287 | 288 | const mapStateToProps = (state) => { 289 | return { 290 | code: state.code.code, 291 | obfuscatedCode: state.code.obfuscatedCode, 292 | obfuscating: state.obfuscating, 293 | } 294 | }; 295 | 296 | export default connect(mapStateToProps)(CodeContainer); 297 | 298 | 299 | const Pane = (props) => { 300 | return ( 301 |
302 | {props.children} 303 |
304 | ) 305 | }; 306 | 307 | Pane.propTypes = { 308 | children: PropTypes.node.isRequired, 309 | }; 310 | -------------------------------------------------------------------------------- /App/reducers/options.js: -------------------------------------------------------------------------------- 1 | import * as types from '../constants/ActionTypes'; 2 | 3 | import { 4 | SOURCEMAP_SEPARATE, 5 | OPTIONS_PRESET_DEFAULT, 6 | IDENTIFIER_NAMES_GENERATOR_HEXADECIMAL, 7 | TARGET_BROWSER, 8 | STRING_ARRAY_ENCODING_NONE, 9 | STRING_ARRAY_ENCODING_BASE64, 10 | STRING_ARRAY_ENCODING_RC4, 11 | STRING_ARRAY_WRAPPERS_TYPE_VARIABLE, 12 | STRING_ARRAY_INDEXES_TYPE_HEXADECIMAL_NUMBER, 13 | RENAME_PROPERTIES_MODE_SAFE, 14 | DOMAIN_LOCK_REDIRECT_URL_ABOUT_BLANK 15 | } from '../containers/OptionsContainer'; 16 | 17 | const initialState = { 18 | optionsPreset: OPTIONS_PRESET_DEFAULT, 19 | 20 | compact: true, 21 | selfDefending: false, 22 | disableConsoleOutput: false, 23 | 24 | debugProtection: false, 25 | debugProtectionInterval: 0, 26 | 27 | splitStrings: false, 28 | 29 | splitStringsChunkLength: 10, 30 | splitStringsChunkLengthEnabled: false, 31 | 32 | stringArray: true, 33 | 34 | stringArrayRotate: true, 35 | stringArrayRotateEnabled: true, 36 | 37 | stringArrayShuffle: true, 38 | stringArrayShuffleEnabled: true, 39 | 40 | simplify: true, 41 | 42 | stringArrayThreshold: 0.75, 43 | stringArrayThresholdEnabled: true, 44 | 45 | stringArrayIndexesType: [ 46 | STRING_ARRAY_INDEXES_TYPE_HEXADECIMAL_NUMBER 47 | ], 48 | 49 | stringArrayIndexShift: true, 50 | 51 | stringArrayCallsTransform: false, 52 | stringArrayCallsTransformThreshold: 0.5, 53 | 54 | stringArrayEncoding: [ 55 | STRING_ARRAY_ENCODING_NONE 56 | ], 57 | stringArrayEncodingEnabled: true, 58 | 59 | stringArrayWrappersCount: 1, 60 | stringArrayWrappersChainedCalls: true, 61 | stringArrayWrappersParametersMaxCount: 2, 62 | stringArrayWrappersType: STRING_ARRAY_WRAPPERS_TYPE_VARIABLE, 63 | 64 | numbersToExpressions: false, 65 | 66 | sourceMap: false, 67 | sourceMapMode: SOURCEMAP_SEPARATE, 68 | sourceMapBaseUrl: '', 69 | sourceMapFileName: '', 70 | 71 | domainLock: [], 72 | domainLockRedirectUrl: DOMAIN_LOCK_REDIRECT_URL_ABOUT_BLANK, 73 | domainLockEnabled: true, 74 | 75 | forceTransformStrings: [], 76 | reservedNames: [], 77 | reservedStrings: [], 78 | 79 | seed: 0, 80 | 81 | controlFlowFlatteningThreshold: 0.75, 82 | controlFlowFlattening: false, 83 | 84 | deadCodeInjectionThreshold: 0.4, 85 | deadCodeInjection: false, 86 | 87 | unicodeEscapeSequence: false, 88 | 89 | renameGlobals: false, 90 | 91 | renameProperties: false, 92 | renamePropertiesMode: RENAME_PROPERTIES_MODE_SAFE, 93 | 94 | target: TARGET_BROWSER, 95 | 96 | identifierNamesGenerator: IDENTIFIER_NAMES_GENERATOR_HEXADECIMAL, 97 | identifiersDictionary: [], 98 | identifiersPrefix: '', 99 | 100 | transformObjectKeys: false, 101 | 102 | ignoreImports: false 103 | 104 | }; 105 | 106 | export const options = (state = initialState, action) => { 107 | 108 | // this is necessary because new options need to be filled with their 109 | // default values and them merged with the state from the localStorage 110 | // which can be outdated when new options are added 111 | // from https://github.com/reactjs/redux/issues/433#issuecomment-129188687 112 | if (!state.hydrated) { 113 | state = {...initialState, ...state, hydrated: true}; 114 | } 115 | 116 | switch (action.type) { 117 | 118 | case types.RESET_OPTIONS: { 119 | return initialState; 120 | } 121 | 122 | case types.SET_OPTIONS_PRESET: { 123 | return { 124 | ...state, 125 | ...action.options, 126 | optionsPreset: action.optionsPreset 127 | }; 128 | } 129 | 130 | case types.TOGGLE_COMPACT_CODE: { 131 | const compact = !state.compact; 132 | return { 133 | ...state, 134 | compact, 135 | selfDefending: state.selfDefending && compact, 136 | }; 137 | } 138 | 139 | case types.TOGGLE_SIMPLIFY: { 140 | return { 141 | ...state, 142 | simplify: !state.simplify, 143 | }; 144 | } 145 | 146 | case types.TOGGLE_SELF_DEFENDING: { 147 | const selfDefending = !state.selfDefending; 148 | return { 149 | ...state, 150 | selfDefending, 151 | compact: state.compact || selfDefending, 152 | }; 153 | } 154 | 155 | case types.TOGGLE_DISABLE_CONSOLE_OUTPUT: 156 | return { 157 | ...state, 158 | disableConsoleOutput: !state.disableConsoleOutput, 159 | }; 160 | 161 | case types.TOGGLE_DEBUG_PROTECTION: { 162 | const debugProtection = !state.debugProtection; 163 | return { 164 | ...state, 165 | debugProtection, 166 | debugProtectionInterval: debugProtection 167 | ? state.debugProtectionInterval 168 | : initialState.debugProtectionInterval, 169 | } 170 | } 171 | 172 | case types.SET_DEBUG_PROTECTION_INTERVAL: { 173 | return { 174 | ...state, 175 | debugProtectionInterval: action.debugProtectionInterval 176 | } 177 | } 178 | 179 | case types.TOGGLE_DEBUG_PROTECTION_INTERVAL: 180 | return { 181 | ...state, 182 | debugProtectionInterval: !state.debugProtectionInterval, 183 | }; 184 | 185 | case types.TOGGLE_SPLIT_STRINGS: { 186 | const splitStrings = !state.splitStrings; 187 | 188 | return { 189 | ...state, 190 | splitStrings, 191 | splitStringsChunkLengthEnabled: splitStrings, 192 | }; 193 | } 194 | 195 | case types.SET_SPLIT_STRINGS_CHUNK_LENGTH: 196 | return { 197 | ...state, 198 | splitStringsChunkLength: action.chunkLength 199 | }; 200 | 201 | case types.TOGGLE_STRING_ARRAY: { 202 | // Also change the TOGGLE_DEAD_CODE_INJECTION below if changed 203 | const stringArray = !state.stringArray; 204 | return { 205 | ...state, 206 | stringArray, 207 | stringArrayRotateEnabled: stringArray, 208 | stringArrayShuffleEnabled: stringArray, 209 | stringArrayThresholdEnabled: stringArray, 210 | stringArrayEncodingEnabled: stringArray, 211 | }; 212 | } 213 | 214 | case types.TOGGLE_STRING_ARRAY_INDEX_SHIFT: 215 | return { 216 | ...state, 217 | stringArrayIndexShift: !state.stringArrayIndexShift 218 | }; 219 | 220 | case types.TOGGLE_STRING_ARRAY_ROTATE: 221 | return { 222 | ...state, 223 | stringArrayRotate: !state.stringArrayRotate 224 | }; 225 | 226 | case types.TOGGLE_STRING_ARRAY_SHUFFLE: 227 | return { 228 | ...state, 229 | stringArrayShuffle: !state.stringArrayShuffle 230 | }; 231 | 232 | case types.SET_STRING_ARRAY_ENCODING: 233 | return { 234 | ...state, 235 | stringArrayEncoding: action.encoding 236 | }; 237 | 238 | case types.SET_STRING_ARRAY_THRESHOLD: 239 | return { 240 | ...state, 241 | stringArrayThreshold: action.threshold 242 | }; 243 | 244 | case types.SET_STRING_ARRAY_INDEXES_TYPE: 245 | return { 246 | ...state, 247 | stringArrayIndexesType: action.indexesType 248 | }; 249 | 250 | case types.SET_STRING_ARRAY_CALLS_TRANSFORM_THRESHOLD: 251 | return { 252 | ...state, 253 | stringArrayCallsTransformThreshold: action.threshold 254 | }; 255 | 256 | case types.TOGGLE_STRING_ARRAY_CALLS_TRANSFORM: 257 | return { 258 | ...state, 259 | stringArrayCallsTransform: !state.stringArrayCallsTransform 260 | }; 261 | 262 | case types.SET_STRING_ARRAY_WRAPPERS_COUNT: 263 | return { 264 | ...state, 265 | stringArrayWrappersCount: action.stringArrayWrappersCount 266 | }; 267 | 268 | case types.SET_STRING_ARRAY_WRAPPERS_PARAMETERS_MAX_COUNT: 269 | return { 270 | ...state, 271 | stringArrayWrappersParametersMaxCount: action.stringArrayWrappersParametersMaxCount 272 | }; 273 | 274 | case types.TOGGLE_STRING_ARRAY_WRAPPERS_CHAINED_CALLS: 275 | return { 276 | ...state, 277 | stringArrayWrappersChainedCalls: !state.stringArrayWrappersChainedCalls 278 | }; 279 | 280 | case types.SET_STRING_ARRAY_WRAPPERS_TYPE: 281 | return { 282 | ...state, 283 | stringArrayWrappersType: action.stringArrayWrappersType 284 | }; 285 | 286 | case types.TOGGLE_SOURCEMAP: { 287 | return { 288 | ...state, 289 | sourceMap: !state.sourceMap 290 | }; 291 | } 292 | 293 | case types.SET_SOURCEMAP_MODE: { 294 | const mode = action.mode; 295 | return { 296 | ...state, 297 | sourceMapMode: mode 298 | }; 299 | } 300 | 301 | case types.SET_SOURCEMAP_BASE_URL: 302 | return { 303 | ...state, 304 | sourceMapBaseUrl: action.baseUrl 305 | }; 306 | 307 | case types.SET_SOURCEMAP_FILE_NAME: 308 | return { 309 | ...state, 310 | sourceMapFileName: action.fileName 311 | }; 312 | 313 | case types.ADD_DOMAIN_LOCK: { 314 | const domain = action.domain; 315 | if (state.domainLock.indexOf(domain) !== -1) 316 | return state; 317 | 318 | return { 319 | ...state, 320 | domainLock: [...state.domainLock, domain], 321 | }; 322 | } 323 | 324 | case types.REMOVE_DOMAIN_LOCK: 325 | return { 326 | ...state, 327 | domainLock: state.domainLock.filter((domain) => domain !== action.domain), 328 | }; 329 | 330 | case types.SET_DOMAIN_LOCK_REDIRECT_URL: 331 | return { 332 | ...state, 333 | domainLockRedirectUrl: action.domainLockRedirectUrl 334 | }; 335 | 336 | case types.ADD_RESERVED_NAME: { 337 | const name = action.name; 338 | if (state.reservedNames.indexOf(name) !== -1) 339 | return state; 340 | 341 | return { 342 | ...state, 343 | reservedNames: [...state.reservedNames, name], 344 | }; 345 | } 346 | 347 | case types.REMOVE_RESERVED_NAME: 348 | return { 349 | ...state, 350 | reservedNames: state.reservedNames.filter((name) => name !== action.name), 351 | }; 352 | 353 | case types.ADD_FORCE_TRANSFORM_STRING: { 354 | const string = action.string; 355 | if (state.forceTransformStrings.indexOf(name) !== -1) 356 | return state; 357 | 358 | return { 359 | ...state, 360 | forceTransformStrings: [...state.forceTransformStrings, string], 361 | }; 362 | } 363 | 364 | case types.REMOVE_FORCE_TRANSFORM_STRING: { 365 | return { 366 | ...state, 367 | forceTransformStrings: state.forceTransformStrings.filter((string) => string !== action.string) 368 | }; 369 | } 370 | 371 | case types.ADD_RESERVED_STRING: { 372 | const string = action.string; 373 | if (state.reservedStrings.indexOf(string) !== -1) 374 | return state; 375 | 376 | return { 377 | ...state, 378 | reservedStrings: [...state.reservedStrings, string], 379 | }; 380 | } 381 | 382 | case types.REMOVE_RESERVED_STRING: 383 | return { 384 | ...state, 385 | reservedStrings: state.reservedStrings.filter((string) => string !== action.string), 386 | }; 387 | 388 | case types.ADD_DICTIONARY_IDENTIFIER: { 389 | const name = action.name; 390 | 391 | return { 392 | ...state, 393 | identifiersDictionary: [...state.identifiersDictionary, name], 394 | }; 395 | } 396 | 397 | case types.REMOVE_DICTIONARY_IDENTIFIER: 398 | return { 399 | ...state, 400 | identifiersDictionary: state.identifiersDictionary.filter((name) => name !== action.name), 401 | }; 402 | 403 | case types.SET_SEED: 404 | return { 405 | ...state, 406 | seed: action.seed 407 | }; 408 | 409 | case types.SET_CONTROL_FLOW_FLATTENING_THRESHOLD: 410 | return { 411 | ...state, 412 | controlFlowFlatteningThreshold: action.threshold 413 | }; 414 | 415 | case types.TOGGLE_CONTROL_FLOW_FLATTENING: 416 | return { 417 | ...state, 418 | controlFlowFlattening: !state.controlFlowFlattening 419 | }; 420 | 421 | case types.SET_DEAD_CODE_INJECTION_THRESHOLD: 422 | return { 423 | ...state, 424 | deadCodeInjectionThreshold: action.threshold 425 | }; 426 | 427 | case types.TOGGLE_DEAD_CODE_INJECTION: { 428 | // Also change the TOGGLE_STRING_ARRAY above if changed 429 | const deadCodeInjection = !state.deadCodeInjection; 430 | const stringArray = state.stringArray || deadCodeInjection; 431 | return { 432 | ...state, 433 | deadCodeInjection: deadCodeInjection, 434 | stringArray, 435 | stringArrayRotateEnabled: stringArray, 436 | stringArrayThresholdEnabled: stringArray, 437 | stringArrayEncodingEnabled: stringArray 438 | }; 439 | } 440 | 441 | case types.TOGGLE_NUMBERS_TO_EXPRESSIONS: 442 | return { 443 | ...state, 444 | numbersToExpressions: !state.numbersToExpressions 445 | }; 446 | 447 | case types.TOGGLE_UNICODE_ESCAPE_SEQUENCE: 448 | return { 449 | ...state, 450 | unicodeEscapeSequence: !state.unicodeEscapeSequence 451 | }; 452 | 453 | case types.TOGGLE_RENAME_GLOBALS: 454 | return { 455 | ...state, 456 | renameGlobals: !state.renameGlobals 457 | }; 458 | 459 | case types.TOGGLE_RENAME_PROPERTIES: 460 | return { 461 | ...state, 462 | renameProperties: !state.renameProperties 463 | }; 464 | 465 | case types.SET_RENAME_PROPERTIES_MODE: 466 | return { 467 | ...state, 468 | renamePropertiesMode: action.renamePropertiesMode 469 | }; 470 | 471 | case types.SET_TARGET: { 472 | const target = action.target; 473 | 474 | const isNodeTarget = target === 'node'; 475 | 476 | return { 477 | ...state, 478 | target, 479 | ...isNodeTarget && { 480 | domainLock: [], 481 | domainLockRedirectUrl: DOMAIN_LOCK_REDIRECT_URL_ABOUT_BLANK 482 | }, 483 | domainLockEnabled: !isNodeTarget 484 | }; 485 | } 486 | 487 | case types.SET_IDENTIFIER_NAMES_GENERATOR: 488 | return { 489 | ...state, 490 | identifierNamesGenerator: action.identifierNamesGenerator 491 | }; 492 | 493 | case types.SET_IDENTIFIERS_PREFIX: 494 | return { 495 | ...state, 496 | identifiersPrefix: action.identifiersPrefix 497 | }; 498 | 499 | case types.TOGGLE_TRANSFORM_OBJECT_KEYS: 500 | return { 501 | ...state, 502 | transformObjectKeys: !state.transformObjectKeys 503 | }; 504 | 505 | case types.TOGGLE_IGNORE_IMPORTS: 506 | return { 507 | ...state, 508 | ignoreImports: !state.ignoreImports 509 | }; 510 | 511 | default: 512 | return state 513 | } 514 | }; 515 | 516 | export function sanitizePersistedOptions(persistedOptions) { 517 | if (typeof persistedOptions.debugProtectionInterval !== 'number') { 518 | persistedOptions.debugProtectionInterval = initialState.debugProtectionInterval; 519 | } 520 | 521 | if (!Array.isArray(persistedOptions.stringArrayEncoding)) { 522 | persistedOptions.stringArrayEncoding = initialState.stringArrayEncoding; 523 | } else { 524 | for (const value of persistedOptions.stringArrayEncoding) { 525 | if ( 526 | value !== STRING_ARRAY_ENCODING_NONE 527 | || value !== STRING_ARRAY_ENCODING_BASE64 528 | || value !== STRING_ARRAY_ENCODING_RC4 529 | ) { 530 | persistedOptions.stringArrayEncoding = initialState.stringArrayEncoding; 531 | 532 | break; 533 | } 534 | } 535 | } 536 | } 537 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | JavaScript Obfuscator Tool 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 26 | 40 | 41 | 43 | 46 | 47 | 48 | 49 | 81 | 82 | 83 | 84 |
85 |
86 |
87 |
88 |
89 |

JavaScript Obfuscator Tool

90 | 91 |
92 | 99 | 106 | 117 |
118 |
119 |

120 | A free and efficient obfuscator for JavaScript (including support of ES2022). Make your code harder to copy and 121 | prevent people from stealing your work. This tool is a Web UI to the excellent (and open source) 122 | javascript-obfuscator@4.0.0 123 | created by Timofey Kachalov. 124 |

125 |
126 |
127 | 128 |
129 |
130 | 131 | 132 | 133 |
134 |
135 |
136 |
137 | 138 |
139 | 140 |
141 | 142 | 148 | 151 |
152 | 153 |
154 |
155 |
156 |
157 |
158 |
159 | 160 |
161 |
162 |

FAQ

163 | 164 |

Why would I want to obfuscate my JavaScript code?

165 |

There are numerous reasons why it's a good idea to protect your code, such as:

166 |
    167 |
  • Prevent anyone from simply copy/pasting your work. This is specially important on 100% client side 168 | projects, such as HTML5 games; 169 |
  • 170 |
  • Removal of comments and whitespace that aren't needed. Making it faster to load and harder to 171 | understand; 172 |
  • 173 |
  • Protection of work that hasn't been paid for yet. You can show your work to the client knowing that they 174 | won't have the source code until the invoice has been paid. 175 |
  • 176 |
177 | 178 |

Is this obfuscator absolutely foolproof?

179 |

No, while it's impossible to recover the exact original source code, someone with the time, knowledge and 180 | patience can reverse-engineer it.

181 |

Since the JavaScript runs on the browser, the browser's JavaScript engine must be able to read and 182 | interpret it, so there's no way to prevent that. And any tool that promises that is not being 183 | honest.

184 | 185 |

Why is my obfuscated code larger than my original source?

186 |

Because the obfuscator introduces new pieces of code that are meant to protect and defend against 187 | debugging and reverse-engineering. Also strings are converted to \xAB hexadecimal code to 188 | make things a little bit harder to understand. You don't have to worry too much about code size because 189 | there is a lot of repetition, so the obfuscated code will be compressed extremely well by your 190 | webserver (if you have GZIP compression enabled on your server, which most do nowadays).

191 | 192 |

Can I run a minifier such as UglifyJS or Google Closure Compiler on the obfuscated output?

193 |

No, it's not recommended and in some cases it'll break the code (such as if you enable self-defending). 194 | You can run your code through a minifier before to make sure that it removes dead code and do other 195 | optimizations, though.

196 | 197 |

Do you store my source code?

198 |

No. The source is processed by our application server, then to the obfuscator and back to the browser, so 199 | it only stays on our server memory for a brief period of time (usually milliseconds).

200 | 201 |

Can I recover the original source code from the obfuscated one?

202 |

No, it's impossible to revert the obfuscated code back to your original code, so keep the original 203 | safe.

204 | 205 |

Does this tool works with Node.js source code?

206 |

Yes.

207 | 208 |

I want to run the obfuscator on my own server/machine. Is it possible?

209 |

Sure. This tool uses a free and open source (BSD-2-Clause licensed) obfuscator written in TypeScript. You 210 | can go to its 211 | GitHub page and read more there.

212 |

There are also a number of plugins, such as: webpack-obfuscator, gulp-javascript-obfuscator 215 | and 216 | grunt-contrib-obfuscator. 217 |

Also, this web app is open-source as well. Check out our GitHub. 219 |

220 | 221 |

What are other similar tools?

222 |

If you're interested in just uglyfing and compressing your code, I suggest JSCompress.com.

224 | 225 |
226 |
227 | 228 |
229 |
230 |
231 |

Support project:

232 | 240 |
Also:
241 |
242 |
(Bitcoin) bc1q203p8nyrstwm7vwzjg3h9l9t6y9ka0umw0rx96
243 |
244 |
245 | Big thanks to all supporters! 246 |
247 |
248 |
249 |
250 | 251 |
252 |
253 |
254 | 255 |
256 | 257 | Cookie Policy | 258 | Privacy Policy 259 | 260 |
261 | 262 |
263 | © 264 | Tiago Serafim, Timofey Kachalov - source-code - Powered by JavaScript Obfuscator 267 | 268 |
269 |
270 |
271 | 272 |
273 | 274 | <% if(htmlWebpackPlugin.files.js) { %> 275 | 276 | <% } %> 277 | 278 | 279 | 280 | -------------------------------------------------------------------------------- /App/containers/OptionsContainer.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useRef } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import {connect} from 'react-redux'; 5 | const ReactMarkdown = require('react-markdown') 6 | 7 | import {Form, Grid, Header, Segment, Divider, Button} from 'semantic-ui-react'; 8 | 9 | import EntryInputContainer from '../containers/EntryInputContainer'; 10 | import {getOptionsMarkdown} from '../util/get-options-markdown'; 11 | import {getHeadingRenderer} from '../util/get-heading-renderer'; 12 | import {getEmojiSupportRenderer} from '../util/get-emoji-support-renderer'; 13 | 14 | import * as types from '../constants/ActionTypes'; 15 | import * as actions from '../actions'; 16 | 17 | export const OPTIONS_PRESET_DEFAULT = 'default'; 18 | export const OPTIONS_PRESET_LOW_OBFUSCATION = 'low-obfuscation'; 19 | export const OPTIONS_PRESET_MEDIUM_OBFUSCATION = 'medium-obfuscation'; 20 | export const OPTIONS_PRESET_HIGH_OBFUSCATION = 'high-obfuscation'; 21 | 22 | const OPTIONS_PRESET_OPTIONS = [ 23 | {text: 'Default', value: OPTIONS_PRESET_DEFAULT}, 24 | {text: 'Low', value: OPTIONS_PRESET_LOW_OBFUSCATION}, 25 | {text: 'Medium', value: OPTIONS_PRESET_MEDIUM_OBFUSCATION}, 26 | {text: 'High', value: OPTIONS_PRESET_HIGH_OBFUSCATION}, 27 | ]; 28 | 29 | export const RENAME_PROPERTIES_MODE_SAFE = 'safe'; 30 | export const RENAME_PROPERTIES_MODE_UNSAFE = 'unsafe'; 31 | 32 | const RENAME_PROPERTIES_MODE_OPTIONS = [ 33 | {text: 'Safe', value: RENAME_PROPERTIES_MODE_SAFE}, 34 | {text: 'Unsafe', value: RENAME_PROPERTIES_MODE_UNSAFE}, 35 | ]; 36 | 37 | export const SOURCEMAP_INLINE = 'inline'; 38 | export const SOURCEMAP_SEPARATE = 'separate'; 39 | 40 | const SOURCEMAP_OPTIONS = [ 41 | {text: 'Inline', value: SOURCEMAP_INLINE}, 42 | {text: 'Separate', value: SOURCEMAP_SEPARATE}, 43 | ]; 44 | 45 | export const STRING_ARRAY_INDEXES_TYPE_HEXADECIMAL_NUMBER = 'hexadecimal-number'; 46 | export const STRING_ARRAY_INDEXES_TYPE_HEXADECIMAL_NUMERIC_STRING = 'hexadecimal-numeric-string'; 47 | 48 | const STRING_ARRAY_INDEXES_TYPE_OPTIONS = [ 49 | {text: 'Hexadecimal Number', value: STRING_ARRAY_INDEXES_TYPE_HEXADECIMAL_NUMBER}, 50 | {text: 'Hexadecimal Numeric String', value: STRING_ARRAY_INDEXES_TYPE_HEXADECIMAL_NUMERIC_STRING} 51 | ]; 52 | 53 | export const STRING_ARRAY_ENCODING_NONE = 'none'; 54 | export const STRING_ARRAY_ENCODING_BASE64 = 'base64'; 55 | export const STRING_ARRAY_ENCODING_RC4 = 'rc4'; 56 | 57 | const STRING_ARRAY_ENCODING_OPTIONS = [ 58 | {text: 'None', value: STRING_ARRAY_ENCODING_NONE}, 59 | {text: 'Base64', value: STRING_ARRAY_ENCODING_BASE64}, 60 | {text: 'RC4', value: STRING_ARRAY_ENCODING_RC4}, 61 | ]; 62 | 63 | export const STRING_ARRAY_WRAPPERS_TYPE_VARIABLE = 'variable'; 64 | export const STRING_ARRAY_WRAPPERS_TYPE_FUNCTION = 'function'; 65 | 66 | const STRING_ARRAY_WRAPPERS_TYPE_OPTIONS = [ 67 | {text: 'Variable', value: STRING_ARRAY_WRAPPERS_TYPE_VARIABLE}, 68 | {text: 'Function', value: STRING_ARRAY_WRAPPERS_TYPE_FUNCTION}, 69 | ]; 70 | 71 | export const TARGET_BROWSER = 'browser'; 72 | export const TARGET_BROWSER_NO_EVAL = 'browser-no-eval'; 73 | export const TARGET_NODE = 'node'; 74 | 75 | const TARGET_OPTIONS = [ 76 | {text: 'Browser', value: TARGET_BROWSER}, 77 | {text: 'Browser No Eval', value: TARGET_BROWSER_NO_EVAL}, 78 | {text: 'Node', value: TARGET_NODE}, 79 | ]; 80 | 81 | export const IDENTIFIER_NAMES_GENERATOR_DICTIONARY = 'dictionary'; 82 | export const IDENTIFIER_NAMES_GENERATOR_HEXADECIMAL = 'hexadecimal'; 83 | export const IDENTIFIER_NAMES_GENERATOR_MANGLED = 'mangled'; 84 | export const IDENTIFIER_NAMES_GENERATOR_MANGLED_SHUFFLED = 'mangled-shuffled'; 85 | 86 | const IDENTIFIER_NAMES_GENERATOR_OPTIONS = [ 87 | {text: 'Dictionary', value: IDENTIFIER_NAMES_GENERATOR_DICTIONARY}, 88 | {text: 'Hexadecimal', value: IDENTIFIER_NAMES_GENERATOR_HEXADECIMAL}, 89 | {text: 'Mangled', value: IDENTIFIER_NAMES_GENERATOR_MANGLED}, 90 | {text: 'Mangled-shuffled', value: IDENTIFIER_NAMES_GENERATOR_MANGLED_SHUFFLED}, 91 | ]; 92 | 93 | export const DOMAIN_LOCK_REDIRECT_URL_ABOUT_BLANK = 'about:blank'; 94 | 95 | const shouldShowAd = (level, headingIndex) => { 96 | if (level !== 3) { 97 | return false 98 | } 99 | 100 | if (headingIndex === null) { 101 | return false; 102 | } 103 | 104 | if (headingIndex === 0) { 105 | return false; 106 | } 107 | 108 | if (headingIndex === 5) { 109 | return true; 110 | } 111 | 112 | return headingIndex % 14 === 0; 113 | } 114 | 115 | const Options = ({dispatch, options}) => { 116 | const headingCounter = useRef(0) 117 | const readmeAdCounter = useRef(0) 118 | 119 | headingCounter.current = 0 120 | readmeAdCounter.current = 0 121 | 122 | useEffect( 123 | () => { 124 | actions.setOptionsPreset(OPTIONS_PRESET_DEFAULT) 125 | }, 126 | [] 127 | ); 128 | 129 | return ( 130 | 131 |
132 | 133 | 134 | 135 | 141 | 142 | 143 | 144 | dispatch(actions.setOptionsPreset(value))} 149 | options={OPTIONS_PRESET_OPTIONS}/> 150 | 151 | 152 | 153 | dispatch(actions.setTarget(value))} 158 | options={TARGET_OPTIONS}/> 159 | 160 | dispatch(actions.setSeed(parseInt(value)))}/> 168 | 169 | 170 | 171 | dispatch(actions.toggleOption(types.TOGGLE_DISABLE_CONSOLE_OUTPUT))}/> 175 | 176 | 177 | 178 | dispatch(actions.toggleOption(types.TOGGLE_SELF_DEFENDING))}/> 182 | 183 | 184 | 185 | dispatch(actions.toggleOption(types.TOGGLE_DEBUG_PROTECTION))}/> 189 | 190 | dispatch(actions.setDebugProtectionInterval(parseInt(value)))} 197 | disabled={!options.debugProtection}/> 198 | 199 | 200 | 201 | dispatch(actions.toggleOption(types.TOGGLE_IGNORE_IMPORTS))}/> 205 | 206 | 207 | 208 | dispatch(actions.addDomainLock(domain))} 212 | actionRemoveEntryFromState={(domain) => dispatch(actions.removeDomainLock(domain))} 213 | placeholder="domain.com" 214 | entries={options.domainLock} 215 | buttonIcon="plus"/> 216 | 217 | dispatch(actions.setDomainLockRedirectUrl(value))}/> 222 | 223 | 224 | 225 | dispatch(actions.toggleOption(types.TOGGLE_SOURCEMAP))}/> 229 | 230 | dispatch(actions.setSourceMapMode(value))} 236 | options={SOURCEMAP_OPTIONS}/> 237 | 238 | dispatch(actions.setSourceMapBaseUrl(value))} 242 | value={options.sourceMapBaseUrl} 243 | placeholder='http://localhost:3000'/> 244 | 245 | dispatch(actions.setSourceMapFileName(value))} 249 | value={options.sourceMapFileName} 250 | placeholder='example'/> 251 | 252 | 253 | 254 | 255 | 256 | 257 |
258 | 259 | Strings Transformations 260 | 261 |
262 | 263 | 264 | 265 | dispatch(actions.toggleOption(types.TOGGLE_STRING_ARRAY))}/> 269 | 270 | dispatch(actions.toggleOption(types.TOGGLE_STRING_ARRAY_ROTATE))}/> 275 | 276 | dispatch(actions.toggleOption(types.TOGGLE_STRING_ARRAY_SHUFFLE))}/> 281 | 282 | dispatch(actions.setStringArrayThreshold(parseFloat(value)))} 290 | disabled={!options.stringArrayThresholdEnabled}/> 291 | 292 | dispatch(actions.toggleOption(types.TOGGLE_STRING_ARRAY_INDEX_SHIFT))}/> 297 | 298 | dispatch(actions.setStringArrayIndexesType(value))} 306 | options={STRING_ARRAY_INDEXES_TYPE_OPTIONS}/> 307 | 308 | dispatch(actions.toggleOption(types.TOGGLE_STRING_ARRAY_CALLS_TRANSFORM))}/> 312 | 313 | dispatch(actions.setStringArrayCallsTransformThreshold(parseFloat(value)))} 321 | disabled={!options.stringArrayCallsTransform}/> 322 | 323 | dispatch(actions.setStringArrayWrappersCount(parseInt(value)))} 330 | disabled={!options.stringArray}/> 331 | 332 | dispatch(actions.setStringArrayWrappersType(value))} 338 | options={STRING_ARRAY_WRAPPERS_TYPE_OPTIONS} 339 | disabled={!options.stringArray || !options.stringArrayWrappersCount} 340 | /> 341 | 342 | dispatch(actions.setStringArrayWrappersParametersMaxCount(parseInt(value)))} 349 | disabled={ 350 | !options.stringArray 351 | || !options.stringArrayWrappersCount 352 | || options.stringArrayWrappersType !== STRING_ARRAY_WRAPPERS_TYPE_FUNCTION 353 | }/> 354 | 355 | dispatch(actions.toggleOption(types.TOGGLE_STRING_ARRAY_WRAPPERS_CHAINED_CALLS))}/> 360 | 361 | dispatch(actions.setStringArrayEncoding(value))} 369 | options={STRING_ARRAY_ENCODING_OPTIONS}/> 370 | 371 | 372 | 373 | dispatch(actions.toggleOption(types.TOGGLE_SPLIT_STRINGS))}/> 377 | 378 | dispatch(actions.setSplitStringsChunkLength(parseInt(value)))} 385 | disabled={!options.splitStringsChunkLengthEnabled}/> 386 | 387 | 388 | 389 | dispatch(actions.toggleOption(types.TOGGLE_UNICODE_ESCAPE_SEQUENCE))}/> 393 | 394 | 395 | 396 | dispatch(actions.addForceTransformString(string))} 399 | actionRemoveEntryFromState={(string) => dispatch(actions.removeForceTransformString(string))} 400 | placeholder="^some *string *or RegExp" 401 | entries={options.forceTransformStrings} 402 | buttonIcon="plus"/> 403 | 404 | dispatch(actions.addReservedString(string))} 407 | actionRemoveEntryFromState={(string) => dispatch(actions.removeReservedString(string))} 408 | placeholder="^some *string *or RegExp" 409 | entries={options.reservedStrings} 410 | buttonIcon="plus"/> 411 | 412 |
413 |
414 | 415 | 416 | 417 |
418 | 419 | Identifiers Transformations 420 | 421 |
422 | 423 | 424 | 425 | dispatch(actions.setIdentifierNamesGenerator(value))} 430 | options={IDENTIFIER_NAMES_GENERATOR_OPTIONS}/> 431 | 432 | dispatch(actions.addDictionaryIdentifier(name))} 436 | actionRemoveEntryFromState={(name) => dispatch(actions.removeDictionaryIdentifier(name))} 437 | placeholder="foo" 438 | entries={options.identifiersDictionary} 439 | buttonIcon="plus"/> 440 | 441 | dispatch(actions.setIdentifiersPrefix(value))} 446 | /> 447 | 448 | 449 | 450 | dispatch(actions.toggleOption(types.TOGGLE_RENAME_GLOBALS))}/> 454 | 455 | 456 | 457 | dispatch(actions.toggleOption(types.TOGGLE_RENAME_PROPERTIES))}/> 461 | 462 | dispatch(actions.setRenamePropertiesMode(value))} 468 | options={RENAME_PROPERTIES_MODE_OPTIONS}/> 469 | 470 | 471 | 472 | dispatch(actions.addReservedName(name))} 475 | actionRemoveEntryFromState={(name) => dispatch(actions.removeReservedName(name))} 476 | placeholder="^someVariable *or *RegExp" 477 | entries={options.reservedNames} 478 | buttonIcon="plus"/> 479 |
480 |
481 | 482 | 483 | 484 |
485 | 486 | Other Transformations 487 | 488 |
489 | 490 | 491 | 492 | dispatch(actions.toggleOption(types.TOGGLE_COMPACT_CODE))}/> 496 | 497 | dispatch(actions.toggleOption(types.TOGGLE_SIMPLIFY))}/> 501 | 502 | 503 | 504 | dispatch(actions.toggleOption(types.TOGGLE_TRANSFORM_OBJECT_KEYS))}/> 508 | 509 | 510 | 511 | dispatch(actions.toggleOption(types.TOGGLE_NUMBERS_TO_EXPRESSIONS))}/> 515 | 516 | 517 | 518 | dispatch(actions.toggleOption(types.TOGGLE_CONTROL_FLOW_FLATTENING))}/> 522 | 523 | dispatch(actions.setControlFlowFlatteningThreshold(parseFloat(value)))} 531 | disabled={!options.controlFlowFlattening}/> 532 | 533 | 534 | 535 | dispatch(actions.toggleOption(types.TOGGLE_DEAD_CODE_INJECTION))}/> 539 | 540 | dispatch(actions.setDeadCodeInjectionThreshold(parseFloat(value)))} 548 | disabled={!options.deadCodeInjection}/> 549 | 550 |
551 |
552 |
553 |
554 | 555 | 556 |
557 | Available Options: 558 |
559 | 560 | 567 |
568 |
569 | ); 570 | }; 571 | 572 | 573 | Options.propTypes = { 574 | dispatch: PropTypes.func.isRequired, 575 | options: PropTypes.object, 576 | }; 577 | 578 | const mapStateToProps = (state) => { 579 | return { 580 | options: state.options, 581 | } 582 | }; 583 | 584 | export default connect(mapStateToProps)(Options); 585 | --------------------------------------------------------------------------------