فهرست منبع

Merge pull request #1 from gchq/master

updating
bwhitn 7 سال پیش
والد
کامیت
47ce240e70
100فایلهای تغییر یافته به همراه9462 افزوده شده و 2186 حذف شده
  1. 1 0
      .eslintignore
  2. 5 6
      .eslintrc.json
  3. 1 12
      .github/ISSUE_TEMPLATE.md
  4. 1 0
      .gitignore
  5. 9 3
      .travis.yml
  6. 185 140
      Gruntfile.js
  7. 16 8
      README.md
  8. BIN
      docs/favicon.ico
  9. 1 1
      docs/jsdoc.conf.json
  10. 300 224
      package-lock.json
  11. 41 32
      package.json
  12. 39 11
      src/core/Chef.js
  13. 197 0
      src/core/ChefWorker.js
  14. 65 24
      src/core/FlowControl.js
  15. 16 5
      src/core/Operation.js
  16. 41 8
      src/core/Recipe.js
  17. 17 7
      src/core/Utils.js
  18. 16 5
      src/core/config/Categories.js
  19. 185 125
      src/core/config/OperationConfig.js
  20. 22 0
      src/core/config/modules/CharEnc.js
  21. 42 0
      src/core/config/modules/Ciphers.js
  22. 44 0
      src/core/config/modules/Code.js
  23. 32 0
      src/core/config/modules/Compression.js
  24. 188 0
      src/core/config/modules/Default.js
  25. 20 0
      src/core/config/modules/Diff.js
  26. 21 0
      src/core/config/modules/Encodings.js
  27. 22 0
      src/core/config/modules/HTTP.js
  28. 48 0
      src/core/config/modules/Hashing.js
  29. 25 0
      src/core/config/modules/Image.js
  30. 28 0
      src/core/config/modules/JSBN.js
  31. 41 0
      src/core/config/modules/OpModules.js
  32. 25 0
      src/core/config/modules/PublicKey.js
  33. 20 0
      src/core/config/modules/Shellcode.js
  34. 23 0
      src/core/config/modules/URL.js
  35. 5722 0
      src/core/lib/DisassembleX86-64.js
  36. 81 17
      src/core/operations/BitwiseOp.js
  37. 6 11
      src/core/operations/ByteRepr.js
  38. 0 2
      src/core/operations/CharEnc.js
  39. 13 29
      src/core/operations/Checksum.js
  40. 264 343
      src/core/operations/DateTime.js
  41. 94 0
      src/core/operations/Diff.js
  42. 2 38
      src/core/operations/Extract.js
  43. 99 0
      src/core/operations/Filetime.js
  44. 20 20
      src/core/operations/HTML.js
  45. 255 57
      src/core/operations/Hash.js
  46. 1 2
      src/core/operations/Hexdump.js
  47. 213 0
      src/core/operations/MS.js
  48. 55 0
      src/core/operations/OTP.js
  49. 0 699
      src/core/operations/PublicKey.js
  50. 5 5
      src/core/operations/Rotate.js
  51. 1 1
      src/core/operations/SeqUtils.js
  52. 96 0
      src/core/operations/Shellcode.js
  53. 1 79
      src/core/operations/StrUtils.js
  54. 27 46
      src/core/operations/URL.js
  55. 3 1
      src/node/index.js
  56. 87 95
      src/web/App.js
  57. 217 0
      src/web/BindingsWaiter.js
  58. 66 7
      src/web/ControlsWaiter.js
  59. 22 70
      src/web/HighlighterWaiter.js
  60. 2 6
      src/web/InputWaiter.js
  61. 12 3
      src/web/Manager.js
  62. 1 3
      src/web/OperationsWaiter.js
  63. 9 3
      src/web/OptionsWaiter.js
  64. 81 0
      src/web/OutputWaiter.js
  65. 28 1
      src/web/RecipeWaiter.js
  66. 183 0
      src/web/WorkerWaiter.js
  67. 56 35
      src/web/html/index.html
  68. 2 2
      src/web/index.js
  69. BIN
      src/web/static/images/breakpoint-16x16.png
  70. BIN
      src/web/static/images/bug-16x16.png
  71. BIN
      src/web/static/images/clean-16x16.png
  72. BIN
      src/web/static/images/code-16x16.png
  73. BIN
      src/web/static/images/cook_female-32x32.png
  74. BIN
      src/web/static/images/cook_male-32x32.png
  75. BIN
      src/web/static/images/copy-16x16.png
  76. BIN
      src/web/static/images/cyberchef-128x128.png
  77. BIN
      src/web/static/images/cyberchef-16x16.png
  78. BIN
      src/web/static/images/cyberchef-256x256.png
  79. BIN
      src/web/static/images/cyberchef-32x32.png
  80. BIN
      src/web/static/images/cyberchef-512x512.png
  81. BIN
      src/web/static/images/cyberchef-64x64.png
  82. BIN
      src/web/static/images/disable_deselected-16x16.png
  83. BIN
      src/web/static/images/disable_selected-16x16.png
  84. BIN
      src/web/static/images/download-24x24.png
  85. BIN
      src/web/static/images/erase-16x16.png
  86. BIN
      src/web/static/images/favourite-16x16.png
  87. BIN
      src/web/static/images/favourite-24x24.png
  88. BIN
      src/web/static/images/fork_me.png
  89. 1 0
      src/web/static/images/gitter-badge.svg
  90. BIN
      src/web/static/images/help-16x16.png
  91. BIN
      src/web/static/images/help-22x22.png
  92. BIN
      src/web/static/images/info-16x16.png
  93. BIN
      src/web/static/images/layout-16x16.png
  94. BIN
      src/web/static/images/mail-16x16.png
  95. BIN
      src/web/static/images/maximise-16x16.png
  96. BIN
      src/web/static/images/open_yellow-16x16.png
  97. BIN
      src/web/static/images/open_yellow-24x24.png
  98. BIN
      src/web/static/images/recycle-16x16.png
  99. BIN
      src/web/static/images/remove-16x16.png
  100. BIN
      src/web/static/images/restore-16x16.png

+ 1 - 0
.eslintignore

@@ -1 +1,2 @@
 src/core/lib/**
 src/core/lib/**
+src/core/config/MetaConfig.js

+ 5 - 6
.eslintrc.json

@@ -28,11 +28,7 @@
         // modify rules from base configurations
         // modify rules from base configurations
         "no-unused-vars": ["error", {
         "no-unused-vars": ["error", {
             "args": "none",
             "args": "none",
-            "vars": "local",
-            // Allow vars that start with a capital letter to be unused.
-            // This is mainly for exported module names which are useful to indicate
-            // the name of the module and may be used to refer to itself in future.
-            "varsIgnorePattern": "^[A-Z]"
+            "vars": "all"
         }],
         }],
         "no-empty": ["error", {
         "no-empty": ["error", {
             "allowEmptyCatch": true
             "allowEmptyCatch": true
@@ -97,6 +93,9 @@
 
 
         "COMPILE_TIME": false,
         "COMPILE_TIME": false,
         "COMPILE_MSG": false,
         "COMPILE_MSG": false,
-        "PKG_VERSION": false
+        "PKG_VERSION": false,
+        "ENVIRONMENT_IS_WORKER": false,
+        "ENVIRONMENT_IS_NODE": false,
+        "ENVIRONMENT_IS_WEB": false
     }
     }
 }
 }

+ 1 - 12
.github/ISSUE_TEMPLATE.md

@@ -5,21 +5,10 @@
 <!-- Misc: -->
 <!-- Misc: -->
 
 
 ### Summary
 ### Summary
-<!-- If you're describing a bug, tell us what's wrong -->
-<!-- If you're suggesting a change/improvement, tell us what it is and how it should work -->
+
 
 
 ### Example
 ### Example
 <!-- If describing a bug, tell us what happens instead of the expected behavior -->
 <!-- If describing a bug, tell us what happens instead of the expected behavior -->
 <!-- Include a link that triggers the bug if possible -->
 <!-- Include a link that triggers the bug if possible -->
 <!-- If you are requesting a new operation, include example input and output -->
 <!-- If you are requesting a new operation, include example input and output -->
 
 
-### Possible solutions
-<!-- Not obligatory, but suggest a fix/reason for the bug, or ideas for how to -->
-<!-- implement the addition or change, including links to relevant resources -->
-
-### Environment
-<!-- Include any relevant details about the environment you experienced the bug in -->
-<!-- This information is displayed in the About/Support pane -->
-* CyberChef compile time: 
-* User-Agent: 
-* [Link to reproduce]()

+ 1 - 0
.gitignore

@@ -6,3 +6,4 @@ docs/*
 !docs/*.conf.json
 !docs/*.conf.json
 !docs/*.ico
 !docs/*.ico
 .vscode
 .vscode
+src/core/config/MetaConfig.js

+ 9 - 3
.travis.yml

@@ -1,6 +1,6 @@
 language: node_js
 language: node_js
 node_js:
 node_js:
-  - node
+  - "8.4"
 install: npm install
 install: npm install
 before_script:
 before_script:
   - npm install -g grunt
   - npm install -g grunt
@@ -22,7 +22,7 @@ deploy:
       repo: gchq/CyberChef
       repo: gchq/CyberChef
       branch: master
       branch: master
   - provider: releases
   - provider: releases
-    skip_cleaup: true
+    skip_cleanup: true
     api_key:
     api_key:
       secure: "HV1WSKv4l/0Y2bKKs1iBJocBcmLj08PCRUeEM/jTwA4jqJ8EiLHWiXtER/D5sEg2iibRVKd2OQjfrmS6bo4AiwdeVgAKmv0FtS2Jw+391N8Nd5AkEANHa5Om/IpHLTL2YRAjpJTsDpY72bMUTJIwjQA3TFJkgrpOw6KYfohOcgbxLpZ4XuNJRU3VL4Hsxdv5V9aOVmfFOmMOVPQlakXy7NgtW5POp1f2WJwgcZxylkR1CjwaqMyXmSoVl46pyH3tr5+dptsQoKSGdi6sIHGA60oDotFPcm+0ifa47wZw+vapuuDi4tdNxhrHGaDMG8xiE0WFDHwQUDlk2/+W7j9SEX0H3Em7us371JXRp56EDwEcDa34VpVkC6i8HGcHK55hnxVbMZXGf3qhOFD8wY7qMbjMRvIpucrMHBi86OfkDfv0vDj2LyvIl5APj/AX50BrE0tfH1MZbH26Jkx4NdlkcxQ14GumarmUqfmVvbX/fsoA6oUuAAE9ZgRRi3KHO4wci6KUcRfdm+XOeUkaBFsL86G3EEYIvrtBTuaypdz+Cx7nd1iPZyWMx5Y1gXnVzha4nBdV4+7l9JIsFggD8QVpw2uHXQiS1KXFjOeqA3DBD8tjMB7q26Fl2fD3jkOo4BTbQ2NrRIZUu/iL+fOmMPsyMt2qulB0yaSBCfkbEq8xrUA="
       secure: "HV1WSKv4l/0Y2bKKs1iBJocBcmLj08PCRUeEM/jTwA4jqJ8EiLHWiXtER/D5sEg2iibRVKd2OQjfrmS6bo4AiwdeVgAKmv0FtS2Jw+391N8Nd5AkEANHa5Om/IpHLTL2YRAjpJTsDpY72bMUTJIwjQA3TFJkgrpOw6KYfohOcgbxLpZ4XuNJRU3VL4Hsxdv5V9aOVmfFOmMOVPQlakXy7NgtW5POp1f2WJwgcZxylkR1CjwaqMyXmSoVl46pyH3tr5+dptsQoKSGdi6sIHGA60oDotFPcm+0ifa47wZw+vapuuDi4tdNxhrHGaDMG8xiE0WFDHwQUDlk2/+W7j9SEX0H3Em7us371JXRp56EDwEcDa34VpVkC6i8HGcHK55hnxVbMZXGf3qhOFD8wY7qMbjMRvIpucrMHBi86OfkDfv0vDj2LyvIl5APj/AX50BrE0tfH1MZbH26Jkx4NdlkcxQ14GumarmUqfmVvbX/fsoA6oUuAAE9ZgRRi3KHO4wci6KUcRfdm+XOeUkaBFsL86G3EEYIvrtBTuaypdz+Cx7nd1iPZyWMx5Y1gXnVzha4nBdV4+7l9JIsFggD8QVpw2uHXQiS1KXFjOeqA3DBD8tjMB7q26Fl2fD3jkOo4BTbQ2NrRIZUu/iL+fOmMPsyMt2qulB0yaSBCfkbEq8xrUA="
     file:
     file:
@@ -39,4 +39,10 @@ deploy:
     on:
     on:
       tags: true
       tags: true
       branch: master
       branch: master
-
+notifications:
+    webhooks:
+        urls:
+            - https://webhooks.gitter.im/e/83c143a6822e218d5b34
+        on_success: change
+        on_failure: always
+        on_start: never

+ 185 - 140
Gruntfile.js

@@ -1,8 +1,18 @@
+"use strict";
+
 const webpack = require("webpack");
 const webpack = require("webpack");
-const ExtractTextPlugin = require("extract-text-webpack-plugin");
 const HtmlWebpackPlugin = require("html-webpack-plugin");
 const HtmlWebpackPlugin = require("html-webpack-plugin");
 const NodeExternals = require("webpack-node-externals");
 const NodeExternals = require("webpack-node-externals");
 const Inliner = require("web-resource-inliner");
 const Inliner = require("web-resource-inliner");
+const fs = require("fs");
+
+/**
+ * Grunt configuration for building the app in various formats.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
 
 
 module.exports = function (grunt) {
 module.exports = function (grunt) {
     grunt.file.defaultEncoding = "utf8";
     grunt.file.defaultEncoding = "utf8";
@@ -11,15 +21,15 @@ module.exports = function (grunt) {
     // Tasks
     // Tasks
     grunt.registerTask("dev",
     grunt.registerTask("dev",
         "A persistent task which creates a development build whenever source files are modified.",
         "A persistent task which creates a development build whenever source files are modified.",
-        ["clean:dev", "webpack:webDev"]);
+        ["clean:dev", "concurrent:dev"]);
 
 
     grunt.registerTask("node",
     grunt.registerTask("node",
         "Compiles CyberChef into a single NodeJS module.",
         "Compiles CyberChef into a single NodeJS module.",
-        ["clean:node", "webpack:node", "chmod:build"]);
+        ["clean:node", "webpack:metaConf", "webpack:node", "chmod:build"]);
 
 
     grunt.registerTask("test",
     grunt.registerTask("test",
         "A task which runs all the tests in test/tests.",
         "A task which runs all the tests in test/tests.",
-        ["clean:test", "webpack:tests", "execute:test"]);
+        ["clean:test", "webpack:metaConf", "webpack:tests", "execute:test"]);
 
 
     grunt.registerTask("docs",
     grunt.registerTask("docs",
         "Compiles documentation in the /docs directory.",
         "Compiles documentation in the /docs directory.",
@@ -27,7 +37,7 @@ module.exports = function (grunt) {
 
 
     grunt.registerTask("prod",
     grunt.registerTask("prod",
         "Creates a production-ready build. Use the --msg flag to add a compile message.",
         "Creates a production-ready build. Use the --msg flag to add a compile message.",
-        ["eslint", "clean:prod", "webpack:webProd", "inline", "chmod"]);
+        ["eslint", "clean:prod", "webpack:metaConf", "webpack:web", "inline", "chmod"]);
 
 
     grunt.registerTask("default",
     grunt.registerTask("default",
         "Lints the code base",
         "Lints the code base",
@@ -35,8 +45,10 @@ module.exports = function (grunt) {
 
 
     grunt.registerTask("inline",
     grunt.registerTask("inline",
         "Compiles a production build of CyberChef into a single, portable web page.",
         "Compiles a production build of CyberChef into a single, portable web page.",
-        runInliner);
+        ["webpack:webInline", "runInliner", "clean:inlineScripts"]);
 
 
+
+    grunt.registerTask("runInliner", runInliner);
     grunt.registerTask("doc", "docs");
     grunt.registerTask("doc", "docs");
     grunt.registerTask("tests", "test");
     grunt.registerTask("tests", "test");
     grunt.registerTask("lint", "eslint");
     grunt.registerTask("lint", "eslint");
@@ -52,31 +64,28 @@ module.exports = function (grunt) {
     grunt.loadNpmTasks("grunt-exec");
     grunt.loadNpmTasks("grunt-exec");
     grunt.loadNpmTasks("grunt-execute");
     grunt.loadNpmTasks("grunt-execute");
     grunt.loadNpmTasks("grunt-accessibility");
     grunt.loadNpmTasks("grunt-accessibility");
+    grunt.loadNpmTasks("grunt-concurrent");
 
 
 
 
     // Project configuration
     // Project configuration
     const compileTime = grunt.template.today("UTC:dd/mm/yyyy HH:MM:ss") + " UTC",
     const compileTime = grunt.template.today("UTC:dd/mm/yyyy HH:MM:ss") + " UTC",
-        banner = "/**\n" +
-            "* CyberChef - The Cyber Swiss Army Knife\n" +
-            "*\n" +
-            "* @copyright Crown Copyright 2016\n" +
-            "* @license Apache-2.0\n" +
-            "*\n" +
-            "*   Copyright 2016 Crown Copyright\n" +
-            "*\n" +
-            '* Licensed under the Apache License, Version 2.0 (the "License");\n' +
-            "* you may not use this file except in compliance with the License.\n" +
-            "* You may obtain a copy of the License at\n" +
-            "*\n" +
-            "*     http://www.apache.org/licenses/LICENSE-2.0\n" +
-            "*\n" +
-            "* Unless required by applicable law or agreed to in writing, software\n" +
-            '* distributed under the License is distributed on an "AS IS" BASIS,\n' +
-            "* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
-            "* See the License for the specific language governing permissions and\n" +
-            "* limitations under the License.\n" +
-            "*/\n",
-        pkg = grunt.file.readJSON("package.json");
+        pkg = grunt.file.readJSON("package.json"),
+        webpackConfig = require("./webpack.config.js"),
+        BUILD_CONSTANTS = {
+            COMPILE_TIME: JSON.stringify(compileTime),
+            COMPILE_MSG: JSON.stringify(grunt.option("compile-msg") || grunt.option("msg") || ""),
+            PKG_VERSION: JSON.stringify(pkg.version),
+            ENVIRONMENT_IS_WORKER: function() {
+                return typeof importScripts === "function";
+            },
+            ENVIRONMENT_IS_NODE: function() {
+                return typeof process === "object" && typeof require === "function";
+            },
+            ENVIRONMENT_IS_WEB: function() {
+                return typeof window === "object";
+            }
+        },
+        moduleEntryPoints = listEntryModules();
 
 
     /**
     /**
      * Compiles a production build of CyberChef into a single, portable web page.
      * Compiles a production build of CyberChef into a single, portable web page.
@@ -105,20 +114,36 @@ module.exports = function (grunt) {
         });
         });
     }
     }
 
 
+    /**
+     * Generates an entry list for all the modules.
+     */
+    function listEntryModules() {
+        const path = "./src/core/config/modules/";
+        let entryModules = {};
+
+        fs.readdirSync(path).forEach(file => {
+            if (file !== "Default.js" && file !== "OpModules.js")
+                entryModules[file.split(".js")[0]] = path + file;
+        });
+
+        return entryModules;
+    }
+
     grunt.initConfig({
     grunt.initConfig({
         clean: {
         clean: {
-            dev: ["build/dev/*"],
-            prod: ["build/prod/*"],
-            test: ["build/test/*"],
-            node: ["build/node/*"],
-            docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico"],
+            dev: ["build/dev/*", "src/core/config/MetaConfig.js"],
+            prod: ["build/prod/*", "src/core/config/MetaConfig.js"],
+            test: ["build/test/*", "src/core/config/MetaConfig.js"],
+            node: ["build/node/*", "src/core/config/MetaConfig.js"],
+            docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico", "!docs/*.png"],
+            inlineScripts: ["build/prod/scripts.js"],
         },
         },
         eslint: {
         eslint: {
             options: {
             options: {
                 configFile: "./.eslintrc.json"
                 configFile: "./.eslintrc.json"
             },
             },
             configs: ["Gruntfile.js"],
             configs: ["Gruntfile.js"],
-            core: ["src/core/**/*.js", "!src/core/lib/**/*"],
+            core: ["src/core/**/*.js", "!src/core/lib/**/*", "!src/core/config/MetaConfig.js"],
             web: ["src/web/**/*.js"],
             web: ["src/web/**/*.js"],
             node: ["src/node/**/*.js"],
             node: ["src/node/**/*.js"],
             tests: ["test/**/*.js"],
             tests: ["test/**/*.js"],
@@ -135,9 +160,16 @@ module.exports = function (grunt) {
                 src: [
                 src: [
                     "src/**/*.js",
                     "src/**/*.js",
                     "!src/core/lib/**/*",
                     "!src/core/lib/**/*",
+                    "!src/core/config/MetaConfig.js"
                 ],
                 ],
             }
             }
         },
         },
+        concurrent: {
+            options: {
+                logConcurrentOutput: true
+            },
+            dev: ["webpack:metaConfDev", "webpack-dev-server:start"]
+        },
         accessibility: {
         accessibility: {
             options: {
             options: {
                 accessibilityLevel: "WCAG2A",
                 accessibilityLevel: "WCAG2A",
@@ -151,114 +183,47 @@ module.exports = function (grunt) {
             }
             }
         },
         },
         webpack: {
         webpack: {
-            options: {
-                plugins: [
-                    new webpack.ProvidePlugin({
-                        $: "jquery",
-                        jQuery: "jquery",
-                        moment: "moment-timezone"
-                    }),
-                    new webpack.BannerPlugin({
-                        banner: banner,
-                        raw: true,
-                        entryOnly: true
-                    }),
-                    new webpack.DefinePlugin({
-                        COMPILE_TIME: JSON.stringify(compileTime),
-                        COMPILE_MSG: JSON.stringify(grunt.option("compile-msg") || grunt.option("msg") || ""),
-                        PKG_VERSION: JSON.stringify(pkg.version)
-                    }),
-                    new ExtractTextPlugin("styles.css"),
-                ],
-                resolve: {
-                    alias: {
-                        jquery: "jquery/src/jquery"
-                    }
-                },
-                module: {
-                    rules: [
-                        {
-                            test: /\.js$/,
-                            exclude: /node_modules/,
-                            loader: "babel-loader?compact=false"
-                        },
-                        {
-                            test: /\.css$/,
-                            use: ExtractTextPlugin.extract({
-                                use: [
-                                    { loader: "css-loader?minimize" },
-                                    { loader: "postcss-loader" },
-                                ]
-                            })
-                        },
-                        {
-                            test: /\.less$/,
-                            use: ExtractTextPlugin.extract({
-                                use: [
-                                    { loader: "css-loader?minimize" },
-                                    { loader: "postcss-loader" },
-                                    { loader: "less-loader" }
-                                ]
-                            })
-                        },
-                        {
-                            test: /\.(ico|eot|ttf|woff|woff2)$/,
-                            loader: "url-loader",
-                            options: {
-                                limit: 10000
-                            }
-                        },
-                        { // First party images are saved as files to be cached
-                            test: /\.(png|jpg|gif|svg)$/,
-                            exclude: /node_modules/,
-                            loader: "file-loader",
-                            options: {
-                                name: "images/[name].[ext]"
-                            }
-                        },
-                        { // Third party images are inlined
-                            test: /\.(png|jpg|gif|svg)$/,
-                            exclude: /web\/static/,
-                            loader: "url-loader",
-                            options: {
-                                limit: 10000
-                            }
-                        },
-                    ]
-                },
-                stats: {
-                    children: false,
-                    warningsFilter: /source-map/
+            options: webpackConfig,
+            metaConf: {
+                target: "node",
+                entry: "./src/core/config/OperationConfig.js",
+                output: {
+                    filename: "MetaConfig.js",
+                    path: __dirname + "/src/core/config/",
+                    library: "MetaConfig",
+                    libraryTarget: "commonjs2",
+                    libraryExport: "default"
                 },
                 },
-                node: {
-                    fs: "empty"
-                }
+                externals: [NodeExternals()],
             },
             },
-            webDev: {
-                target: "web",
-                entry: "./src/web/index.js",
+            metaConfDev: {
+                target: "node",
+                entry: "./src/core/config/OperationConfig.js",
                 output: {
                 output: {
-                    filename: "scripts.js",
-                    path: __dirname + "/build/dev"
+                    filename: "MetaConfig.js",
+                    path: __dirname + "/src/core/config/",
+                    library: "MetaConfig",
+                    libraryTarget: "commonjs2",
+                    libraryExport: "default"
                 },
                 },
-                plugins: [
-                    new HtmlWebpackPlugin({
-                        filename: "index.html",
-                        template: "./src/web/html/index.html",
-                        compileTime: compileTime,
-                        version: pkg.version,
-                    })
-                ],
+                externals: [NodeExternals()],
                 watch: true
                 watch: true
             },
             },
-            webProd: {
+            web: {
                 target: "web",
                 target: "web",
-                entry: "./src/web/index.js",
+                entry: Object.assign({
+                    main: "./src/web/index.js"
+                }, moduleEntryPoints),
                 output: {
                 output: {
-                    filename: "scripts.js",
                     path: __dirname + "/build/prod"
                     path: __dirname + "/build/prod"
                 },
                 },
+                resolve: {
+                    alias: {
+                        "./config/modules/OpModules.js": "./config/modules/Default.js"
+                    }
+                },
                 plugins: [
                 plugins: [
+                    new webpack.DefinePlugin(BUILD_CONSTANTS),
                     new webpack.optimize.UglifyJsPlugin({
                     new webpack.optimize.UglifyJsPlugin({
                         compress: {
                         compress: {
                             "screw_ie8": true,
                             "screw_ie8": true,
@@ -268,9 +233,10 @@ module.exports = function (grunt) {
                         },
                         },
                         comments: false,
                         comments: false,
                     }),
                     }),
-                    new HtmlWebpackPlugin({ // Main version
+                    new HtmlWebpackPlugin({
                         filename: "index.html",
                         filename: "index.html",
                         template: "./src/web/html/index.html",
                         template: "./src/web/html/index.html",
+                        chunks: ["main"],
                         compileTime: compileTime,
                         compileTime: compileTime,
                         version: pkg.version,
                         version: pkg.version,
                         minify: {
                         minify: {
@@ -280,7 +246,27 @@ module.exports = function (grunt) {
                             minifyCSS: true
                             minifyCSS: true
                         }
                         }
                     }),
                     }),
-                    new HtmlWebpackPlugin({ // Inline version
+                ]
+            },
+            webInline: {
+                target: "web",
+                entry: "./src/web/index.js",
+                output: {
+                    filename: "scripts.js",
+                    path: __dirname + "/build/prod"
+                },
+                plugins: [
+                    new webpack.DefinePlugin(BUILD_CONSTANTS),
+                    new webpack.optimize.UglifyJsPlugin({
+                        compress: {
+                            "screw_ie8": true,
+                            "dead_code": true,
+                            "unused": true,
+                            "warnings": false
+                        },
+                        comments: false,
+                    }),
+                    new HtmlWebpackPlugin({
                         filename: "cyberchef.htm",
                         filename: "cyberchef.htm",
                         template: "./src/web/html/index.html",
                         template: "./src/web/html/index.html",
                         compileTime: compileTime,
                         compileTime: compileTime,
@@ -302,7 +288,10 @@ module.exports = function (grunt) {
                 output: {
                 output: {
                     filename: "index.js",
                     filename: "index.js",
                     path: __dirname + "/build/test"
                     path: __dirname + "/build/test"
-                }
+                },
+                plugins: [
+                    new webpack.DefinePlugin(BUILD_CONSTANTS)
+                ]
             },
             },
             node: {
             node: {
                 target: "node",
                 target: "node",
@@ -313,21 +302,77 @@ module.exports = function (grunt) {
                     path: __dirname + "/build/node",
                     path: __dirname + "/build/node",
                     library: "CyberChef",
                     library: "CyberChef",
                     libraryTarget: "commonjs2"
                     libraryTarget: "commonjs2"
+                },
+                plugins: [
+                    new webpack.DefinePlugin(BUILD_CONSTANTS)
+                ]
+            }
+        },
+        "webpack-dev-server": {
+            options: {
+                webpack: webpackConfig,
+                host: "0.0.0.0",
+                disableHostCheck: true,
+                overlay: true,
+                inline: false,
+                clientLogLevel: "error",
+                stats: {
+                    children: false,
+                    chunks: false,
+                    modules: false,
+                    warningsFilter: /source-map/,
+                }
+            },
+            start: {
+                webpack: {
+                    target: "web",
+                    entry: Object.assign({
+                        main: "./src/web/index.js"
+                    }, moduleEntryPoints),
+                    resolve: {
+                        alias: {
+                            "./config/modules/OpModules.js": "./config/modules/Default.js"
+                        }
+                    },
+                    plugins: [
+                        new webpack.DefinePlugin(BUILD_CONSTANTS),
+                        new HtmlWebpackPlugin({
+                            filename: "index.html",
+                            template: "./src/web/html/index.html",
+                            chunks: ["main"],
+                            compileTime: compileTime,
+                            version: pkg.version,
+                        })
+                    ]
                 }
                 }
             }
             }
         },
         },
         copy: {
         copy: {
             ghPages: {
             ghPages: {
                 options: {
                 options: {
-                    process: function (content) {
+                    process: function (content, srcpath) {
                         // Add Google Analytics code to index.html
                         // Add Google Analytics code to index.html
-                        content = content.replace("</body></html>",
-                            grunt.file.read("src/web/static/ga.html") + "</body></html>");
-                        return grunt.template.process(content);
-                    }
+                        if (srcpath.indexOf("index.html") >= 0) {
+                            content = content.replace("</body></html>",
+                                grunt.file.read("src/web/static/ga.html") + "</body></html>");
+                            return grunt.template.process(content, srcpath);
+                        } else {
+                            return content;
+                        }
+                    },
+                    noProcess: ["**", "!**/*.html"]
                 },
                 },
-                src: "build/prod/index.html",
-                dest: "build/prod/index.html"
+                files: [
+                    {
+                        src: "build/prod/index.html",
+                        dest: "build/prod/index.html"
+                    },
+                    {
+                        expand: true,
+                        src: "docs/**",
+                        dest: "build/prod/"
+                    }
+                ]
             }
             }
         },
         },
         chmod: {
         chmod: {

+ 16 - 8
README.md

@@ -1,8 +1,12 @@
 # CyberChef
 # CyberChef
 
 
 [![Build Status](https://travis-ci.org/gchq/CyberChef.svg?branch=master)](https://travis-ci.org/gchq/CyberChef)
 [![Build Status](https://travis-ci.org/gchq/CyberChef.svg?branch=master)](https://travis-ci.org/gchq/CyberChef)
-[![npm](https://badge.fury.io/js/cyberchef.svg)](https://www.npmjs.com/package/cyberchef)
-![](https://reposs.herokuapp.com/?path=gchq/CyberChef&color=brightgreen)
+[![dependencies Status](https://david-dm.org/gchq/CyberChef/status.svg)](https://david-dm.org/gchq/CyberChef)
+[![npm](http://img.shields.io/npm/v/cyberchef.svg)](https://www.npmjs.com/package/cyberchef)
+![](https://reposs.herokuapp.com/?path=gchq/CyberChef&color=blue)
+[![](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/gchq/CyberChef/blob/master/LICENSE)
+[![Gitter](https://badges.gitter.im/gchq/CyberChef.svg)](https://gitter.im/gchq/CyberChef?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+
 
 
 #### *The Cyber Swiss Army Knife*
 #### *The Cyber Swiss Army Knife*
 
 
@@ -34,8 +38,10 @@ You can use as many operations as you like in simple or complex ways. Some examp
  - [Convert a date and time to a different time zone][3]
  - [Convert a date and time to a different time zone][3]
  - [Parse a Teredo IPv6 address][4]
  - [Parse a Teredo IPv6 address][4]
  - [Convert data from a hexdump, then decompress][5]
  - [Convert data from a hexdump, then decompress][5]
- - [Display multiple timestamps as full dates][6]
- - [Carry out different operations on data of different types][7]
+ - [Decrypt and disassemble shellcode][6]
+ - [Display multiple timestamps as full dates][7]
+ - [Carry out different operations on data of different types][8]
+ - [Use parts of the input as arguments to operations][9]
 
 
 
 
 ## Features
 ## Features
@@ -56,7 +62,7 @@ You can use as many operations as you like in simple or complex ways. Some examp
  - Search
  - Search
      - If you know the name of the operation you want or a word associated with it, start typing it into the search field and any matching operations will immediately be shown.
      - If you know the name of the operation you want or a word associated with it, start typing it into the search field and any matching operations will immediately be shown.
  - Highlighting
  - Highlighting
-     - When you highlight text in the input or output, the offset and length values will be displayed and, if possible, the corresponding data will be highlighted in the output or input respectively (example: [highlight the word 'question' in the input to see where it appears in the output][8]).
+     - When you highlight text in the input or output, the offset and length values will be displayed and, if possible, the corresponding data will be highlighted in the output or input respectively (example: [highlight the word 'question' in the input to see where it appears in the output][10]).
  - Save to file and load from file
  - Save to file and load from file
      - You can save the output to a file at any time or load a file by dragging and dropping it into the input field (note that files larger than about 500kb may cause your browser to hang or even crash due to the way that browsers handle large amounts of textual data).
      - You can save the output to a file at any time or load a file by dragging and dropping it into the input field (note that files larger than about 500kb may cause your browser to hang or even crash due to the way that browsers handle large amounts of textual data).
  - CyberChef is entirely client-side
  - CyberChef is entirely client-side
@@ -92,6 +98,8 @@ CyberChef is released under the [Apache 2.0 Licence](https://www.apache.org/lice
   [3]: https://gchq.github.io/CyberChef/#recipe=Translate_DateTime_Format('Standard%20date%20and%20time','DD/MM/YYYY%20HH:mm:ss','UTC','dddd%20Do%20MMMM%20YYYY%20HH:mm:ss%20Z%20z','Australia/Queensland')&input=MTUvMDYvMjAxNSAyMDo0NTowMA
   [3]: https://gchq.github.io/CyberChef/#recipe=Translate_DateTime_Format('Standard%20date%20and%20time','DD/MM/YYYY%20HH:mm:ss','UTC','dddd%20Do%20MMMM%20YYYY%20HH:mm:ss%20Z%20z','Australia/Queensland')&input=MTUvMDYvMjAxNSAyMDo0NTowMA
   [4]: https://gchq.github.io/CyberChef/#recipe=Parse_IPv6_address()&input=MjAwMTowMDAwOjQxMzY6ZTM3ODo4MDAwOjYzYmY6M2ZmZjpmZGQy
   [4]: https://gchq.github.io/CyberChef/#recipe=Parse_IPv6_address()&input=MjAwMTowMDAwOjQxMzY6ZTM3ODo4MDAwOjYzYmY6M2ZmZjpmZGQy
   [5]: https://gchq.github.io/CyberChef/#recipe=From_Hexdump()Gunzip()&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu/y7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb/3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw
   [5]: https://gchq.github.io/CyberChef/#recipe=From_Hexdump()Gunzip()&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu/y7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb/3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw
-  [6]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA
-  [7]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',2,10)To_Hex('Space')Return()To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA
-  [8]: https://gchq.github.io/CyberChef/#recipe=XOR(%7B'option':'Hex','string':'3a'%7D,'',false)To_Hexdump(16,false,false)&input=VGhlIGFuc3dlciB0byB0aGUgdWx0aW1hdGUgcXVlc3Rpb24gb2YgbGlmZSwgdGhlIFVuaXZlcnNlLCBhbmQgZXZlcnl0aGluZyBpcyA0Mi4
+  [6]: https://gchq.github.io/CyberChef/#recipe=RC4(%7B'option':'UTF8','string':'secret'%7D,'Hex','Hex')Disassemble_x86('64','Full%20x86%20architecture',16,0,true,true)&input=MjFkZGQyNTQwMTYwZWU2NWZlMDc3NzEwM2YyYTM5ZmJlNWJjYjZhYTBhYWJkNDE0ZjkwYzZjYWY1MzEyNzU0YWY3NzRiNzZiM2JiY2QxOTNjYjNkZGZkYmM1YTI2NTMzYTY4NmI1OWI4ZmVkNGQzODBkNDc0NDIwMWFlYzIwNDA1MDcxMzhlMmZlMmIzOTUwNDQ2ZGIzMWQyYmM2MjliZTRkM2YyZWIwMDQzYzI5M2Q3YTVkMjk2MmMwMGZlNmRhMzAwNzJkOGM1YTZiNGZlN2Q4NTlhMDQwZWVhZjI5OTczMzYzMDJmNWEwZWMxOQ
+  [7]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA
+  [8]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',2,10)To_Hex('Space')Return()To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA
+  [9]: https://gchq.github.io/CyberChef/#recipe=Register('key%3D(%5B%5C%5Cda-f%5D*)',true,false)Find_/_Replace(%7B'option':'Regex','string':'.*data%3D(.*)'%7D,'$1',true,false,true)RC4(%7B'option':'Hex','string':'$R0'%7D,'Hex','Latin1')&input=aHR0cDovL21hbHdhcmV6LmJpei9iZWFjb24ucGhwP2tleT0wZTkzMmE1YyZkYXRhPThkYjdkNWViZTM4NjYzYTU0ZWNiYjMzNGUzZGIxMQ
+  [10]: https://gchq.github.io/CyberChef/#recipe=XOR(%7B'option':'Hex','string':'3a'%7D,'',false)To_Hexdump(16,false,false)&input=VGhlIGFuc3dlciB0byB0aGUgdWx0aW1hdGUgcXVlc3Rpb24gb2YgbGlmZSwgdGhlIFVuaXZlcnNlLCBhbmQgZXZlcnl0aGluZyBpcyA0Mi4

BIN
docs/favicon.ico


+ 1 - 1
docs/jsdoc.conf.json

@@ -19,7 +19,7 @@
         "outputSourcePath": true,
         "outputSourcePath": true,
         "dateFormat": "ddd MMM Do YYYY",
         "dateFormat": "ddd MMM Do YYYY",
         "sort": false,
         "sort": false,
-        "logoFile": "../build/prod/images/cyberchef-32x32.png",
+        "logoFile": "cyberchef-32x32.png",
         "cleverLinks": false,
         "cleverLinks": false,
         "monospaceLinks": false,
         "monospaceLinks": false,
         "protocol": "html://",
         "protocol": "html://",

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 300 - 224
package-lock.json


+ 41 - 32
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "cyberchef",
   "name": "cyberchef",
-  "version": "5.16.3",
+  "version": "6.4.6",
   "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
   "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
   "author": "n1474335 <n1474335@gmail.com>",
   "author": "n1474335 <n1474335@gmail.com>",
   "homepage": "https://gchq.github.io/CyberChef",
   "homepage": "https://gchq.github.io/CyberChef",
@@ -30,67 +30,76 @@
   "main": "build/node/CyberChef.js",
   "main": "build/node/CyberChef.js",
   "bugs": "https://github.com/gchq/CyberChef/issues",
   "bugs": "https://github.com/gchq/CyberChef/issues",
   "devDependencies": {
   "devDependencies": {
-    "babel-core": "^6.24.0",
-    "babel-loader": "^7.1.1",
-    "babel-preset-env": "^1.6.0",
-    "css-loader": "^0.28.4",
+    "babel-core": "^6.26.0",
+    "babel-loader": "^7.1.2",
+    "babel-preset-env": "^1.6.1",
+    "css-loader": "^0.28.7",
     "exports-loader": "^0.6.4",
     "exports-loader": "^0.6.4",
-    "extract-text-webpack-plugin": "^3.0.0",
-    "file-loader": "^0.11.2",
-    "grunt": ">=0.4.5",
+    "extract-text-webpack-plugin": "^3.0.2",
+    "file-loader": "^1.1.5",
+    "grunt": ">=1.0.1",
     "grunt-accessibility": "~5.0.0",
     "grunt-accessibility": "~5.0.0",
     "grunt-chmod": "~1.1.1",
     "grunt-chmod": "~1.1.1",
+    "grunt-concurrent": "^2.3.1",
     "grunt-contrib-clean": "~1.1.0",
     "grunt-contrib-clean": "~1.1.0",
     "grunt-contrib-copy": "~1.0.0",
     "grunt-contrib-copy": "~1.0.0",
-    "grunt-eslint": "^20.0.0",
+    "grunt-eslint": "^20.1.0",
     "grunt-exec": "~3.0.0",
     "grunt-exec": "~3.0.0",
     "grunt-execute": "^0.2.2",
     "grunt-execute": "^0.2.2",
-    "grunt-jsdoc": "^2.1.0",
+    "grunt-jsdoc": "^2.2.0",
     "grunt-webpack": "^3.0.2",
     "grunt-webpack": "^3.0.2",
     "html-webpack-plugin": "^2.30.1",
     "html-webpack-plugin": "^2.30.1",
     "imports-loader": "^0.7.1",
     "imports-loader": "^0.7.1",
-    "ink-docstrap": "^1.1.4",
+    "ink-docstrap": "^1.3.2",
     "jsdoc-babel": "^0.3.0",
     "jsdoc-babel": "^0.3.0",
-    "less": "^2.7.2",
+    "less": "^2.7.3",
     "less-loader": "^4.0.5",
     "less-loader": "^4.0.5",
-    "postcss-css-variables": "^0.7.0",
-    "postcss-import": "^10.0.0",
-    "postcss-loader": "^2.0.5",
-    "style-loader": "^0.18.2",
-    "url-loader": "^0.5.8",
-    "web-resource-inliner": "^4.1.0",
-    "webpack": "^3.4.1",
-    "webpack-node-externals": "^1.6.0"
+    "postcss-css-variables": "^0.8.0",
+    "postcss-import": "^11.0.0",
+    "postcss-loader": "^2.0.8",
+    "style-loader": "^0.19.0",
+    "url-loader": "^0.6.2",
+    "val-loader": "^1.1.0",
+    "web-resource-inliner": "^4.2.0",
+    "webpack": "^3.8.1",
+    "webpack-dev-server": "^2.9.4",
+    "webpack-node-externals": "^1.6.0",
+    "worker-loader": "^1.1.0"
   },
   },
   "dependencies": {
   "dependencies": {
-    "babel-polyfill": "^6.23.0",
+    "babel-polyfill": "^6.26.0",
     "bootstrap": "^3.3.7",
     "bootstrap": "^3.3.7",
-    "bootstrap-colorpicker": "^2.5.1",
+    "bootstrap-colorpicker": "^2.5.2",
     "bootstrap-switch": "^3.3.4",
     "bootstrap-switch": "^3.3.4",
-    "crypto-api": "^0.6.2",
+    "crypto-api": "^0.7.5",
     "crypto-js": "^3.1.9-1",
     "crypto-js": "^3.1.9-1",
-    "diff": "^3.3.0",
-    "escodegen": "^1.8.1",
+    "diff": "^3.4.0",
+    "escodegen": "^1.9.0",
     "esmangle": "^1.0.1",
     "esmangle": "^1.0.1",
     "esprima": "^4.0.0",
     "esprima": "^4.0.0",
     "exif-parser": "^0.1.12",
     "exif-parser": "^0.1.12",
     "google-code-prettify": "^1.0.5",
     "google-code-prettify": "^1.0.5",
-    "jquery": "^3.1.1",
+    "jquery": "^3.2.1",
+    "js-crc": "^0.2.0",
+    "js-sha3": "^0.6.1",
     "jsbn": "^1.1.0",
     "jsbn": "^1.1.0",
-    "jsonpath": "^0.2.12",
-    "jsrsasign": "8.0.3",
+    "jsonpath": "^1.0.0",
+    "jsrsasign": "8.0.4",
     "lodash": "^4.17.4",
     "lodash": "^4.17.4",
-    "moment": "^2.17.1",
-    "moment-timezone": "^0.5.11",
+    "moment": "^2.19.2",
+    "moment-timezone": "^0.5.14",
+    "node-md6": "^0.1.0",
+    "otp": "^0.1.3",
     "sladex-blowfish": "^0.8.1",
     "sladex-blowfish": "^0.8.1",
-    "sortablejs": "^1.5.1",
-    "split.js": "^1.2.0",
+    "sortablejs": "^1.7.0",
+    "split.js": "^1.3.5",
     "vkbeautify": "^0.99.3",
     "vkbeautify": "^0.99.3",
     "xmldom": "^0.1.27",
     "xmldom": "^0.1.27",
     "xpath": "0.0.24",
     "xpath": "0.0.24",
     "zlibjs": "^0.3.1"
     "zlibjs": "^0.3.1"
   },
   },
   "scripts": {
   "scripts": {
+    "start": "grunt dev",
     "build": "grunt prod",
     "build": "grunt prod",
     "test": "grunt test",
     "test": "grunt test",
     "docs": "grunt docs"
     "docs": "grunt docs"

+ 39 - 11
src/core/Chef.js

@@ -30,7 +30,6 @@ const Chef = function() {
  * @returns {string} response.result - The output of the recipe
  * @returns {string} response.result - The output of the recipe
  * @returns {string} response.type - The data type of the result
  * @returns {string} response.type - The data type of the result
  * @returns {number} response.progress - The position that we have got to in the recipe
  * @returns {number} response.progress - The position that we have got to in the recipe
- * @returns {number} response.options - The app options object (which may have been changed)
  * @returns {number} response.duration - The number of ms it took to execute the recipe
  * @returns {number} response.duration - The number of ms it took to execute the recipe
  * @returns {number} response.error - The error object thrown by a failed operation (false if no error)
  * @returns {number} response.error - The error object thrown by a failed operation (false if no error)
 */
 */
@@ -40,12 +39,7 @@ Chef.prototype.bake = async function(inputText, recipeConfig, options, progress,
         containsFc = recipe.containsFlowControl(),
         containsFc = recipe.containsFlowControl(),
         error      = false;
         error      = false;
 
 
-    // Reset attemptHighlight flag
-    if (options.hasOwnProperty("attemptHighlight")) {
-        options.attemptHighlight = true;
-    }
-
-    if (containsFc) options.attemptHighlight = false;
+    if (containsFc && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
 
 
     // Clean up progress
     // Clean up progress
     if (progress >= recipeConfig.length) {
     if (progress >= recipeConfig.length) {
@@ -74,9 +68,10 @@ Chef.prototype.bake = async function(inputText, recipeConfig, options, progress,
     try {
     try {
         progress = await recipe.execute(this.dish, progress);
         progress = await recipe.execute(this.dish, progress);
     } catch (err) {
     } catch (err) {
-        // Return the error in the result so that everything else gets correctly updated
-        // rather than throwing it here and losing state info.
-        error = err;
+        console.log(err);
+        error = {
+            displayStr: err.displayStr,
+        };
         progress = err.progress;
         progress = err.progress;
     }
     }
 
 
@@ -86,7 +81,6 @@ Chef.prototype.bake = async function(inputText, recipeConfig, options, progress,
             this.dish.get(Dish.STRING),
             this.dish.get(Dish.STRING),
         type: Dish.enumLookup(this.dish.type),
         type: Dish.enumLookup(this.dish.type),
         progress: progress,
         progress: progress,
-        options: options,
         duration: new Date().getTime() - startTime,
         duration: new Date().getTime() - startTime,
         error: error
         error: error
     };
     };
@@ -123,4 +117,38 @@ Chef.prototype.silentBake = function(recipeConfig) {
     return new Date().getTime() - startTime;
     return new Date().getTime() - startTime;
 };
 };
 
 
+
+/**
+ * Calculates highlight offsets if possible.
+ *
+ * @param {Object[]} recipeConfig
+ * @param {string} direction
+ * @param {Object} pos - The position object for the highlight.
+ * @param {number} pos.start - The start offset.
+ * @param {number} pos.end - The end offset.
+ * @returns {Object}
+ */
+Chef.prototype.calculateHighlights = function(recipeConfig, direction, pos) {
+    const recipe = new Recipe(recipeConfig);
+    const highlights = recipe.generateHighlightList();
+
+    if (!highlights) return false;
+
+    for (let i = 0; i < highlights.length; i++) {
+        // Remove multiple highlights before processing again
+        pos = [pos[0]];
+
+        const func = direction === "forward" ? highlights[i].f : highlights[i].b;
+
+        if (typeof func == "function") {
+            pos = func(pos, highlights[i].args);
+        }
+    }
+
+    return {
+        pos: pos,
+        direction: direction
+    };
+};
+
 export default Chef;
 export default Chef;

+ 197 - 0
src/core/ChefWorker.js

@@ -0,0 +1,197 @@
+/**
+ * Web Worker to handle communications between the front-end and the core.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+
+import "babel-polyfill";
+import Chef from "./Chef.js";
+import OperationConfig from "./config/MetaConfig.js";
+import OpModules from "./config/modules/Default.js";
+
+
+// Set up Chef instance
+self.chef = new Chef();
+
+self.OpModules = OpModules;
+self.OperationConfig = OperationConfig;
+
+// Tell the app that the worker has loaded and is ready to operate
+self.postMessage({
+    action: "workerLoaded",
+    data: {}
+});
+
+/**
+ * Respond to message from parent thread.
+ *
+ * Messages should have the following format:
+ * {
+ *     action: "bake" | "silentBake",
+ *     data: {
+ *         input: {string},
+ *         recipeConfig: {[Object]},
+ *         options: {Object},
+ *         progress: {number},
+ *         step: {boolean}
+ *     } | undefined
+ * }
+ */
+self.addEventListener("message", function(e) {
+    // Handle message
+    const r = e.data;
+    switch (r.action) {
+        case "bake":
+            bake(r.data);
+            break;
+        case "silentBake":
+            silentBake(r.data);
+            break;
+        case "docURL":
+            // Used to set the URL of the current document so that scripts can be
+            // imported into an inline worker.
+            self.docURL = r.data;
+            break;
+        case "highlight":
+            calculateHighlights(
+                r.data.recipeConfig,
+                r.data.direction,
+                r.data.pos
+            );
+            break;
+        default:
+            break;
+    }
+});
+
+
+/**
+ * Baking handler
+ *
+ * @param {Object} data
+ */
+async function bake(data) {
+    // Ensure the relevant modules are loaded
+    loadRequiredModules(data.recipeConfig);
+
+    try {
+        const response = await self.chef.bake(
+            data.input,          // The user's input
+            data.recipeConfig,   // The configuration of the recipe
+            data.options,        // Options set by the user
+            data.progress,       // The current position in the recipe
+            data.step            // Whether or not to take one step or execute the whole recipe
+        );
+
+        self.postMessage({
+            action: "bakeSuccess",
+            data: response
+        });
+    } catch (err) {
+        self.postMessage({
+            action: "bakeError",
+            data: err
+        });
+    }
+}
+
+
+/**
+ * Silent baking handler
+ */
+function silentBake(data) {
+    const duration = self.chef.silentBake(data.recipeConfig);
+
+    self.postMessage({
+        action: "silentBakeComplete",
+        data: duration
+    });
+}
+
+
+/**
+ * Checks that all required modules are loaded and loads them if not.
+ *
+ * @param {Object} recipeConfig
+ */
+function loadRequiredModules(recipeConfig) {
+    recipeConfig.forEach(op => {
+        let module = self.OperationConfig[op.op].module;
+
+        if (!OpModules.hasOwnProperty(module)) {
+            console.log("Loading module " + module);
+            self.sendStatusMessage("Loading module " + module);
+            self.importScripts(self.docURL + "/" + module + ".js");
+        }
+    });
+}
+
+
+/**
+ * Calculates highlight offsets if possible.
+ *
+ * @param {Object[]} recipeConfig
+ * @param {string} direction
+ * @param {Object} pos - The position object for the highlight.
+ * @param {number} pos.start - The start offset.
+ * @param {number} pos.end - The end offset.
+ */
+function calculateHighlights(recipeConfig, direction, pos) {
+    pos = self.chef.calculateHighlights(recipeConfig, direction, pos);
+
+    self.postMessage({
+        action: "highlightsCalculated",
+        data: pos
+    });
+}
+
+
+/**
+ * Send status update to the app.
+ *
+ * @param {string} msg
+ */
+self.sendStatusMessage = function(msg) {
+    self.postMessage({
+        action: "statusMessage",
+        data: msg
+    });
+};
+
+
+/**
+ * Send an option value update to the app.
+ *
+ * @param {string} option
+ * @param {*} value
+ */
+self.setOption = function(option, value) {
+    self.postMessage({
+        action: "optionUpdate",
+        data: {
+            option: option,
+            value: value
+        }
+    });
+};
+
+
+/**
+ * Send register values back to the app.
+ *
+ * @param {number} opIndex
+ * @param {number} numPrevRegisters
+ * @param {string[]} registers
+ */
+self.setRegisters = function(opIndex, numPrevRegisters, registers) {
+    self.postMessage({
+        action: "setRegisters",
+        data: {
+            opIndex: opIndex,
+            numPrevRegisters: numPrevRegisters,
+            registers: registers
+        }
+    });
+};

+ 65 - 24
src/core/FlowControl.js

@@ -13,22 +13,6 @@ import Dish from "./Dish.js";
  */
  */
 const FlowControl = {
 const FlowControl = {
 
 
-    /**
-     * @constant
-     * @default
-     */
-    FORK_DELIM: "\\n",
-    /**
-     * @constant
-     * @default
-     */
-    MERGE_DELIM: "\\n",
-    /**
-     * @constant
-     * @default
-     */
-    FORK_IGNORE_ERRORS: false,
-
     /**
     /**
      * Fork operation.
      * Fork operation.
      *
      *
@@ -107,15 +91,72 @@ const FlowControl = {
 
 
 
 
     /**
     /**
-     * @constant
-     * @default
-     */
-    JUMP_NUM: 0,
-    /**
-     * @constant
-     * @default
+     * Register operation.
+     *
+     * @param {Object} state - The current state of the recipe.
+     * @param {number} state.progress - The current position in the recipe.
+     * @param {Dish} state.dish - The Dish being operated on.
+     * @param {Operation[]} state.opList - The list of operations in the recipe.
+     * @returns {Object} The updated state of the recipe.
      */
      */
-    MAX_JUMPS: 10,
+    runRegister: function(state) {
+        const ings = state.opList[state.progress].getIngValues(),
+            extractorStr = ings[0],
+            i = ings[1],
+            m = ings[2];
+
+        let modifiers = "";
+        if (i) modifiers += "i";
+        if (m) modifiers += "m";
+
+        const extractor = new RegExp(extractorStr, modifiers),
+            input = state.dish.get(Dish.STRING),
+            registers = input.match(extractor);
+
+        if (!registers) return state;
+
+        if (ENVIRONMENT_IS_WORKER()) {
+            self.setRegisters(state.progress, state.numRegisters, registers.slice(1));
+        }
+
+        /**
+         * Replaces references to registers (e.g. $R0) with the contents of those registers.
+         *
+         * @param {string} str
+         * @returns {string}
+         */
+        function replaceRegister(str) {
+            // Replace references to registers ($Rn) with contents of registers
+            return str.replace(/(\\*)\$R(\d{1,2})/g, (match, slashes, regNum) => {
+                const index = parseInt(regNum, 10) + 1;
+                if (index <= state.numRegisters || index >= state.numRegisters + registers.length)
+                    return match;
+                if (slashes.length % 2 !== 0) return match.slice(1); // Remove escape
+                return slashes + registers[index - state.numRegisters];
+            });
+        }
+
+        // Step through all subsequent ops and replace registers in args with extracted content
+        for (let i = state.progress + 1; i < state.opList.length; i++) {
+            if (state.opList[i].isDisabled()) continue;
+
+            let args = state.opList[i].getIngValues();
+            args = args.map(arg => {
+                if (typeof arg !== "string" && typeof arg !== "object") return arg;
+
+                if (typeof arg === "object" && arg.hasOwnProperty("string")) {
+                    arg.string = replaceRegister(arg.string);
+                    return arg;
+                }
+                return replaceRegister(arg);
+            });
+            state.opList[i].setIngValues(args);
+        }
+
+        state.numRegisters += registers.length - 1;
+        return state;
+    },
+
 
 
     /**
     /**
      * Jump operation.
      * Jump operation.

+ 16 - 5
src/core/Operation.js

@@ -1,5 +1,7 @@
 import Dish from "./Dish.js";
 import Dish from "./Dish.js";
 import Ingredient from "./Ingredient.js";
 import Ingredient from "./Ingredient.js";
+import OperationConfig from "./config/MetaConfig.js";
+import OpModules from "./config/modules/OpModules.js";
 
 
 
 
 /**
 /**
@@ -11,10 +13,10 @@ import Ingredient from "./Ingredient.js";
  *
  *
  * @class
  * @class
  * @param {string} operationName
  * @param {string} operationName
- * @param {Object} operationConfig
  */
  */
-const Operation = function(operationName, operationConfig) {
+const Operation = function(operationName) {
     this.name             = operationName;
     this.name             = operationName;
+    this.module           = "";
     this.description      = "";
     this.description      = "";
     this.inputType        = -1;
     this.inputType        = -1;
     this.outputType       = -1;
     this.outputType       = -1;
@@ -25,8 +27,8 @@ const Operation = function(operationName, operationConfig) {
     this.disabled         = false;
     this.disabled         = false;
     this.ingList          = [];
     this.ingList          = [];
 
 
-    if (operationConfig) {
-        this._parseConfig(operationConfig);
+    if (OperationConfig.hasOwnProperty(this.name)) {
+        this._parseConfig(OperationConfig[this.name]);
     }
     }
 };
 };
 
 
@@ -38,19 +40,28 @@ const Operation = function(operationName, operationConfig) {
  * @param {Object} operationConfig
  * @param {Object} operationConfig
  */
  */
 Operation.prototype._parseConfig = function(operationConfig) {
 Operation.prototype._parseConfig = function(operationConfig) {
+    this.module           = operationConfig.module;
     this.description      = operationConfig.description;
     this.description      = operationConfig.description;
     this.inputType        = Dish.typeEnum(operationConfig.inputType);
     this.inputType        = Dish.typeEnum(operationConfig.inputType);
     this.outputType       = Dish.typeEnum(operationConfig.outputType);
     this.outputType       = Dish.typeEnum(operationConfig.outputType);
-    this.run              = operationConfig.run;
     this.highlight        = operationConfig.highlight;
     this.highlight        = operationConfig.highlight;
     this.highlightReverse = operationConfig.highlightReverse;
     this.highlightReverse = operationConfig.highlightReverse;
     this.flowControl      = operationConfig.flowControl;
     this.flowControl      = operationConfig.flowControl;
+    this.run              = OpModules[this.module][this.name];
 
 
     for (let a = 0; a < operationConfig.args.length; a++) {
     for (let a = 0; a < operationConfig.args.length; a++) {
         const ingredientConfig = operationConfig.args[a];
         const ingredientConfig = operationConfig.args[a];
         const ingredient = new Ingredient(ingredientConfig);
         const ingredient = new Ingredient(ingredientConfig);
         this.addIngredient(ingredient);
         this.addIngredient(ingredient);
     }
     }
+
+    if (this.highlight === "func") {
+        this.highlight = OpModules[this.module][`${this.name}-highlight`];
+    }
+
+    if (this.highlightReverse === "func") {
+        this.highlightReverse = OpModules[this.module][`${this.name}-highlightReverse`];
+    }
 };
 };
 
 
 
 

+ 41 - 8
src/core/Recipe.js

@@ -1,5 +1,4 @@
 import Operation from "./Operation.js";
 import Operation from "./Operation.js";
-import OperationConfig from "./config/OperationConfig.js";
 
 
 
 
 /**
 /**
@@ -30,8 +29,7 @@ const Recipe = function(recipeConfig) {
 Recipe.prototype._parseConfig = function(recipeConfig) {
 Recipe.prototype._parseConfig = function(recipeConfig) {
     for (let c = 0; c < recipeConfig.length; c++) {
     for (let c = 0; c < recipeConfig.length; c++) {
         const operationName = recipeConfig[c].op;
         const operationName = recipeConfig[c].op;
-        const operationConfig = OperationConfig[operationName];
-        const operation = new Operation(operationName, operationConfig);
+        const operation = new Operation(operationName);
         operation.setIngValues(recipeConfig[c].args);
         operation.setIngValues(recipeConfig[c].args);
         operation.setBreakpoint(recipeConfig[c].breakpoint);
         operation.setBreakpoint(recipeConfig[c].breakpoint);
         operation.setDisabled(recipeConfig[c].disabled);
         operation.setDisabled(recipeConfig[c].disabled);
@@ -147,7 +145,7 @@ Recipe.prototype.lastOpIndex = function(startIndex) {
  */
  */
 Recipe.prototype.execute = async function(dish, startFrom) {
 Recipe.prototype.execute = async function(dish, startFrom) {
     startFrom = startFrom || 0;
     startFrom = startFrom || 0;
-    let op, input, output, numJumps = 0;
+    let op, input, output, numJumps = 0, numRegisters = 0;
 
 
     for (let i = startFrom; i < this.opList.length; i++) {
     for (let i = startFrom; i < this.opList.length; i++) {
         op = this.opList[i];
         op = this.opList[i];
@@ -164,15 +162,17 @@ Recipe.prototype.execute = async function(dish, startFrom) {
             if (op.isFlowControl()) {
             if (op.isFlowControl()) {
                 // Package up the current state
                 // Package up the current state
                 let state = {
                 let state = {
-                    "progress": i,
-                    "dish":     dish,
-                    "opList":   this.opList,
-                    "numJumps": numJumps
+                    "progress":     i,
+                    "dish":         dish,
+                    "opList":       this.opList,
+                    "numJumps":     numJumps,
+                    "numRegisters": numRegisters
                 };
                 };
 
 
                 state = await op.run(state);
                 state = await op.run(state);
                 i = state.progress;
                 i = state.progress;
                 numJumps = state.numJumps;
                 numJumps = state.numJumps;
+                numRegisters = state.numRegisters;
             } else {
             } else {
                 output = await op.run(input, op.getIngValues());
                 output = await op.run(input, op.getIngValues());
                 dish.set(output, op.outputType);
                 dish.set(output, op.outputType);
@@ -217,4 +217,37 @@ Recipe.prototype.fromString = function(recipeStr) {
     this._parseConfig(recipeConfig);
     this._parseConfig(recipeConfig);
 };
 };
 
 
+
+/**
+ * Generates a list of all the highlight functions assigned to operations in the recipe, if the
+ * entire recipe supports highlighting.
+ *
+ * @returns {Object[]} highlights
+ * @returns {function} highlights[].f
+ * @returns {function} highlights[].b
+ * @returns {Object[]} highlights[].args
+ */
+Recipe.prototype.generateHighlightList = function() {
+    const highlights = [];
+
+    for (let i = 0; i < this.opList.length; i++) {
+        let op = this.opList[i];
+        if (op.isDisabled()) continue;
+
+        // If any breakpoints are set, do not attempt to highlight
+        if (op.isBreakpoint()) return false;
+
+        // If any of the operations do not support highlighting, fail immediately.
+        if (op.highlight === false || op.highlight === undefined) return false;
+
+        highlights.push({
+            f: op.highlight,
+            b: op.highlightReverse,
+            args: op.getIngValues()
+        });
+    }
+
+    return highlights;
+};
+
 export default Recipe;
 export default Recipe;

+ 17 - 7
src/core/Utils.js

@@ -234,7 +234,7 @@ const Utils = {
      * @returns {string}
      * @returns {string}
      */
      */
     printable: function(str, preserveWs) {
     printable: function(str, preserveWs) {
-        if (typeof window !== "undefined" && window.app && !window.app.options.treatAsUtf8) {
+        if (ENVIRONMENT_IS_WEB() && window.app && !window.app.options.treatAsUtf8) {
             str = Utils.byteArrayToChars(Utils.strToByteArray(str));
             str = Utils.byteArrayToChars(Utils.strToByteArray(str));
         }
         }
 
 
@@ -384,8 +384,12 @@ const Utils = {
         let wordArray = CryptoJS.enc.Utf8.parse(str),
         let wordArray = CryptoJS.enc.Utf8.parse(str),
             byteArray = Utils.wordArrayToByteArray(wordArray);
             byteArray = Utils.wordArrayToByteArray(wordArray);
 
 
-        if (typeof window !== "undefined" && str.length !== wordArray.sigBytes) {
-            window.app.options.attemptHighlight = false;
+        if (str.length !== wordArray.sigBytes) {
+            if (ENVIRONMENT_IS_WORKER()) {
+                self.setOption("attemptHighlight", false);
+            } else if (ENVIRONMENT_IS_WEB()) {
+                window.app.options.attemptHighlight = false;
+            }
         }
         }
         return byteArray;
         return byteArray;
     },
     },
@@ -405,7 +409,7 @@ const Utils = {
      * Utils.strToCharcode("你好");
      * Utils.strToCharcode("你好");
      */
      */
     strToCharcode: function(str) {
     strToCharcode: function(str) {
-        const charcode = new Array();
+        const charcode = [];
 
 
         for (let i = 0; i < str.length; i++) {
         for (let i = 0; i < str.length; i++) {
             let ord = str.charCodeAt(i);
             let ord = str.charCodeAt(i);
@@ -448,8 +452,13 @@ const Utils = {
             let wordArray = new CryptoJS.lib.WordArray.init(words, byteArray.length),
             let wordArray = new CryptoJS.lib.WordArray.init(words, byteArray.length),
                 str = CryptoJS.enc.Utf8.stringify(wordArray);
                 str = CryptoJS.enc.Utf8.stringify(wordArray);
 
 
-            if (typeof window !== "undefined" && str.length !== wordArray.sigBytes)
-                window.app.options.attemptHighlight = false;
+            if (str.length !== wordArray.sigBytes) {
+                if (ENVIRONMENT_IS_WORKER()) {
+                    self.setOption("attemptHighlight", false);
+                } else if (ENVIRONMENT_IS_WEB()) {
+                    window.app.options.attemptHighlight = false;
+                }
+            }
             return str;
             return str;
         } catch (err) {
         } catch (err) {
             // If it fails, treat it as ANSI
             // If it fails, treat it as ANSI
@@ -1235,7 +1244,8 @@ const Utils = {
         "Forward slash": /\//g,
         "Forward slash": /\//g,
         "Backslash":     /\\/g,
         "Backslash":     /\\/g,
         "0x":            /0x/g,
         "0x":            /0x/g,
-        "\\x":           /\\x/g
+        "\\x":           /\\x/g,
+        "None":          /\s+/g // Included here to remove whitespace when there shouldn't be any
     },
     },
 
 
 
 

+ 16 - 5
src/core/config/Categories.js

@@ -122,6 +122,8 @@ const Categories = [
             "AND",
             "AND",
             "ADD",
             "ADD",
             "SUB",
             "SUB",
+            "Bit shift left",
+            "Bit shift right",
             "Rotate left",
             "Rotate left",
             "Rotate right",
             "Rotate right",
             "ROT13",
             "ROT13",
@@ -245,20 +247,24 @@ const Categories = [
             "MD2",
             "MD2",
             "MD4",
             "MD4",
             "MD5",
             "MD5",
+            "MD6",
             "SHA0",
             "SHA0",
             "SHA1",
             "SHA1",
-            "SHA224",
-            "SHA256",
-            "SHA384",
-            "SHA512",
+            "SHA2",
             "SHA3",
             "SHA3",
-            "RIPEMD-160",
+            "Keccak",
+            "Shake",
+            "RIPEMD",
+            "HAS-160",
+            "Whirlpool",
+            "Snefru",
             "HMAC",
             "HMAC",
             "Fletcher-8 Checksum",
             "Fletcher-8 Checksum",
             "Fletcher-16 Checksum",
             "Fletcher-16 Checksum",
             "Fletcher-32 Checksum",
             "Fletcher-32 Checksum",
             "Fletcher-64 Checksum",
             "Fletcher-64 Checksum",
             "Adler-32 Checksum",
             "Adler-32 Checksum",
+            "CRC-16 Checksum",
             "CRC-32 Checksum",
             "CRC-32 Checksum",
             "TCP/IP Checksum",
             "TCP/IP Checksum",
         ]
         ]
@@ -282,6 +288,7 @@ const Categories = [
             "XPath expression",
             "XPath expression",
             "JPath expression",
             "JPath expression",
             "CSS selector",
             "CSS selector",
+            "Microsoft Script Decoder",
             "Strip HTML tags",
             "Strip HTML tags",
             "Diff",
             "Diff",
             "To Snake case",
             "To Snake case",
@@ -296,7 +303,10 @@ const Categories = [
             "Frequency distribution",
             "Frequency distribution",
             "Detect File Type",
             "Detect File Type",
             "Scan for Embedded Files",
             "Scan for Embedded Files",
+            "Disassemble x86",
             "Generate UUID",
             "Generate UUID",
+            "Generate TOTP",
+            "Generate HOTP",
             "Render Image",
             "Render Image",
             "Remove EXIF",
             "Remove EXIF",
             "Extract EXIF",
             "Extract EXIF",
@@ -308,6 +318,7 @@ const Categories = [
         ops: [
         ops: [
             "Fork",
             "Fork",
             "Merge",
             "Merge",
+            "Register",
             "Jump",
             "Jump",
             "Conditional Jump",
             "Conditional Jump",
             "Return",
             "Return",

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 185 - 125
src/core/config/OperationConfig.js


+ 22 - 0
src/core/config/modules/CharEnc.js

@@ -0,0 +1,22 @@
+import CharEnc from "../../operations/CharEnc.js";
+
+
+/**
+ * CharEnc module.
+ *
+ * Libraries:
+ *  - cptable
+ *  - CryptoJS
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.CharEnc = {
+    "Encode text": CharEnc.runEncode,
+    "Decode text": CharEnc.runDecode,
+};
+
+export default OpModules;

+ 42 - 0
src/core/config/modules/Ciphers.js

@@ -0,0 +1,42 @@
+import Cipher from "../../operations/Cipher.js";
+
+
+/**
+ * Ciphers module.
+ *
+ * Libraries:
+ *  - CryptoJS
+ *  - Blowfish
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.Ciphers = {
+    "AES Encrypt":          Cipher.runAesEnc,
+    "AES Decrypt":          Cipher.runAesDec,
+    "Blowfish Encrypt":     Cipher.runBlowfishEnc,
+    "Blowfish Decrypt":     Cipher.runBlowfishDec,
+    "DES Encrypt":          Cipher.runDesEnc,
+    "DES Decrypt":          Cipher.runDesDec,
+    "Triple DES Encrypt":   Cipher.runTripleDesEnc,
+    "Triple DES Decrypt":   Cipher.runTripleDesDec,
+    "Rabbit Encrypt":       Cipher.runRabbitEnc,
+    "Rabbit Decrypt":       Cipher.runRabbitDec,
+    "Derive PBKDF2 key":    Cipher.runPbkdf2,
+    "Derive EVP key":       Cipher.runEvpkdf,
+    "RC4":                  Cipher.runRc4,
+    "RC4 Drop":             Cipher.runRc4drop,
+    "Vigenère Encode":      Cipher.runVigenereEnc,
+    "Vigenère Decode":      Cipher.runVigenereDec,
+    "Bifid Cipher Encode":  Cipher.runBifidEnc,
+    "Bifid Cipher Decode":  Cipher.runBifidDec,
+    "Affine Cipher Encode": Cipher.runAffineEnc,
+    "Affine Cipher Decode": Cipher.runAffineDec,
+    "Atbash Cipher":        Cipher.runAtbash,
+    "Substitute":           Cipher.runSubstitute,
+};
+
+export default OpModules;

+ 44 - 0
src/core/config/modules/Code.js

@@ -0,0 +1,44 @@
+import JS from "../../operations/JS.js";
+import Code from "../../operations/Code.js";
+
+
+/**
+ * Code module.
+ *
+ * Libraries:
+ *  - lodash
+ *  - vkbeautify
+ *  - xmldom
+ *  - xpath
+ *  - jpath
+ *  - googlecodeprettify
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.Code = {
+    "JavaScript Parser":     JS.runParse,
+    "JavaScript Beautify":   JS.runBeautify,
+    "JavaScript Minify":     JS.runMinify,
+    "Syntax highlighter":    Code.runSyntaxHighlight,
+    "Generic Code Beautify": Code.runGenericBeautify,
+    "JSON Beautify":         Code.runJsonBeautify,
+    "JSON Minify":           Code.runJsonMinify,
+    "XML Beautify":          Code.runXmlBeautify,
+    "XML Minify":            Code.runXmlMinify,
+    "SQL Beautify":          Code.runSqlBeautify,
+    "SQL Minify":            Code.runSqlMinify,
+    "CSS Beautify":          Code.runCssBeautify,
+    "CSS Minify":            Code.runCssMinify,
+    "XPath expression":      Code.runXpath,
+    "CSS selector":          Code.runCSSQuery,
+    "To Snake case":         Code.runToSnakeCase,
+    "To Camel case":         Code.runToCamelCase,
+    "To Kebab case":         Code.runToKebabCase,
+    "JPath expression":      Code.runJpath,
+};
+
+export default OpModules;

+ 32 - 0
src/core/config/modules/Compression.js

@@ -0,0 +1,32 @@
+import Compress from "../../operations/Compress.js";
+
+
+/**
+ * Compression module.
+ *
+ * Libraries:
+ *  - zlib.js
+ *  - bzip2.js
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.Compression = {
+    "Raw Deflate":      Compress.runRawDeflate,
+    "Raw Inflate":      Compress.runRawInflate,
+    "Zlib Deflate":     Compress.runZlibDeflate,
+    "Zlib Inflate":     Compress.runZlibInflate,
+    "Gzip":             Compress.runGzip,
+    "Gunzip":           Compress.runGunzip,
+    "Zip":              Compress.runPkzip,
+    "Unzip":            Compress.runPkunzip,
+    "Bzip2 Decompress": Compress.runBzip2Decompress,
+    "Tar":              Compress.runTar,
+    "Untar":            Compress.runUntar,
+
+};
+
+export default OpModules;

+ 188 - 0
src/core/config/modules/Default.js

@@ -0,0 +1,188 @@
+import FlowControl from "../../FlowControl.js";
+import Base from "../../operations/Base.js";
+import Base58 from "../../operations/Base58.js";
+import Base64 from "../../operations/Base64.js";
+import BCD from "../../operations/BCD.js";
+import BitwiseOp from "../../operations/BitwiseOp.js";
+import ByteRepr from "../../operations/ByteRepr.js";
+import Convert from "../../operations/Convert.js";
+import DateTime from "../../operations/DateTime.js";
+import Endian from "../../operations/Endian.js";
+import Entropy from "../../operations/Entropy.js";
+import Extract from "../../operations/Extract.js";
+import FileType from "../../operations/FileType.js";
+import Hexdump from "../../operations/Hexdump.js";
+import HTML from "../../operations/HTML.js";
+import MAC from "../../operations/MAC.js";
+import MorseCode from "../../operations/MorseCode.js";
+import MS from "../../operations/MS.js";
+import NetBIOS from "../../operations/NetBIOS.js";
+import Numberwang from "../../operations/Numberwang.js";
+import OS from "../../operations/OS.js";
+import OTP from "../../operations/OTP.js";
+import QuotedPrintable from "../../operations/QuotedPrintable.js";
+import Rotate from "../../operations/Rotate.js";
+import SeqUtils from "../../operations/SeqUtils.js";
+import StrUtils from "../../operations/StrUtils.js";
+import Tidy from "../../operations/Tidy.js";
+import Unicode from "../../operations/Unicode.js";
+import UUID from "../../operations/UUID.js";
+
+
+/**
+ * Default module.
+ *
+ * The Default module is for operations that are expected to be very commonly used or
+ * do not require any libraries. This module is loaded into the app at compile time.
+ *
+ * Libraries:
+ *  - Utils.js
+ *    - CryptoJS
+ *  - otp
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.Default = {
+    "To Hexdump":           Hexdump.runTo,
+    "From Hexdump":         Hexdump.runFrom,
+    "To Hex":               ByteRepr.runToHex,
+    "From Hex":             ByteRepr.runFromHex,
+    "To Octal":             ByteRepr.runToOct,
+    "From Octal":           ByteRepr.runFromOct,
+    "To Charcode":          ByteRepr.runToCharcode,
+    "From Charcode":        ByteRepr.runFromCharcode,
+    "To Decimal":           ByteRepr.runToDecimal,
+    "From Decimal":         ByteRepr.runFromDecimal,
+    "To Binary":            ByteRepr.runToBinary,
+    "From Binary":          ByteRepr.runFromBinary,
+    "To Hex Content":       ByteRepr.runToHexContent,
+    "From Hex Content":     ByteRepr.runFromHexContent,
+    "To Base64":            Base64.runTo,
+    "From Base64":          Base64.runFrom,
+    "Show Base64 offsets":  Base64.runOffsets,
+    "To Base32":            Base64.runTo32,
+    "From Base32":          Base64.runFrom32,
+    "To Base58":            Base58.runTo,
+    "From Base58":          Base58.runFrom,
+    "To Base":              Base.runTo,
+    "From Base":            Base.runFrom,
+    "To BCD":               BCD.runToBCD,
+    "From BCD":             BCD.runFromBCD,
+    "To HTML Entity":       HTML.runToEntity,
+    "From HTML Entity":     HTML.runFromEntity,
+    "Strip HTML tags":      HTML.runStripTags,
+    "Parse colour code":    HTML.runParseColourCode,
+    "Unescape Unicode Characters": Unicode.runUnescape,
+    "To Quoted Printable":  QuotedPrintable.runTo,
+    "From Quoted Printable": QuotedPrintable.runFrom,
+    "Swap endianness":      Endian.runSwapEndianness,
+    "ROT13":                Rotate.runRot13,
+    "ROT47":                Rotate.runRot47,
+    "Rotate left":          Rotate.runRotl,
+    "Rotate right":         Rotate.runRotr,
+    "Bit shift left":       BitwiseOp.runBitShiftLeft,
+    "Bit shift right":      BitwiseOp.runBitShiftRight,
+    "XOR":                  BitwiseOp.runXor,
+    "XOR Brute Force":      BitwiseOp.runXorBrute,
+    "OR":                   BitwiseOp.runXor,
+    "NOT":                  BitwiseOp.runNot,
+    "AND":                  BitwiseOp.runAnd,
+    "ADD":                  BitwiseOp.runAdd,
+    "SUB":                  BitwiseOp.runSub,
+    "To Morse Code":        MorseCode.runTo,
+    "From Morse Code":      MorseCode.runFrom,
+    "Format MAC addresses": MAC.runFormat,
+    "Encode NetBIOS Name":  NetBIOS.runEncodeName,
+    "Decode NetBIOS Name":  NetBIOS.runDecodeName,
+    "Regular expression":   StrUtils.runRegex,
+    "Offset checker":       StrUtils.runOffsetChecker,
+    "To Upper case":        StrUtils.runUpper,
+    "To Lower case":        StrUtils.runLower,
+    "Find / Replace":       StrUtils.runFindReplace,
+    "Split":                StrUtils.runSplit,
+    "Filter":               StrUtils.runFilter,
+    "Escape string":        StrUtils.runEscape,
+    "Unescape string":      StrUtils.runUnescape,
+    "Head":                 StrUtils.runHead,
+    "Tail":                 StrUtils.runTail,
+    "Remove whitespace":    Tidy.runRemoveWhitespace,
+    "Remove null bytes":    Tidy.runRemoveNulls,
+    "Drop bytes":           Tidy.runDropBytes,
+    "Take bytes":           Tidy.runTakeBytes,
+    "Pad lines":            Tidy.runPad,
+    "Reverse":              SeqUtils.runReverse,
+    "Sort":                 SeqUtils.runSort,
+    "Unique":               SeqUtils.runUnique,
+    "Count occurrences":    SeqUtils.runCount,
+    "Add line numbers":     SeqUtils.runAddLineNumbers,
+    "Remove line numbers":  SeqUtils.runRemoveLineNumbers,
+    "Expand alphabet range": SeqUtils.runExpandAlphRange,
+    "Convert distance":     Convert.runDistance,
+    "Convert area":         Convert.runArea,
+    "Convert mass":         Convert.runMass,
+    "Convert speed":        Convert.runSpeed,
+    "Convert data units":   Convert.runDataSize,
+    "Parse UNIX file permissions": OS.runParseUnixPerms,
+    "Parse DateTime":       DateTime.runParse,
+    "Translate DateTime Format": DateTime.runTranslateFormat,
+    "From UNIX Timestamp":  DateTime.runFromUnixTimestamp,
+    "To UNIX Timestamp":    DateTime.runToUnixTimestamp,
+    "Strings":              Extract.runStrings,
+    "Extract IP addresses": Extract.runIp,
+    "Extract email addresses": Extract.runEmail,
+    "Extract MAC addresses": Extract.runMac,
+    "Extract URLs":         Extract.runUrls,
+    "Extract domains":      Extract.runDomains,
+    "Extract file paths":   Extract.runFilePaths,
+    "Extract dates":        Extract.runDates,
+    "Microsoft Script Decoder": MS.runDecodeScript,
+    "Entropy":              Entropy.runEntropy,
+    "Frequency distribution": Entropy.runFreqDistrib,
+    "Detect File Type":     FileType.runDetect,
+    "Scan for Embedded Files": FileType.runScanForEmbeddedFiles,
+    "Generate UUID":        UUID.runGenerateV4,
+    "Numberwang":           Numberwang.run,
+    "Generate TOTP":        OTP.runTOTP,
+    "Generate HOTP":        OTP.runHOTP,
+    "Fork":                 FlowControl.runFork,
+    "Merge":                FlowControl.runMerge,
+    "Register":             FlowControl.runRegister,
+    "Jump":                 FlowControl.runJump,
+    "Conditional Jump":     FlowControl.runCondJump,
+    "Return":               FlowControl.runReturn,
+    "Comment":              FlowControl.runComment,
+
+
+    /*
+        Highlighting functions.
+
+        This is a temporary solution as highlighting should be entirely
+        overhauled at some point.
+    */
+    "From Base64-highlight":          Base64.highlightFrom,
+    "From Base64-highlightReverse":   Base64.highlightTo,
+    "To Base64-highlight":            Base64.highlightTo,
+    "To Base64-highlightReverse":     Base64.highlightFrom,
+    "From Hex-highlight":             ByteRepr.highlightFrom,
+    "From Hex-highlightReverse":      ByteRepr.highlightTo,
+    "To Hex-highlight":               ByteRepr.highlightTo,
+    "To Hex-highlightReverse":        ByteRepr.highlightFrom,
+    "From Charcode-highlight":        ByteRepr.highlightFrom,
+    "From Charcode-highlightReverse": ByteRepr.highlightTo,
+    "To Charcode-highlight":          ByteRepr.highlightTo,
+    "To Charcode-highlightReverse":   ByteRepr.highlightFrom,
+    "From Binary-highlight":          ByteRepr.highlightFromBinary,
+    "From Binary-highlightReverse":   ByteRepr.highlightToBinary,
+    "To Binary-highlight":            ByteRepr.highlightToBinary,
+    "To Binary-highlightReverse":     ByteRepr.highlightFromBinary,
+    "From Hexdump-highlight":         Hexdump.highlightFrom,
+    "From Hexdump-highlightReverse":  Hexdump.highlightTo,
+    "To Hexdump-highlight":           Hexdump.highlightTo,
+    "To Hexdump-highlightReverse":    Hexdump.highlightFrom,
+};
+
+export default OpModules;

+ 20 - 0
src/core/config/modules/Diff.js

@@ -0,0 +1,20 @@
+import Diff from "../../operations/Diff.js";
+
+
+/**
+ * Diff module.
+ *
+ * Libraries:
+ *  - JsDIff
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.Diff = {
+    "Diff": Diff.runDiff,
+};
+
+export default OpModules;

+ 21 - 0
src/core/config/modules/Encodings.js

@@ -0,0 +1,21 @@
+import Punycode from "../../operations/Punycode.js";
+
+
+/**
+ * Encodings module.
+ *
+ * Libraries:
+ *  - punycode
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.Encodings = {
+    "To Punycode":   Punycode.runToAscii,
+    "From Punycode": Punycode.runToUnicode,
+};
+
+export default OpModules;

+ 22 - 0
src/core/config/modules/HTTP.js

@@ -0,0 +1,22 @@
+import HTTP from "../../operations/HTTP.js";
+
+
+/**
+ * HTTP module.
+ *
+ * Libraries:
+ *  - UAS_parser
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.HTTP = {
+    "HTTP request":       HTTP.runHTTPRequest,
+    "Strip HTTP headers": HTTP.runStripHeaders,
+    "Parse User Agent":   HTTP.runParseUserAgent,
+};
+
+export default OpModules;

+ 48 - 0
src/core/config/modules/Hashing.js

@@ -0,0 +1,48 @@
+import Checksum from "../../operations/Checksum.js";
+import Hash from "../../operations/Hash.js";
+
+
+/**
+ * Hashing module.
+ *
+ * Libraries:
+ *  - CryptoApi
+ *  - node-md6
+ *  - js-sha3
+ *  - ./Checksum.js
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.Hashing = {
+    "Analyse hash":         Hash.runAnalyse,
+    "Generate all hashes":  Hash.runAll,
+    "MD2":                  Hash.runMD2,
+    "MD4":                  Hash.runMD4,
+    "MD5":                  Hash.runMD5,
+    "MD6":                  Hash.runMD6,
+    "SHA0":                 Hash.runSHA0,
+    "SHA1":                 Hash.runSHA1,
+    "SHA2":                 Hash.runSHA2,
+    "SHA3":                 Hash.runSHA3,
+    "Keccak":               Hash.runKeccak,
+    "Shake":                Hash.runShake,
+    "RIPEMD":               Hash.runRIPEMD,
+    "HAS-160":              Hash.runHAS,
+    "Whirlpool":            Hash.runWhirlpool,
+    "Snefru":               Hash.runSnefru,
+    "HMAC":                 Hash.runHMAC,
+    "Fletcher-8 Checksum":  Checksum.runFletcher8,
+    "Fletcher-16 Checksum": Checksum.runFletcher16,
+    "Fletcher-32 Checksum": Checksum.runFletcher32,
+    "Fletcher-64 Checksum": Checksum.runFletcher64,
+    "Adler-32 Checksum":    Checksum.runAdler32,
+    "CRC-16 Checksum":      Checksum.runCRC16,
+    "CRC-32 Checksum":      Checksum.runCRC32,
+    "TCP/IP Checksum":      Checksum.runTCPIP,
+};
+
+export default OpModules;

+ 25 - 0
src/core/config/modules/Image.js

@@ -0,0 +1,25 @@
+import Image from "../../operations/Image.js";
+
+
+/**
+ * Image module.
+ *
+ * Libraries:
+ *  - exif-parser
+ *  - remove-exif
+ *  - ./FileType.js
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.Image = {
+    "Extract EXIF": Image.runExtractEXIF,
+    "Remove EXIF":  Image.runRemoveEXIF,
+    "Render Image": Image.runRenderImage,
+
+};
+
+export default OpModules;

+ 28 - 0
src/core/config/modules/JSBN.js

@@ -0,0 +1,28 @@
+import IP from "../../operations/IP.js";
+import Filetime from "../../operations/Filetime.js";
+
+
+/**
+ * JSBN module.
+ *
+ * Libraries:
+ *  - jsbn
+ *  - ./Checksum.js
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.JSBN = {
+    "Parse IP range":     IP.runParseIpRange,
+    "Parse IPv6 address": IP.runParseIPv6,
+    "Parse IPv4 header":  IP.runParseIPv4Header,
+    "Change IP format":   IP.runChangeIpFormat,
+    "Group IP addresses": IP.runGroupIps,
+    "Windows Filetime to UNIX Timestamp": Filetime.runFromFiletimeToUnix,
+    "UNIX Timestamp to Windows Filetime": Filetime.runToFiletimeFromUnix,
+};
+
+export default OpModules;

+ 41 - 0
src/core/config/modules/OpModules.js

@@ -0,0 +1,41 @@
+/**
+ * Imports all modules for builds which do not load modules separately.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+
+import OpModules from "./Default.js";
+import CharEncModule from "./CharEnc.js";
+import CipherModule from "./Ciphers.js";
+import CodeModule from "./Code.js";
+import CompressionModule from "./Compression.js";
+import DiffModule from "./Diff.js";
+import EncodingModule from "./Encodings.js";
+import HashingModule from "./Hashing.js";
+import HTTPModule from "./HTTP.js";
+import ImageModule from "./Image.js";
+import JSBNModule from "./JSBN.js";
+import PublicKeyModule from "./PublicKey.js";
+import ShellcodeModule from "./Shellcode.js";
+import URLModule from "./URL.js";
+
+Object.assign(
+    OpModules,
+    CharEncModule,
+    CipherModule,
+    CodeModule,
+    CompressionModule,
+    DiffModule,
+    EncodingModule,
+    HashingModule,
+    HTTPModule,
+    ImageModule,
+    JSBNModule,
+    PublicKeyModule,
+    ShellcodeModule,
+    URLModule
+);
+
+export default OpModules;

+ 25 - 0
src/core/config/modules/PublicKey.js

@@ -0,0 +1,25 @@
+import PublicKey from "../../operations/PublicKey.js";
+
+
+/**
+ * PublicKey module.
+ *
+ * Libraries:
+ *  - jsrsasign
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.PublicKey = {
+    "Parse X.509 certificate":  PublicKey.runParseX509,
+    "Parse ASN.1 hex string":   PublicKey.runParseAsn1HexString,
+    "PEM to Hex":               PublicKey.runPemToHex,
+    "Hex to PEM":               PublicKey.runHexToPem,
+    "Hex to Object Identifier": PublicKey.runHexToObjectIdentifier,
+    "Object Identifier to Hex": PublicKey.runObjectIdentifierToHex,
+};
+
+export default OpModules;

+ 20 - 0
src/core/config/modules/Shellcode.js

@@ -0,0 +1,20 @@
+import Shellcode from "../../operations/Shellcode.js";
+
+
+/**
+ * Shellcode module.
+ *
+ * Libraries:
+ *  - DisassembleX86-64.js
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.Shellcode = {
+    "Disassemble x86": Shellcode.runDisassemble,
+};
+
+export default OpModules;

+ 23 - 0
src/core/config/modules/URL.js

@@ -0,0 +1,23 @@
+import URL_ from "../../operations/URL.js";
+
+
+/**
+ * URL module.
+ *
+ * Libraries:
+ *  - Utils.js
+ *  - url
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.URL = {
+    "URL Encode": URL_.runTo,
+    "URL Decode": URL_.runFrom,
+    "Parse URI":  URL_.runParse,
+};
+
+export default OpModules;

+ 5722 - 0
src/core/lib/DisassembleX86-64.js

@@ -0,0 +1,5722 @@
+/*-------------------------------------------------------------------------------------------------------------------------
+Binary byte code array.
+---------------------------------------------------------------------------------------------------------------------------
+Function ^LoadBinCode()^ takes a string input of hex and loads it into the BinCode array it is recommended that the location
+the hex string is read from a file, or sector matches the disassemblers set base address using function ^SetBasePosition()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var BinCode = [];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+When Bit Mode is 2 the disassembler will default to decoding 64 bit binary code possible settings are 0=16 bit, 1=32 bit, 2=64 bit.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var BitMode = 2;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The variable CodePos is the position in the BinCode array starts at 0 for each new section loaded in by ^LoadBinCode()^.
+---------------------------------------------------------------------------------------------------------------------------
+The function ^NextByte()^ moves CodePos, and the Disassemblers Base address by one stored in Pos64, Pos32.
+The BinCode array is designed for loading in a section of binary that is supposed to be from the set Base address in Pos64, and Pos32.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var CodePos = 0x00000000;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The Pos64, and Pos32 is the actual base address that instructions are supposed to be from in memory when they are loaded
+into the BinCode array using the Function ^LoadBinCode()^.
+---------------------------------------------------------------------------------------------------------------------------
+The function ^SetBasePosition()^ sets the base location in Pos64, and Pos32, and Code Segment.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var Pos64 = 0x00000000, Pos32 = 0x00000000;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Code Segment is used in 16 bit binaries in which the segment is times 16 (Left Shift 4) added to the 16 bit address position.
+This was done to load more programs in 16 bit space at an selected segment location. In 16 bit X86 processors the instruction
+pointer register counts from 0000 hex to FFFF hex and starts over at 0000 hex. Allowing a program to be a max length of
+65535 bytes long. The Code Segment is multiplied by 16 then is added to the instruction pointer position in memory.
+---------------------------------------------------------------------------------------------------------------------------
+In 32 bit, and 64 bit the address combination is large enough that segmented program loading was no longer required.
+However 32 bit still supports Segmented addressing if used, but 64 bit binaries do not. Also if the code segment is set
+36, or higher in 32 bit binaries this sets SEG:OFFSET address format for each instructions Memory position.
+---------------------------------------------------------------------------------------------------------------------------
+In 64 bit mode, an programs instructions are in a 64 bit address using the processors full instruction pointer, but in 32
+bit instructions the first 32 bit of the instruction pointer is used. In 16 bit the first 16 bits of the instruction pointer
+is used, but with the code segment. Each instruction is executed in order by the Instruction pointer that goes in sectional sizes
+"RIP (64)/EIP (32)/IP (16)" Depending on the Bit mode the 64 bit CPU is set in, or if the CPU is 32 bit to begin with.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var CodeSeg = 0x0000;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The InstructionHex String stores the Bytes of decoded instructions. It is shown to the left side of the disassembled instruction.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var InstructionHex = "";
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The InstructionPos String stores the start position of a decoded binary instruction in memory from the function ^GetPosition()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var InstructionPos = "";
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Decoding display options.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var ShowInstructionHex = true; //setting to show the hex code of the instruction beside the decoded instruction output.
+var ShowInstructionPos = true; //setting to show the instruction address position.
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The Opcode, and Opcode map.
+---------------------------------------------------------------------------------------------------------------------------
+The first 0 to 255 (Byte) value that is read is the selected instruction code, however some codes are used as Adjustment to
+remove limitations that are read by the function ^DecodePrefixAdjustments()^.
+---------------------------------------------------------------------------------------------------------------------------
+Because X86 was limited to 255 instructions An number was sacrificed to add more instructions.
+By using one of the 0 to 255 instructions like 15 which is "0F" as an hex number the next 0 to 255 value is an hole
+new set of 0 to 255 instructions these are called escape code prefixes.
+---------------------------------------------------------------------------------------------------------------------------
+Bellow XX is the opcode combined with the adjustment escape codes thus how opcode is used numerically in the disassembler.
+---------------------------------------------------------------------------------------------------------------------------
+00,00000000 = 0, lower 8 bit opcode at max 00,11111111 = 255. (First byte opcodes XX) Opcodes values 0 to 255.
+01,00000000 = 256, lower 8 bit opcode at max 01,11111111 = 511. (Two byte opcodes 0F XX) Opcodes values 256 to 511.
+10,00000000 = 512, lower 8 bit opcode at max 10,11111111 = 767. (Three byte opcodes 0F 38 XX) Opcodes values 512 to 767.
+11,00000000 = 768, lower 8 bit opcode at max 11,11111111 = 1023. (Three byte opcodes 0F 3A XX) Opcodes values 768 to 1023.
+---------------------------------------------------------------------------------------------------------------------------
+The lower 8 bits is the selectable opcode 0 to 255 plus one from 255 is 1,00000000 = 256 thus 256 acts as the place holder.
+The vector adjustment codes contain an map bit selection the map bits go in order to the place holder map bits are in.
+This makes it so the map bits can be placed where the place holder bits are.
+---------------------------------------------------------------------------------------------------------------------------
+VEX.mmmmm = 000_00b (1-byte map), 000_01b (2-byte map), 000_10b (0Fh,38h), 000_11b (0Fh,3Ah)
+EVEX.mm = 00b (1-byte map), 01b (2-byte map), 10b (0Fh,38h), 11b (0Fh,3Ah)
+--------------------------------------------------------------------------------------------------------------------------
+Function ^DecodePrefixAdjustments()^ reads opcodes that act as settings it only ends when Opcode is an actual
+instruction code value 0 to 1023 inducing escape codes. Opcode is Used by function ^DecodeOpcode()^ with the Mnemonic array.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var Opcode = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Opcode is used as the index for the point in the structure to land on in the "Mnemonics".
+---------------------------------------------------------------------------------------------------------------------------
+X86 has an amazing architectural pattern that is like an fractal in many ways. Previously an experiment was done to make
+this an one dimensional array, but after testing it proved that it was slower because each of the branches had to be
+calculated to an unique index in memory in which lots of combinations map to the same instructions well some changed.
+The calculation took more time than comparing if an index is an reference to another array to optionally use an encoding.
+---------------------------------------------------------------------------------------------------------------------------
+The first branch is an array 2 in size which separates opcodes that change between register, and memory mode.
+---------------------------------------------------------------------------------------------------------------------------
+The second branch is an array 8 in size which uses an register as an 0 to 7 value for the selected instruction code called grouped opcodes.
+The second branch can be branched into another array 8 in size this covers the last three bits of the ModR/M byte for static opcodes.
+---------------------------------------------------------------------------------------------------------------------------
+The third branch is an array 4 in size which is the SIMD modes. The third branch can branch to an array 4 in size again under
+any of the 4 elements in the SIMD modes for instructions that change by vector extension type.
+---------------------------------------------------------------------------------------------------------------------------
+The fifth branch is an array 3 in size which branches to encoding's that change by the set size attribute.
+---------------------------------------------------------------------------------------------------------------------------
+Each branch can be combined in any combination, but only in order. If we branch to an array 2 in size under an specific opcode
+like this ["",""] then decide to branch memory mode to an array 4 in size we end up with ["",["","","",""]] for making it only
+active in memory mode and controlled by SIMD modes, but then if we decide to branch one of the 4 SIMD modes to an array 8
+in size for register opcode separation under one SIMD mode, or an few we can't. We can only branch to an array 3 in size
+as that comes next after the array 4 in size. WE also do not need the first branch to be an array it can be an single opcode
+encoding. We also do not need the first branch to be an array 2 in size it can be any starting branch then the rest must go
+in order from that branch point.
+---------------------------------------------------------------------------------------------------------------------------
+Opcode is used by the function ^DecodeOpcode()^ after ^DecodePrefixAdjustments()^.
+The function ^DecodeOpcode()^ Gives back the instructions name.
+--------------------------------------------------------------------------------------------------------------------------*/
+
+const Mnemonics = [
+  /*------------------------------------------------------------------------------------------------------------------------
+  First Byte operations 0 to 255.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "ADD","ADD","ADD","ADD","ADD","ADD","PUSH ES","POP ES",
+  "OR","OR","OR","OR","OR","OR","PUSH CS"
+  ,
+  "" //*Two byte instructions prefix sets opcode 01,000000000 next byte read is added to the lower 8 bit's.
+  ,
+  "ADC","ADC","ADC","ADC","ADC","ADC","PUSH SS","POP SS",
+  "SBB","SBB","SBB","SBB","SBB","SBB","PUSH DS","POP DS",
+  "AND","AND","AND","AND","AND","AND",
+  "ES:[", //Extra segment override sets SegOveride "ES:[".
+  "DAA",
+  "SUB","SUB","SUB","SUB","SUB","SUB",
+  "CS:[", //Code segment override sets SegOveride "CS:[".
+  "DAS",
+  "XOR","XOR","XOR","XOR","XOR","XOR",
+  "SS:[", //Stack segment override sets SegOveride "SS:[".
+  "AAA",
+  "CMP","CMP","CMP","CMP","CMP","CMP",
+  "DS:[", //Data Segment override sets SegOveride "DS:[".
+  "AAS",
+  /*------------------------------------------------------------------------------------------------------------------------
+  Start of Rex Prefix adjustment setting uses opcodes 40 to 4F. These opcodes are only decoded as adjustment settings
+  by the function ^DecodePrefixAdjustments()^ while in 64 bit mode. If not in 64 bit mode the codes are not read
+  by the function ^DecodePrefixAdjustments()^ which allows the opcode to be set 40 to 4F hex in which the defined
+  instructions bellow are used by ^DecodeOpcode()^.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "INC","INC","INC","INC","INC","INC","INC","INC",
+  "DEC","DEC","DEC","DEC","DEC","DEC","DEC","DEC",
+  /*------------------------------------------------------------------------------------------------------------------------
+  End of the Rex Prefix adjustment setting opcodes.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "PUSH","PUSH","PUSH","PUSH","PUSH","PUSH","PUSH","PUSH",
+  "POP","POP","POP","POP","POP","POP","POP","POP",
+  ["PUSHA","PUSHAD",""],["POPA","POPAD",""],
+  ["BOUND","BOUND",""], //EVEX prefix adjustment settings only if used in register to register, or in 64 bit mode, otherwise the defined BOUND instruction is used.
+  "MOVSXD",
+  "FS:[","GS:[", //Sets SegOveride "FS:[" next opcode sets "GS:[".
+  "","", //Operand Size, and Address size adjustment to ModR/M.
+  "PUSH","IMUL","PUSH","IMUL",
+  "INS","INS","OUTS","OUTS",
+  "JO","JNO","JB","JAE","JE","JNE","JBE","JA",
+  "JS","JNS","JP","JNP","JL","JGE","JLE","JG",
+  ["ADD","OR","ADC","SBB","AND","SUB","XOR","CMP"], //Group opcode uses the ModR/M register selection 0 though 7 giving 8 instruction in one opcode.
+  ["ADD","OR","ADC","SBB","AND","SUB","XOR","CMP"],
+  ["ADD","OR","ADC","SBB","AND","SUB","XOR","CMP"],
+  ["ADD","OR","ADC","SBB","AND","SUB","XOR","CMP"],
+  "TEST","TEST","XCHG","XCHG",
+  "MOV","MOV","MOV","MOV","MOV",
+  ["LEA","???"], //*ModR/M Register, and memory mode separation.
+  "MOV",
+  ["POP","???","???","???","???","???","???","???"],
+  [["NOP","","",""],["NOP","","",""],["PAUSE","","",""],["NOP","","",""]],
+  "XCHG","XCHG","XCHG","XCHG","XCHG","XCHG","XCHG",
+  ["CWDE","CBW","CDQE"], //*Opcode 0 to 3 for instructions that change name by size setting.
+  ["CDQ","CWD","CQO"],
+  "CALL","WAIT",
+  ["PUSHFQ","PUSHF","PUSHFQ"],
+  ["POPFQ","POPF","POPFQ"],
+  "SAHF","LAHF",
+  "MOV","MOV","MOV","MOV",
+  "MOVS","MOVS",
+  "CMPS","CMPS",
+  "TEST","TEST",
+  "STOS","STOS",
+  "LODS","LODS",
+  "SCAS","SCAS",
+  "MOV","MOV","MOV","MOV","MOV","MOV","MOV","MOV",
+  "MOV","MOV","MOV","MOV","MOV","MOV","MOV","MOV",
+  ["ROL","ROR","RCL","RCR","SHL","SHR","SAL","SAR"],
+  ["ROL","ROR","RCL","RCR","SHL","SHR","SAL","SAR"],
+  "RET","RET",
+  "LES", //VEX prefix adjustment settings only if used in register to register, or in 64 bit mode, otherwise the defined instruction is used.
+  "LDS", //VEX prefix adjustment settings only if used in register to register, or in 64 bit mode, otherwise the defined instruction is used.
+  [
+    "MOV","???","???","???","???","???","???",
+    ["XABORT","XABORT","XABORT","XABORT","XABORT","XABORT","XABORT","XABORT"]
+  ],
+  [
+    "MOV","???","???","???","???","???","???",
+    ["XBEGIN","XBEGIN","XBEGIN","XBEGIN","XBEGIN","XBEGIN","XBEGIN","XBEGIN"]
+  ],
+  "ENTER","LEAVE","RETF","RETF","INT","INT","INTO",
+  ["IRETD","IRET","IRETQ"],
+  ["ROL","ROR","RCL","RCR","SHL","SHR","SAL","SAR"],
+  ["ROL","ROR","RCL","RCR","SHL","SHR","SAL","SAR"],
+  ["ROL","ROR","RCL","RCR","SHL","SHR","SAL","SAR"],
+  ["ROL","ROR","RCL","RCR","SHL","SHR","SAL","SAR"],
+  "AAMB","AADB","???",
+  "XLAT",
+  /*------------------------------------------------------------------------------------------------------------------------
+  X87 FPU.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  [
+    ["FADD","FMUL","FCOM","FCOMP","FSUB","FSUBR","FDIV","FDIVR"],
+    ["FADD","FMUL","FCOM","FCOMP","FSUB","FSUBR","FDIV","FDIVR"]
+  ],
+  [
+    ["FLD","???","FST","FSTP","FLDENV","FLDCW","FNSTENV","FNSTCW"],
+    [
+      "FLD","FXCH",
+      ["FNOP","???","???","???","???","???","???","???"],
+      "FSTP1",
+      ["FCHS","FABS","???","???","FTST","FXAM","???","???"],
+      ["FLD1","FLDL2T","FLDL2E","FLDPI","FLDLG2","FLDLN2","FLDZ","???"],
+      ["F2XM1","FYL2X","FPTAN","FPATAN","FXTRACT","FPREM1","FDECSTP","FINCSTP"],
+      ["FPREM","FYL2XP1","FSQRT","FSINCOS","FRNDINT","FSCALE","FSIN","FCOS"]
+    ]
+  ],
+  [
+    ["FIADD","FIMUL","FICOM","FICOMP","FISUB","FISUBR","FIDIV","FIDIVR"],
+    [
+      "FCMOVB","FCMOVE","FCMOVBE","FCMOVU","???",
+      ["???","FUCOMPP","???","???","???","???","???","???"],
+      "???","???"
+    ]
+  ],
+  [
+    ["FILD","FISTTP","FIST","FISTP","???","FLD","???","FSTP"],
+    [
+      "CMOVNB","FCMOVNE","FCMOVNBE","FCMOVNU",
+      ["FENI","FDISI","FNCLEX","FNINIT","FSETPM","???","???","???"],
+      "FUCOMI","FCOMI","???"
+    ]
+  ],
+  [
+    ["FADD","FMUL","FCOM","DCOMP","FSUB","FSUBR","FDIV","FDIVR"],
+    ["FADD","FMUL","FCOM2","FCOMP3","FSUBR","FSUB","FDIVR","FDIV"]
+  ],
+  [
+    ["FLD","FISTTP","FST","FSTP","FRSTOR","???","FNSAVE","FNSTSW"],
+    ["FFREE","FXCH4","FST","FSTP","FUCOM","FUCOMP","???","???"]
+  ],
+  [
+    ["FIADD","FIMUL","FICOM","FICOMP","FISUB","FISUBR","FIDIV","FIDIVR"],
+    [
+      "FADDP","FMULP","FCOMP5",
+      ["???","FCOMPP","???","???","???","???","???","???"],
+      "FSUBRP","FSUBP","FDIVRP","FDIVP"
+    ]
+  ],
+  [
+    ["FILD","FISTTP","FIST","FISTP","FBLD","FILD","FBSTP","FISTP"],
+    [
+      "FFREEP","FXCH7","FSTP8","FSTP9",
+      ["FNSTSW","???","???","???","???","???","???","???"],
+      "FUCOMIP","FCOMIP","???"
+    ]
+  ],
+  /*------------------------------------------------------------------------------------------------------------------------
+  End of X87 FPU.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "LOOPNE","LOOPE","LOOP","JRCXZ",
+  "IN","IN","OUT","OUT",
+  "CALL","JMP","JMP","JMP",
+  "IN","IN","OUT","OUT",
+  /*------------------------------------------------------------------------------------------------------------------------
+  The Repeat, and lock prefix opcodes apply to the next opcode.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "LOCK", //Adds LOCK to the start of instruction. When Opcode F0 hex is read by function ^DecodePrefixAdjustments()^ sets PrefixG2 to LOCK.
+  "ICEBP", //Instruction ICEBP.
+  "REPNE", //Adds REPNE (Opcode F2 hex) to the start of instruction. Read by function ^DecodePrefixAdjustments()^ sets PrefixG1 to REPNE.
+  "REP", //Adds REP (Opcode F3 hex) to the start of instruction. Read by function ^DecodePrefixAdjustments()^ sets PrefixG1 to REP.
+  /*------------------------------------------------------------------------------------------------------------------------
+  End of Repeat, and lock instruction adjustment codes.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "HLT","CMC",
+  ["TEST","???","NOT","NEG","MUL","IMUL","DIV","IDIV"],
+  ["TEST","???","NOT","NEG","MUL","IMUL","DIV","IDIV"],
+  "CLC","STC","CLI","STI","CLD","STD",
+  ["INC","DEC","???","???","???","???","???","???"],
+  [
+    ["INC","DEC","CALL","CALL","JMP","JMP","PUSH","???"],
+    ["INC","DEC","CALL","???","JMP","???","PUSH","???"]
+  ],
+  /*------------------------------------------------------------------------------------------------------------------------
+  Two Byte Opcodes 256 to 511. Opcodes plus 256 goes to 511 used by escape code "0F", Or
+  set directly by adding map bits "01" because "01 00000000" bin = 256 plus opcode.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  [
+    ["SLDT","STR","LLDT","LTR","VERR","VERW","JMPE","???"],
+    ["SLDT","STR","LLDT","LTR","VERR","VERW","JMPE","???"]
+  ],
+  [
+    ["SGDT","SIDT","LGDT","LIDT","SMSW","???","LMSW","INVLPG"],
+    [
+      ["???","VMCALL","VMLAUNCH","VMRESUME","VMXOFF","???","???","???"],
+      ["MONITOR","MWAIT","CLAC","STAC","???","???","???","ENCLS"],
+      ["XGETBV","XSETBV","???","???","VMFUNC","XEND","XTEST","ENCLU"],
+      ["VMRUN","VMMCALL","VMLOAD","VMSAVE","STGI","CLGI","SKINIT","INVLPGA"],
+      "SMSW","???","LMSW",
+      ["SWAPGS","RDTSCP","MONITORX","MWAITX","???","???","???","???"]
+    ]
+  ],
+  ["LAR","LAR"],["LSL","LSL"],"???",
+  "SYSCALL","CLTS","SYSRET","INVD",
+  "WBINVD","???","UD2","???",
+  [["PREFETCH","PREFETCHW","???","???","???","???","???","???"],"???"],
+  "FEMMS",
+  "", //3DNow Instruction name is encoded by the IMM8 operand.
+  [
+    ["MOVUPS","MOVUPD","MOVSS","MOVSD"],
+    ["MOVUPS","MOVUPD","MOVSS","MOVSD"]
+  ],
+  [
+    ["MOVUPS","MOVUPD","MOVSS","MOVSD"],
+    ["MOVUPS","MOVUPD","MOVSS","MOVSD"]
+  ],
+  [
+    ["MOVLPS","MOVLPD","MOVSLDUP","MOVDDUP"],
+    ["MOVHLPS","???","MOVSLDUP","MOVDDUP"]
+  ],
+  [["MOVLPS","MOVLPD","???","???"],"???"],
+  ["UNPCKLPS","UNPCKLPD","???","???"], //An instruction with 4 operations uses the 4 SIMD modes as an Vector instruction.
+  ["UNPCKHPS","UNPCKHPD","???","???"],
+  [["MOVHPS","MOVHPD","MOVSHDUP","???"],["MOVLHPS","???","MOVSHDUP","???"]],
+  [["MOVHPS","MOVHPD","???","???"],"???"],
+  [["PREFETCHNTA","PREFETCHT0","PREFETCHT1","PREFETCHT2","???","???","???","???"],"???"],
+  "???",
+  [[["BNDLDX","","",""],["BNDMOV","","",""],["BNDCL","","",""],["BNDCU","","",""]],
+  ["???",["BNDMOV","","",""],["BNDCL","","",""],["BNDCU","","",""]]],
+  [[["BNDSTX","","",""],["BNDMOV","","",""],["BNDMK","","",""],["BNDCN","","",""]],
+  ["???",["BNDMOV","","",""],"???",["BNDCN","","",""]]],
+  "???","???","???",
+  "NOP",
+  ["???","MOV"],["???","MOV"], //CR and DR register Move
+  ["???","MOV"],["???","MOV"], //CR and DR register Move
+  ["???","MOV"],"???", //TR (TEST REGISTER) register Move
+  ["???","MOV"],"???", //TR (TEST REGISTER) register Move
+  [
+    ["MOVAPS","MOVAPS","MOVAPS","MOVAPS"],
+    ["MOVAPD","MOVAPD","MOVAPD","MOVAPD"],
+    "???","???"
+  ],
+  [
+    [
+      ["MOVAPS","MOVAPS","MOVAPS","MOVAPS"],
+      ["MOVAPD","MOVAPD","MOVAPD","MOVAPD"],
+      ["","","",["MOVNRAPS","MOVNRNGOAPS","MOVNRAPS"]],
+      ["","","",["MOVNRAPD","MOVNRNGOAPD","MOVNRAPD"]]
+    ],
+    [
+      ["MOVAPS","MOVAPS","MOVAPS","MOVAPS"],
+      ["MOVAPD","MOVAPD","MOVAPD","MOVAPD"],
+      "???","???"
+    ]
+  ],
+  [
+    ["CVTPI2PS","","",""],["CVTPI2PD","","",""], //Is not allowed to be Vector encoded.
+    "CVTSI2SS","CVTSI2SD"
+  ],
+  [
+    [
+      "MOVNTPS","MOVNTPD",
+      ["MOVNTSS","","",""],["MOVNTSD","","",""] //SSE4a can not be vector encoded.
+    ],"???"
+  ],
+  [
+    ["CVTTPS2PI","","",""],["CVTTPD2PI","","",""], //Is not allowed to be Vector encoded.
+    "CVTTSS2SI","CVTTSD2SI"
+  ],
+  [
+    ["CVTPS2PI","","",""],["CVTPD2PI","","",""], //Is not allowed to be Vector encoded.
+    "CVTSS2SI","CVTSD2SI"
+  ],
+  ["UCOMISS","UCOMISD","???","???"],
+  ["COMISS","COMISD","???","???"],
+  "WRMSR","RDTSC","RDMSR","RDPMC",
+  "SYSENTER","SYSEXIT","???",
+  "GETSEC",
+  "", //*Three byte instructions prefix combo 0F 38 (Opcode = 01,00111000) sets opcode 10,000000000 next byte read is added to the lower 8 bit's.
+  "???",
+  "", //*Three byte instructions prefix combo 0F 3A (Opcode = 01,00111010) sets opcode 11,000000000 next byte read is added to the lower 8 bit's.
+  "???","???","???","???","???",
+  "CMOVO",
+  [
+    ["CMOVNO",["KANDW","","KANDQ"],"",""],
+    ["CMOVNO",["KANDB","","KANDD"],"",""],"",""
+  ],
+  [
+    ["CMOVB",["KANDNW","","KANDNQ"],"",""],
+    ["CMOVB",["KANDNB","","KANDND"],"",""],"",""
+  ],
+  [["CMOVAE","KANDNR","",""],"","",""],
+  [
+    ["CMOVE",["KNOTW","","KNOTQ"],"",""],
+    ["CMOVE",["KNOTB","","KNOTD"],"",""],"",""
+  ],
+  [
+    ["CMOVNE",["KORW","","KORQ"],"",""],
+    ["CMOVNE",["KORB","","KORD"],"",""],"",""
+  ],
+  [
+    ["CMOVBE",["KXNORW","","KXNORQ"],"",""],
+    ["CMOVBE",["KXNORB","","KXNORD"],"",""],"",""
+  ],
+  [
+    ["CMOVA",["KXORW","","KXORQ"],"",""],
+    ["CMOVA",["KXORB","","KXORD"],"",""],"",""
+  ],
+  [["CMOVS","KMERGE2L1H","",""],"","",""],
+  [["CMOVNS","KMERGE2L1L","",""],"","",""],
+  [
+    ["CMOVP",["KADDW","","KADDQ"],"",""],
+    ["CMOVP",["KADDB","","KADDD"],"",""],"",""
+  ],
+  [
+    ["CMOVNP",["KUNPCKWD","","KUNPCKDQ"],"",""],
+    ["CMOVNP",["KUNPCKBW","","???"],"",""],"",""
+  ],
+  "CMOVL","CMOVGE","CMOVLE","CMOVG",
+  [
+    "???",
+    [
+      ["MOVMSKPS","MOVMSKPS","",""],["MOVMSKPD","MOVMSKPD","",""],
+      "???","???"
+    ]
+  ],
+  ["SQRTPS","SQRTPD","SQRTSS","SQRTSD"],
+  [
+    ["RSQRTPS","RSQRTPS","",""],"???",
+    ["RSQRTSS","RSQRTSS","",""],"???"
+  ],
+  [
+    ["RCPPS","RCPPS","",""],"???",
+    ["RCPSS","RCPSS","",""],"???"
+  ],
+  ["ANDPS","ANDPD","???","???"],
+  ["ANDNPS","ANDNPD","???","???"],
+  ["ORPS","ORPD","???","???"],
+  ["XORPS","XORPD","???","???"],
+  [
+    ["ADDPS","ADDPS","ADDPS","ADDPS"],
+    ["ADDPD","ADDPD","ADDPD","ADDPD"],
+    "ADDSS","ADDSD"
+  ],
+  [
+    ["MULPS","MULPS","MULPS","MULPS"],
+    ["MULPD","MULPD","MULPD","MULPD"],
+    "MULSS","MULSD"
+  ],
+  [
+    ["CVTPS2PD","CVTPS2PD","CVTPS2PD","CVTPS2PD"],
+    ["CVTPD2PS","CVTPD2PS","CVTPD2PS","CVTPD2PS"],
+    "CVTSS2SD","CVTSD2SS"
+  ],
+  [["CVTDQ2PS","","CVTQQ2PS"],["CVTPS2DQ","","???"],"CVTTPS2DQ","???"],
+  [
+    ["SUBPS","SUBPS","SUBPS","SUBPS"],
+    ["SUBPD","SUBPD","SUBPD","SUBPD"],
+    "SUBSS","SUBSD"
+  ],
+  ["MINPS","MINPD","MINSS","MINSD"],
+  ["DIVPS","DIVPD","DIVSS","DIVSD"],
+  ["MAXPS","MAXPD","MAXSS","MAXSD"],
+  [["PUNPCKLBW","","",""],"PUNPCKLBW","",""],
+  [["PUNPCKLWD","","",""],"PUNPCKLWD","",""],
+  [["PUNPCKLDQ","","",""],"PUNPCKLDQ","",""],
+  [["PACKSSWB","","",""],"PACKSSWB","",""],
+  [["PCMPGTB","","",""],["PCMPGTB","PCMPGTB","PCMPGTB",""],"",""],
+  [["PCMPGTW","","",""],["PCMPGTW","PCMPGTW","PCMPGTW",""],"",""],
+  [["PCMPGTD","","",""],["PCMPGTD","PCMPGTD",["PCMPGTD","","???"],["PCMPGTD","","???"]],"",""],
+  [["PACKUSWB","","",""],"PACKUSWB","",""],
+  [["PUNPCKHBW","","",""],"PUNPCKHBW","",""],
+  [["PUNPCKHWD","","",""],"PUNPCKHWD","",""],
+  [["PUNPCKHDQ","","",""],["PUNPCKHDQ","","???"],"",""],
+  [["PACKSSDW","","",""],["PACKSSDW","","???"],"",""],
+  ["???","PUNPCKLQDQ","???","???"],
+  ["???","PUNPCKHQDQ","???","???"],
+  [["MOVD","","",""],["MOVD","","MOVQ"],"",""],
+  [
+    [
+      ["MOVQ","","",""],
+      ["MOVDQA","MOVDQA",["MOVDQA32","","MOVDQA64"],["MOVDQA32","","MOVDQA64"]],
+      ["MOVDQU","MOVDQU",["MOVDQU32","","MOVDQU64"],""],
+      ["","",["MOVDQU8","","MOVDQU16"],""]
+    ],
+    [
+      ["MOVQ","","",""],
+      ["MOVDQA","MOVDQA",["MOVDQA32","","MOVDQA64"],["MOVDQA32","","MOVDQA64"]],
+      ["MOVDQU","MOVDQU",["MOVDQU32","","MOVDQU64"],""],
+      ["","",["MOVDQU8","","MOVDQU16"],""]
+    ]
+  ],
+  [
+    ["PSHUFW","","",""],
+    ["PSHUFD","PSHUFD",["PSHUFD","","???"],["PSHUFD","","???"]],
+    "PSHUFHW",
+    "PSHUFLW"
+  ],
+  [
+    "???",
+    [
+      "???","???",
+      [["PSRLW","","",""],"PSRLW","",""],"???",
+      [["PSRAW","","",""],"PSRAW","",""],"???",
+      [["PSLLW","","",""],"PSLLW","",""],"???"
+    ]
+  ],
+  [
+    ["???",["","",["PRORD","","PRORQ"],""],"???","???"],
+    ["???",["","",["PROLD","","PROLQ"],""],"???","???"],
+    [["PSRLD","","",""],["PSRLD","PSRLD",["PSRLD","","???"],["PSRLD","","???"]],"",""],
+    "???",
+    [["PSRAD","","",""],["PSRAD","PSRAD",["PSRAD","","PSRAQ"],["PSRAD","","???"]],"",""],
+    "???",
+    [["PSLLD","","",""],["PSLLD","PSLLD",["PSLLD","","???"],["PSLLD","","???"]],"",""],
+    "???"
+  ],
+  [
+    "???",
+    [
+      "???","???",
+      [["PSRLQ","PSRLQ","",""],"PSRLQ","",""],["???","PSRLDQ","???","???"],
+      "???","???",
+      [["PSLLQ","PSLLQ","",""],"PSLLQ","",""],["???","PSLLDQ","???","???"]
+    ]
+  ],
+  [["PCMPEQB","","",""],["PCMPEQB","PCMPEQB","PCMPEQB",""],"",""],
+  [["PCMPEQW","","",""],["PCMPEQW","PCMPEQW","PCMPEQW",""],"",""],
+  [["PCMPEQD","","",""],["PCMPEQD","PCMPEQD",["PCMPEQD","","???"],["PCMPEQD","","???"]],"",""],
+  [["EMMS",["ZEROUPPER","ZEROALL",""],"",""],"???","???","???"],
+  [
+    ["VMREAD","",["CVTTPS2UDQ","","CVTTPD2UDQ"],""],
+    ["EXTRQ","",["CVTTPS2UQQ","","CVTTPD2UQQ"],""],
+    ["???","","CVTTSS2USI",""],
+    ["INSERTQ","","CVTTSD2USI",""]
+  ],
+  [
+    ["VMWRITE","",["CVTPS2UDQ","","CVTPD2UDQ"], ""],
+    ["EXTRQ","",["CVTPS2UQQ","","CVTPD2UQQ"],""],
+    ["???","","CVTSS2USI",""],
+    ["INSERTQ","","CVTSD2USI",""]
+  ],
+  [
+    "???",
+    ["","",["CVTTPS2QQ","","CVTTPD2QQ"],""],
+    ["","",["CVTUDQ2PD","","CVTUQQ2PD"],"CVTUDQ2PD"],
+    ["","",["CVTUDQ2PS","","CVTUQQ2PS"],""]
+  ],
+  [
+    "???",
+    ["","",["CVTPS2QQ","","CVTPD2QQ"],""],
+    ["","","CVTUSI2SS",""],
+    ["","","CVTUSI2SD",""]
+  ],
+  [
+    "???",["HADDPD","HADDPD","",""],
+    "???",["HADDPS","HADDPS","",""]
+  ],
+  [
+    "???",["HSUBPD","HSUBPD","",""],
+    "???",["HSUBPS","HSUBPS","",""]
+  ],
+  [["MOVD","","",""],["MOVD","","MOVQ"],["MOVQ","MOVQ",["???","","MOVQ"],""],"???"],
+  [
+    ["MOVQ","","",""],
+    ["MOVDQA","MOVDQA",["MOVDQA32","","MOVDQA64"],["MOVDQA32","","MOVDQA64"]],
+    ["MOVDQU","MOVDQU",["MOVDQU32","","MOVDQU64"],""],
+    ["???","",["MOVDQU8","","MOVDQU16"],""]
+  ],
+  "JO","JNO","JB","JAE",
+  [["JE","JKZD","",""],"","",""],[["JNE","JKNZD","",""],"","",""], //K1OM.
+  "JBE","JA","JS","JNS","JP","JNP","JL","JGE","JLE","JG",
+  [
+    ["SETO",["KMOVW","","KMOVQ"],"",""],
+    ["SETO",["KMOVB","","KMOVD"],"",""],"",""
+  ],
+  [
+    ["SETNO",["KMOVW","","KMOVQ"],"",""],
+    ["SETNO",["KMOVB","","KMOVD"],"",""],"",""
+  ],
+  [
+    ["SETB",["KMOVW","","???"],"",""],
+    ["SETB",["KMOVB","","???"],"",""],"",
+    ["SETB",["KMOVD","","KMOVQ"],"",""]
+  ],
+  [
+    ["SETAE",["KMOVW","","???"],"",""],
+    ["SETAE",["KMOVB","","???"],"",""],"",
+    ["SETAE",["KMOVD","","KMOVQ"],"",""]
+  ],
+  "SETE",[["SETNE","KCONCATH","",""],"","",""],
+  "SETBE",[["SETA","KCONCATL","",""],"","",""],
+  [
+    ["SETS",["KORTESTW","","KORTESTQ"],"",""],
+    ["SETS",["KORTESTB","","KORTESTD"],"",""],"",""
+  ],
+  [
+    ["SETNS",["KTESTW","","KTESTQ"],"",""],
+    ["SETNS",["KTESTB","","KTESTD"],"",""],"",""
+  ],
+  "SETP","SETNP","SETL","SETGE","SETLE","SETG",
+  "PUSH","POP",
+  "CPUID", //Identifies the CPU and which Instructions the current CPU can use.
+  "BT",
+  "SHLD","SHLD",
+  "XBTS","IBTS",
+  "PUSH","POP",
+  "RSM",
+  "BTS",
+  "SHRD","SHRD",
+  [
+    [
+      ["FXSAVE","???","FXSAVE64"],["FXRSTOR","???","FXRSTOR64"],
+      "LDMXCSR","STMXCSR",
+      ["XSAVE","","XSAVE64"],["XRSTOR","","XRSTOR64"],
+      ["XSAVEOPT","CLWB","XSAVEOPT64"],
+      ["CLFLUSHOPT","CLFLUSH",""]
+    ],
+    [
+      ["???","???",["RDFSBASE","","",""],"???"],["???","???",["RDGSBASE","","",""],"???"],
+      ["???","???",["WRFSBASE","","",""],"???"],["???","???",["WRGSBASE","","",""],"???"],
+      "???",
+      ["LFENCE","???","???","???","???","???","???","???"],
+      ["MFENCE","???","???","???","???","???","???","???"],
+      ["SFENCE","???","???","???","???","???","???","???"]
+    ]
+  ],
+  "IMUL",
+  "CMPXCHG","CMPXCHG",
+  ["LSS","???"],
+  "BTR",
+  ["LFS","???"],
+  ["LGS","???"],
+  "MOVZX","MOVZX",
+  [
+    ["JMPE","","",""],"???",
+    ["POPCNT","POPCNT","",""],"???"
+  ],
+  "???",
+  ["???","???","???","???","BT","BTS","BTR","BTC"],
+  "BTC",
+  [
+    ["BSF","","",""],"???",
+    ["TZCNT","TZCNT","",""],["BSF","TZCNTI","",""]
+  ],
+  [
+    ["BSR","","",""],"???",
+    ["LZCNT","LZCNT","",""],["BSR","","",""]
+  ],
+  "MOVSX","MOVSX",
+  "XADD","XADD",
+  [
+    ["CMP,PS,","CMP,PS,","CMP,PS,","CMP,PS,"],
+    ["CMP,PD,","CMP,PD,","CMP,PD,","CMP,PD,"],
+    ["CMP,SS,","CMP,SS,","CMP,SS,",""],
+    ["CMP,SD,","CMP,SD,","CMP,SD,",""]
+  ],
+  ["MOVNTI","???"],
+  [["PINSRW","","",""],"PINSRW","",""],
+  ["???",[["PEXTRW","","",""],"PEXTRW","",""]],
+  ["SHUFPS","SHUFPD","???","???"],
+  [
+    [
+      "???",
+      ["CMPXCHG8B","","CMPXCHG16B"],
+      "???",
+      ["XRSTORS","","XRSTORS64"],
+      ["XSAVEC","","XSAVEC64"],
+      ["XSAVES","","XSAVES64"],
+      ["VMPTRLD","VMCLEAR","VMXON","???"],["VMPTRST","???","???","???"]
+    ],
+    [
+      "???",
+      ["SSS","???","???","???","???","???","???","???"], //Synthetic virtual machine operation codes.
+      "???","???","???","???",
+      "RDRAND","RDSEED"
+    ]
+  ],
+  "BSWAP","BSWAP","BSWAP","BSWAP","BSWAP","BSWAP","BSWAP","BSWAP",
+  ["???",["ADDSUBPD","ADDSUBPD","",""],"???",["ADDSUBPS","ADDSUBPS","",""]],
+  [["PSRLW","","",""],"PSRLW","",""],
+  [["PSRLD","","",""],["PSRLD","PSRLD",["PSRLD","","???"],""],"",""],
+  [["PSRLQ","","",""],"PSRLQ","",""],
+  [["PADDQ","","",""],"PADDQ","",""],
+  [["PMULLW","","",""],"PMULLW","",""],
+  [
+    ["???","MOVQ","???","???"],
+    ["???","MOVQ",["MOVQ2DQ","","",""],["MOVDQ2Q","","",""]]
+  ],
+  ["???",[["PMOVMSKB","","",""],["PMOVMSKB","PMOVMSKB","",""],"???","???"]],
+  [["PSUBUSB","","",""],"PSUBUSB","",""],
+  [["PSUBUSW","","",""],"PSUBUSW","",""],
+  [["PMINUB","","",""],"PMINUB","",""],
+  [["PAND","","",""],["PAND","PAND",["PANDD","","PANDQ"],["PANDD","","PANDQ"]],"",""],
+  [["PADDUSB","","",""],"PADDUSB","",""],
+  [["PADDUSW","","",""],"PADDUSW","",""],
+  [["PMAXUB","","",""],"PMAXUB","",""],
+  [["PANDN","","",""],["PANDN","PANDN",["PANDND","","PANDNQ"],["PANDND","","PANDNQ"]],"",""],
+  [["PAVGB","","",""],"PAVGB","",""],
+  [
+    [["PSRAW","","",""],["PSRAW","PSRAW","PSRAW",""],"",""],
+    [["PSRAW","","",""],["PSRAW","PSRAW","PSRAW",""],"",""]
+  ],
+  [["PSRAD","","",""],["PSRAD","PSRAD",["PSRAD","","PSRAQ"],""],"",""],
+  [["PAVGW","","",""],"PAVGW","",""],
+  [["PMULHUW","","",""],"PMULHUW","",""],
+  [["PMULHW","","",""],"PMULHW","",""],
+  [
+    "???",
+    ["CVTTPD2DQ","CVTTPD2DQ","CVTTPD2DQ",""],
+    ["CVTDQ2PD","CVTDQ2PD",["CVTDQ2PD","CVTDQ2PD","CVTQQ2PD"],"CVTDQ2PD"],
+    "CVTPD2DQ"
+  ],
+  [[["MOVNTQ","","",""],["MOVNTDQ","","???"],"???","???"],"???"],
+  [["PSUBSB","","",""],"PSUBSB","",""],
+  [["PSUBSW","","",""],"PSUBSW","",""],
+  [["PMINSW","","",""],"PMINSW","",""],
+  [["POR","","",""],["POR","POR",["PORD","","PORQ"],["PORD","","PORQ"]],"",""],
+  [["PADDSB","","",""],"PADDSB","",""],
+  [["PADDSW","","",""],"PADDSW","",""],
+  [["PMAXSW","","",""],"PMAXSW","",""],
+  [["PXOR","","",""],["PXOR","PXOR",["PXORD","","PXORQ"],["PXORD","","PXORQ"]],"",""],
+  [["???","???","???",["LDDQU","LDDQU","",""]],"???"],
+  [["PSLLW","","",""],"PSLLW","",""],
+  [["PSLLD","","",""],["PSLLD","","???"],"",""],
+  [["PSLLQ","","",""],"PSLLQ","",""],
+  [["PMULUDQ","","",""],"PMULUDQ","",""],
+  [["PMADDWD","","",""],"PMADDWD","",""],
+  [["PSADBW","","",""],"PSADBW","",""],
+  ["???",[["MASKMOVQ","","",""],["MASKMOVDQU","MASKMOVDQU","",""],"???","???"]],
+  [["PSUBB","","",""],"PSUBB","",""],
+  [["PSUBW","","",""],"PSUBW","",""],
+  [["PSUBD","","",""],["PSUBD","PSUBD",["PSUBD","","???"],["PSUBD","","???"]],"",""],
+  [["PSUBQ","","",""],"PSUBQ","",""],
+  [["PADDB","","",""],"PADDB","",""],
+  [["PADDW","","",""],"PADDW","",""],
+  [["PADDD","","",""],["PADDD","PADDD",["PADDD","","???"],["PADDD","","???"]],"",""],
+  "???",
+  /*------------------------------------------------------------------------------------------------------------------------
+  Three Byte operations 0F38. Opcodes plus 512 goes to 767 used by escape codes "0F,38", Or
+  set directly by adding map bits "10" because "10 00000000" bin = 512 plus opcode.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  [["PSHUFB","","",""],"PSHUFB","???","???"],
+  [["PHADDW","","",""],["PHADDW","PHADDW","",""],"???","???"],
+  [["PHADDD","","",""],["PHADDD","PHADDD","",""],"???","???"],
+  [["PHADDSW","","",""],["PHADDSW","PHADDSW","",""],"???","???"],
+  [["PMADDUBSW","","",""],"PMADDUBSW","???","???"],
+  [["PHSUBW","","",""],["PHSUBW","PHSUBW","",""],"???","???"],
+  [["PHSUBD","","",""],["PHSUBD","PHSUBD","",""],"???","???"],
+  [["PHSUBSW","","",""],["PHSUBSW","PHSUBSW","",""],"???","???"],
+  [["PSIGNB","","",""],["PSIGNB","PSIGNB","",""],"???","???"],
+  [["PSIGNW","","",""],["PSIGNW","PSIGNW","",""],"???","???"],
+  [["PSIGND","","",""],["PSIGND","PSIGND","",""],"???","???"],
+  [["PMULHRSW","","",""],"PMULHRSW","???","???"],
+  ["???",["","PERMILPS",["PERMILPS","","???"],""],"???","???"],
+  ["???",["","PERMILPD","PERMILPD",""],"???","???"],
+  ["???",["","TESTPS","",""],"???","???"],
+  ["???",["","TESTPD","",""],"???","???"],
+  ["???",["PBLENDVB","PBLENDVB","PSRLVW",""],["","","PMOVUSWB",""],"???"],
+  ["???",["","","PSRAVW",""],["","","PMOVUSDB",""],"???"],
+  ["???",["","","PSLLVW",""],["","","PMOVUSQB",""],"???"],
+  ["???",["","CVTPH2PS",["CVTPH2PS","","???"],""],["","","PMOVUSDW",""],"???"],
+  ["???",["BLENDVPS","BLENDVPS",["PRORVD","","PRORVQ"],""],["","","PMOVUSQW",""],"???"],
+  ["???",["BLENDVPD","BLENDVPD",["PROLVD","","PROLVQ"],""],["","","PMOVUSQD",""],"???"],
+  ["???",["","PERMPS",["PERMPS","","PERMPD"],""],"???","???"],
+  ["???",["PTEST","PTEST","",""],"???","???"],
+  ["???",["","BROADCASTSS",["BROADCASTSS","","???"],["BROADCASTSS","","???"]],"???","???"],
+  ["???",["","BROADCASTSD",["BROADCASTF32X2","","BROADCASTSD"],["???","","BROADCASTSD"]],"???","???"],
+  ["???",["","BROADCASTF128",["BROADCASTF32X4","","BROADCASTF64X2"],["BROADCASTF32X4","","???"]],"???","???"],
+  ["???",["","",["BROADCASTF32X8","","BROADCASTF64X4"],["???","","BROADCASTF64X4"]],"???","???"],
+  [["PABSB","","",""],"PABSB","???","???"],
+  [["PABSW","","",""],"PABSW","???","???"],
+  [["PABSD","","",""],["PABSD","","???"],"???","???"],
+  ["???",["","","PABSQ",""],"???","???"],
+  ["???","PMOVSXBW",["","","PMOVSWB",""],"???"],
+  ["???","PMOVSXBD",["","","PMOVSDB",""],"???"],
+  ["???","PMOVSXBQ",["","","PMOVSQB",""],"???"],
+  ["???","PMOVSXWD",["","","PMOVSDW",""],"???"],
+  ["???","PMOVSXWQ",["","","PMOVSQW",""],"???"],
+  ["???","PMOVSXDQ",["","","PMOVSQD",""],"???"],
+  ["???",["","",["PTESTMB","","PTESTMW"],""],["","",["PTESTNMB","","PTESTNMW"],""],"???"],
+  ["???",["","",["PTESTMD","","PTESTMQ"],["PTESTMD","","???"]],["","",["PTESTNMD","","PTESTNMQ"],""],"???"],
+  ["???","PMULDQ",["","",["PMOVM2B","","PMOVM2W"],""],"???"],
+  ["???",["PCMPEQQ","PCMPEQQ","PCMPEQQ",""],["","",["PMOVB2M","","PMOVW2M"],""],"???"],
+  [["???",["MOVNTDQA","","???"],"???","???"],["???","???",["","",["???","","PBROADCASTMB2Q"],""],"???"]],
+  ["???",["PACKUSDW","","???"],"???","???"],
+  ["???",["","MASKMOVPS",["SCALEFPS","","SCALEFPD"],""],"???","???"],
+  ["???",["","MASKMOVPD",["SCALEFSS","","SCALEFSD"],""],"???","???"],
+  ["???",["","MASKMOVPS","",""],"???","???"],
+  ["???",["","MASKMOVPD","",""],"???","???"],
+  ["???","PMOVZXBW",["","","PMOVWB",""],"???"],
+  ["???","PMOVZXBD",["","","PMOVDB",""],"???"],
+  ["???","PMOVZXBQ",["","","PMOVQB",""],"???"],
+  ["???","PMOVZXWD",["","","PMOVDW",""],"???"],
+  ["???","PMOVZXWQ",["","","PMOVQW",""],"???"],
+  ["???","PMOVZXDQ",["","",["PMOVQD","PMOVQD",""],""],"???"],
+  ["???",["","PERMD",["PERMD","","PERMQ"],["PERMD","","???"]],"???","???"],
+  ["???",["PCMPGTQ","PCMPGTQ","PCMPGTQ",""],"???","???"],
+  ["???","PMINSB",["","",["PMOVM2D","","PMOVM2Q"],""],"???"],
+  ["???",["PMINSD","PMINSD",["PMINSD","","PMINSQ"],["PMINSD","","???"]],["","",["PMOVD2M","","PMOVQ2M"],""],"???"],
+  ["???","PMINUW",["","","PBROADCASTMW2D",""],"???"],
+  ["???",["PMINUD","PMINUD",["PMINUD","","PMINUQ"],["PMINUD","","???"]],"???","???"],
+  ["???","PMAXSB","???","???"],
+  ["???",["PMAXSD","PMAXSD",["PMAXSD","","PMAXSQ"],["PMAXSD","","???"]],"???","???"],
+  ["???","PMAXUW","???","???"],
+  ["???",["PMAXUD","PMAXUD",["PMAXUD","","PMAXUQ"],["PMAXUD","","???"]],"???","???"],
+  ["???",["PMULLD","PMULLD",["PMULLD","","PMULLQ"],["PMULLD","",""]],"???","???"],
+  ["???",["PHMINPOSUW",["PHMINPOSUW","PHMINPOSUW",""],"",""],"???","???"],
+  ["???",["","",["GETEXPPS","","GETEXPPD"],["GETEXPPS","","GETEXPPD"]],"???","???"],
+  ["???",["","",["GETEXPSS","","GETEXPSD"],""],"???","???"],
+  ["???",["","",["PLZCNTD","","PLZCNTQ"],""],"???","???"],
+  ["???",["",["PSRLVD","","PSRLVQ"],["PSRLVD","","PSRLVQ"],["PSRLVD","","???"]],"???","???"],
+  ["???",["",["PSRAVD","",""],["PSRAVD","","PSRAVQ"],["PSRAVD","","???"]],"???","???"],
+  ["???",["",["PSLLVD","","PSLLVQ"],["PSLLVD","","PSLLVQ"],["PSLLVD","","???"]],"???","???"],
+  "???","???","???","???",
+  ["???",["","",["RCP14PS","","RCP14PD"],""],"???","???"],
+  ["???",["","",["RCP14SS","","RCP14SD"],""],"???","???"],
+  ["???",["","",["RSQRT14PS","","RSQRT14PD"],""],"???","???"],
+  ["???",["","",["RSQRT14SS","","RSQRT14SD"],""],"???","???"],
+  ["???",["","","",["ADDNPS","","ADDNPD"]],"???","???"],
+  ["???",["","","",["GMAXABSPS","","???"]],"???","???"],
+  ["???",["","","",["GMINPS","","GMINPD"]],"???","???"],
+  ["???",["","","",["GMAXPS","","GMAXPD"]],"???","???"],
+  "",
+  ["???",["","","",["FIXUPNANPS","","FIXUPNANPD"]],"???","???"],
+  "","",
+  ["???",["","PBROADCASTD",["PBROADCASTD","","???"],["PBROADCASTD","","???"]],"???","???"],
+  ["???",["","PBROADCASTQ",["BROADCASTI32X2","","PBROADCASTQ"],["???","","PBROADCASTQ"]],"???","???"],
+  ["???",["","BROADCASTI128",["BROADCASTI32X4","","BROADCASTI64X2"],["BROADCASTI32X4","","???"]],"???","???"],
+  ["???",["","",["BROADCASTI32X8","","BROADCASTI64X4"],["???","","BROADCASTI64X4"]],"???","???"],
+  ["???",["","","",["PADCD","","???"]],"???","???"],
+  ["???",["","","",["PADDSETCD","","???"]],"???","???"],
+  ["???",["","","",["PSBBD","","???"]],"???","???"],
+  ["???",["","","",["PSUBSETBD","","???"]],"???","???"],
+  "???","???","???","???",
+  ["???",["","",["PBLENDMD","","PBLENDMQ"],["PBLENDMD","","PBLENDMQ"]],"???","???"],
+  ["???",["","",["BLENDMPS","","BLENDMPD"],["BLENDMPS","","BLENDMPD"]],"???","???"],
+  ["???",["","",["PBLENDMB","","PBLENDMW"],""],"???","???"],
+  "???","???","???","???","???",
+  ["???",["","","",["PSUBRD","","???"]],"???","???"],
+  ["???",["","","",["SUBRPS","","SUBRPD"]],"???","???"],
+  ["???",["","","",["PSBBRD","","???"]],"???","???"],
+  ["???",["","","",["PSUBRSETBD","","???"]],"???","???"],
+  "???","???","???","???",
+  ["???",["","","",["PCMPLTD","","???"]],"???","???"],
+  ["???",["","",["PERMI2B","","PERMI2W"],""],"???","???"],
+  ["???",["","",["PERMI2D","","PERMI2Q"],""],"???","???"],
+  ["???",["","",["PERMI2PS","","PERMI2PD"],""],"???","???"],
+  ["???",["","PBROADCASTB",["PBROADCASTB","","???"],""],"???","???"],
+  ["???",["","PBROADCASTW",["PBROADCASTW","","???"],""],"???","???"],
+  ["???",["???",["","",["PBROADCASTB","","???"],""],"???","???"]],
+  ["???",["???",["","",["PBROADCASTW","","???"],""],"???","???"]],
+  ["???",["","",["PBROADCASTD","","PBROADCASTQ"],""],"???","???"],
+  ["???",["","",["PERMT2B","","PERMT2W"],""],"???","???"],
+  ["???",["","",["PERMT2D","","PERMT2Q"],""],"???","???"],
+  ["???",["","",["PERMT2PS","","PERMT2PD"],""],"???","???"],
+  [["???","INVEPT","???","???"],"???"],
+  [["???","INVVPID","???","???"],"???"],
+  [["???","INVPCID","???","???"],"???"],
+  ["???",["???","???","PMULTISHIFTQB","???"],"???","???"],
+  ["???",["","","",["SCALEPS","","???"]],"???","???"],
+  "???",
+  ["???",["","","",["PMULHUD","","???"]],"???","???"],
+  ["???",["","","",["PMULHD","","???"]],"???","???"],
+  ["???",["","",["EXPANDPS","","EXPANDPD"],""],"???","???"],
+  ["???",["","",["PEXPANDD","","PEXPANDQ"],""],"???","???"],
+  ["???",["","",["COMPRESSPS","","COMPRESSPD"],""],"???","???"],
+  ["???",["","",["PCOMPRESSD","","PCOMPRESSQ"],""],"???","???"],
+  "???",
+  ["???",["","",["PERMB","","PERMW"],""],"???","???"],
+  "???","???",
+  ["???",["",["PGATHERDD","","PGATHERDQ"],["PGATHERDD","","PGATHERDQ"],["PGATHERDD","","PGATHERDQ"]],"???","???"],
+  ["???",["",["PGATHERQD","","PGATHERQQ"],["PGATHERQD","","PGATHERQQ"],""],"???","???"],
+  ["???",["",["GATHERDPS","","GATHERDPD"],["GATHERDPS","","GATHERDPD"],["GATHERDPS","","GATHERDPD"]],"???","???"],
+  ["???",["",["GATHERQPS","","GATHERQPD"],["GATHERQPS","","GATHERQPD"],""],"???","???"],
+  "???","???",
+  ["???",["",["FMADDSUB132PS","","FMADDSUB132PD"],["FMADDSUB132PS","","FMADDSUB132PD"],""],"???","???"],
+  ["???",["",["FMSUBADD132PS","","FMSUBADD132PD"],["FMSUBADD132PS","","FMSUBADD132PD"],""],"???","???"],
+  ["???",["",["FMADD132PS","","FMADD132PD"],["FMADD132PS","","FMADD132PD"],["FMADD132PS","","FMADD132PD"]],"???","???"],
+  ["???",["",["FMADD132SS","","FMADD132SD"],["FMADD132SS","","FMADD132SD"],""],"???","???"],
+  ["???",["",["FMSUB132PS","","FMSUB132PD"],["FMSUB132PS","","FMSUB132PD"],["FMSUB132PS","","FMSUB132PD"]],"???","???"],
+  ["???",["",["FMSUB132SS","","FMSUB132SD"],["FMSUB132SS","","FMSUB132SD"],""],"???","???"],
+  ["???",["",["FNMADD132PS","","FNMADD132PD"],["FNMADD132PS","","FNMADD132PD"],["NMADD132PS","","FNMADD132PD"]],"???","???"],
+  ["???",["",["FNMADD132SS","","FNMADD132SD"],["FNMADD132SS","","FNMADD132SD"],""],"???","???"],
+  ["???",["",["FNMSUB132PS","","FNMSUB132PD"],["FNMSUB132PS","","FNMSUB132PD"],["FNMSUB132PS","","FNMSUB132PS"]],"???","???"],
+  ["???",["",["FNMSUB132SS","","FNMSUB132SD"],["FNMSUB132SS","","FNMSUB132SD"],""],"???","???"],
+  ["???",["","",["PSCATTERDD","","PSCATTERDQ"],["PSCATTERDD","","PSCATTERDQ"]],"???","???"],
+  ["???",["","",["PSCATTERQD","","PSCATTERQQ"],""],"???","???"],
+  ["???",["","",["SCATTERDPS","","SCATTERDPD"],["SCATTERDPS","","SCATTERDPD"]],"???","???"],
+  ["???",["","",["SCATTERQPS","","SCATTERQPD"],""],"???","???"],
+  ["???",["","","",["FMADD233PS","","???"]],"???","???"],
+  "???",
+  ["???",["",["FMADDSUB213PS","","FMADDSUB213PD"],["FMADDSUB213PS","","FMADDSUB213PD"],""],"???","???"],
+  ["???",["",["FMSUBADD213PS","","FMSUBADD213PD"],["FMSUBADD213PS","","FMSUBADD213PD"],""],"???","???"],
+  ["???",["",["FMADD213PS","","FMADD213PD"],["FMADD213PS","","FMADD213PD"],["FMADD213PS","","FMADD213PD"]],"???","???"],
+  ["???",["",["FMADD213SS","","FMADD213SD"],["FMADD213SS","","FMADD213SD"],""],"???","???"],
+  ["???",["",["FMSUB213PS","","FMSUB213PD"],["FMSUB213PS","","FMSUB213PD"],["FMSUB213PS","","FMSUB213PD"]],"???","???"],
+  ["???",["",["FMSUB213SS","","FMSUB213SD"],["FMSUB213SS","","FMSUB213SD"],""],"???","???"],
+  ["???",["",["FNMADD213PS","","FNMADD213PD"],["FNMADD213PS","","FNMADD213PD"],["FNMADD213PS","","FNMADD213PD"]],"???","???"],
+  ["???",["",["FNMADD213SS","","FNMADD213SD"],["FNMADD213SS","","FNMADD213SD"],""],"???","???"],
+  ["???",["",["FNMSUB213PS","","FNMSUB213PD"],["FNMSUB213PS","","FNMSUB213PD"],["FNMSUB213PS","","FNMSUB213PD"]],"???","???"],
+  ["???",["",["FNMSUB213SS","","FNMSUB213SD"],["FNMSUB213SS","","FNMSUB213SD"],""],"???","???"],
+  "???","???","???","???",
+  ["???",["","","PMADD52LUQ",["PMADD233D","","???"]],"???","???"],
+  ["???",["","","PMADD52HUQ",["PMADD231D","","???"]],"???","???"],
+  ["???",["",["FMADDSUB231PS","","FMADDSUB231PD"],["FMADDSUB231PS","","FMADDSUB231PD"],""],"???","???"],
+  ["???",["",["FMSUBADD231PS","","FMSUBADD231PD"],["FMSUBADD231PS","","FMSUBADD231PD"],""],"???","???"],
+  ["???",["",["FMADD231PS","","FMADD231PD"],["FMADD231PS","","FMADD231PD"],["FMADD231PS","","FMADD231PD"]],"???","???"],
+  ["???",["",["FMADD231SS","","FMADD231SD"],["FMADD231SS","","FMADD231SD"],""],"???","???"],
+  ["???",["",["FMSUB231PS","","FMSUB231PD"],["FMSUB231PS","","FMSUB231PD"],["FMSUB231PS","","FMSUB231PD"]],"???","???"],
+  ["???",["",["FMSUB231SS","","FMSUB231SD"],["FMSUB231SS","","FMSUB231SD"],""],"???","???"],
+  ["???",["",["FNMADD231PS","","FNMADD231PD"],["FNMADD231PS","","FNMADD231PD"],["FNMADD231PS","","FNMADD231PD"]],"???","???"],
+  ["???",["",["FNMADD231SS","","FNMADD231SD"],["FNMADD231SS","","FNMADD231SD"],""],"???","???"],
+  ["???",["",["FNMSUB231PS","","FNMSUB231PD"],["FNMSUB231PS","","FNMSUB231PD"],["FNMSUB231PS","","FNMSUB231PD"]],"???","???"],
+  ["???",["",["FNMSUB231SS","","FNMSUB231SD"],["FNMSUB231SS","","FNMSUB231SD"],""],"???","???"],
+  "???","???","???","???",
+  ["???",["","",["PCONFLICTD","","PCONFLICTQ"],""],"???","???"],
+  "???",
+  [
+    [
+      ["???",["","","",["GATHERPF0HINTDPS","","GATHERPF0HINTDPD"]],"???","???"],
+      ["???",["","",["GATHERPF0DPS","","GATHERPF0DPD"],["GATHERPF0DPS","",""]],"???","???"],
+      ["???",["","",["GATHERPF1DPS","","GATHERPF1DPD"],["GATHERPF1DPS","",""]],"???","???"],
+      "???",
+      ["???",["","","",["SCATTERPF0HINTDPS","","SCATTERPF0HINTDPD"]],"???","???"],
+      ["???",["","",["SCATTERPF0DPS","","SCATTERPF0DPD"],["VSCATTERPF0DPS","",""]],"???","???"],
+      ["???",["","",["SCATTERPF1DPS","","SCATTERPF1DPD"],["VSCATTERPF1DPS","",""]],"???","???"],
+      "???"
+    ],"???"
+  ],
+  [
+    [
+      "???",
+      ["???",["","",["GATHERPF0QPS","","GATHERPF0QPD"],""],"???","???"],
+      ["???",["","",["GATHERPF1QPS","","GATHERPF1QPD"],""],"???","???"],
+      "???","???",
+      ["???",["","",["SCATTERPF0QPS","","SCATTERPF0QPD"],""],"???","???"],
+      ["???",["","",["SCATTERPF1QPS","","SCATTERPF1QPD"],""],"???","???"],
+      "???"
+    ],"???"
+  ],
+  [["SHA1NEXTE","","",""],["","",["EXP2PS","","EXP2PD"],["EXP223PS","","???"]],"???","???"],
+  [["SHA1MSG1","","",""],["","","",["LOG2PS","","???"]],"???","???"],
+  [["SHA1MSG2","","",""],["","",["RCP28PS","","RCP28PD"],["RCP23PS","","???"]],"???","???"],
+  [["SHA256RNDS2","","",""],["","",["RCP28SS","","RCP28SD"],["RSQRT23PS","","???"]],"???","???"],
+  [["SHA256MSG1","","",""],["","",["RSQRT28PS","","RSQRT28PD"],["ADDSETSPS","","???"]],"???","???"],
+  [["SHA256MSG2","","",""],["","",["RSQRT28SS","","RSQRT28SD"],["PADDSETSD","","???"]],"???","???"],
+  "???","???",
+  [[["","","",["LOADUNPACKLD","","LOADUNPACKLQ"]],["","","",["PACKSTORELD","","PACKSTORELQ"]],"???","???"],"???"],
+  [[["","","",["LOADUNPACKLPS","","LOADUNPACKLPD"]],["","","",["PACKSTORELPS","","PACKSTORELPD"]],"???","???"],"???"],
+  "???","???",
+  [[["","","",["LOADUNPACKHD","","LOADUNPACKHQ"]],["","","",["PACKSTOREHD","","PACKSTOREHQ"]],"???","???"],"???"],
+  [[["","","",["LOADUNPACKHPS","","LOADUNPACKHPD"]],["","","",["PACKSTOREHPS","","PACKSTOREHPD"]],"???","???"],"???"],
+  "???","???","???","???","???",
+  ["???",["AESIMC","AESIMC","",""],"???","???"],
+  ["???",["AESENC","AESENC","",""],"???","???"],
+  ["???",["AESENCLAST","AESENCLAST","",""],"???","???"],
+  ["???",["AESDEC","AESDEC","",""],"???","???"],
+  ["???",["AESDECLAST","AESDECLAST","",""],"???","???"],
+  "???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???",
+  [
+    ["MOVBE","","",""],
+    ["MOVBE","","",""],"???",
+    ["CRC32","","",""]
+  ],
+  [
+    ["MOVBE","","",""],
+    ["MOVBE","","",""],"???",
+    ["CRC32","","",""]
+  ],
+  ["???",["","ANDN","",""],"???","???"],
+  [
+    "???",
+    ["???",["","BLSR","",""],"???","???"],
+    ["???",["","BLSMSK","",""],"???","???"],
+    ["???",["","BLSI","",""],"???","???"],
+    "???","???","???","???"
+  ],"???",
+  [
+    ["","BZHI","",""],"???",
+    ["","PEXT","",""],
+    ["","PDEP","",""]
+  ],
+  [
+    "???",
+    ["ADCX","","",""],
+    ["ADOX","","",""],
+    ["","MULX","",""]
+  ],
+  [
+    ["","BEXTR","",""],
+    ["","SHLX","",""],
+    ["","SARX","",""],
+    ["","SHRX","",""]
+  ],
+  "???","???","???","???","???","???","???","???",
+  /*------------------------------------------------------------------------------------------------------------------------
+  Three Byte operations 0F38. Opcodes plus 768 goes to 767 used by escape codes "0F, 3A", Or
+  set directly by adding map bits "11" because "11 00000000" bin = 768 plus opcode.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  ["???",["","PERMQ","PERMQ",""],"???","???"],
+  ["???",["","PERMPD","PERMPD",""],"???","???"],
+  ["???",["",["PBLENDD","",""],"",""],"???","???"],
+  ["???",["","",["ALIGND","","ALIGNQ"],["ALIGND","","???"]],"???","???"],
+  ["???",["","PERMILPS",["PERMILPS","","???"],""],"???","???"],
+  ["???",["","PERMILPD","PERMILPD",""],"???","???"],
+  ["???",["","PERM2F128","",""],"???","???"],
+  ["???",["","","",["PERMF32X4","","???"]],"???","???"],
+  ["???",["ROUNDPS","ROUNDPS",["RNDSCALEPS","","???"],""],"???","???"],
+  ["???",["ROUNDPD","ROUNDPD","RNDSCALEPD",""],"???","???"],
+  ["???",["ROUNDSS","ROUNDSS",["RNDSCALESS","","???"],""],"???","???"],
+  ["???",["ROUNDSD","ROUNDSD","RNDSCALESD",""],"???","???"],
+  ["???",["BLENDPS","BLENDPS","",""],"???","???"],
+  ["???",["BLENDPD","BLENDPD","",""],"???","???"],
+  ["???",["PBLENDW","PBLENDW","",""],"???","???"],
+  [["PALIGNR","","",""],"PALIGNR","???","???"],
+  "???","???","???","???",
+  [["???","PEXTRB","???","???"],["???","PEXTRB","???","???"]],
+  [["???","PEXTRW","???","???"],["???","PEXTRW","???","???"]],
+  ["???",["PEXTRD","","PEXTRQ"],"???","???"],
+  ["???","EXTRACTPS","???","???"],
+  ["???",["","INSERTF128",["INSERTF32X4","","INSERTF64X2"],""],"???","???"],
+  ["???",["","EXTRACTF128",["EXTRACTF32X4","","EXTRACTF64X2"],""],"???","???"],
+  ["???",["","",["INSERTF32X8","","INSERTF64X4"],""],"???","???"],
+  ["???",["","",["EXTRACTF32X8","","EXTRACTF64X4"],""],"???","???"],
+  "???",
+  ["???",["","CVTPS2PH",["CVTPS2PH","","???"],""],"???","???"],
+  ["???",["","",["PCMP,UD,","","PCMP,UQ,"],["PCMP,UD,","","???"]],"???","???"],
+  ["???",["","",["PCM,PD,","","PCM,PQ,"],["PCM,PD,","","???"]],"???","???"],
+  ["???","PINSRB","???","???"],
+  ["???",["INSERTPS","","???"],"???","???"],
+  ["???",["",["PINSRD","","PINSRQ"],["PINSRD","","PINSRQ"],""],"???","???"],
+  ["???",["","",["SHUFF32X4","","SHUFF64X2"],""],"???","???"],
+  "???",
+  ["???",["","",["PTERNLOGD","","PTERNLOGQ"],""],"???","???"],
+  ["???",["","",["GETMANTPS","","GETMANTPD"],["GETMANTPS","","GETMANTPD"]],"???","???"],
+  ["???",["","",["GETMANTSS","","GETMANTSD"],""],"???","???"],
+  "???","???","???","???","???","???","???","???",
+  ["???",["",["KSHIFTRB","","KSHIFTRW"],"",""],"???","???"],
+  ["???",["",["KSHIFTRD","","KSHIFTRQ"],"",""],"???","???"],
+  ["???",["",["KSHIFTLB","","KSHIFTLW"],"",""],"???","???"],
+  ["???",["",["KSHIFTLD","","KSHIFTLQ"],"",""],"???","???"],
+  "???","???","???","???",
+  ["???",["","INSERTI128",["INSERTI32X4","","INSERTI64X2"],""],"???","???"],
+  ["???",["","EXTRACTI128",["EXTRACTI32X4","","EXTRACTI64X2"],""],"???","???"],
+  ["???",["","",["INSERTI32X8","","INSERTI64X4"],""],"???","???"],
+  ["???",["","",["EXTRACTI32X8","","EXTRACTI64X4"],""],"???","???"],
+  "???","???",
+  ["???",["","KEXTRACT",["PCMP,UB,","","PCMP,UW,"],""],"???","???"],
+  ["???",["","",["PCM,PB,","","PCM,PW,"],""],"???","???"],
+  ["???",["DPPS","DPPS","",""],"???","???"],
+  ["???",["DPPD","DPPD","",""],"???","???"],
+  ["???",["MPSADBW","MPSADBW",["DBPSADBW","","???"],""],"???","???"],
+  ["???",["","",["SHUFI32X4","","SHUFI64X2"],""],"???","???"],
+  ["???",["PCLMULQDQ","PCLMULQDQ","",""],"???","???"],
+  "???",
+  ["???",["","PERM2I128","",""],"???","???"],
+  "???",
+  ["???",["",["PERMIL2PS","","PERMIL2PS"],"",""],"???","???"],
+  ["???",["",["PERMIL2PD","","PERMIL2PD"],"",""],"???","???"],
+  ["???",["","BLENDVPS","",""],"???","???"],
+  ["???",["","BLENDVPD","",""],"???","???"],
+  ["???",["","PBLENDVB","",""],"???","???"],
+  "???","???","???",
+  ["???",["","",["RANGEPS","","RANGEPD"],""],"???","???"],
+  ["???",["","",["RANGESS","","RANGESD"],""],"???","???"],
+  ["???",["","","",["RNDFXPNTPS","","RNDFXPNTPD"]],"???","???"],
+  "???",
+  ["???",["","",["FIXUPIMMPS","","FIXUPIMMPD"],""],"???","???"],
+  ["???",["","",["FIXUPIMMSS","","FIXUPIMMSD"],""],"???","???"],
+  ["???",["","",["REDUCEPS","","REDUCEPD"],""],"???","???"],
+  ["???",["","",["REDUCESS","","REDUCESD"],""],"???","???"],
+  "???","???","???","???",
+  ["???",["",["FMADDSUBPS","","FMADDSUBPS"],"",""],"???","???"],
+  ["???",["",["FMADDSUBPD","","FMADDSUBPD"],"",""],"???","???"],
+  ["???",["",["FMSUBADDPS","","FMSUBADDPS"],"",""],"???","???"],
+  ["???",["",["FMSUBADDPD","","FMSUBADDPD"],"",""],"???","???"],
+  ["???",["PCMPESTRM","PCMPESTRM","",""],"???","???"],
+  ["???",["PCMPESTRI","PCMPESTRI","",""],"???","???"],
+  ["???",["PCMPISTRM","PCMPISTRM","",""],"???","???"],
+  ["???",["PCMPISTRI","PCMPISTRI","",""],"???","???"],
+  "???","???",
+  ["???",["","",["FPCLASSPS","","FPCLASSPD"],""],"???","???"],
+  ["???",["","",["FPCLASSSS","","FPCLASSSD"],""],"???","???"],
+  ["???",["",["FMADDPS","","FMADDPS"],"",""],"???","???"],
+  ["???",["",["FMADDPD","","FMADDPD"],"",""],"???","???"],
+  ["???",["",["FMADDSS","","FMADDSS"],"",""],"???","???"],
+  ["???",["",["FMADDSD","","FMADDSD"],"",""],"???","???"],
+  ["???",["",["FMSUBPS","","FMSUBPS"],"",""],"???","???"],
+  ["???",["",["FMSUBPD","","FMSUBPD"],"",""],"???","???"],
+  ["???",["",["FMSUBSS","","FMSUBSS"],"",""],"???","???"],
+  ["???",["",["FMSUBSD","","FMSUBSD"],"",""],"???","???"],
+  "???","???","???","???","???","???","???","???",
+  ["???",["",["FNMADDPS","","FNMADDPS"],"",""],"???","???"],
+  ["???",["",["FNMADDPD","","FNMADDPD"],"",""],"???","???"],
+  ["???",["",["FNMADDSS","","FNMADDSS"],"",""],"???","???"],
+  ["???",["",["FNMADDSD","","FNMADDSD"],"",""],"???","???"],
+  ["???",["",["FNMSUBPS","","FNMSUBPS"],"",""],"???","???"],
+  ["???",["",["FNMSUBPD","","FNMSUBPD"],"",""],"???","???"],
+  ["???",["",["FNMSUBSS","","FNMSUBSS"],"",""],"???","???"],
+  ["???",["",["FNMSUBSD","","FNMSUBSD"],"",""],"???","???"],
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???",
+  [["","","","CVTFXPNTUDQ2PS"],["","","",["CVTFXPNTPS2UDQ","","???"]],"???",["","","","CVTFXPNTPD2UDQ"]],
+  [["","","","CVTFXPNTDQ2PS"],["","","",["CVTFXPNTPS2DQ","","???"]],"???","???"],
+  "SHA1RNDS4",
+  "???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  ["???",["AESKEYGENASSIST","AESKEYGENASSIST","",""],"???","???"],
+  "???","???","???","???","???","???",
+  ["???","???","???",["","","","CVTFXPNTPD2DQ"]],
+  "???","???","???","???","???","???","???","???","???",
+  ["???","???","???",["","RORX","",""]],
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  /*------------------------------------------------------------------------------------------------------------------------
+  AMD XOP 8.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "VPMACSSWW","VPMACSSWD","VPMACSSDQL","???","???","???","???","???","???",
+  "VPMACSSDD","VPMACSSDQH","???","???","???","???","???","VPMACSWW","VPMACSWD","VPMACSDQL",
+  "???","???","???","???","???","???","VPMACSDD","VPMACSDQH",
+  "???","???",["VPCMOV","","VPCMOV"],["VPPERM","","VPPERM"],"???","???","VPMADCSSWD",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "VPMADCSWD","???","???","???","???","???","???","???","???","???",
+  "VPROTB","VPROTW","VPROTD","VPROTQ","???","???","???","???","???","???","???","???",
+  "VPCOM,B,","VPCOM,W,","VPCOM,D,","VPCOM,Q,","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "VPCOM,UB,","VPCOM,UW,","VPCOM,UD,","VPCOM,UQ,",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  /*------------------------------------------------------------------------------------------------------------------------
+  AMD XOP 9.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "???",
+  ["???","BLCFILL","BLSFILL","BLCS","TZMSK","BLCIC","BLSIC","T1MSKC"],["???","BLCMSK","???","???","???","???","BLCI","???"],
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  ["???",["LLWPCB","SLWPCB","???","???","???","???","???","???"]],
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "VFRCZPS","VFRCZPD","VFRCZSS","VFRCZSD","???","???","???","???","???","???","???","???","???","???","???","???",
+  ["VPROTB","","VPROTB"],["VPROTW","","VPROTW"],["VPROTD","","VPROTD"],["VPROTQ","","VPROTQ"],
+  ["VPSHLB","","VPSHLB"],["VPSHLW","","VPSHLW"],["VPSHLD","","VPSHLD"],["VPSHLQ","","VPSHLQ"],
+  ["VPSHAB","","VPSHAB"],["VPSHAW","","VPSHAW"],["VPSHAD","","VPSHAD"],["VPSHAQ","","VPSHAQ"],
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "VPHADDBW","VPHADDBD","VPHADDBQ","???","???","VPHADDWD","VPHADDWQ","???","???","???","VPHADDDQ","???","???","???","???","???",
+  "VPHADDUBWD","VPHADDUBD","VPHADDUBQ","???","???","VPHADDUWD","VPHADDUWQ","???","???","???","VPHADDUDQ","???","???","???","???","???",
+  "VPHSUBBW","VPHSUBWD","VPHSUBDQ","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  /*------------------------------------------------------------------------------------------------------------------------
+  AMD XOP A.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "BEXTR","???",["LWPINS","LWPVAL","???","???","???","???","???","???"],
+  "???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  L1OM Vector.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  "???","???","???","???","DELAY","???","???","???","???","???","???","???","???","???","???","???",
+  [["VLOADD","VLOADQ","",""],"???"],"???",
+  [["VLOADUNPACKLD","VLOADUNPACKLQ","",""],"???"],
+  [["VLOADUNPACKHD","VLOADUNPACKHQ","",""],"???"],
+  [["VSTORED","VSTOREQ","",""],"???"],"???",
+  [["VPACKSTORELD","VPACKSTORELQ","",""],"???"],
+  [["VPACKSTOREHD","VPACKSTOREHQ","",""],"???"],
+  ["VGATHERD","???"],["VGATHERPFD","???"],"???",["VGATHERPF2D","???"],
+  ["VSCATTERD","???"],["VSCATTERPFD","???"],"???",["VSCATTERPF2D","???"],
+  ["VCMP,PS,","VCMP,PD,","",""],"VCMP,PI,","VCMP,PU,","???",
+  ["VCMP,PS,","VCMP,PD,","",""],"VCMP,PI,","VCMP,PU,","???",
+  "???","???","???","???","???","???","???","???",
+  "VTESTPI","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  ["VADDPS","VADDPD","",""],"VADDPI","???","VADDSETCPI","???","VADCPI","VADDSETSPS","VADDSETSPI",
+  ["VADDNPS","VADDNPD","",""],"???","???","???","???","???","???","???",
+  ["VSUBPS","VSUBPD","",""],"VSUBPI","???","VSUBSETBPI","???","VSBBPI","???","???",
+  ["VSUBRPS","VSUBRPD","",""],"VSUBRPI","???","VSUBRSETBPI","???","VSBBRPI","???","???",
+  ["VMADD231PS","VMADD231PD","",""],"VMADD231PI",
+  ["VMADD213PS","VMADD213PD","",""],"???",
+  ["VMADD132PS","VMADD132PD","",""],"???",
+  "VMADD233PS","VMADD233PI",
+  ["VMSUB231PS","VMSUB231PD","",""],"???",
+  ["VMSUB213PS","VMSUB213PD","",""],"???",
+  ["VMSUB132PS","VMSUB132PD","",""],"???","???","???",
+  ["VMADDN231PS","VMADDN231PD","",""],"???",
+  ["VMADDN213PS","VMADDN213PD","",""],"???",
+  ["VMADDN132PS","VMADDN132PD","",""],"???","???","???",
+  ["VMSUBR231PS","VMSUBR231PD","",""],"???",
+  ["VMSUBR213PS","VMSUBR213PD","",""],"???",
+  ["VMSUBR132PS","VMSUBR132PD","",""],"???",
+  ["VMSUBR23C1PS","VMSUBR23C1PD","",""],"???",
+  ["VMULPS","VMULPD","",""],"VMULHPI","VMULHPU","VMULLPI","???","???","VCLAMPZPS","VCLAMPZPI",
+  ["VMAXPS","VMAXPD","",""],"VMAXPI","VMAXPU","???",
+  ["VMINPS","VMINPD","",""],"VMINPI","VMINPU","???",
+  ["???","VCVT,PD2PS,","",""],["VCVTPS2PI","VCVT,PD2PI,","",""],["VCVTPS2PU","VCVT,PD2PU,","",""],"???",
+  ["???","VCVT,PS2PD,","",""],["VCVTPI2PS","VCVT,PI2PD,","",""],["VCVTPU2PS","VCVT,PU2PD,","",""],"???",
+  "VROUNDPS","???","VCVTINSPS2U10","VCVTINSPS2F11","???","VCVTPS2SRGB8","VMAXABSPS","???",
+  "VSLLPI","VSRAPI","VSRLPI","???",
+  ["VANDNPI","VANDNPQ","",""],["VANDPI","VANDPQ","",""],
+  ["VORPI","VORPQ","",""],["VXORPI","VXORPQ","",""],
+  "VBINTINTERLEAVE11PI","VBINTINTERLEAVE21PI","???","???","???","???","???","???",
+  "VEXP2LUTPS","VLOG2LUTPS","VRSQRTLUTPS","???","VGETEXPPS","???","???","???",
+  "VSCALEPS","???","???","???","???","???","???","???",
+  "VRCPRESPS","???","VRCPREFINEPS","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "???","???","???","???","???","???","???","???","???","???","???","???","???","???","???","???",
+  "VFIXUPPS","VSHUF128X32","VINSERTFIELDPI","VROTATEFIELDPI","???","???","???","???",
+  "???","???","???","???","???","???","???","???",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  L1OM Mask, Mem, and bit opcodes.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  ["???","BSFI"],["???","BSFI"],["???","BSFI"],["???","BSFI"],
+  ["???","BSRI"],["???","BSRI"],["???","BSRI"],["???","BSRI"],
+  ["???","BSFF"],["???","BSFF"],["???","BSFF"],["???","BSFF"],
+  ["???","BSRF"],["???","BSRF"],["???","BSRF"],["???","BSRF"],
+  ["???","BITINTERLEAVE11"],["???","BITINTERLEAVE11"],["???","BITINTERLEAVE11"],["???","BITINTERLEAVE11"],
+  ["???","BITINTERLEAVE21"],["???","BITINTERLEAVE21"],["???","BITINTERLEAVE21"],["???","BITINTERLEAVE21"],
+  ["???","INSERTFIELD"],["???","INSERTFIELD"],["???","INSERTFIELD"],["???","INSERTFIELD"],
+  ["???","ROTATEFIELD"],["???","ROTATEFIELD"],["???","ROTATEFIELD"],["???","ROTATEFIELD"],
+  ["???","COUNTBITS"],["???","COUNTBITS"],["???","COUNTBITS"],["???","COUNTBITS"],
+  ["???","QUADMASK16"],["???","QUADMASK16"],["???","QUADMASK16"],["???","QUADMASK16"],
+  "???","???","???","???",
+  "VKMOVLHB",
+  [["CLEVICT1","CLEVICT2","LDVXCSR","STVXCSR","???","???","???","???"],"???"],
+  [["VPREFETCH1","VPREFETCH2","???","???","???","???","???","???"],"???"],
+  [["VPREFETCH1","VPREFETCH2","???","???","???","???","???","???"],"???"],
+  "VKMOV","VKMOV","VKMOV","VKMOV",
+  "VKNOT","VKANDNR","VKANDN","VKAND",
+  "VKXNOR","VKXOR","VKORTEST","VKOR",
+  "???","VKSWAPB",
+  ["???",["DELAY","SPFLT","???","???","???","???","???","???"]],
+  ["???",["DELAY","SPFLT","???","???","???","???","???","???"]]
+];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The Operand type array each operation code can use different operands that must be decoded after the select Opcode.
+Basically some instruction may use the ModR/M talked about above while some may use an Immediate, or Both.
+An Immediate input uses the byte after the opcode as a number some instructions combine a number and an ModR/M address selection
+By using two bytes for each encoding after the opcode. X86 uses very few operand types for input selections to instructions, but
+there are many useful combinations. The order the operands are "displayed" is the order they are in the Operands string for the
+operation code.
+---------------------------------------------------------------------------------------------------------------------------
+The first 2 digits is the selected operand type, and for if the operand can change size. Again more opcodes where sacrificed
+to make this an setting Opcode "66" goes 16 bit this is explained in detail in the SizeAttrSelect variable section that is
+adjusted by the function ^DecodePrefixAdjustments()^. The Variable SizeAttrSelect effects all operand formats that are decoded by
+different functions except for single size. Don't forget X86 uses very few operand types in which different prefix adjustments
+are used to add extra functionality to each operand type. The next two numbers is the operands size settings.
+If the operand number is set to the operand version that can not change size then the next two numbers act as a single size for
+faster decoding. Single size is also used to select numbers that are higher than the max size to select special registers that
+are used by some instructions like Debug Registers.
+---------------------------------------------------------------------------------------------------------------------------
+Registers have 8, 16, 32, 64, 128, 256, 512 names. The selected ModR/M address location uses a pointer name that shows it's select
+size then it's location in left, and right brackets like "QWORD PTR[Address]". The pointer name changes by sizes 8, 16, 64, 128, 256, 512.
+---------------------------------------------------------------------------------------------------------------------------
+Used by function ^DecodeOpcode()^ after ^DecodePrefixAdjustments()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+const Operands = [
+  //------------------------------------------------------------------------------------------------------------------------
+  //First Byte operations.
+  //------------------------------------------------------------------------------------------------------------------------
+  "06000A000003","070E0B0E0003","0A0006000003","0B0E070E0003","16000C000003","170E0DE60003","","",
+  "06000A000003","070E0B0E0003","0A0006000003","0B0E070E0003","16000C000003","170E0DE60003","","",
+  "06000A000003","070E0B0E0003","0A0006000003","0B0E070E0003","16000C000003","170E0DE60003","","",
+  "06000A000003","070E0B0E0003","0A0006000003","0B0E070E0003","16000C000003","170E0DE60003","","",
+  "06000A000003","070E0B0E0003","0A0006000003","0B0E070E0003","16000C000003","170E0DE60003","","",
+  "06000A000003","070E0B0E0003","0A0006000003","0B0E070E0003","16000C000003","170E0DE60003","","",
+  "06000A000003","070E0B0E0003","0A0006000003","0B0E070E0003","16000C000003","170E0DE60003","","",
+  "06000A00","070E0B0E","0A000600","0B0E070E","16000C00","170E0DE6","","",
+  "03060003","03060003","03060003","03060003","03060003","03060003","03060003","03060003",
+  "03060003","03060003","03060003","03060003","03060003","03060003","03060003","03060003",
+  "030A","030A","030A","030A","030A","030A","030A","030A",
+  "030A","030A","030A","030A","030A","030A","030A","030A",
+  ["","",""],["","",""],
+  ["0A020606","0A010604",""],
+  "0B0E0704",
+  "","","","",
+  "0DE6","0B0E070E0DE6",
+  "0DA1","0B0E070E0DE1",
+  "22001A01","230E1A01","1A012000","1A01210E",
+  "10000002000C","10000002000C","10000002000C","10000002000C","10000002000C","10000002000C","10000002000C","10000002000C",
+  "10000002000C","10000002000C","10000002000C","10000002000C","10000002000C","10000002000C","10000002000C","10000002000C",
+  ["06000C000003","06000C000003","06000C000003","06000C000003","06000C000003","06000C000003","06000C000003","06000C00"],
+  ["070E0DE60003","070E0DE60003","070E0DE60003","070E0DE60003","070E0DE60003","070E0DE60003","070E0DE60003","070E0DE6"],
+  ["06000C000003","06000C000003","06000C000003","06000C000003","06000C000003","06000C000003","06000C000003","06000C00"],
+  ["070E0DE10003","070E0DE10003","070E0DE10003","070E0DE10003","070E0DE10003","070E0DE10003","070E0DE10003","070E0DE1"],
+  "06000A00","070E0B0E",
+  "0A0006000003","0B0E070E0003",
+  "06000A000001","070E0B0E0001",
+  "0A0006000001","0B0E070E0001",
+  "06020A080001",
+  ["0B0E0601",""],
+  "0A0806020001",
+  ["070A","","","","","","",""],
+  [["","","",""],["","","",""],["","","",""],["","","",""]],
+  "170E030E0003","170E030E0003","170E030E0003","170E030E0003","170E030E0003","170E030E0003","170E030E0003",
+  ["","",""],["","",""],
+  "0D060C01", //CALL Ap (w:z).
+  "",
+  ["","",""],["","",""],
+  "","",
+  "160004000001","170E050E0001",
+  "040016000001","050E170E0001",
+  "22002000","230E210E",
+  "22002000","230E210E",
+  "16000C00","170E0DE6",
+  "22001600","230E170E","16002000","170E210E","16002200","170E230E",
+  "02000C000001","02000C000001","02000C000001","02000C000001","02000C000001","02000C000001","02000C000001","02000C000001",
+  "030E0D0E0001","030E0D0E0001","030E0D0E0001","030E0D0E0001","030E0D0E0001","030E0D0E0001","030E0D0E0001","030E0D0E0001",
+  ["06000C00","06000C00","06000C00","06000C00","06000C00","06000C00","06000C00","06000C00"],
+  ["070E0C00","070E0C00","070E0C00","070E0C00","070E0C00","070E0C00","070E0C00","070E0C00"],
+  "0C010008","0008",
+  "0B060906","0B060906",
+  [
+    "06000C000001","","","","","","",
+    ["0C00","0C00","0C00","0C00","0C00","0C00","0C00","0C00"]
+  ],
+  [
+    "070E0D060001","","","","","","",
+    ["1002","1002","1002","1002","1002","1002","1002","1002"]
+  ],
+  "0C010C00","",
+  "0C01","","2C00",
+  "0C00","",
+  ["","",""],
+  ["06002A00","06002A00","06002A00","06002A00","06002A00","06002A00","06002A00","06002A00"],
+  ["070E2A00","070E2A00","070E2A00","070E2A00","070E2A00","070E2A00","070E2A00","070E2A00"],
+  ["06001800","06001800","06001800","06001800","06001800","06001800","06001800","06001800"],
+  ["070E1800","070E1800","070E1800","070E1800","070E1800","070E1800","070E1800","070E1800"],
+  "0C00","0C00","",
+  "1E00",
+  /*------------------------------------------------------------------------------------------------------------------------
+  X87 FPU.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  [
+    ["0604","0604","0604","0604","0604","0604","0604","0604"],
+    ["24080609","24080609","0609","0609","24080609","24080609","24080609","24080609"]
+  ],
+  [
+    ["0604","","0604","0604","0601","0602","0601","0602"],
+    [
+      "0609","0609",
+      ["","","","","","","",""],
+      "0609",
+      ["","","","","","","",""],
+      ["","","","","","","",""],
+      ["","","","","","","",""],
+      ["","","","","","","",""]
+    ]
+  ],
+  [
+    ["0604","0604","0604","0604","0604","0604","0604","0604"],
+    [
+      "24080609","24080609","24080609","24080609","",
+      ["","","","","","","",""],"",""
+    ]
+  ],
+  [
+    ["0604","0604","0604","0604","","0607","","0607",""],
+    [
+      "24080609","24080609","24080609","24080609",
+      ["","","","","","","",""],
+      "24080609","24080609",""
+    ]
+  ],
+  [
+    ["0606","0606","0606","0606","0606","0606","0606","0606"],
+    ["06092408","06092408","0609","0609","06092408","06092408","06092408","06092408"]
+  ],
+  [
+    ["0606","0606","0606","0606","0606","","0601","0602"],
+    ["0609","0609","0609","0609","0609","0609","",""]
+  ],
+  [
+    ["0602","0602","0602","0602","0602","0602","0602","0602"],
+    [
+      "06092408","06092408","0609",
+      ["","","","","","","",""],
+      "06092408","06092408","06092408","06092408"
+    ]
+  ],
+  [
+    ["0602","0602","0602","0602","0607","0606","0607","0606"],
+    [
+      "0609","0609","0609","0609",
+      ["1601","","","","","","",""],
+      "24080609","24080609",
+      ""
+    ]
+  ],
+  /*------------------------------------------------------------------------------------------------------------------------
+  End of X87 FPU.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "10000004","10000004","10000004","10000004",
+  "16000C00","170E0C00","0C001600","0C00170E",
+  "10020008",
+  "10020008",
+  "0D060C01", //JMP Ap (w:z).
+  "100000040004",
+  "16001A01","170E1A01",
+  "1A011600","1A01170E",
+  "","","","","","",
+  ["06000C00","","06000003","06000003","16000600","0600","16000600","0600"],
+  ["070E0D06","","070E0003","070E0003","170E070E","070E","170E070E","170E070E"],
+  "","","","","","",
+  ["06000003","06000003","","","","","",""],
+  [
+    ["070E0003","070E0003","070A0004","090E0008","070A0008","090E0008","070A",""],
+    ["070E0003","070E0003","070A0008","","070A0008","","070A",""]
+  ],
+  /*------------------------------------------------------------------------------------------------------------------------
+  Two Byte operations.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  [
+    ["0602","0602","0602","0602","0602","0602","070E",""],
+    ["070E","070E","0601","0601","0601","0601","070E",""]
+  ],
+  [
+    ["0908","0908","0908","0908","0602","","0602","0601"],
+    [
+      ["","","","","","","",""],
+      ["170819081B08","17081908","","","","","",""],
+      ["","","","","","","",""],
+      ["1708","","1708","1708","","","1602","17081802"],
+      "070E","","0601",
+      ["","","170819081B08","170819081B08","","","",""]
+    ]
+  ],
+  ["0B0E0612","0B0E070E"],["0B0E0612","0B0E070E"],"",
+  "","","","",
+  "","","","",
+  [["0601","0601","","","","","",""],""],
+  "",
+  "0A0A06A9", //3DNow takes ModR/M, IMM8.
+  [
+    ["0B700770","0B700770","0A040603","0A040609"],
+    ["0B700770","0B700770","0A0412040604","0A0412040604"]
+  ],
+  [
+    ["07700B70","07700B70","06030A04","06090A04"],
+    ["07700B70","07700B70","060412040A04","060412040A04"]
+  ],
+  [
+    ["0A0412040606","0A0412040606","0B700770","0B700768"],
+    ["0A0412040604","","0B700770","0B700770"]
+  ],
+  [["06060A04","06060A04","",""],""],
+  ["0B70137007700140","0B70137007700140","",""],
+  ["0B70137007700140","0B70137007700140","",""],
+  [["0A0412040606","0A0412040606","0B700770",""],["0A0412040604","","0B700770",""]],
+  [["06060A04","06060A04","",""],""],
+  [["0601","0601","0601","0601","","","",""],""],
+  "",
+  [[["0A0B07080180","","",""],["0A0B07100180","","",""],["0A0B07080180","","",""],["0A0B07080180","","",""]],
+  ["",["0A0B060B","","",""],["0A0B07080180","","",""],["0A0B07080180","","",""]]],
+  [[["07080A0B0180","","",""],["07100A0B0180","","",""],["0A0B07080180","","",""],["0A0B07080180","","",""]],
+  ["",["0A0B060B","","",""],"",["0A0B07080180","","",""]]],
+  "","","",
+  "070E",
+  ["","07080A0C0001"],["","07080A0D0001"],
+  ["","0A0C07080001"],["","0A0D07080001"],
+  ["","07080A0E0001"],"",
+  ["","0A0E07080001"],"",
+  [
+    ["0A040648","0B300730","0B700770","0A06066C0130"],
+    ["0A040648","0B300730","0B700770","0A06066C0130"],
+    "",""
+  ],
+  [
+    [
+      ["06480A04","07300B30","07700B70","066C0A060130"],
+      ["06480A04","07300B30","07700B70","066C0A060130"],
+      ["","","",["066C0A060138","066C0A060138","066C0A060138"]],
+      ["","","",["066C0A060138","066C0A060138","066C0A060138"]]
+    ],
+    [
+      ["06480A04","07300B30","07700B70","066C0A06"],
+      ["06480A04","07300B30","07700B70","066C0A06"],
+      "",""
+    ]
+  ],
+  [
+    ["0A0406A9","","",""],["0A0406A9","","",""], //Not Allowed to be Vector encoded.
+    "0A041204070C010A","0A041204070C010A"
+  ],
+  [
+    [
+      "07700B70","07700B70",
+      ["06030A04","","",""],["06060A04","","",""] //SSE4a can not be vector encoded.
+    ],""
+  ],
+  [
+    ["0A0A0649","","",""],["0A0A0648","","",""], //Not allowed to be Vector encoded.
+    "0B0C06430109","0B0C06490109"
+  ],
+  [
+    ["0A0A0649","","",""],["0A0A0648","","",""], //Not allowed to be vector encoded.
+    "0B0C0643010A","0B0C0649010A"
+  ],
+  ["0A0406430101","0A0406490101","",""],
+  ["0A0406430101","0A0406490101","",""],
+  "","","","",
+  "","","",
+  "",
+  "",//Three byte opcodes 0F38
+  "",
+  "",//Three byte opcodes 0F3A
+  "","","","","",
+  "0B0E070E",
+  [
+    ["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],
+    ["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],"",""
+  ],
+  [
+    ["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],
+    ["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],"",""
+  ],
+  [["0B0E070E0180","0A0F06FF","",""],"","",""],
+  [
+    ["0B0E070E0180",["0A0F06FF","","0A0F06FF"],"",""],
+    ["0B0E070E0180",["0A0F06FF","","0A0F06FF"],"",""],"",""
+  ],
+  [
+    ["0A02070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],
+    ["0A02070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],"",""
+  ],
+  [
+    ["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],
+    ["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],"",""
+  ],
+  [
+    ["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],
+    ["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],"",""
+  ],
+  [["0B0E070E0180","0A0F06FF","",""],"","",""],
+  [["0B0E070E0180","0A0F06FF","",""],"","",""],
+  [
+    ["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],
+    ["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],"",""
+  ],
+  [
+    ["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],
+    ["0B0E070E0180",["0A0F120F06FF","",""],"",""],"",""
+  ],
+  "0B0E070E","0B0E070E","0B0E070E","0B0E070E",
+  ["",[["0B0C0648","0B0C0730","",""],["0B0C0648","0B0C0730","",""],"",""]],
+  ["0B7007700142","0B7007700142","0A04120406430102","0A04120406490102"],
+  [
+    ["0A040648","0A040648","",""],"",
+    ["0A040643","0A0412040643","",""],""
+  ],
+  [
+    ["0A040648","0A040648","",""],"",
+    ["0A040643","0A0412040643","",""],""
+  ],
+  ["0B70137007700140","0B70137007700140","",""],
+  ["0B70137007700140","0B70137007700140","",""],
+  ["0B70137007700140","0B70137007700140","",""],
+  ["0B70137007700140","0B70137007700140","",""],
+  [
+    ["0A040648","0B3013300730","0B70137007700152","0A061206066C0152"],
+    ["0A040648","0B3013300730","0B70137007700152","0A061206066C0152"],
+    "0A04120406430102","0A04120406460102"
+  ],
+  [
+    ["0A040648","0B3013300730","0B70137007700152","0A061206066C0152"],
+    ["0A040648","0B3013300730","0B70137007700152","0A061206066C0152"],
+    "0A04120406430102","0A04120406460102"
+  ],
+  [
+    ["0A040648","0B300718","0B7007380151","0A06065A0171"],
+    ["0A040648","0B180730","0B3807700152","0A05066C0152"],
+    "0A04120406430101","0A04120406460102"
+  ],
+  [["0B7007700142","","0B380770014A"],["0B700770014A","",""],"0B7007700141",""],
+  [
+    ["0A040648","0B3013300730","0B70137007700152","0A061206066C0152"],
+    ["0A040648","0B3013300730","0B70137007700152","0A061206066C0152"],
+    "0A04120406430102","0A04120406460102"
+  ],
+  ["0B70137007700141","0B70137007700141","0A04120406430101","0A04120406460101"],
+  ["0B70137007700142","0B70137007700142","0A04120406430102","0A04120406460102"],
+  ["0B70137007700141","0B70137007700141","0A04120406430101","0A04120406460101"],
+  [["0A0A06A3","","",""],"0B70137007700108","",""],
+  [["0A0A06A3","","",""],"0B70137007700108","",""],
+  [["0A0A06A3","","",""],"0B701370077001400108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730","0A0F137007700108",""],"",""], 
+  [["0A0A06A9","","",""],["0A040648","0B3013300730","0A0F137007700108",""],"",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730",["0A0F137007700148","",""],["0A0F1206066C0148","",""]],"",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],["0B70137007700148","",""],"",""],
+  [["0A0A06A9","","",""],["0B70137007700148","",""],"",""],
+  ["","0B70137007700140","",""],
+  ["","0B70137007700140","",""],
+  [["0A0A070C","","",""],["0A04070C0108","","0A04070C0108"],"",""],
+  [
+    [
+      ["0A0A06A9","", "",""],
+      ["0B700770","0B700770",["0B7007700108","","0B700770"],["0A06066C0128","","0A06066C0120"]],
+      ["0A040710","0B700770",["0B700770","","0B7007700108"],""],
+      ["","",["0B7007700108","","0B700770"],""]
+    ],
+    [
+      ["0A0A06A9","", "",""],
+      ["0B700770","0B700770",["0B7007700108","","0B700770"],["0A06066C0148","","0A06066C0140"]],
+      ["0A040710","0B700770",["0B700770","","0B7007700108"],""],
+      ["","",["0B7007700108","","0B700770"],""]
+    ]
+  ],
+  [
+    ["0A0A06A90C00","","",""],
+    ["0A0406480C00","0B3007300C00",["0B7007700C000108","",""],["0A06066C0C000108","",""]],
+    "0B7007700C000108",
+    "0B7007700C000108"
+  ],
+  [
+    "",
+    [
+      "","",
+      [["060A0C00","","",""],"137007700C000108","",""],"",
+      [["060A0C00","","",""],"137007700C000108","",""],"",
+      [["060A0C00","","",""],"137007700C000108","",""],""
+    ]
+  ],
+  [
+    ["",["","",["137007700C000148","","137007700C000140"],""],"",""],
+    ["",["","",["137007700C000148","","137007700C000140"],""],"",""],
+    [["060A0C00","","",""],["06480C00","133007300C00",["137007700C000148","",""],["1206066C0C000148","",""]],"",""],
+    "",
+    [["060A0C00","","",""],["06480C00","133007300C00",["137007700C000148","","137007700C000140"],["1206066C0C000148","",""]],"",""],
+    "",
+    [["060A0C00","","",""],["06480C00","133007300C00",["137007700C000148","",""],["1206066C0C000148","",""]],"",""],
+    ""
+  ],
+  [
+    "",
+    [
+      "","",
+      [["137007700C00","137007700C00","",""],"137007700C000140","",""],["","137007700C000108","",""],
+      "","",
+      [["137007700C00","137007700C00","",""],"137007100C000140","",""],["","137007700C000108","",""]
+    ]
+  ],
+  [["0A0A06A9","","",""],["0A040710","13300B300730","0A0F137007700108",""],"",""],
+  [["0A0A06A9","","",""],["0A040710","13300B300730","0A0F137007700108",""],"",""],
+  [["0A0A06A9","","",""],["0A040710","13300B300730",["0A0F137007700148","",""],["0A0F1206066C0148","",""]],"",""],
+  [["",["","",""],"",""],"","",""],
+  [
+    ["07080B080180","",["0B7007700141","","0B3807700149"],""],
+    ["064F0C000C00","",["0B7007380149","","0B7007700141"],""],
+    ["","","0B0C06440109",""],
+    ["0A04064F0C000C00","","0B0C06460109",""]
+  ],
+  [
+    ["0B0807080180","",["0B7007700142","","0B380770014A"],""],
+    ["0A04064F","",["0B700738014A","","0B7007700142"],""],
+    ["","","0B0C0644010A",""],
+    ["0A04064F","","0B0C0646010A",""]
+  ],
+  [
+    "",
+    ["","",["0B7007380149","","0B7007700141"],""],
+    ["","",["0B7007380142","","0B700770014A"],"0A06065A0170"],
+    ["","",["0B700770014A","","0B3807700142"],""]
+  ],
+  [
+    "",
+    ["","",["0B700738014A","","0B7007700142"],""],
+    ["","","0A041204070C010A",""],
+    ["","","0A041204070C010A",""]
+  ],
+  [
+    "",["0A040604","0B7013700770","",""],
+    "",["0A040604","0B7013700770","",""]
+  ],
+  [
+    "",["0A040604","0B7013700770","",""],
+    "",["0A040604","0B7013700770","",""]
+  ],
+  [["070C0A0A","","",""],["06240A040108","","06360A040108"],["0A040646","0A040646",["","","0A0406460108"],""],""],
+  [
+    ["06A90A0A","","",""],
+    ["06480A04","07300B30",["07700B700108","","07700B70"],["066C0A060128","","066C0A060120"]],
+    ["06480A04","07300B30",["07700B70","","07700B700108"],""],
+    ["","",["07700B700108","","07700B70"],""]
+  ],
+  "1106000C","1106000C","1106000C","1106000C",
+  [["1106000C","120F1002","",""],"","",""],[["1106000C","120F1002","",""],"","",""],
+  "1106000C","1106000C","1106000C","1106000C","1106000C","1106000C","1106000C","1106000C","1106000C","1106000C",
+  [
+    ["0600",["0A0F06F2","","0A0F06F6"],"",""],
+    ["0600",["0A0F06F0","","0A0F06F4"],"",""],"",""
+  ],
+  [
+    ["0600",["06120A0F","","06360A0F"],"",""],
+    ["0600",["06000A0F","","06240A0F"],"",""],"",""
+  ],
+  [
+    ["0600",["0A0F062F","",""],"",""],
+    ["0600",["0A0F062F","",""],"",""],"",
+    ["0600",["0A0F062F","","0A0F063F"],"",""]
+  ],
+  [
+    ["0600",["062F0A0F","",""],"",""],
+    ["0600",["062F0A0F","",""],"",""],"",
+    ["0600",["062F0A0F","","063F0A0F"],"",""]
+  ],
+  "0600",[["0600","0A03120F06FF","",""],"","",""],
+  "0600",[["0600","0A03120F06FF","",""],"","",""],
+  [
+    ["0600",["0A0F06FF","","0A0F06FF"],"",""],
+    ["0600",["0A0F06FF","","0A0F06FF"],"",""],"",""
+  ],
+  [
+    ["0600",["0A0F06FF","","0A0F06FF"],"",""],
+    ["0600",["0A0F06FF","","0A0F06FF"],"",""],"",""
+  ],
+  "0600","0600","0600","0600","0600","0600",
+  "2608","2608",
+  "",
+  "070E0B0E0003",
+  "070E0B0E0C00","070E0B0E1800",
+  "0B0E070E","070E0B0E",
+  "2808","2808",
+  "",
+  "070E0B0E0003",
+  "070E0B0E0C00","070E0B0E1800",
+  [
+    [
+      ["0601","","0601"],["0601","","0601"],
+      "0603","0603",
+      ["0601","","0601"],["0601","","0601"],
+      ["0601","0601","0601"],
+      ["0601","0601",""]
+    ],
+    [
+      ["","",["0602","","",""],""],["","",["0602","","",""],""],
+      ["","",["0602","","",""],""],["","",["0602","","",""],""],
+      "",
+      ["","","","","","","",""],
+      ["","","","","","","",""],
+      ["","","","","","","",""]
+    ]
+  ],
+  "0B0E070E",
+  "06000A000003","070E0B0E0003",
+  ["0B0E090E",""],
+  "070E0B0E0003",
+  ["0B0E090E",""],
+  ["0B0E090E",""],
+  "0B0E0600","0B0E0602",
+  [
+    ["1002","","",""],"",
+    ["0B060706","0A020602","",""],""
+  ],"",
+  ["","","","","070E0C000003","070E0C000003","070E0C000003","070E0C000003"],
+  "0B0E070E0003",
+  [
+    ["0B0E070E0180","","",""],"",
+    ["0B0E070E0180","0A020602","",""],["0B0E070E0180","0A020602","",""]
+  ],
+  [
+    ["0B0E070E0180","","",""],"",
+    ["0B0E070E0180","0A020602","",""],["0B0E070E0180","","",""]
+  ],
+  "0B0E0600","0B0E0602",
+  "06000A000003","070E0B0E0003",
+  [
+    ["0A0406480C00","0B30133007300C00","0A0F137007700C000151","0A0F066C0C000151"],
+    ["0A0406480C00","0B30133007300C00","0A0F137007700C000151","0A0F066C0C000151"],
+    ["0A0406440C00","0A04120406480C00","0A0F120406440C000151",""],
+    ["0A0406490C00","0A04120406480C00","0A0F120406460C000151",""]
+  ],
+  ["06030A02",""],
+  [["0A0A06220C00","","",""],"0A04120406220C000108","",""],
+  ["",[["06020A0A0C00","","",""],"06020A040C000108","",""]],
+  ["0B70137007700C000140","0B70137007700C000140","",""],
+  [
+    [
+      "",
+      ["06060003","","060B0003"],
+      "",
+      ["0601","","0601"],
+      ["0601","","0601"],
+      ["0601","","0601"],
+      ["0606","0606","0606",""],["0606","","",""]
+    ],
+    [
+      "",
+      ["","","","","","","",""],
+      "","","","",
+      "070E","070E"
+    ]
+  ],
+  "030E","030E","030E","030E","030E","030E","030E","030E",
+  ["",["0A040648","0B3013300730","",""],"",["0A040648","0B3013300730","",""]],
+  [["0A0A06A9","","",""],"0B70137006480108","",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300648",["0B70137006480108","",""],""],"",""],
+  [["0A0A06A9","","",""],"0B70137006480100","",""],
+  [["0A0A06A9","","",""],"0B70137007700140","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [
+    ["","06490A040100","",""],
+    ["","06490A040100",["0A040649","","",""],["0A040649","","",""]]
+  ],
+  ["",[["0B0C06A0","","",""],["0B0C0640","0B0C0730","",""],"",""]],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730",["0B70137007700148","","0B70137007700140"],["0A061206066C0148","","0A061206066C0140"]],"",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730",["0B70137007700148","","0B70137007700140"],["0A061206066C0148","","0A061206066C0140"]],"",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [
+    [["0A0A06A9","","",""],["0A040648","0B3013300648","0B70137006480108",""],"",""],
+    [["0A0A06A9","","",""],["0A040648","0B3013300730","0B70137006480108",""],"",""]
+  ],
+  [["0A0A06A9","","",""],["0A040648","0B3013300648",["0B70137006480108","","0B7013700648"],""],"",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [
+    "",
+    ["0A040648","0A040730","0B3807700141",""],
+    ["0A040649","0B300738",["0A0406480140","0B7007380140","0B700770014A"],"0A06065A0170"],
+    "0B3807700142"
+  ],
+  [[["06090A0A","","",""],["07700B700108","",""],"",""],""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730",["0B70137007700148","","0B70137007700140"],["0A061206066C0148","","0A061206066C0140"]],"",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730",["0B70137007700148","","0B70137007700140"],["0A061206066C0148","","0A061206066C0140"]],"",""],
+  [["","","",["0A040648","0A040730","",""]],"0000"],
+  [["0A0A06A9","","",""],"0B70137006480108","",""],
+  [["0A0A06A9","","",""],["0B70137006480108","",""],"",""],
+  [["0A0A06A9","","",""],"0B7013700648","",""],
+  [["0A0A06A9","","",""],"0B70137007700140","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  ["",[["0A0A060A","","",""],["0B040648","0B040648","",""],"",""]],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730",["0B70137007700148","",""],["0A061206066C0148","",""]],"",""],
+  [["0A0A06A9","","",""],"0B70137007700140","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730",["0B70137007700148","",""],["0A061206066C0148","",""]],"",""],
+  "",
+  /*------------------------------------------------------------------------------------------------------------------------
+  Three Byte operations 0F38.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730","",""],"",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730","",""],"",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730","",""],"",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730","",""],"",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730","",""],"",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730","",""],"",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730","",""],"",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730","",""],"",""],
+  [["0A0A06A9","","",""],["0A040648","0B3013300730","",""],"",""],
+  [["0A0A06A9","","",""],"0B70137007700108","",""],
+  ["",["","0B3013300730",["0B70137007700148","",""],""],"",""],
+  ["",["","0B3013300730","0B70137007700140",""],"",""],
+  ["",["","0B300730","",""],"",""],
+  ["",["","0B300730","",""],"",""],
+  ["",["0A0406482E00","0B30133007301530","0B7013700770",""],["","","07380B70",""],""],
+  ["",["","","0B7013700770",""],["","","071C0B70",""],""],
+  ["",["","","0B7013700770",""],["","","070E0B70",""],""],
+  ["",["","0B300718",["0B7007380109","",""],""],["","","07380B70",""],""],
+  ["",["0A0407102E00","0B30133007301530",["0B70137007700148","","0B70137007700140"],""],["","","071C0B70",""],""],
+  ["",["0A0407102E00","0B30133007301530",["0B70137007700148","","0B70137007700140"],""],["","","07380B70",""],""],
+  ["",["","0B3013300730",["0B70137007700148","","0B70137007700140"],""],"",""],
+  ["",["0A040648","0B300730","",""],"",""],
+  ["",["","0B300644",["0B7006440138","",""],["0A0606440138","",""]],"",""],
+  ["",["","0A050646",["0B6806460108","","0B700646"],["","","0A060646"]],"",""],
+  ["",["","0A050648",["0B6806480138","","0B680648"],["0A0606480138","",""]],"",""],
+  ["",["","",["0A06065A0108","","0A06065A"],["","","0A06065A"]],"",""],
+  [["0A0A06A9","","",""],"0B7007700108","",""],
+  [["0A0A06A9","","",""],"0B7007700108","",""],
+  [["0A0A06A9","","",""],["0B7007700148","",""],"",""],
+  ["",["","","0B7007700140",""],"",""],
+  ["","0B7007380108",["","","07380B70",""],""],
+  ["","0B70071C0108",["","","071C0B70",""],""],
+  ["","0B70070E0108",["","","070E0B70",""],""],
+  ["","0B7007380108",["","","07380B70",""],""],
+  ["","0B70071C0108",["","","071C0B70",""],""],
+  ["","0B7007380108",["","","07380B70",""],""],
+  ["",["","",["0A0F137007700108","","0A0F13700770"],""],["","",["0A0F13700770","","0A0F137007700108"],""],""],
+  ["",["","",["0A0F137007700148","","0A0F137007700140"],["0A0F1206066C0148","",""]],["","",["0A0F137007700140","","0A0F137007700148"],""],""],
+  ["","0B70137007700140",["","",["0B7006FF","","0B7006FF0108"],""],""],
+  ["",["0A040648","0B3013300730","0A0F137007700140",""],["","",["0A0F0770","","0A0F07700108"],""],""],
+  [["",["0B7007700108","",""],"",""],["","",["","",["","","0B7006FF0108"],""],""]],
+  ["",["0B70137007700148","",""],"",""],
+  ["",["","0B3013300730",["0B7013700770014A","","0B70137007700142"],""],"",""],
+  ["",["","0B3013300730",["0A0412040644014A","","0A04120406480142"],""],"",""],
+  ["",["","073013300B30","",""],"",""],
+  ["",["","0B3013300730","",""],"",""],
+  ["","0B7007380108",["","","07380B70",""],""],
+  ["","0B70071C0108",["","","071C0B70",""],""],
+  ["","0B70070E0108",["","","070E0B70",""],""],
+  ["","0B7007380108",["","","07380B70",""],""],
+  ["","0B70071C0108",["","","071C0B70",""],""],
+  ["","0B7007380108",["","",["06480A04","07380B70",""],""],""],
+  ["",["","0A051205065A",["0B70137007700148","","0B70137007700140"],["0A061206066C0108","",""]],"",""],
+  ["",["0A040710","0B3013300730","0A0F137007700140",""],"",""],
+  ["","0B70137007700108",["","",["0B7006FF","","0B7006FF0108"],""],""],
+  ["",["0A0412040648","0B3013300730",["0B70137007700148","","0B70137007700140"],["0A061206066C0148","",""]],["","",["0A0F0770","","0A0F07700108"],""],""],
+  ["","0B70137007700108",["","","0B7006FF0100",""],""],
+  ["",["0A0412040648","0B3013300730",["0B70137007700148","","0B70137007700140"],["0A061206066C0148","",""]],"",""],
+  ["","0B70137007700108","",""],
+  ["",["0A0412040648","0B3013300730",["0B70137007700148","","0B70137007700140"],["0A061206066C0148","",""]],"",""],
+  ["","0B70137007700108","",""],
+  ["",["0A0412040648","0B3013300730",["0B70137007700148","","0B70137007700140"],["0A061206066C0148","",""]],"",""],
+  ["",["0A0412040648","0B3013300730",["0B70137007700148","","0B70137007700140"],["0A061206066C0148","",""]],"",""],
+  ["",["0A040648",["0A040648","0A040648","",""],"",""],"",""],
+  ["",["","",["0B7007700159","","0B7007700151"],["0A06066C0159","","0A06066C0151"]],"",""],
+  ["",["","",["0A0412040644010A","","0A04120406460102"],""],"",""],
+  ["",["","",["0B7007700148","","0B7007700140"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B70137007700148","","0B70137007700140"],["0A061206066C0148","",""]],"",""],
+  ["",["",["0B3013300730","",""],["0B70137007700148","","0B70137007700140"],["0A061206066C0148","",""]],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B70137007700148","","0B70137007700140"],["0A061206066C0148","",""]],"",""],
+  "","","","",
+  ["",["","",["0B7007700148","","0B7007700140"],""],"",""],
+  ["",["","",["0A04120406440108","","0A0412040646"],""],"",""],
+  ["",["","",["0B7007700148","","0B7007700140"],""],"",""],
+  ["",["","",["0A04120406440108","","0A0412040646"],""],"",""],
+  ["",["","","",["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["","","",["0A061206066C0159","",""]],"",""],
+  ["",["","","",["0A061206066C0159","","0A061206066C0151"]],"",""],
+  ["",["","","",["0A061206066C0159","","0A061206066C0151"]],"",""],
+  "",
+  ["",["","","",["0A061206066C0149","","0A061206066C0141"]],"",""],
+  "","",
+  ["",["","0B300644",["0B7006440128","",""],["0A0606440128","",""]],"",""],
+  ["",["","0B300646",["0B7006460128","","0B7006460120"],["","","0A0606460120"]],"",""],
+  ["",["","0A050648",["0B6806480128","","0B6806480120"],["0A0606480128","",""]],"",""],
+  ["",["","",["0A06065A0128","","0A06065A0120"],["","","0A06065A0120"]],"",""],
+  ["",["","","",["0A06120F066C0148","",""]],"",""],
+  ["",["","","",["0A06120F066C0148","",""]],"",""],
+  ["",["","","",["0A06120F066C0148","",""]],"",""],
+  ["",["","","",["0A06120F066C0148","",""]],"",""],
+  "","","","",
+  ["",["","",["0B70137007700148","","0B70137007700140"],["0A061206066C0148","","0A061206066C0140"]],"",""],
+  ["",["","",["0B70137007700158","","0B70137007700150"],["0A061206066C0158","","0A061206066C0150"]],"",""],
+  ["",["","",["0B70137007700108","","0B7013700770"],""],"",""],
+  "","","","","",
+  ["",["","","",["0A061206066C0148","",""]],"",""],
+  ["",["","","",["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["","","",["0A06120F066C0148","",""]],"",""],
+  ["",["","","",["0A06120F066C0148","",""]],"",""],
+  "","","","",
+  ["",["","","",["0A0F1206066C0148","",""]],"",""],
+  ["",["","",["0B70137007700108","","0B7013700770"],""],"",""],
+  ["",["","",["0B70137007700148","","0B70137007700140"],""],"",""],
+  ["",["","",["0B70137007700148","","0B70137007700140"],""],"",""],
+  ["",["","0B300640",["0B7006400108","",""],""],"",""],
+  ["",["","0B300642",["0B7006420108","",""],""],"",""],
+  ["",["",["","",["0B7006000108","",""],""],"",""]],
+  ["",["",["","",["0B7006100108","",""],""],"",""]],
+  ["",["","",["0B70062F0108","","0B70063F"],""],"",""],
+  ["",["","",["0B70137007700108","","0B7013700770"],""],"",""],
+  ["",["","",["0B70137007700148","","0B70137007700140"],""],"",""],
+  ["",["","",["0B70137007700148","","0B70137007700140"],""],"",""],
+  [["","0B0C060B0180","",""],""],
+  [["","0B0C060B0180","",""],""],
+  [["","0B0C060B0180","",""],""],
+  ["",["","","0B70137007700140",""],"",""],
+  ["",["","","",["0A061206066C014A","",""]],"",""],
+  "",
+  ["",["","","",["0A061206066C0148","",""]],"",""],
+  ["",["","","",["0A061206066C0148","",""]],"",""],
+  ["",["","",["0B7007700108","","0B700770"],""],"",""],
+  ["",["","",["0B7007700108","","0B700770"],""],"",""],
+  ["",["","",["07700B700108","","07700B70"],""],"",""],
+  ["",["","",["07700B700108","","07700B70"],""],"",""],
+  "",
+  ["",["","",["0B70137007700108","","0B7013700770"],""],"",""],
+  "","",
+  ["",["",["0B30073013300124","","0B30064813300124"],["0B700770012C","","0B7007380124"],["0A06066C012C","","0A06065A0124"]],"",""],
+  ["",["",["0A04073012040104","","0B30073013300104"],["0B380770010C","","0B7007700104"],""],"",""],
+  ["",["",["0B30073013300134","","0B30064813300134"],["0B700770013C","","0B7007380134"],["0A06066C013C","","0A06065A0104"]],"",""],
+  ["",["",["0A04073012040104","","0B30073013300104"],["0B380770010C","","0B7007700104"],""],"",""],
+  "","",
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040714","","0A0412040718"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040714","","0A0412040718"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040714","","0A0412040718"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040714","","0A0412040718"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  ["",["","",["07700B70010C","","07380B700104"],["066C0A06012C","","065A0A060124"]],"",""],
+  ["",["","",["07700B38010C","","07700B700104"],""],"",""],
+  ["",["","",["07700B70013C","","07380B700134"],["066C0A06013C","","065A0A060134"]],"",""],
+  ["",["","",["07700B38010C","","07700B700104"],""],"",""],
+  ["",["","","",["0A061206066C011A","",""]],"",""],
+  "",
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040644","","0A0412040646"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040644","","0A0412040646"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040644","","0A0412040646"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040644","","0A0412040646"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  "","","","",
+  ["",["","","0B70137007700140",["0A061206066C0118","",""]],"",""],
+  ["",["","","0B70137007700140",["0A061206066C0148","",""]],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040644","","0A0412040646"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040644","","0A0412040646"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040644","","0A0412040646"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  ["",["",["0B3013300730","","0B3013300730"],["0B7013700770014A","","0B70137007700142"],["0A061206066C015A","","0A061206066C0152"]],"",""],
+  ["",["",["0A0412040644","","0A0412040646"],["0A0412040644010A","","0A04120406460102"],""],"",""],
+  "","","","",
+  ["",["","",["0B7007700148","","0B7007700140"],""],"",""],
+  "",
+  [
+    [
+      ["",["","","",["060C013C","","060A0134"]],"",""],
+      ["",["","",["060C013C","","060A0134"],["060C013C","",""]],"",""],
+      ["",["","",["060C013C","","070A0134"],["060C013C","",""]],"",""],
+      "",
+      ["",["","","",["060C013C","","060A0134"]],"",""],
+      ["",["","",["060C013C","","060A0134"],["060C013C","",""]],"",""],
+      ["",["","",["060C013C","","060A0134"],["060C013C","",""]],"",""],
+      ""
+    ],""
+  ],
+  [
+    [
+      "",
+      ["",["","",["060C010C","","060C0104"],""],"",""],
+      ["",["","",["060C010C","","060C0104"],""],"",""],
+      "","",
+      ["",["","",["060C010C","","060C0104"],""],"",""],
+      ["",["","",["060C010C","","060C0104"],""],"",""],
+      ""
+    ],""
+  ],
+  [["0A040648","","",""],["","",["0A06066C0159","","0A06066C0151"],["0A06066C0109","",""]],"",""],
+  [["0A040648","","",""],["","","",["0A06066C0109","",""]],"",""],
+  [["0A040648","","",""],["","",["0A06066C0159","","0A06066C0151"],["0A06066C0109","",""]],"",""],
+  [["0A0406482E00","","",""],["","",["0A04120406440109","","0A04120406460101"],["0A06066C0109","",""]],"",""],
+  [["0A040648","","",""],["","",["0A06066C0159","","0A06066C0151"],["0A06066C015A","",""]],"",""],
+  [["0A040648","","",""],["","",["0A04120406440109","","0A04120406460101"],["0A06066C0148","",""]],"",""],
+  "","",
+  [[["","","",["0A06060C0120","","0A06060C0128"]],["","","",["060C0A060128","","060C0A060120"]],"",""],""],
+  [[["","","",["0A06060C0130","","0A06060C0138"]],["","","",["060C0A060138","","060C0A060130"]],"",""],""],
+  "","",
+  [[["","","",["0A06060C0120","","0A06060C0128"]],["","","",["060C0A060128","","060C0A060120"]],"",""],""],
+  [[["","","",["0A06060C0130","","0A06060C0138"]],["","","",["060C0A060138","","060C0A060130"]],"",""],""],
+  "","","","","",
+  ["",["0A040648","0A040648","",""],"",""],
+  ["",["0A040648","0A0412040648","",""],"",""],
+  ["",["0A040648","0A0412040648","",""],"",""],
+  ["",["0A040648","0A0412040648","",""],"",""],
+  ["",["0A040648","0A0412040648","",""],"",""],
+  "","","","","","","","","","","","","","","","",
+  [
+    ["0B0E070E0180","","",""],
+    ["0B0E070E0180","","",""],"",
+    ["0B0C06000180","","",""]
+  ],
+  [
+    ["070E0B0E0180","","",""],
+    ["070E0B0E0180","","",""],"",
+    ["0B0C070E0180","","",""]
+  ],
+  ["",["","0B0C130C070C","",""],"",""],
+  [
+    "",
+    ["",["","130C070C","",""],"",""],
+    ["",["","130C070C","",""],"",""],
+    ["",["","130C070C","",""],"",""],
+    "","","",""
+  ],"",
+  [
+    ["","0B0C070C130C","",""],"",
+    ["","0B0C130C070C","",""],
+    ["","0B0C130C070C","",""]
+  ],
+  [
+    "",
+    ["0B0C070C","","",""],
+    ["0B0C070C","","",""],
+    ["","0B0C130C070C1B0C","",""]
+  ],
+  [
+    ["","0B0C130C070C","",""],
+    ["","0B0C130C070C","",""],
+    ["","0B0C130C070C","",""],
+    ["","0B0C130C070C","",""]
+  ],
+  "","","","","","","","",
+  /*------------------------------------------------------------------------------------------------------------------------
+  Three Byte operations 0F3A.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  ["",["","0A05065A0C00","0B7007700C000140",""],"",""],
+  ["",["","0A05065A0C00","0B7007700C000140",""],"",""],
+  ["",["",["0B30133007300C00","",""],"",""],"",""],
+  ["",["","",["0B70137007700C000148","","0B70137007700C000140"],["0A061206066C0C000108","",""]],"",""],
+  ["",["","0B3007300C00",["0B7007700C000148","",""],""],"",""],
+  ["",["","0B3007300C00","0B7007700C000140",""],"",""],
+  ["",["","0A051205065A0C00","",""],"",""],
+  ["",["","","",["0A06066C0C000108","",""]],"",""],
+  ["",["0A0406480C00","0B3007300C00",["0B7007700C000149","",""],""],"",""],
+  ["",["0A0406480C00","0B3007300C00","0B7007700C000141",""],"",""],
+  ["",["0A0406440C00","0A04120406440C00",["0A04120406440C000109","",""],""],"",""],
+  ["",["0A0406460C00","0A04120406460C00","0A04120406460C000101",""],"",""],
+  ["",["0A0406480C00","0B30133007300C00","",""],"",""],
+  ["",["0A0406480C00","0B30133007300C00","",""],"",""],
+  ["",["0A0406480C00","0B30133007300C00","",""],"",""],
+  [["0A0A06A90C00","","",""],"0B70137007700C000108","",""],
+  "","","","",
+  [["","06000A040C000108","",""],["","070C0A040C000108","",""]],
+  [["","06020A040C000108","",""],["","070C0A040C000108","",""]],
+  ["",["06240A040C000108","","06360A040C00"],"",""],
+  ["","070C0A040C000108","",""],
+  ["",["","0A05120506480C00",["0B70137006480C000108","","0B70137006480C00"],""],"",""],
+  ["",["","06480A050C00",["06480B700C000108","","06480B700C00"],""],"",""],
+  ["",["","",["0A061206065A0C000108","","0A061206065A0C00"],""],"",""],
+  ["",["","",["065A0A060C000108","","065A0A060C00"],""],"",""],
+  "",
+  ["",["","07180B300C00",["07380B700C000109","",""],""],"",""],
+  ["",["","",["0A0F137007700C000148","","0A0F137007700C000140"],["0A0F1206066C0C000148","",""]],"",""],
+  ["",["","",["0A0F137007700C000148","","0A0F137007700C000140"],["0A0F1206066C0C000148","",""]],"",""],
+  ["","0A04120406200C000108","",""],
+  ["",["0A04120406440C000108","",""],"",""],
+  ["",["",["0A04120406240C00","","0A04120406360C00"],["0A04120406240C000108","","0A04120406360C00"],""],"",""],
+  ["",["","",["0B70137007700C000148","","0B70137007700C000140"],""],"",""],
+  "",
+  ["",["","",["0B70137007700C000148","","0B70137007700C000140"],""],"",""],
+  ["",["","",["0B7007700C000149","","0B7007700C000141"],["0A06066C0C000159","","0A06066C0C000151"]],"",""],
+  ["",["","",["0A04120406440C000109","","0A04120406460C000101"],""],"",""],
+  "","","","","","","","",
+  ["",["",["0A0F06FF0C00","","0A0F06FF0C00"],"",""],"",""],
+  ["",["",["0A0F06FF0C00","","0A0F06FF0C00"],"",""],"",""],
+  ["",["",["0A0F06FF0C00","","0A0F06FF0C00"],"",""],"",""],
+  ["",["",["0A0F06FF0C00","","0A0F06FF0C00"],"",""],"",""],
+  "","","","",
+  ["",["","0A05120506480C00",["0B70137006480C000108","","0B70137006480C00"],""],"",""],
+  ["",["","06480A050C00",["06480B700C000108","","06480B700C00"],""],"",""],
+  ["",["","",["0A061206065A0C000108","","0A061206065A0C00"],""],"",""],
+  ["",["","",["065A0A060C000108","","065A0A060C00"],""],"",""],
+  "","",
+  ["",["","0A0F063F0C00",["0A0F137007700C000108","","0A0F137007700C00"],""],"",""],
+  ["",["","",["0A0F137007700C000108","","0A0F137007700C00"],""],"",""],
+  ["",["0A0406480C00","0B30133007300C00","",""],"",""],
+  ["",["0A0406480C00","0A04120406480C00","",""],"",""],
+  ["",["0A0406480C00","0B30133007300C00",["0B70137007700C000108","",""],""],"",""],
+  ["",["","",["0B70137007700C000148","","0B70137007700C000140"],""],"",""],
+  ["",["0A0406480C00","0A04120406480C00","",""],"",""],
+  "",
+  ["",["","0A051205065A0C00","",""],"",""],
+  "",
+  ["",["",["0B301330073015300E00","","0B301330153007300E00"],"",""],"",""],
+  ["",["",["0B301330073015300E00","","0B301330153007300E00"],"",""],"",""],
+  ["",["","0B30133007301530","",""],"",""],
+  ["",["","0B30133007301530","",""],"",""],
+  ["",["","0A051205065A1505","",""],"",""],
+  "","","",
+  ["",["","",["0B70137007700C000149","","0B70137007700C000141"],""],"",""],
+  ["",["","",["0A04120406440C000109","","0A04120406460C000101"],""],"",""],
+  ["",["","","",["0A06066C0C000159","","0A06066C0C000151"]],"",""],
+  "",
+  ["",["","",["0B70137007700C000149","","0B70137007700C000141"],""],"",""],
+  ["",["","",["0A04120406440C000109","","0A04120406460C000101"],""],"",""],
+  ["",["","",["0B7007700C000149","","0B7007700C000141"],""],"",""],
+  ["",["","",["0A04120406440C000109","","0A04120406460C000101"],""],"",""],
+  "","","","",
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["0A0406480C00","0A0406480C00","",""],"",""],
+  ["",["0A0406480C00","0A0406480C00","",""],"",""],
+  ["",["0A0406480C00","0A0406480C00","",""],"",""],
+  ["",["0A0406480C00","0A0406480C00","",""],"",""],
+  "","",
+  ["",["","",["0A0F07700C000148","","0A0F07700C000140"],""],"",""],
+  ["",["","",["0A0F06440C000108","","0A0F06460C00"],""],"",""],
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["",["0A04120406441530","","0A04120415300644"],"",""],"",""],
+  ["",["",["0A04120406461530","","0A04120415300646"],"",""],"",""],
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["",["0A04120406441530","","0A04120415300644"],"",""],"",""],
+  ["",["",["0A04120406461530","","0A04120415300646"],"",""],"",""],
+  "","","","","","","","",
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["",["0A04120406441530","","0A04120415300644"],"",""],"",""],
+  ["",["",["0A04120406461530","","0A04120415300646"],"",""],"",""],
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["",["0B30133007301530","","0B30133015300730"],"",""],"",""],
+  ["",["",["0A04120406441530","","0A04120415300644"],"",""],"",""],
+  ["",["",["0A04120406461530","","0A04120415300646"],"",""],"",""],
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","",
+  [["","","","0A06066C0C000141"],["","","",["0A06066C0C000159","",""]],"",["","","","0A06066C0C000151"]],
+  [["","","","0A06066C0C000141"],["","","",["0A06066C0C000159","",""]],"",""],
+  "0A0406480C00","","","",
+  "","","","","","","","","","","","","","","",
+  ["",["0A0406480C00","0A0406480C00","",""],"",""],
+  "","","","","","",
+  ["","","",["","","","0A06066C0C000151"]],
+  "","","","","","","","","",
+  ["","","",["","0B0C070C0C00","",""]],
+  "","","","","","","","","","","","","","","",
+  /*------------------------------------------------------------------------------------------------------------------------
+  AMD XOP 8.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","",
+  "0A04120406481404","0A04120406481404","0A04120406481404","","","","","","",
+  "0A04120406481404","0A04120406481404","","","","","","0A04120406481404","0A04120406481404","0A04120406481404",
+  "","","","","","","0A04120406481404","0A04120406481404",
+  "","",["0B30133007301530","","0B30133015300730"],["0A04120406481404","","0A04120414040648"],"","","0A04120406481404",
+  "","","","","","","","","","","","","","","",
+  "0A04120406481404","","","","","","","","","","0A0406480C00","0A0406480C00","0A0406480C00","0A0406480C00",
+  "","","","","","","","",
+  "0A04120406480C00","0A04120406480C00","0A04120406480C00","0A04120406480C00",
+  "","","","","","","","","","","","","","","","","","","","","","","","","","","","",
+  "0A04120406480C00","0A04120406480C00","0A04120406480C00","0A04120406480C00",
+  "","","","","","","","","","","","","","","","",
+  /*------------------------------------------------------------------------------------------------------------------------
+  AMD XOP 9.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "",
+  ["","130C070C","130C070C","130C070C","130C070C","130C070C","130C070C","130C070C"],
+  ["","130C070C","","","","","130C070C",""],
+  "","","","","","","","","","","","","","","",
+  ["",["070C","070C","","","","","",""]],
+  "","","","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","","",
+  "0B300730","0B300730","0B300730","0B300730",
+  "","","","","","","","","","","","",
+  ["0A0406481204","","0A0412040648"],["0A0406481204","","0A0412040648"],["0A0406481204","","0A0412040648"],["0A0406481204","","0A0412040648"],
+  ["0A0406481204","","0A0412040648"],["0A0406481204","","0A0412040648"],["0A0406481204","","0A0412040648"],["0A0406481204","","0A0412040648"],
+  ["0A0406481204","","0A0412040648"],["0A0406481204","","0A0412040648"],["0A0406481204","","0A0412040648"],["0A0406481204","","0A0412040648"],
+  "","","","","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","","","",
+  "0A040648","0A040648","0A040648","","","0A040648","0A040648","","","","0A040648","","","","","",
+  "0A040648","0A040648","0A040648","","","0A040648","0A040648","","","","0A040648","","","","","",
+  "0A040648","0A040648","0A040648","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","",
+  /*------------------------------------------------------------------------------------------------------------------------
+  AMD XOP A.
+  ------------------------------------------------------------------------------------------------------------------------*/
+  "","","","","","","","","","","","","","","","",
+  "0B0C070C0C020180","",["130C06240C020180","130C06240C020180","","","","","",""],
+  "","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  L1OM Vector.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  "","","","","1206","","","","","","","","","","","",
+  [["0A0606610120","0A0606610120","",""],""],"",
+  [["0A0606610120","0A0606610120","",""],""],
+  [["0A0606610120","0A0606610120","",""],""],
+  [["0A0606610100","0A0606610100","",""],""],"",
+  [["0A0606610100","0A0606610100","",""],""],
+  [["0A0606610100","0A0606610100","",""],""],
+  ["0A06066C0124",""],["066C0124",""],"",["066C0124",""],
+  ["066C0A060104",""],["066C0104",""],"",["066C0104",""],
+  ["0A0F120606610150","0A0F120606610150","",""],"0A0F120606610140","0A0F120606610140","",
+  ["0A0F120606610150","0A0F120606610150","",""],"0A0F120606610140","0A0F120606610140","",
+  "","","","","","","","",
+  "0A0F120606610140","","","","","","","","","","","","","","","",
+  ["0A06120606610150","0A06120606610150","",""],"0A06120606610140","","0A06120F06610140","","0A06120F06610140","0A06120606610150","0A06120606610140",
+  ["0A06120606610150","0A06120606610150","",""],"","","","","","","",
+  ["0A06120606610150","0A06120606610150","",""],"0A06120606610140","","0A06120F06610140","","0A06120F06610140","","",
+  ["0A06120606610150","0A06120606610150","",""],"0A06120606610140","","0A06120F06610140","","0A06120F06610140","","",
+  ["0A06120606610150","0A06120606610150","",""],"0A06120606610140",
+  ["0A06120606610150","0A06120606610150","",""],"",
+  ["0A06120606610150","0A06120606610150","",""],"",
+  "0A06120606610150","0A06120606610140",
+  ["0A06120606610150","0A06120606610150","",""],"",
+  ["0A06120606610150","0A06120606610150","",""],"",
+  ["0A06120606610150","0A06120606610150","",""],"","","",
+  ["0A06120606610150","0A06120606610150","",""],"",
+  ["0A06120606610150","0A06120606610150","",""],"",
+  ["0A06120606610150","0A06120606610150","",""],"","","",
+  ["0A06120606610150","0A06120606610150","",""],"",
+  ["0A06120606610150","0A06120606610150","",""],"",
+  ["0A06120606610150","0A06120606610150","",""],"",
+  ["0A06120606610150","0A06120606610150","",""],"",
+  ["0A06120606610150","0A06120606610150","",""],"0A06120606610140","0A06120606610140","0A06120606610140","","","0A06120606610150","0A06120606610140",
+  ["0A06120606610150","0A06120606610150","",""],"0A06120606610140","0A06120606610140","",
+  ["0A06120606610150","0A06120606610150","",""],"0A06120606610140","0A06120606610140","",
+  ["","0A0606610152","",""],["0A0606610153","0A0606610152","",""],["0A0606610153","0A0606610152","",""],"",
+  ["","0A0606610158","",""],["0A0606610141","0A0606610148","",""],["0A0606610141","0A0606610148","",""],"",
+  "0A0606610153","","0A0606610150","0A0606610152","","0A0606610150","0A0606610150","",
+  "0A06120606610140","0A06120606610140","0A06120606610140","",
+  ["0A06120606610140","0A06120606610140","",""],["0A06120606610140","0A06120606610140","",""],
+  ["0A06120606610140","0A06120606610140","",""],["0A06120606610140","0A06120606610140","",""],
+  "0A06120606610140","0A06120606610140","","","","","","",
+  "0A0606610140","0A0606610150","0A0606610150","","0A0606610150","","","",
+  "0A06120606610140","","","","","","","",
+  "0A0606610150","","0A06120606610150","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "0A0606610C010150","0A0606610C000C00","0A06120606610C010140","0A0606610C010140","","","","",
+  "","","","","","","","",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  L1OM Mask, Mem, and bit opcodes.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  ["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],
+  ["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],
+  ["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],
+  ["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],
+  ["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],
+  ["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],
+  ["","0B0E070E0C010C000C00"],["","0B0E070E0C010C000C00"],["","0B0E070E0C010C000C00"],["","0B0E070E0C010C000C00"],
+  ["","0B0E070E0C010C000C00"],["","0B0E070E0C010C000C00"],["","0B0E070E0C010C000C00"],["","0B0E070E0C010C000C00"],
+  ["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],
+  ["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],["","0B0E070E"],
+  "","","","",
+  "06FF0A0F",
+  [["0601","0601","0604","0604","","","",""],""],
+  [["0601","0601","","","","","",""],""],
+  [["0601","0601","","","","","",""],""],
+  "06FF0A0F","06FF0B06","07060A0F","06FF0B06",
+  "06FF0A0F","06FF0A0F","06FF0A0F","06FF0A0F",
+  "06FF0A0F","06FF0A0F","06FF0A0F","06FF0A0F",
+  "","06FF0A0F",
+  ["",["0B07","0B07","","","","","",""]],
+  ["",["0B07","0B07","","","","","",""]]
+];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+3DNow uses the byte after the operands as the select instruction code, so in the Mnemonics there is no instruction name, but
+in the Operands array the operation code 0F0F which is two byte opcode 0x10F (using the disassemblers opcode value system)
+automatically takes operands ModR/M, and MM register. Once the operands are decoded the byte value after the operands is
+the selected instruction code for 3DNow. The byte value is an 0 to 255 value so the listing is 0 to 255.
+---------------------------------------------------------------------------------------------------------------------------
+At the very end of the function ^DecodeInstruction()^ an undefined instruction name with the operands MM, and MM/MMWORD is
+compared for if the operation code is 0x10F then the next byte is read and is used as the selected 3DNow instruction.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+const M3DNow = [
+  "","","","","","","","","","","","","PI2FW","PI2FD","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","PFNACC","","","","PFPNACC","",
+  "PFCMPGE","","","","PFMIN","","PFRCP","PFRSQRT","","","FPSUB","","","","FPADD","",
+  "PFCMPGT","","","","PFMAX","","PFRCPIT1","PFRSQIT1","","","PFSUBR","","","","PFACC","",
+  "PFCMPEQ","","","","PFMUL","","PFRCPIT2","PMULHRW","","","","PSWAPD","","","","PAVGUSB",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","","",
+  "","","","","","","","","","","","","","","",""
+];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Virtual machine synthetic operation codes is under two byte operation code 0FC7 which is opcode 0x1C7 using the disassemblers
+opcode value system. The operation code 0x1C7 is an group opcode containing 3 operation codes, but only one of the codes
+is used in the ModR/M grouped opcode for synthetic virtual machine operation codes. The ModR/M byte has to be in register mode
+using register code 001 for the virtual machine synthetic operation codes. The effective address has to be set 000 which uses
+the full ModR/M byte as an static opcode encoding under the group opcode 001. This makes the operation code 0F C7 C8.
+The resulting instruction name in the Mnemonics map is "SSS", and takes no Operands in the Operands array. The two bytes after
+0F C7 C8 are used as the select synthetic operation code. Only the first 4 values of both bytes have an select operation code,
+so an 5x5 map is used to keep the mapping small.
+---------------------------------------------------------------------------------------------------------------------------
+When the operation code is 0F C7 and takes the ModR/M byte value C8 the operation code is "SSS" with no operands.
+At the very end of the function ^DecodeInstruction()^ an instruction that is "SSS" is compared if it is instruction "SSS".
+If it is operation "SSS" then the two bytes are then read as two codes which are used as the selected operation code in the 5x5 map.
+---------------------------------------------------------------------------------------------------------------------------
+link to the patent https://www.google.com/patents/US7552426
+-------------------------------------------------------------------------------------------------------------------------*/
+
+const MSynthetic = [
+  "VMGETINFO","VMSETINFO","VMDXDSBL","VMDXENBL","",
+  "VMCPUID","VMHLT","VMSPLAF","","",
+  "VMPUSHFD","VMPOPFD","VMCLI","VMSTI","VMIRETD",
+  "VMSGDT","VMSIDT","VMSLDT","VMSTR","",
+  "VMSDTE","","","",""
+];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Condition codes Note that the SSE, and MVEX versions are limited to the first 7 condition codes.
+XOP condition codes map differently.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+const ConditionCodes = [
+  "EQ","LT","LE","UNORD","NEQ","NLT","NLE","ORD", //SSE/L1OM/MVEX.
+  "EQ_UQ","NGE","NGT","FALSE","NEQ_OQ","GE","GT","TRUE", //VEX/EVEX.
+  "EQ_OS","LT_OQ","LE_OQ","UNORD_S","NEQ_US","NLT_UQ","NLE_UQ","ORD_S", //VEX/EVEX.
+  "EQ_US","NGE_UQ","NGT_UQ","FALSE_OS","NEQ_OS","GE_OQ","GT_OQ","TRUE_US", //VEX/EVEX.
+  "LT","LE","GT","GE","EQ","NEQ","FALSE","TRUE" //XOP.
+];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The Decoded operation name.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var Instruction = "";
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The Instructions operands.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var InsOperands = "";
+
+/*-------------------------------------------------------------------------------------------------------------------------
+This object stores a single decoded Operand, and gives it an number in OperandNum (Operand Number) for the order they are
+read in the operand string. It also stores all of the Settings for the operand.
+---------------------------------------------------------------------------------------------------------------------------
+Each Operand is sorted into an decoder array in the order they are decoded by the CPU in series.
+---------------------------------------------------------------------------------------------------------------------------
+Used by function ^DecodeOperandString()^ Which sets the operands active and gives them there settings along the X86Decoder array.
+---------------------------------------------------------------------------------------------------------------------------
+The following X86 patent link might help http://www.google.com/patents/US7640417
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var Operand = function(){
+  return(
+    {
+      Type:0, //The operand type some operands have different formats like DecodeImmediate() which has a type input.
+      BySizeAttrubute:false, //Effects how size is used depends on which operand type for which operand across the decoder array.
+      /*-------------------------------------------------------------------------------------------------------------------------
+      How Size is used depends on the operand it is along the decoder array for which function it uses to
+      decode Like DecodeRegValue(), or Decode_ModRM_SIB_Address(), and lastly DecodeImmediate() as they all take the BySize.
+      -------------------------------------------------------------------------------------------------------------------------*/
+      Size:0x00, //The Setting.
+      OperandNum:0, //The operand number basically the order each operand is read in the operand string.
+      Active:false, //This is set by the set function not all operand are used across the decoder array.
+      //set the operands attributes then set it active in the decoder array.
+      set:function(T, BySize, Settings, OperandNumber)
+      {
+        this.Type = T;
+        this.BySizeAttrubute = BySize;
+        this.Size = Settings;
+        this.OpNum = OperandNumber; //Give the operand the number it was read in the operand string.
+        this.Active = true; //set the operand active so it's settings are decoded by the ^DecodeOperands()^ function.
+      },
+      //Deactivates the operand after they are decoded by the ^DecodeOperands()^ function.
+      Deactivate:function(){ this.Active = false; }
+    }
+  );
+};
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The Decoder array is the order each operand is decoded after the select opcode if used. They are set during the decoding of
+the operand string using the function ^DecodeOperandString()^ which also gives each operand an number for the order they are
+read in. Then they are decoded by the Function ^DecodeOperands()^ which decodes each set operand across the X86Decoder in order.
+The number the operands are set during the decoding of the operand string is the order they will be positioned after decoding.
+As the operands are decoded they are also Deactivated so the next instruction can be decoded using different operands.
+---------------------------------------------------------------------------------------------------------------------------
+The following X86 patent link might help http://www.google.com/patents/US7640417
+---------------------------------------------------------------------------------------------------------------------------
+Used by functions ^DecodeOperandString()^, and ^DecodeOperands()^, after function ^DecodeOpcode()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var X86Decoder = [
+  /*-------------------------------------------------------------------------------------------------------------------------
+  First operand that is always decoded is "Reg Opcode" if used.
+  Uses the function ^DecodeRegValue()^ the input RValue is the three first bits of the opcode.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  new Operand(), //Reg Opcode if used.
+  /*-------------------------------------------------------------------------------------------------------------------------
+  The Second operand that is decoded in series is the ModR/M address if used.
+  Reads a byte using function ^Decode_ModRM_SIB_Value()^ gives it to the function ^Decode_ModRM_SIB_Address()^ which only
+  reads the Mode, and Base register for the address, and then decodes the SIB byte if base register is "100" binary in value.
+  does not use the Register value in the ModR/M because the register can also be used as a group opcode used by the
+  function ^DecodeOpcode()^, or uses a different register in single size with a different address pointer.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  new Operand(), //ModR/M address if used.
+  /*-------------------------------------------------------------------------------------------------------------------------
+  The third operand that is decoded if used is for the ModR/M reg bits.
+  Uses the already decoded byte from ^Decode_ModRM_SIB_Value()^ gives the three bit reg value to the function ^DecodeRegValue()^.
+  The ModR/M address, and reg are usually used together, but can also change direction in the encoding string.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  new Operand(), //ModR/M reg bits if used.
+  /*-------------------------------------------------------------------------------------------------------------------------
+  The fourth operand that is decoded in sequence is the first Immediate input if used.
+  The function ^DecodeImmediate()^ starts reading bytes as a number for input to instruction.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  new Operand(), //First Immediate if used.
+  /*-------------------------------------------------------------------------------------------------------------------------
+  The fifth operand that is decoded in sequence is the second Immediate input if used.
+  The function ^DecodeImmediate()^ starts reading bytes as a number for input to instruction.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  new Operand(), //Second Immediate if used (Note that the instruction "Enter" uses two immediate inputs).
+  /*-------------------------------------------------------------------------------------------------------------------------
+  The sixth operand that is decoded in sequence is the third Immediate input if used.
+  The function ^DecodeImmediate()^ starts reading bytes as a number for input to instruction.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  new Operand(), //Third Immediate if used (Note that the Larrabee vector instructions can use three immediate inputs).
+  /*-------------------------------------------------------------------------------------------------------------------------
+  Vector adjustment codes allow the selection of the vector register value that is stored into variable
+  VectorRegister that applies to the selected SSE instruction that is read after that uses it.
+  The adjusted vector value is given to the function ^DecodeRegValue()^.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  new Operand(), //Vector register if used. And if vector adjustments are applied to the SSE instruction.
+  /*-------------------------------------------------------------------------------------------------------------------------
+  Immediate Register encoding if used.
+  During the decoding of the immediate operands the ^DecodeImmediate()^ function stores the read IMM into an variable called
+  IMMValue. The upper four bits of IMMValue is given to the input RValue to the function ^DecodeRegValue()^.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  new Operand(), //Immediate Register encoding if used.
+  /*-------------------------------------------------------------------------------------------------------------------------
+  It does not matter which order the explicit operands decode as they do not require reading another byte after the opcode.
+  Explicit operands are selected internally in the cpu for instruction codes that only use one register, or pointer, or number input.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  new Operand(), //Explicit Operand one.
+  new Operand(), //Explicit Operand two.
+  new Operand(), //Explicit Operand three.
+  new Operand()  //Explicit Operand four.
+];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+SizeAttrSelect controls the General arithmetic extended sizes "8/16/32/64", and SIMD Vector register extended sizes "128/256/512/1024".
+---------------------------------------------------------------------------------------------------------------------------
+General arithmetic sizes "8/16/32/64" change by operand override which makes all operands go 16 bit.
+The width bit which is in the REX prefix makes operands go all 64 bits the changes depend on the instructions adjustable size.
+The value system goes as follows: 0=8, or 16, then 1=Default32, then 2=Max64. Smallest to largest in order.
+Changeable from prefixes. Code 66 hex is operand override, 48 hex is the REX.W setting. By default operands are 32 bit
+in size in both 32 bit mode, and 64 bit modes so by default the Size attribute setting is 1 in value so it lines up with 32.
+In the case of fewer size settings the size system aligns in order to the correct prefix settings.
+---------------------------------------------------------------------------------------------------------------------------
+If in 16 bit mode the 16 bit operand size trades places with 32, so when the operand override is used it goes from 16 to 32.
+Also in 32 bit mode any size that is 64 changes to 32, but except for operands that do not use the BySize system.
+---------------------------------------------------------------------------------------------------------------------------
+During Vector instructions size settings "128/256/512" use the SizeAttrSelect as the vector length setting as a 0 to 3 value from
+smallest to largest Note 1024 is Reserved the same system used for General arithmetic sizes "8/16/32/64" that go in order.
+If an operand is used that is 32/64 in size the Width bit allows to move between Sizes 32/64 separately.
+---------------------------------------------------------------------------------------------------------------------------
+Used by the function ^GetOperandSize()^ which uses a fast base 2 logarithm system.
+The function ^DecodeOpcode()^ also uses the current size setting for operation names that change name by size, Or
+In vector instructions the select instruction by size is used to Add additional instructions between the width bit (W=0), and (W=1).
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var SizeAttrSelect = 1;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The Width bit is used in combination with SizeAttrSelect only with Vector instructions.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var WidthBit = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Pointer size plus 16 bit's used by FAR JUMP and other instructions.
+For example FAR JUMP is size attributes 16/32/64 normally 32 is the default size, but it is 32+16=48 FWORD PTR.
+In 16 bit CPU mode the FAR jump defaults to 16 bits, but because it is a far jump it is 16+16=32 which is DWORD PTR.
+Set by the function ^DecodeOperandString()^ for if the ModR/M operand type is far pointer address.
+---------------------------------------------------------------------------------------------------------------------------
+Used by the function ^Decode_ModRM_SIB_Address()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var FarPointer = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+AddressOverride is hex opcode 67 then when used with any operation that uses the ModR/M in address mode the ram address
+goes down one in bit mode. Switches 64 address mode to 32 bit address mode, and in 32 bit mode the address switches to
+16 bit address mode which uses a completely different ModR/M format. When in 16 bit mode the address switches to 32 bit.
+Set true when Opcode 67 is read by ^DecodePrefixAdjustments()^ which effects the next opcode that is not a prefix opcode
+then is set false after instruction decodes.
+---------------------------------------------------------------------------------------------------------------------------
+Used by the function ^Decode_ModRM_SIB_Address()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var AddressOverride = false;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Extended Register value changes by the "R bit" in the REX prefix, or by the "Double R bit" settings in EVEX Extension
+which makes the Register operand reach to a max value of 32 registers along the register array.
+Normally the Register selection in ModR/M, is limited to three bits in binary 000 = 0 to 111 = 7.
+RegExtend stores the two binary bits that are added onto the three bit register selection.
+---------------------------------------------------------------------------------------------------------------------------
+When RegExtend is 00,000 the added lower three bits is 00,000 = 0 to 00,111 = 7.
+When RegExtend is 01,000 the added lower three bits is 01,000 = 8 to 01,111 = 15.
+When RegExtend is 10,000 the added lower three bits is 10,000 = 16 to 10,111 = 23.
+When RegExtend is 11,000 the added lower three bits is 11,000 = 24 to 10,111 = 31.
+---------------------------------------------------------------------------------------------------------------------------
+The Register expansion bits make the binary number from a 3 bit number to a 5 bit number by combining the EVEX.R'R bits.
+The REX opcode, and EVEX opcode 62 hex are decoded with function ^DecodePrefixAdjustments()^ which contain R bit settings.
+---------------------------------------------------------------------------------------------------------------------------
+Used by function ^DecodeRegValue()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var RegExtend = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The base register is used in ModR/M address mode, and Register mode and can be extended to 8 using the "B bit" setting
+from the REX prefix, or VEX Extension, and EVEX Extension, however in EVEX the tow bits "X, and B" are used together to
+make the base register reach 32 in register value if the ModR/M is in Register mode.
+---------------------------------------------------------------------------------------------------------------------------
+The highest the Base Register can be extended is from a 3 bit number to a 5 bit number.
+---------------------------------------------------------------------------------------------------------------------------
+Used by the function ^Decode_ModRM_SIB_Address()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var BaseExtend = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The index register is used in ModR/M memory address mode if the base register is "100" bin in the ModR/M which sets SIB mode.
+The Index register can be extended to 8 using the "X bit" setting when the Index register is used.
+The X bit setting is used in the REX prefix settings, and also the VEX Extension, and EVEX Extension.
+---------------------------------------------------------------------------------------------------------------------------
+The highest the Index Register can be extended is from a 3 bit number to a 4 bit number.
+---------------------------------------------------------------------------------------------------------------------------
+Used by the function ^Decode_ModRM_SIB_Address()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var IndexExtend = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+SegOverride is the bracket that is added onto the start of the decoded address it is designed this way so that if a segment
+Override Prefix is used it is stored with the segment.
+---------------------------------------------------------------------------------------------------------------------------
+used by function ^Decode_ModRM_SIB_Address()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var SegOverride = "[";
+
+/*-------------------------------------------------------------------------------------------------------------------------
+This may seem confusing, but the 8 bit high low registers are used all in "low order" when any REX prefix is used.
+Set RexActive true when the REX Prefix is used, for the High, and low Register separation.
+---------------------------------------------------------------------------------------------------------------------------
+Used by function ^DecodeRegValue()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var RexActive = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The SIMD value is set according to SIMD MODE by prefixes (none, 66, F2, F3), or by the value of VEX.pp, and EVEX.pp.
+Changes the selected instruction in ^DecodeOpcode()^ only for SSE vector opcodes that have 4 possible instructions in
+one instruction for the 4 modes otherwise 66 is Operand override, and F2 is REPNE, and F3 is REP prefix adjustments.
+By reusing some of the already used Prefix adjustments more opcodes did not have to be sacrificed.
+---------------------------------------------------------------------------------------------------------------------------
+SIMD is set 00 in binary by default, SIMD is set 01 in binary when opcode 66 is read by ^DecodePrefixAdjustments()^,
+SIMD is set 10 in binary when opcode F2 is read by ^DecodePrefixAdjustments()^, and SIMD is set 11 in binary when F3 is read
+by ^DecodePrefixAdjustments()^.
+---------------------------------------------------------------------------------------------------------------------------
+The VEX, and EVEX adjustment codes contain SIMD mode adjustment bits in which each code that is used to change the mode go
+in the same order as SIMD. This allows SIMD to be set directly by the VEX.pp, and EVEX.pp bit value.
+---------------------------------------------------------------------------------------------------------------------------
+VEX.pp = 00b (None), 01b (66h), 10b (F2h), 11b (F3h)
+EVEX.pp = 00b (None), 01b (66h), 10b (F2h), 11b (F3h)
+---------------------------------------------------------------------------------------------------------------------------
+Used by the function ^DecodeOpcode()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var SIMD = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Vect is set true during the decoding of an instruction code. If the instruction is an Vector instruction 4 in length for
+the four modes then Vect is set true. When Vect is set true the Function ^Decode_ModRM_SIB_Address()^ Will decode the
+ModR/M as a Vector address.
+---------------------------------------------------------------------------------------------------------------------------
+Set By function ^DecodeOpcode()^, and used by function ^Decode_ModRM_SIB_Address()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var Vect = false;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+In AVX512 The width bit can be ignored, or used. The width bit relates to the SIMD mode for size of the numbers in the vector.
+Modes N/A, F3 are 32 bit, while 66, F2 are 64 bit. The width bit has to be set for the extend data size for
+most AVX512 instructions unless the width bit is ignored. Some AVX512 vectors can also broadcast round to there extend data size
+controlled by the width bit extend size and SIMD mode.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var IgnoresWidthbit = false;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The VSIB setting is used for vectors that multiply the displacement by the Element size of the vectors, and use index as an vector pointer.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var VSIB = false;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+EVEX also has error suppression modes {ER} controlled by vector length, and if the broadcast round is active in register mode,
+or {SAE} suppresses all exceptions then it can not change rounding mode by vector length.
+MVEX also has error suppression modes {ER} controlled by conversion mode, and if the MVEX.E bit is set to round in register mode,
+or {SAE} suppresses all exceptions then it can not change rounding mode by vector length.
+L1OM vectors use {ER} as round control, and {SEA} as exponent adjustment.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var RoundingSetting = 0; //1 = SAE, and 2 = ER.
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The MVEX prefix can Integer convert, and Float convert, and Broadcast round using Swizzle.
+The EVEX prefix can only Broadcast round using an "b" control which sets the Broadcast round option for Swizzle.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var Swizzle = false; //Swizzle based instruction. If false then Up, or Down conversion.
+var Up = false; //Only used if Swizzle is false. If set false then it is an down conversion.
+var Float = false; //If False Integer data is used.
+var VectS = 0x00; //Stores the three vector settings Swizzle, Up, and Float, for faster comparison to special cases.
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The Extension is set 2 during opcode 62 hex for EVEX in which the ^DecodePrefixAdjustments()^ decodes the settings, but if
+the bit that must be set 0 for EVEX is set 1 then Extension is set 3 for MVEX.
+The Extension is set 1 during opcodes C4, and C5 hex in which the ^DecodePrefixAdjustments()^ decodes the settings for the VEX prefixes.
+---------------------------------------------------------------------------------------------------------------------------
+An instruction that has 4 opcode combinations based on SIMD can use another 4 in length separator in the select SIMD mode
+which selects the opcode based on extension used. This is used to separate codes that can be Vector adjusted, and not.
+Some codes can only be used in VEX, but not EVEX, and not all EVEX can be MVEX encoded as the EVEX versions were introduced after,
+also MMX instruction can not be used with vector adjustments.
+---------------------------------------------------------------------------------------------------------------------------
+By default Extension is 0 for decoding instructions normally.
+---------------------------------------------------------------------------------------------------------------------------
+Used by function ^DecodeOpcode()^ adds the letter "V" to the instruction name to show it uses Vector adjustments.
+When the Function ^DecodeOpcode()^ completes if Vect is not true and an Extension is active the instruction is invalid.
+Used By function ^DecodeOperandString()^ which allows the Vector operand to be used if existent in the operand string.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var Extension = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+MVEX/EVEX conversion modes. MVEX can directly set the conversion mode between float, or integer, to broadcast round using option bits.
+The EVEX Extension only has the broadcast rounding control. In which some instructions support "]{1to16}" (B32), or "]{1to8}" (B64)
+Based on the data size using the width bit setting. EVEX only can use the 1ToX broadcast round control.
+---------------------------------------------------------------------------------------------------------------------------
+Used by function ^Decode_ModRM_SIB_Address()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var ConversionMode = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+MVEX/EVEX rounding modes. In EVEX if the ModR/M is used in register mode and Bround Is active.
+The EVEX Error Suppression type is set by the RoundingSetting {ER}, and {SAE} settings for if the instruction supports it.
+The MVEX version allows the use of both rounding modes. MVEX can select the rounding type using option bits if the
+"MVEX.E" control is set in an register to register operation.
+---------------------------------------------------------------------------------------------------------------------------
+The function ^Decode_ModRM_SIB_Address()^ sets RoundMode.
+The function DecodeInstruction() adds the error Suppression to the end of the instruction.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var RoundMode = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+MVEX/EVEX register round modes.
+---------------------------------------------------------------------------------------------------------------------------
+Some instructions use SAE which suppresses all errors, but if an instruction uses {er} the 4 others are used by vector length.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+const RoundModes = [
+  "","","","","","","","", //First 8 No rounding mode.
+  /*-------------------------------------------------------------------------------------------------------------------------
+  MVEX/EVEX round Modes {SAE} Note MVEX (1xx) must be set 4 or higher, while EVEX uses upper 4 in rounding mode by vector length.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  ", {Error}", ", {Error}", ", {Error}", ", {Error}", ", {SAE}", ", {SAE}", ", {SAE}", ", {SAE}",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  L1OM/MVEX/EVEX round modes {ER}. L1OM uses the first 4, and EVEX uses the upper 4, while MVEX can use all 8.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  ", {RN}", ", {RD}", ", {RU}", ", {RZ}", ", {RN-SAE}", ", {RD-SAE}", ", {RU-SAE}", ", {RZ-SAE}",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  MVEX/EVEX round modes {SAE}, {ER} Both rounding modes can not possibly be set both at the same time.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  "0B", "4B", "5B", "8B", "16B", "24B", "31B", "32B" //L1OM exponent adjustments.
+];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+L1OM/MVEX register swizzle modes. When an swizzle operation is done register to register.
+Note L1OM skips swizzle type DACB thus the last swizzle type is an repeat of the DACB as the last L1OM swizzle.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+const RegSwizzleModes = [ "", "CDAB", "BADC", "DACB", "AAAA", "BBBB", "CCCC", "DDDD", "DACB" ];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+EVEX does not support conversion modes. Only broadcast round of 1To16, or 1To8 controlled by the data size.
+---------------------------------------------------------------------------------------------------------------------------
+MVEX.sss permits the use of conversion types by value without relating to the Swizzle conversion type.
+However During Up, and Down conversion MVEX does not allow Broadcast round control.
+---------------------------------------------------------------------------------------------------------------------------
+L1OM.CCCCC can only be used with Up, and Down conversion data types, and L1OM.sss can only be used with broadcast round.
+L1OM.SSS can only be used with swizzle conversions.
+---------------------------------------------------------------------------------------------------------------------------
+The Width bit relates to the data size of broadcast round as 32 bit it is X=16, and 64 bit number are larger and are X=8 in the "(1, or 4)ToX".
+The Width bit also relates to the Up conversion, and down conversion data size.
+Currently in K1OM, and L1OM there are no 64 bit Up, or Down conversions.
+---------------------------------------------------------------------------------------------------------------------------
+Note 66 hex is used as data size 64 in L1OM.
+---------------------------------------------------------------------------------------------------------------------------
+The element to grab from the array bellow is calculated mathematically.
+Note each element is an multiple of 2 in which the first element is the 32 size, and second element is 64 size.
+Lastly the elements are in order to the "CCCCC" value, and "SSS" value times 2, and plus 1 if 64 data size.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+const ConversionModes = [
+  //------------------------------------------------------------------------
+  "", "", //Not used.
+  //------------------------------------------------------------------------
+  "1To16", "1To8", //Settable as L1OM.sss/MVEX.sss = 001. Settable using EVEX broadcast round.
+  "4To16", "4To8", //Settable as L1OM.sss/MVEX.sss = 010. Settable using EVEX broadcast round.
+  //------------------------------------------------------------------------
+  "Float16", "Error", //Settable as "MVEX.sss = 011", and "L1OM.sss = 110 , L1OM.CCCCC = 00001".
+  //------------------------------------------------------------------------
+  "Float16RZ", "Error", //Settable only as L1OM.CCCCC = 00010.
+  //------------------------------------------------------------------------
+  "SRGB8", "Error", //Settable only as L1OM.CCCCC = 00011.
+  /*------------------------------------------------------------------------
+  MVEX/L1OM Up conversion, and down conversion types.
+  ------------------------------------------------------------------------*/
+  "UInt8", "Error", //Settable as L1OM.sss/MVEX.sss = 100, and L1OM.CCCCC = 00100.
+  "SInt8", "Error", //Settable as L1OM.sss/MVEX.sss = 101, and L1OM.CCCCC = 00101.
+  //------------------------------------------------------------------------
+  "UNorm8", "Error", //Settable as L1OM.sss = 101, or L1OM.CCCCC = 00110.
+  "SNorm8", "Error", //Settable as L1OM.CCCCC = 00111.
+  //------------------------------------------------------------------------
+  "UInt16", "Error", //Settable as L1OM.sss/MVEX.sss = 110, and L1OM.CCCCC = 01000
+  "SInt16", "Error", //Settable as L1OM.sss/MVEX.sss = 111, and L1OM.CCCCC = 01001
+  //------------------------------------------------------------------------
+  "UNorm16", "Error", //Settable as L1OM.CCCCC = 01010.
+  "SNorm16", "Error", //Settable as L1OM.CCCCC = 01011.
+  "UInt8I", "Error", //Settable as L1OM.CCCCC = 01100.
+  "SInt8I", "Error", //Settable as L1OM.CCCCC = 01101.
+  "UInt16I", "Error", //Settable as L1OM.CCCCC = 01110.
+  "SInt16I", "Error", //Settable as L1OM.CCCCC = 01111.
+  /*------------------------------------------------------------------------
+  L1OM Up conversion, and field conversion.
+  ------------------------------------------------------------------------*/
+  "UNorm10A", "Error", //Settable as L1OM.CCCCC = 10000. Also Usable as Integer Field control.
+  "UNorm10B", "Error", //Settable as L1OM.CCCCC = 10001. Also Usable as Integer Field control.
+  "UNorm10C", "Error", //Settable as L1OM.CCCCC = 10010. Also Usable as Integer Field control.
+  "UNorm2D", "Error", //Settable as L1OM.CCCCC = 10011. Also Usable as Integer Field control.
+  //------------------------------------------------------------------------
+  "Float11A", "Error", //Settable as L1OM.CCCCC = 10100. Also Usable as Float Field control.
+  "Float11B", "Error", //Settable as L1OM.CCCCC = 10101. Also Usable as Float Field control.
+  "Float10C", "Error", //Settable as L1OM.CCCCC = 10110. Also Usable as Float Field control.
+  "Error", "Error", //Settable as L1OM.CCCCC = 10111. Also Usable as Float Field control.
+  /*------------------------------------------------------------------------
+  Unused Conversion modes.
+  ------------------------------------------------------------------------*/
+  "Error", "Error", //Settable as L1OM.CCCCC = 11000.
+  "Error", "Error", //Settable as L1OM.CCCCC = 11001.
+  "Error", "Error", //Settable as L1OM.CCCCC = 11010.
+  "Error", "Error", //Settable as L1OM.CCCCC = 11011.
+  "Error", "Error", //Settable as L1OM.CCCCC = 11100.
+  "Error", "Error", //Settable as L1OM.CCCCC = 11101.
+  "Error", "Error", //Settable as L1OM.CCCCC = 11110.
+  "Error", "Error"  //Settable as L1OM.CCCCC = 11111.
+];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The VEX Extension, and MVEX/EVEX Extension have an Vector register selection built in for Vector operation codes that use the
+vector register. This operand is only read in the "operand string" if an VEX, or EVEX prefix was decoded by the
+function ^DecodePrefixAdjustments()^, and making Extension 1 for VEX, or 2 for EVEX instead of 0 by default.
+During a VEX, or EVEX version of the SSE instruction the vector bits are a 4 bit binary value of 0 to 15, and are extended
+in EVEX and MVEX to 32 by adding the EVEX.V, or MVEX.V bit to the vector register value.
+---------------------------------------------------------------------------------------------------------------------------
+Used with the function ^DecodeRegValue()^ to decode the Register value.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var VectorRegister = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The MVEX/EVEX Extension has an mask Register value selection for {K0-K7} mask to destination operand.
+The K mask register is always displayed to the destination operand in any Vector instruction used with MVEX/EVEX settings.
+---------------------------------------------------------------------------------------------------------------------------
+The {K} is added onto the first operand in OpNum before returning the decoded operands from the function ^DecodeOperands()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var MaskRegister = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The EVEX Extension has an zero mask bit setting for {z} zeroing off the registers.
+---------------------------------------------------------------------------------------------------------------------------
+The {z} is added onto the first operand in OpNum before returning the decoded operands from the function ^DecodeOperands()^.
+---------------------------------------------------------------------------------------------------------------------------
+In L1OM/MVEX this is used as the {NT}/{EH} control which when used with an memory address that supports it will prevent
+the data from going into the cache memory. Used as Hint control in the function ^Decode_ModRM_SIB_Address()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var HInt_ZeroMerg = false;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Some operands use the value of the Immediate operand as an opcode, or upper 4 bits as Another register, or condition codes.
+The Immediate is decoded normally, but this variable stores the integer value of the first IMM byte for the other byte
+encodings if used.
+---------------------------------------------------------------------------------------------------------------------------
+Used By the function ^DecodeOpcode()^ for condition codes, and by ^DecodeOperands()^ using the upper four bits as a register.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var IMMValue = 0;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Prefix G1, and G2 are used with Intel HLE, and other prefix codes such as repeat the instruction Codes F2, F3 which can be
+applied to any instruction unless it is an SIMD instruction which uses F2, and F3 as the SIMD Mode.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var PrefixG1 = "", PrefixG2 = "";
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Intel HLE is used with basic arithmetic instructions like Add, and subtract, and shift operations.
+Intel HLE instructions replace the Repeat F2, and F3, also lock F0 with XACQUIRE, and XRELEASE.
+---------------------------------------------------------------------------------------------------------------------------
+This is used by function ^DecodeInstruction()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var XRelease = false, XAcquire = false;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Intel HLE flip "G1 is used as = REP (XACQUIRE), or RENP (XRELEASE)", and "G2 is used as = LOCK" if the lock prefix was
+not read first then G1, and G2 flip. Also XACQUIRE, and XRELEASE replace REP, and REPNE if the LOCK prefix is used with
+REP, or REPNE if the instruction supports Intel HLE.
+---------------------------------------------------------------------------------------------------------------------------
+This is used by function ^DecodeInstruction()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var HLEFlipG1G2 = false;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Replaces segment overrides CS, and DS with HT, and HNT prefix for Branch taken and not taken used by jump instructions.
+---------------------------------------------------------------------------------------------------------------------------
+This is used by functions ^Decode_ModRM_SIB_Address()^, and ^DecodeInstruction()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var HT = false;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Instruction that support MPX replace the REPNE prefix with BND if operation is a MPX instruction.
+---------------------------------------------------------------------------------------------------------------------------
+This is used by function ^DecodeInstruction()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var BND = false;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The Invalid Instruction variable is very important as some bit settings in vector extensions create invalid operation codes.
+Also some opcodes are invalid in different cpu bit modes.
+---------------------------------------------------------------------------------------------------------------------------
+Function ^DecodePrefixAdjustments()^ Set the Invalid Opcode if an instruction or prefix is compared that is invalid for CPU bit mode.
+The function ^DecodeInstruction()^ returns an invalid instruction if Invalid Operation is used for CPU bit mode.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+var InvalidOp = false;
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The Register array holds arrays in order from 0 though 7 for the GetOperandSize function Which goes by Prefix size settings,
+and SIMD Vector length instructions using the adjusted variable SizeAttrSelect.
+---------------------------------------------------------------------------------------------------------------------------
+Used by functions ^DecodeRegValue()^, ^Decode_ModRM_SIB_Address()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+const REG = [
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 0 Is used only if the value returned from the GetOperandSize is 0 in value which is the 8 bit general use
+  Arithmetic registers names. Note that these same registers can be made 16 bit across instead of using just the first 8 bit
+  in size it depends on the instruction codes extension size.
+  ---------------------------------------------------------------------------------------------------------------------------
+  The function ^GetOperandSize()^ takes the size value the instruction uses for it's register selection by looking up binary
+  bit positions in the size value in log 2. Different instructions can be adjusted to different sizes using the operand size
+  override adjustment code, or width bit to adjust instructions to 64 in size introduced by AMD64, and EM64T in 64 bit computers.
+  ---------------------------------------------------------------------------------------------------------------------------
+  REG array Index 0 is the first 8 bit's of Arithmetic registers, however they can be used in both high, and low order in
+  which the upper 16 bit's is used as 8 bit's for H (High part), and the first 8 bits is L (LOW part) unless the rex prefix is
+  used then the first 8 bit's is used by all general use arithmetic registers. Because of this the array is broken into two
+  name listings that is used with the "RValue" number given to the function ^DecodeRegValue()^.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    /*-------------------------------------------------------------------------------------------------------------------------
+    8 bit registers without any rex prefix active is the normal low byte to high byte order of the
+    first 4 general use registers "A, C, D, and B" using 8 bits.
+    -------------------------------------------------------------------------------------------------------------------------*/
+    [
+      //Registers 8 bit names without any rex prefix index 0 to 7.
+      "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH"
+    ],
+    /*-------------------------------------------------------------------------------------------------------------------------
+    8 bit registers with any rex prefix active uses all 15 registers in low byte order.
+    -------------------------------------------------------------------------------------------------------------------------*/
+    [
+      //Registers 8 bit names with any rex prefix index 0 to 7.
+      "AL", "CL", "DL", "BL", "SPL", "BPL", "SIL", "DIL",
+      /*-------------------------------------------------------------------------------------------------------------------------
+      Registers 8 bit names Extended using the REX.R extend setting in the Rex prefix, or VEX.R bit, or EVEX.R.
+      What ever RegExtend is set based on prefix settings is added to the select Reg Index
+      -------------------------------------------------------------------------------------------------------------------------*/
+      "R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B"
+    ]
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 1 Is used only if the value returned from the GetOperandSize function is 1 in value in which bellow is the
+  general use Arithmetic register names 16 in size.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //Registers 16 bit names index 0 to 15.
+    "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", "R8W", "R9W", "R10W", "R11W", "R12W", "R13W", "R14W", "R15W"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 2 Is used only if the value from the GetOperandSize function is 2 in value in which bellow is the
+  general use Arithmetic register names 32 in size.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //Registers 32 bit names index 0 to 15.
+    "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "R8D", "R9D", "R10D", "R11D", "R12D", "R13D", "R14D", "R15D"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 3 Is used only if the value returned from the GetOperandSize function is 3 in value in which bellow is the
+  general use Arithmetic register names 64 in size.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //general use Arithmetic registers 64 names index 0 to 15.
+    "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 4 SIMD registers 128 across in size names. The SIMD registers are used by the SIMD Vector math unit.
+  Used only if the value from the GetOperandSize function is 4 in value.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //Register XMM names index 0 to 15.
+    "XMM0", "XMM1", "XMM2", "XMM3", "XMM4", "XMM5", "XMM6", "XMM7", "XMM8", "XMM9", "XMM10", "XMM11", "XMM12", "XMM13", "XMM14", "XMM15",
+    /*-------------------------------------------------------------------------------------------------------------------------
+    Register XMM names index 16 to 31.
+    Note different bit settings in the EVEX prefixes allow higher Extension values in the Register Extend variables.
+    -------------------------------------------------------------------------------------------------------------------------*/
+    "XMM16", "XMM17", "XMM18", "XMM19", "XMM20", "XMM21", "XMM22", "XMM23", "XMM24", "XMM25", "XMM26", "XMM27", "XMM28", "XMM29", "XMM30", "XMM31"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 5 SIMD registers 256 across in size names.
+  Used only if the value from the GetOperandSize function is 5 in value. Set by vector length setting.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //Register YMM names index 0 to 15.
+    "YMM0", "YMM1", "YMM2", "YMM3", "YMM4", "YMM5", "YMM6", "YMM7", "YMM8", "YMM9", "YMM10", "YMM11", "YMM12", "YMM13", "YMM14", "YMM15",
+    /*-------------------------------------------------------------------------------------------------------------------------
+    Register YMM names index 16 to 31.
+    Note different bit settings in the EVEX prefixes allow higher Extension values in the Register Extend variables.
+    -------------------------------------------------------------------------------------------------------------------------*/
+    "YMM16", "YMM17", "YMM18", "YMM19", "YMM20", "YMM21", "YMM22", "YMM23", "YMM24", "YMM25", "YMM26", "YMM27", "YMM28", "YMM29", "YMM30", "YMM31"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 6 SIMD registers 512 across in size names.
+  Used only if the value from the GetOperandSize function is 6 in value. Set by Vector length setting.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //Register ZMM names index 0 to 15.
+    "ZMM0", "ZMM1", "ZMM2", "ZMM3", "ZMM4", "ZMM5", "ZMM6", "ZMM7", "ZMM8", "ZMM9", "ZMM10", "ZMM11", "ZMM12", "ZMM13", "ZMM14", "ZMM15",
+    /*-------------------------------------------------------------------------------------------------------------------------
+    Register ZMM names index 16 to 31.
+    Note different bit settings in the EVEX prefixes allow higher Extension values in the Register Extend variables.
+    -------------------------------------------------------------------------------------------------------------------------*/
+    "ZMM16", "ZMM17", "ZMM18", "ZMM19", "ZMM20", "ZMM21", "ZMM22", "ZMM23", "ZMM24", "ZMM25", "ZMM26", "ZMM27", "ZMM28", "ZMM29", "ZMM30", "ZMM31"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 7 SIMD registers 1024 bit. The SIMD registers have not been made this long yet.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //Register unknowable names index 0 to 15.
+    "?MM0", "?MM1", "?MM2", "?MM3", "?MM4", "?MM5", "?MM6", "?MM7", "?MM8", "?MM9", "?MM10", "?MM11", "?MM12", "?MM13", "?MM14", "?MM15",
+    /*-------------------------------------------------------------------------------------------------------------------------
+    Register unknowable names index 16 to 31.
+    Note different bit settings in the EVEX prefixes allow higher Extension values in the Register Extend variables.
+    -------------------------------------------------------------------------------------------------------------------------*/
+    "?MM16", "?MM17", "?MM18", "?MM19", "?MM20", "?MM21", "?MM22", "?MM23", "?MM24", "?MM25", "?MM26", "?MM27", "?MM28", "?MM29", "?MM30", "?MM31"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  The Registers bellow do not change size they are completely separate, thus are used for special purposes. These registers
+  are selected by using size as a value for the index instead instead of giving size to the function ^GetOperandSize()^.
+  ---------------------------------------------------------------------------------------------------------------------------
+  REG array Index 8 Segment Registers.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //Segment Registers names index 0 to 7
+    "ES", "CS", "SS", "DS", "FS", "GS", "ST(-2)", "ST(-1)"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 9 Stack, and MM registers used by the X87 Float point unit.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //ST registers Names index 0 to 7
+    //note these are used with the X87 FPU, but are aliased to MM in MMX SSE.
+    "ST(0)", "ST(1)", "ST(2)", "ST(3)", "ST(4)", "ST(5)", "ST(6)", "ST(7)"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG index 10 Intel MM qword technology MMX vector instructions.
+  ---------------------------------------------------------------------------------------------------------------------------
+  These can not be used with Vector length adjustment used in vector extensions. The MM register are the ST registers aliased
+  to MM register. Instructions that use these registers use the the SIMD vector unit registers (MM), these are called the old
+  MMX vector instructions. When Intel added the SSE instructions to the SIMD math vector unit the new 128 bit XMM registers,
+  are added into the SIMD unit then they ware made longer in size 256, then 512 across in length, with 1024 (?MM Reserved)
+  In which the vector length setting was added to control there size though vector setting adjustment codes. Instruction
+  that can be adjusted by vector length are separate from the MM registers, but still use the same SIMD unit. Because of this
+  some Vector instruction codes can not be used with vector extension setting codes.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //Register MM names index 0 to 7
+    "MM0", "MM1", "MM2", "MM3", "MM4", "MM5", "MM6", "MM7"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG Array Index 11 bound registers introduced with MPX instructions.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //BND0 to BND3,and CR0 to CR3 for two byte opcodes 0x0F1A,and 0x0F1B register index 0 to 7
+    "BND0", "BND1", "BND2", "BND3", "CR0", "CR1", "CR2", "CR3"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 12 control registers depending on the values they are set changes the modes of the CPU.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //control Registers index 0 to 15
+    "CR0", "CR1", "CR2", "CR3", "CR4", "CR5", "CR6", "CR7", "CR8", "CR9", "CR10", "CR11", "CR12", "CR13", "CR14", "CR15"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 13 Debug mode registers.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //debug registers index 0 to 15
+    "DR0", "DR1", "DR2", "DR3", "DR4", "DR5", "DR6", "DR7", "DR8", "DR9", "DR10", "DR11", "DR12", "DR13", "DR14", "DR15"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG array Index 14 test registers.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //TR registers index 0 to 7
+    "TR0", "TR1", "TR2", "TR3", "TR4", "TR5", "TR6", "TR7"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG Array Index 15 SIMD vector mask registers.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    //K registers index 0 to 7, because of vector extensions it is repeated till last extension.
+    "K0", "K1", "K2", "K3", "K4", "K5", "K6", "K7","K0", "K1", "K2", "K3", "K4", "K5", "K6", "K7",
+    "K0", "K1", "K2", "K3", "K4", "K5", "K6", "K7","K0", "K1", "K2", "K3", "K4", "K5", "K6", "K7"
+  ],
+  /*-------------------------------------------------------------------------------------------------------------------------
+  REG Array Index 16 SIMD L1OM vector registers.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  [
+    "V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15",
+    "V16", "V17", "V18", "V19", "V20", "V21", "V22", "V23", "V24", "V25", "V26", "V27", "V28", "V29", "V30", "V31"
+  ]
+];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+RAM Pointer sizes are controlled by the GetOperandSize function which uses the Size Setting attributes for
+the select pointer in the PTR array alignment. The REG array above uses the same alignment to the returned
+size attribute except address pointers have far address pointers which are 16 bits plus there (8, or 16)/32/64 size attribute.
+---------------------------------------------------------------------------------------------------------------------------
+Far pointers add 16 bits to the default pointer sizes.
+16 bits become 16+16=32 DWORD, 32 bits becomes 32+16=48 FWORD, and 64+16=80 TBYTE.
+The function GetOperandSize goes 0=8 bit, 1=16 bit, 2=32 bit, 3=64 bit, 4=128, 5=256, 6=512, 7=1024.
+---------------------------------------------------------------------------------------------------------------------------
+The pointers are stored in doubles this is so every second position is each size setting.
+So the Returned size attribute has to be in multiples of 2 each size multiplied by 2 looks like this.
+(0*2=0)=8 bit, (1*2=2)=16 bit, (2*2=4)=32 bit, (3*2=6)=64 bit, (4*2=8)=128, (5*2=10)=256, (6*2=12)=512.
+This is the same as moving by 2 this is why each pointer is in groups of two before the next line.
+When the 16 bit shift is used for far pointers only plus one is added for the 16 bit shifted name of the pointer.
+---------------------------------------------------------------------------------------------------------------------------
+Used by the function ^Decode_ModRM_SIB_Address()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+const PTR = [
+  /*-------------------------------------------------------------------------------------------------------------------------
+  Pointer array index 0 when GetOperandSize returns size 0 then times 2 for 8 bit pointer.
+  In plus 16 bit shift array index 0 is added by 1 making 0+1=1 no pointer name is used.
+  The blank pointer is used for instructions like LEA which loads the effective address.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  "BYTE PTR ","",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  Pointer array index 2 when GetOperandSize returns size 1 then times 2 for 16 bit pointer alignment.
+  In plus 16 bit shift index 2 is added by 1 making 2+1=3 The 32 bit pointer name is used (mathematically 16+16=32).
+  -------------------------------------------------------------------------------------------------------------------------*/
+  "WORD PTR ","DWORD PTR ",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  Pointer array index 4 when GetOperandSize returns size 2 then multiply by 2 for index 4 for the 32 bit pointer.
+  In plus 16 bit shift index 4 is added by 1 making 4+1=5 the 48 bit Far pointer name is used (mathematically 32+16=48).
+  -------------------------------------------------------------------------------------------------------------------------*/
+  "DWORD PTR ","FWORD PTR ",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  Pointer array index 6 when GetOperandSize returns size 3 then multiply by 2 gives index 6 for the 64 bit pointer.
+  The Non shifted 64 bit pointer has two types the 64 bit vector "MM", and regular "QWORD" the same as the REG array.
+  In plus 16 bit shift index 6 is added by 1 making 6+1=7 the 80 bit TBYTE pointer name is used (mathematically 64+16=80).
+  -------------------------------------------------------------------------------------------------------------------------*/
+  "QWORD PTR ","TBYTE PTR ",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  Pointer array index 8 when GetOperandSize returns size 4 then multiply by 2 gives index 8 for the 128 bit Vector pointer.
+  In far pointer shift the MMX vector pointer is used.
+  MM is designed to be used when the by size system is false using index 9 for Pointer, and index 10 for Reg.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  "XMMWORD PTR ","MMWORD PTR ",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  Pointer array index 10 when GetOperandSize returns size 5 then multiply by 2 gives index 10 for the 256 bit SIMD pointer.
+  In far pointer shift the OWORD pointer is used with the bounds instructions it is also designed to be used when the by size is set false same as MM.
+  -------------------------------------------------------------------------------------------------------------------------*/
+  "YMMWORD PTR ","OWORD PTR ",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  Pointer array index 12 when GetOperandSize returns size 6 then multiply by 2 gives index 12 for the 512 bit pointer.
+  In plus 16 bit shift index 12 is added by 1 making 12+1=13 there is no 528 bit pointer name (mathematically 5126+16=528).
+  -------------------------------------------------------------------------------------------------------------------------*/
+  "ZMMWORD PTR ","ERROR PTR ",
+  /*-------------------------------------------------------------------------------------------------------------------------
+  Pointer array index 14 when GetOperandSize returns size 7 then multiply by 2 gives index 12 for the 1024 bit pointer.
+  In plus 16 bit shift index 14 is added by 1 making 12+1=13 there is no 1 bit pointer name (mathematically 5126+16=528).
+  -------------------------------------------------------------------------------------------------------------------------*/
+  "?MMWORD PTR ","ERROR PTR "];
+
+/*-------------------------------------------------------------------------------------------------------------------------
+SIB byte scale Note the Scale bits value is the selected index of the array bellow only used under
+a Memory address that uses the SIB Address mode which uses another byte for the address selection.
+---------------------------------------------------------------------------------------------------------------------------
+used by the ^Decode_ModRM_SIB_Address function()^.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+const scale = [
+ "", //when scale bits are 0 in value no scale multiple is used
+ "*2", //when scale bits are 1 in value a scale multiple of times two is used
+ "*4", //when scale bits are 2 in value a scale multiple of times four is used
+ "*8"  //when scale bits are 3 in value a scale multiple of times eight is used
+ ];
+ 
+/*-------------------------------------------------------------------------------------------------------------------------
+This function changes the Mnemonics array, for older instruction codes used by specific X86 cores that are under the same instruction codes.
+---------------------------------------------------------------------------------------------------------------------------
+Input "type" can be any number 0 to 6. If the input is 0 it sets the mnemonics back to normal.
+If input "type" is set 1 it will adjust the few conflicting mask instructions to the K1OM instruction names used by the knights corner processor.
+If input "type" is set 2 it will adjust the mnemonic array to decode Larrabee instructions.
+If input "type" is set 3 it will adjust the mnemonic array to decode Cyrix instructions which are now deprecated from the architecture.
+If input "type" is set 4 it will adjust the mnemonic array to decode Geode instructions which are now deprecated from the architecture.
+If input "type" is set 5 it will adjust the mnemonic array to decode Centaur instructions which are now deprecated from the architecture.
+If input "type" is set 6 it will adjust the mnemonic array to decode instruction for the X86/486 CPU which conflict with the vector unit instructions with UMOV.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function CompatibilityMode( type )
+{
+  //Reset the changeable sections of the Mnemonics array, and operand encoding array.
+  
+  Mnemonics[0x062] = ["BOUND","BOUND",""];
+  Mnemonics[0x110] = [["MOVUPS","MOVUPD","MOVSS","MOVSD"],["MOVUPS","MOVUPD","MOVSS","MOVSD"]];
+  Mnemonics[0x111] = [["MOVUPS","MOVUPD","MOVSS","MOVSD"],["MOVUPS","MOVUPD","MOVSS","MOVSD"]];
+  Mnemonics[0x112] = [["MOVLPS","MOVLPD","MOVSLDUP","MOVDDUP"],["MOVHLPS","???","MOVSLDUP","MOVDDUP"]];
+  Mnemonics[0x113] = [["MOVLPS","MOVLPD","???","???"],"???"];
+  Mnemonics[0x138] = ""; Mnemonics[0x139] = "???"; Mnemonics[0x13A] = ""; Mnemonics[0x13B] = "???"; Mnemonics[0x13C] = "???"; Mnemonics[0x13D] = "???"; Mnemonics[0x13F] = "???";
+  Mnemonics[0x141] = [["CMOVNO",["KANDW","","KANDQ"],"",""],["CMOVNO",["KANDB","","KANDD"],"",""],"",""];
+  Mnemonics[0x142] = [["CMOVB",["KANDNW","","KANDNQ"],"",""],["CMOVB",["KANDNB","","KANDND"],"",""],"",""];
+  Mnemonics[0x144] = [["CMOVE",["KNOTW","","KNOTQ"],"",""],["CMOVE",["KNOTB","","KNOTD"],"",""],"",""];
+  Mnemonics[0x145] = [["CMOVNE",["KORW","","KORQ"],"",""],["CMOVNE",["KORB","","KORD"],"",""],"",""];
+  Mnemonics[0x146] = [["CMOVBE",["KXNORW","","KXNORQ"],"",""],["CMOVBE",["KXNORB","","KXNORD"],"",""],"",""];
+  Mnemonics[0x147] = [["CMOVA",["KXORW","","KXORQ"],"",""],["CMOVA",["KXORB","","KXORD"],"",""],"",""];
+  Mnemonics[0x150] = ["???",[["MOVMSKPS","MOVMSKPS","",""],["MOVMSKPD","MOVMSKPD","",""],"???","???"]];
+  Mnemonics[0x151] = ["SQRTPS","SQRTPD","SQRTSS","SQRTSD"];
+  Mnemonics[0x152] = [["RSQRTPS","RSQRTPS","",""],"???",["RSQRTSS","RSQRTSS","",""],"???"];
+  Mnemonics[0x154] = ["ANDPS","ANDPD","???","???"];
+  Mnemonics[0x155] = ["ANDNPS","ANDNPD","???","???"];
+  Mnemonics[0x158] = [["ADDPS","ADDPS","ADDPS","ADDPS"],["ADDPD","ADDPD","ADDPD","ADDPD"],"ADDSS","ADDSD"];
+  Mnemonics[0x159] = [["MULPS","MULPS","MULPS","MULPS"],["MULPD","MULPD","MULPD","MULPD"],"MULSS","MULSD"];
+  Mnemonics[0x15A] = [["CVTPS2PD","CVTPS2PD","CVTPS2PD","CVTPS2PD"],["CVTPD2PS","CVTPD2PS","CVTPD2PS","CVTPD2PS"],"CVTSS2SD","CVTSD2SS"];
+  Mnemonics[0x15B] = [[["CVTDQ2PS","","CVTQQ2PS"],"CVTPS2DQ",""],"???","CVTTPS2DQ","???"];
+  Mnemonics[0x15C] = [["SUBPS","SUBPS","SUBPS","SUBPS"],["SUBPD","SUBPD","SUBPD","SUBPD"],"SUBSS","SUBSD"];
+  Mnemonics[0x15D] = ["MINPS","MINPD","MINSS","MINSD"];
+  Mnemonics[0x15E] = ["DIVPS","DIVPD","DIVSS","DIVSD"];
+  Mnemonics[0x178] = [["VMREAD","",["CVTTPS2UDQ","","CVTTPD2UDQ"],""],["EXTRQ","",["CVTTPS2UQQ","","CVTTPD2UQQ"],""],["???","","CVTTSS2USI",""],["INSERTQ","","CVTTSD2USI",""]];
+  Mnemonics[0x179] = [["VMWRITE","",["CVTPS2UDQ","","CVTPD2UDQ"],""],["EXTRQ","",["CVTPS2UQQ","","CVTPD2UQQ"],""],["???","","CVTSS2USI",""],["INSERTQ","","CVTSD2USI",""]];
+  Mnemonics[0x17A] = ["???",["","",["CVTTPS2QQ","","CVTTPD2QQ"],""],["","",["CVTUDQ2PD","","CVTUQQ2PD"],"CVTUDQ2PD"],["","",["CVTUDQ2PS","","CVTUQQ2PS"],""]];
+  Mnemonics[0x17B] = ["???",["","",["CVTPS2QQ","","CVTPD2QQ"],""],["","","CVTUSI2SS",""],["","","CVTUSI2SD",""]];
+  Mnemonics[0x17C] = ["???",["HADDPD","HADDPD","",""],"???",["HADDPS","HADDPS","",""]];
+  Mnemonics[0x17D] = ["???",["HSUBPD","HSUBPD","",""],"???",["HSUBPS","HSUBPS","",""]];
+  Mnemonics[0x17E] = [["MOVD","","",""],["MOVD","","MOVQ"],["MOVQ","MOVQ",["???","","MOVQ"],""],"???"],
+  Mnemonics[0x190] = [["SETO",["KMOVW","","KMOVQ"],"",""],["SETO",["KMOVB","","KMOVD"],"",""],"",""];
+  Mnemonics[0x192] = [["SETB",["KMOVW","","???"],"",""],["SETB",["KMOVB","","???"],"",""],"",["SETB",["KMOVD","","KMOVQ"],"",""]];
+  Mnemonics[0x193] = [["SETAE",["KMOVW","","???"],"",""],["SETAE",["KMOVB","","???"],"",""],"",["SETAE",["KMOVD","","KMOVQ"],"",""]];
+  Mnemonics[0x198] = [["SETS",["KORTESTW","","KORTESTQ"],"",""],["SETS",["KORTESTB","","KORTESTD"],"",""],"",""];
+  Mnemonics[0x1A6] = "XBTS";
+  Mnemonics[0x1A7] = "IBTS";
+
+  Operands[0x110] = [["0B700770","0B700770","0A040603","0A040609"],["0B700770","0B700770","0A0412040604","0A0412040604"]];
+  Operands[0x111] = [["07700B70","07700B70","06030A04","06090A04"],["07700B70","07700B70","060412040A04","060412040A04"]];
+  Operands[0x112] = [["0A0412040606","0A0412040606","0B700770","0B700768"],["0A0412040604","","0B700770","0B700770"]];
+  Operands[0x113] = [["06060A04","06060A04","",""],""];
+  Operands[0x141] = [["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],"",""];
+  Operands[0x142] = [["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],"",""];
+  Operands[0x144] = [["0B0E070E0180",["0A0F06FF","","0A0F06FF"],"",""],["0B0E070E0180",["0A0F06FF","","0A0F06FF"],"",""],"",""];
+  Operands[0x145] = [["0A02070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],["0A02070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],"",""];
+  Operands[0x146] = [["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],"",""];
+  Operands[0x147] = [["0B0E070E0180",["0A0F120F06FF","","0A0F120F06FF"],"",""],["0B0E070E0180",["0A0F120F06FF","",""],"",""],"",""];
+  Operands[0x150] = ["",[["0B0C0648","0B0C0730","",""],["0B0C0648","0B0C0730","",""],"",""]];
+  Operands[0x151] = ["0B7007700112","0B7007700112","0A04120406430102","0A04120406490102"];
+  Operands[0x152] = [["0A040648","0A040648","",""],"",["0A040643","0A0412040643","",""],""];
+  Operands[0x154] = ["0B70137007700110","0B70137007700110","",""];
+  Operands[0x155] = ["0B70137007700110","0B70137007700110","",""];
+  Operands[0x158] = [["0A040648","0B3013300730","0B70137007700112","0A061206066C0172"],["0A040648","0B3013300730","0B70137007700112","0A061206066C0112"],"0A04120406430102","0A04120406460102"];
+  Operands[0x159] = [["0A040648","0B3013300730","0B70137007700112","0A061206066C0172"],["0A040648","0B3013300730","0B70137007700112","0A061206066C0112"],"0A04120406430102","0A04120406460102"];
+  Operands[0x15A] = [["0A040648","0B300718","0B7007380111","0A06065A0111"],["0A040648","0B180730","0B3807700112","0A05066C0112"],"0A04120406430101","0A04120406460102"];
+  Operands[0x15B] = [[["0B7007700112","","0B380770011A"],"0B700770011A","",""],"","0B7007700111",""];
+  Operands[0x15C] = [["0A060648","0B3013300730","0B70137007700112","0A061206066C0172"],["0A060648","0B3013300730","0B70137007700112","0A061206066C0112"],"0A04120406430102","0A04120406460102"];
+  Operands[0x15D] = ["0B70137007700111","0B70137007700111","0A04120406430101","0A04120406460101"];
+  Operands[0x15E] = ["0B70137007700112","0B70137007700112","0A04120406430102","0A04120406460102"];
+  Operands[0x178] = [["07080B080180","",["0B7007700111","","0B3807700119"],""],["064F0C000C00","",["0B7007380119","","0B7007700111"],""],["","","0B0C06440109",""],["0A04064F0C000C00","","0B0C06460109",""]];
+  Operands[0x179] = [["0B0807080180","",["0B7007700112","","0B380770011A"],""],["0A04064F","",["0B700738011A","","0B7007700112"],""],["","","0B0C0644010A",""],["0A04064F","","0B0C0646010A",""]];
+  Operands[0x17A] = ["",["","",["0B7007380119","","0B7007700111"],""],["","",["0B7007380112","","0B700770011A"],"0A06065A0112"],["","",["0B700770011A","","0B3807700112"],""]];
+  Operands[0x17B] = ["",["","",["0B700738011A","","0B7007700112"],""],["","","0A041204070C010A",""],["","","0A041204070C010A",""]];
+  Operands[0x17C] = ["",["0A040604","0B7013700770","",""],"",["0A040604","0B7013700770","",""]];
+  Operands[0x17D] = ["",["0A040604","0B7013700770","",""],"",["0A040604","0B7013700770","",""]];
+  Operands[0x17E] = [["070C0A0A","","",""],["06240A040108","","06360A040108"],["0A040646","0A040646",["","","0A0406460108"],""],""];
+  Operands[0x190] = [["0600",["0A0F0612","","0A0F0636"],"",""],["0600",["0A0F0600","","0A0F0624"],"",""],"",""];
+  Operands[0x192] = [["0600",["0A0F06F4","",""],"",""],["0600",["0A0F06F4","",""],"",""],"",["0600",["0A0F06F6","","0A0F06F6"],"",""]];
+  Operands[0x193] = [["0600",["06F40A0F","",""],"",""],["0600",["06F40A0F","",""],"",""],"",["0600",["06F60A0F","","06F60A0F"],"",""]];
+  Operands[0x198] = [["0600",["0A0F06FF","","0A0F06FF"],"",""],["0600",["0A0F06FF","","0A0F06FF"],"",""],"",""];
+  Operands[0x1A6] = "0B0E070E";
+  Operands[0x1A7] = "070E0B0E";
+  
+  //Adjust the VEX mask instructions for K1OM (Knights corner) which conflict with the enhanced AVX512 versions.
+	
+  if( type === 1 )
+  {
+    Mnemonics[0x141] = [["CMOVNO","KAND","",""],"","",""];
+    Mnemonics[0x142] = [["CMOVB","KANDN","",""],"","",""];
+    Mnemonics[0x144] = [["CMOVE","KNOT","",""],"","",""];
+    Mnemonics[0x145] = [["CMOVNE","KOR","",""],"","",""];
+    Mnemonics[0x146] = [["CMOVBE","KXNOR","",""],"","",""];
+    Mnemonics[0x147] = [["CMOVA","KXOR","",""],"","",""];
+    Mnemonics[0x190] = [["SETO","KMOV","",""],"","",""];
+    Mnemonics[0x192] = [["SETB","KMOV","",""],"","",""];
+    Mnemonics[0x193] = [["SETAE","KMOV","",""],"","",""];
+    Mnemonics[0x198] = [["SETS","KORTEST","",""],"","",""];
+    Operands[0x141] = [["0B0E070E0180","0A0F06FF","",""],"","",""];
+    Operands[0x142] = [["0B0E070E0180","0A0F06FF","",""],"","",""];
+    Operands[0x144] = [["0B0E070E0180","0A0F06FF","",""],"","",""];
+    Operands[0x145] = [["0A02070E0180","0A0F06FF","",""],"","",""];
+    Operands[0x146] = [["0B0E070E0180","0A0F06FF","",""],"","",""];
+    Operands[0x147] = [["0B0E070E0180","0A0F06FF","",""],"","",""];
+    Operands[0x190] = [["0600","0A0F06FF","",""],"","",""];
+    Operands[0x192] = [["0600","06FF0B06","",""],"","",""];
+    Operands[0x193] = [["0600","07060A0F","",""],"","",""];
+    Operands[0x198] = [["0600","0A0F06FF","",""],"","",""];
+  }
+  
+  //Disable Knights corner, and AVX512, for L1OM (Intel Larrabee).
+  
+  if( type === 2 )
+  {
+    Mnemonics[0x62] = "";
+  }
+
+  //Adjust the Mnemonics, and Operand encoding, for the Cyrix processors.
+
+  if( type === 3 )
+  {
+    Mnemonics[0x138] = "SMINT"; Mnemonics[0x13A] = "BB0_RESET"; Mnemonics[0x13B] = "BB1_RESET"; Mnemonics[0x13C] = "CPU_WRITE"; Mnemonics[0x13D] = "CPU_READ";
+    Mnemonics[0x150] = "PAVEB"; Mnemonics[0x151] = "PADDSIW"; Mnemonics[0x152] = "PMAGW";
+    Mnemonics[0x154] = "PDISTIB"; Mnemonics[0x155] = "PSUBSIW";
+    Mnemonics[0x158] = "PMVZB"; Mnemonics[0x159] = "PMULHRW"; Mnemonics[0x15A] = "PMVNZB";
+    Mnemonics[0x15B] = "PMVLZB"; Mnemonics[0x15C] = "PMVGEZB"; Mnemonics[0x15D] = "PMULHRIW";
+    Mnemonics[0x15E] = "PMACHRIW";
+    Mnemonics[0x178] = "SVDC"; Mnemonics[0x179] = "RSDC"; Mnemonics[0x17A] = "SVLDT";
+    Mnemonics[0x17B] = "RSLDT"; Mnemonics[0x17C] = "SVTS"; Mnemonics[0x17D] = "RSTS";
+    Mnemonics[0x17E] = "SMINT";
+    Operands[0x150] = "0A0A06A9"; Operands[0x151] = "0A0A06A9"; Mnemonics[0x152] = "0A0A06A9";
+    Operands[0x154] = "0A0A06AF"; Operands[0x155] = "0A0A06A9";
+    Operands[0x158] = "0A0A06AF"; Operands[0x159] = "0A0A06A9"; Mnemonics[0x15A] = "0A0A06AF";
+    Operands[0x15B] = "0A0A06AF"; Operands[0x15C] = "0A0A06AF"; Mnemonics[0x15D] = "0A0A06A9";
+    Operands[0x15E] = "0A0A06AF";
+    Operands[0x178] = "30000A08"; Operands[0x179] = "0A083000"; Operands[0x17A] = "3000";
+    Operands[0x17B] = "3000"; Operands[0x17C] = "3000"; Operands[0x17D] = "3000";
+    Operands[0x17E] = "";
+  }
+  
+  //Adjust the Mnemonics, and Operand encoding, for the Geode processor.
+  
+  if( type === 4 )
+  {
+    Mnemonics[0x138] = "SMINT"; Mnemonics[0x139] = "DMINT"; Mnemonics[0x13A] = "RDM";
+  }
+  
+  //Adjust the Mnemonics, for the Centaur processor.
+
+  if( type === 5 )
+  {
+    Mnemonics[0x13F] = "ALTINST";
+    Mnemonics[0x1A6] = ["???",["MONTMUL","XSA1","XSA256","???","???","???","???","???"]];
+    Mnemonics[0x1A7] = [
+      "???",
+      [
+        "XSTORE",
+        ["???","???","XCRYPT-ECB","???"],
+        ["???","???","XCRYPT-CBC","???"],
+        ["???","???","XCRYPT-CTR","???"],
+        ["???","???","XCRYPT-CFB","???"],
+        ["???","???","XCRYPT-OFB","???"],
+        "???",
+        "???"
+      ]
+    ];
+    Operands[0x1A6] = ["",["","","","","","","",""]];
+    Operands[0x1A7] = [
+      "",
+      [
+        "",
+        ["","","",""],
+        ["","","",""],
+        ["","","",""],
+        ["","","",""],
+        ["","","",""],
+        "",
+        ""
+      ]
+    ];
+  }
+  
+  //Adjust the Mnemonics, for the X86/486 processor and older.
+  
+  if( type === 6 )
+  {
+    Mnemonics[0x110] = "UMOV"; Mnemonics[0x111] = "UMOV"; Mnemonics[0x112] = "UMOV"; Mnemonics[0x113] = "UMOV";
+    Mnemonics[0x1A6] = "CMPXCHG"; Mnemonics[0x1A7] = "CMPXCHG";
+    Operands[0x110] = "06000A00"; Operands[0x111] = "070E0B0E"; Operands[0x112] = "0A000600"; Operands[0x113] = "0B0E070E";
+    Operands[0x1A6] = ""; Operands[0x1A7] = "";
+  }
+  
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+This function loads the BinCode array using an hex string as input, and Resets the Code position along the array, but does not
+reset the base address. This allows programs to be decoded in sections well maintaining the accurate 64 bit base address.
+---------------------------------------------------------------------------------------------------------------------------
+The function "SetBasePosition()" sets the location that the Code is from in memory.
+The function "GotoPosition()" tests if the address is within rage of the current loaded binary.
+The function "GetPosition()" Gives back the current base address in it's proper format for the current BitMode.
+---------------------------------------------------------------------------------------------------------------------------
+If the hex input is invalid returns false.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function LoadBinCode( HexStr )
+{
+  //Clear BinCode, and Reset Code Position in Bin Code array.
+
+  BinCode = []; CodePos = 0;
+
+  //Iterate though the hex string and covert to 0 to 255 byte values into the BinCode array.
+
+  var len = HexStr.length;
+
+  for( var i = 0, el = 0, Sing = 0, int32 = 0; i < len; i += 8 )
+  {
+    //It is faster to read 8 hex digits at a time if possible.
+
+    int32 = parseInt( HexStr.slice( i, i + 8 ), 16 );
+
+    //If input is invalid return false.
+
+    if( isNaN( int32 ) ){ return ( false ); }
+
+    //If the end of the Hex string is reached and is not 8 digits the number has to be lined up.
+
+    ( ( len - i ) < 8 ) && ( int32 <<= ( 8 - len - i ) << 2 );
+
+    //The variable sing corrects the unusable sing bits during the 4 byte rotation algorithm.
+
+    Sing = int32;
+
+    //Remove the Sing bit value if active for when the number is changed to int32 during rotation.
+
+    int32 ^= int32 & 0x80000000;
+
+    //Rotate the 32 bit int so that each number is put in order in the BinCode array. Add the Sing Bit positions back though each rotation.
+
+    int32 = ( int32 >> 24 ) | ( ( int32 << 8 ) & 0x7FFFFFFF );
+    BinCode[el++] = ( ( ( Sing >> 24 ) & 0x80 ) | int32 ) & 0xFF;
+    int32 = ( int32 >> 24 ) | ( ( int32 << 8 ) & 0x7FFFFFFF );
+    BinCode[el++] = ( ( ( Sing >> 16 ) & 0x80 ) | int32 ) & 0xFF;
+    int32 = ( int32 >> 24 ) | ( ( int32 << 8 ) & 0x7FFFFFFF );
+    BinCode[el++] = ( ( ( Sing >> 8 ) & 0x80 ) | int32 ) & 0xFF;
+    int32 = ( int32 >> 24 ) | ( ( int32 << 8 ) & 0x7FFFFFFF );
+    BinCode[el++] = ( ( Sing & 0x80 ) | int32 ) & 0xFF;
+  }
+
+  //Remove elements past the Number of bytes in HexStr because int 32 is always 4 bytes it is possible to end in an uneven number.
+
+  len >>= 1;
+
+  for(; len < BinCode.length; BinCode.pop() );
+
+  //Return true for that the binary code loaded properly.
+
+  return ( true );
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+This function moves the address by one and caries to 64 section for the Base address. The BitMode settings limit how much of
+the 64 bit address is used in functions "GetPosition()", and "GotoPosition()", for the type of binary being disassemble.
+This function also moves the binary code array position CodePos by one basically this function is used to progress the
+disassembler as it is decoding a sequence of bytes.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function NextByte()
+{
+  //Add the current byte as hex to InstructionHex which will be displayed beside the decoded instruction.
+  //After an instruction decodes InstructionHex is only added beside the instruction if ShowInstructionHex is active.
+
+  if ( CodePos < BinCode.length ) //If not out of bounds.
+  {
+    //Convert current byte to String, and pad.
+    var t;
+
+    ( ( t = BinCode[CodePos++].toString(16) ).length === 1) && ( t = "0" + t );
+
+    //Add it to the current bytes used for the decode instruction.
+
+    InstructionHex += t;
+
+    //Continue the Base address.
+
+    ( ( Pos32 += 1 ) > 0xFFFFFFFF ) && ( Pos32 = 0, ( ( Pos64 += 1 ) > 0xFFFFFFFF ) && ( Pos64 = 0 ) );
+  }
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Takes a 64/32/16 bit hex string and sets it as the address position depending on the address format it is split into an
+segment, and offset address. Note that the Code Segment is used in 16 bit code. Also code segment is also used in 32 bit
+if set 36, or higher. Effects instruction location in memory when decoding a program.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function SetBasePosition( Address )
+{
+  //Split the Segment:offset.
+
+  var t = Address.split(":");
+
+  //Set the 16 bit code segment position if there is one.
+
+  if ( typeof t[1] !== "undefined" ){ CodeSeg = parseInt( t[0].slice( t[0].length - 4 ), 16 ); Address = t[1]; }
+
+  //Adjust the Instruction pointer 16(IP)/32(EIP)/64(RIP). Also varies based on Bit Mode.
+
+  var Len = Address.length;
+
+  if( Len >= 9 && BitMode == 2 ){ Pos64 = parseInt( Address.slice( Len - 16, Len - 8 ), 16 ); }
+  if( Len >= 5 && BitMode >= 1 && !( BitMode == 1 & CodeSeg >= 36 ) ){ Pos32 = parseInt( Address.slice( Len - 8 ), 16 ); }
+  else if( Len >= 1 && BitMode >= 0 ){ Pos32 = ( Pos32 & 0xFFFF0000 ) | ( parseInt( Address.slice( Len - 4 ), 16 ) ); }
+
+  //Convert Pos32 to undignified integer.
+
+  if ( Pos32 < 0 ) { Pos32 += 0x100000000; }
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Gives back the current Instruction address position.
+In 16 bit an instruction location is Bound to the code segment location in memory, and the first 16 bit of the instruction pointer 0 to 65535.
+In 32 bit an instruction location uses the first 32 bit's of the instruction pointer.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function GetPosition()
+{
+  //If 16 bit Seg:Offset, or if 32 bit and CodeSeg is 36, or higher.
+
+  if( BitMode === 0 | ( BitMode === 1 & CodeSeg >= 36 ) )
+  {
+    for ( var S16 = ( Pos32 & 0xFFFF ).toString(16); S16.length < 4; S16 = "0" + S16 );
+    for ( var Seg = ( CodeSeg ).toString(16); Seg.length < 4; Seg = "0" + Seg );
+    return( ( Seg + ":" + S16 ).toUpperCase() );
+  }
+
+  //32 bit, and 64 bit section.
+
+  var S64="", S32="";
+
+  //If 32 bit or higher.
+
+  if( BitMode >= 1 )
+  {
+    for ( S32 = Pos32.toString(16); S32.length < 8; S32 = "0" + S32 );
+  }
+
+  //If 64 bit.
+
+  if( BitMode === 2 )
+  {
+    for ( S64 = Pos64.toString(16); S64.length < 8; S64 = "0" + S64 );
+  }
+
+  //Return the 32/64 address.
+
+  return ( ( S64 + S32 ).toUpperCase() );
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Moves the dissembler 64 bit address, and CodePos to correct address. Returns false if address location is out of bounds.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function GotoPosition( Address )
+{
+  //Current address location.
+
+  var LocPos32 = Pos32;
+  var LocPos64 = Pos64;
+  var LocCodeSeg = CodeSeg;
+
+  //Split the by Segment:offset address format.
+
+  var t = Address.split(":");
+
+  //Set the 16 bit code segment location if there is one.
+
+  if ( typeof t[1] !== "undefined" )
+  {
+    LocCodeSeg = parseInt(t[0].slice( t[0].length - 4 ), 16);
+    Address = t[1];
+  }
+
+  var len = Address.length;
+
+  //If the address is 64 bit's long, and bit mode is 64 bit adjust the 64 bit location.
+
+  if( len >= 9 && BitMode === 2 )
+  {
+    LocPos64 = parseInt( Address.slice( len - 16, len - 8 ), 16 );
+  }
+
+  //If the address is 32 bit's long, and bit mode is 32 bit, or higher adjust the 32 bit location.
+
+  if( len >= 5 && BitMode >= 1 & !( BitMode === 1 & CodeSeg >= 36 ) )
+  {
+    LocPos32 = parseInt( Address.slice( len - 8 ), 16 );
+  }
+
+  //Else If the address is 16 bit's long, and bit mode is 16 bit, or higher adjust the first 16 bit's in location 32.
+
+  else if( len >= 1 && BitMode >= 0 )
+  {
+    LocPos32 = ( LocPos32 - LocPos32 + parseInt( Address.slice( len - 4 ), 16 ) );
+  }
+
+  //Find the difference between the current base address and the selected address location.
+
+  var Dif32 = Pos32 - LocPos32, Dif64 = Pos64 - LocPos64;
+
+  //Only calculate the Code Segment location if The program uses 16 bit address mode otherwise the
+  //code segment does not affect the address location.
+
+  if( ( BitMode === 1 & CodeSeg >= 36 ) || BitMode === 0 )
+  {
+    Dif32 += ( CodeSeg - LocCodeSeg ) << 4;
+  }
+
+  //Before adjusting the Code Position Backup the Code Position in case that the address is out of bounds.
+
+  t = CodePos;
+
+  //Subtract the difference to the CodePos position.
+
+  CodePos -= Dif64 * 4294967296 + Dif32;
+
+  //If code position is out of bound for the loaded binary in the BinCode array, or
+  //is a negative index return false and reset CodePos.
+
+  if( CodePos < 0 || CodePos > BinCode.length )
+  {
+    CodePos = t; return ( false );
+  }
+
+  //Set the base address so that it matches the Selected address location that Code position is moved to in relative space in the BinCode Array.
+
+  CodeSeg = LocCodeSeg;
+  Pos32 = LocPos32
+  Pos64 = LocPos64;
+
+  //Return true for that the address Position is moved in range correctly.
+
+  return ( true );
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Finds bit positions to the Size attribute indexes in REG array, and the Pointer Array. For the Size Attribute variations.
+---------------------------------------------------------------------------------------------------------------------------
+The SizeAttribute settings is 8 digits big consisting of 1, or 0 to specify the the extended size that an operand can be made.
+In which an value of 01100100 is decoded as "0 = 1024, 1 = 512, 1 = 256, 0 = 128, 0 = 64, 1 = 32, 0 = 16, 0 = 8".
+In which the largest bit position is 512, and is the 6th number "0 = 7, 1 = 6, 1 = 5, 0 = 4, 0 = 3, 1 = 2, 0 = 1, 0 = 0".
+In which 6 is the bit position for 512 as the returned Size . Each size is in order from 0 to 7, thus the size given back
+from this function Lines up With the Pinter array, and Register array indexes for the register names by size, and Pointers.
+---------------------------------------------------------------------------------------------------------------------------
+The variable SizeAttrSelect is separate from this function it is adjusted by prefixes that adjust Vector size, and General purpose registers.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function GetOperandSize( SizeAttribute )
+{
+  /*----------------------------------------------------------------------------------------------------------------------------------------
+  Each S value goes in order to the vector length value in EVEX, and VEX Smallest to biggest in perfect alignment.
+  SizeAttrSelect is set 1 by default, unless it is set 0 to 3 by the vector length bit's in the EVEX prefix, or 0 to 1 in the VEX prefix.
+  In which if it is not an Vector instruction S2 acts as the mid default size attribute in 32 bit mode, and 64 bit mode for all instructions.
+  ----------------------------------------------------------------------------------------------------------------------------------------*/
+
+  var S4 = 0, S3 = 0, S2 = 0, S1 = 0, S0 = -1; //Note S0 is Vector size 1024, which is unused.
+
+  /*----------------------------------------------------------------------------------------------------------------------------------------
+  Lookup the Highest active bit in the SizeAttribute value giving the position the bit is in the number. S1 will be the biggest size attribute.
+  In which this size attribute is only used when the extended size is active from the Rex prefix using the W (width) bit setting.
+  In which sets variable SizeAttrSelect to 2 in value when the Width bit prefix setting is decoded, or if it is an Vector this is the
+  Max vector size 512 in which when the EVEX.L'L bit's are set 10 = 2 sets SizeAttrSelect 2, note 11 = 3 is reserved for vectors 1024 in size.
+  ----------------------------------------------------------------------------------------------------------------------------------------*/
+
+  S1 = SizeAttribute; S1 = ( ( S1 & 0xF0 ) !== 0 ? ( S1 >>= 4, 4 ) : 0 ) | ( ( S1 & 0xC ) !== 0 ? ( S1 >>= 2, 2 ) : 0 ) | ( ( S1 >>= 1 ) !== 0 );
+
+  /*----------------------------------------------------------------------------------------------------------------------------------------
+  If there is no size attributes then set S1 to -1 then the rest are set to S1 as they should have no size setting.
+  ----------------------------------------------------------------------------------------------------------------------------------------*/
+
+  if( SizeAttribute === 0 ) { S1 = -1; }
+
+  /*----------------------------------------------------------------------------------------------------------------------------------------
+  Convert the Bit Position of S1 into it's value and remove it by subtracting it into the SizeAttribute settings.
+  ----------------------------------------------------------------------------------------------------------------------------------------*/
+
+  SizeAttribute -= ( 1 << S1 );
+
+  /*----------------------------------------------------------------------------------------------------------------------------------------
+  Lookup the Highest Second active bit in the SizeAttribute value giving the position the bit is in the number.
+  In which S2 will be the default size attribute when SizeAttrSelect is 1 and has not been changed by prefixes, or If this is an vector
+  SizeAttrSelect is set one by the EVEX.L'L bit's 01 = 1, or VEX.L is active 1 = 1 in which the Mid vector size is used.
+  In which 256 is the Mid vector size some vectors are smaller some go 64/128/256 in which the mid size is 128.
+  ----------------------------------------------------------------------------------------------------------------------------------------*/
+
+  S2 = SizeAttribute; S2 = ( ( S2 & 0xF0 ) !== 0 ? ( S2 >>= 4, 4 ) : 0 ) | ( ( S2 & 0xC ) !== 0 ? ( S2 >>= 2, 2 ) : 0 ) | ( ( S2 >>= 1 ) !== 0 );
+
+  /*----------------------------------------------------------------------------------------------------------------------------------------
+  Convert the Bit Position of S2 into it's value and remove it by subtracting it if it is not 0.
+  ----------------------------------------------------------------------------------------------------------------------------------------*/
+
+  if( S2 !== 0 ) { SizeAttribute -= ( 1 << S2 ); }
+
+  /*----------------------------------------------------------------------------------------------------------------------------------------
+  If it is 0 The highest size attribute is set as the default operand size. So S2 is aliased to S1, if there is no other Size setting attributes.
+  ----------------------------------------------------------------------------------------------------------------------------------------*/
+
+  else { S2 = S1; }
+
+  /*----------------------------------------------------------------------------------------------------------------------------------------
+  Lookup the Highest third active bit in the SizeAttribute value giving the position the bit is in the number.
+  The third Size is only used if the Operand override prefix is used setting SizeAttrSelect to 0, or if this is an vector the
+  EVEX.L'L bit's are 00 = 0 sets SizeAttrSelect 0, or VEX.L = 0 in which SizeAttrSelect is 0 using the smallest vector size.
+  ----------------------------------------------------------------------------------------------------------------------------------------*/
+
+  S3 = SizeAttribute; S3 = ( ( S3 & 0xF0 ) !== 0 ? ( S3 >>= 4, 4 ) : 0 ) | ( ( S3 & 0xC ) !== 0 ? ( S3 >>= 2, 2 ) : 0 ) | ( ( S3 >>= 1 ) !== 0 );
+
+  /*----------------------------------------------------------------------------------------------------------------------------------------
+  Convert the Bit Position of S3 into it's value and remove it by subtracting it if it is not 0.
+  ----------------------------------------------------------------------------------------------------------------------------------------*/
+
+  if( S3 !== 0 ) { SizeAttribute -= ( 1 << S3 ); }
+
+  /*----------------------------------------------------------------------------------------------------------------------------------------
+  If it is 0 The second size attribute is set as the operand size. So S3 is aliased to S2, if there is no other Size setting attributes.
+  ----------------------------------------------------------------------------------------------------------------------------------------*/
+
+  else { S3 = S2; if( S2 !== 2 ) { S2 = S1; } };
+
+  //In 32/16 bit mode the operand size must never exceed 32.
+
+  if ( BitMode <= 1 && S2 >= 3 && !Vect )
+  {
+    if( ( S1 | S2 | S3 ) === S3 ){ S1 = 2; S3 = 2; } //If single size all adjust 32.
+    S2 = 2; //Default operand size 32.
+  }
+
+  //In 16 bit mode The operand override is always active until used. This makes all operands 16 bit size.
+  //When Operand override is used it is the default 32 size. Flip S3 with S2.
+
+  if( BitMode === 0 && !Vect ) { var t = S3; S3 = S2; S2 = t; }
+
+  //If an Vect is active, then EVEX.W, VEX.W, or XOP.W bit acts as 32/64.
+
+  if( ( Vect || Extension > 0 ) && ( ( S1 + S2 + S3 ) === 7 | ( S1 + S2 + S3 ) === 5 ) ) { Vect = false; return( ( [ S2, S1 ] )[ WidthBit & 1 ] ); }
+
+  //If it is an vector, and Bround is active vector goes max size.
+
+  if( Vect && ConversionMode === 1 )
+  {
+    S0 = S1; S3 = S1; S2 = S1;
+  }
+
+  //Note the fourth size that is -1 in the returned size attribute is Vector length 11=3 which is invalid unless Intel decides to add 1024 bit vectors.
+  //The only time S0 is not negative one is if vector broadcast round is active.
+
+  return( ( [ S3, S2, S1, S0 ] )[ SizeAttrSelect ] );
+
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+This function returns an array with three numbers.
+---------------------------------------------------------------------------------------------------------------------------
+The first element is the two bits for the ModR/M byte for Register mode, Memory mode, and Displacement settings, or the SIB byte
+scale as a number value 0 to 3 if it is not an ModR/M byte since they both use the same bit grouping.
+The second element is the three bits for the ModR/M byte Opcode/Reg bits, or the SIB Index Register value as a number value 0 to 7.
+The third element is the last three bits for the ModR/M byte the R/M bits, or the SIB Base Register value as a number value 0 to 7.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function Decode_ModRM_SIB_Value()
+{
+  //Get the current position byte value
+
+  var v = BinCode[CodePos];
+
+  //The first tow binary digits of the read byte is the Mode bits of the ModR/M byte or
+  //The first tow binary digits of the byte is the Scale bits of the SIB byte.
+
+  var ModeScale = (v >> 6) & 0x03; //value 0 to 3
+
+  //The three binary digits of the read byte after the first two digits is the OpcodeReg Value of the ModR/M byte or
+  //The three binary digits of the read byte after the first two digits is the Index Register value for the SIB byte.
+
+  var OpcodeRegIndex = (v >> 3) & 0x07; //value 0 to 7
+
+  //The three binary digits at the end of the read byte is the R/M (Register,or Memory) Value of the ModR/M byte or
+  //The three binary digits at the end of the read byte is the Base Register Value of the SIB byte.
+
+  var RMBase = v & 0x07; //value 0 to 7
+
+  //Put the array together containing the three indexes with the value
+  //Note both the ModR/M byte and SIB byte use the same bit value pattern
+
+  var ByteValueArray = [
+    ModeScale,//Index 0 is the first tow bits for the Mode, or Scale Depending on what the byte value is used for.
+    OpcodeRegIndex,//Index 1 is the three bits for the OpcodeReg, or Index Depending on what the byte value is used for.
+    RMBase //Index 2 is the three bits for the RM, or BASE bits Depending on what the byte value is used for.
+  ];
+
+  //Move the Decoders Position by one.
+  
+  NextByte();
+
+  //return the array containing the decoded values of the byte.
+
+  return (ByteValueArray);
+
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+When input type is value 0 decode the immediate input regularly to it's size setting for accumulator Arithmetic, and IO.
+When input type is value 1 decode the immediate input regularly, but zeros out the upper 4 bits for Register encoding.
+When input type is value 2 decode the immediate as a relative address used by jumps, and function calls.
+When input type is value 3 decode the immediate as a Integer Used by Displacements.
+---------------------------------------------------------------------------------------------------------------------------
+The function argument SizeSetting is the size attributes of the IMM that is decoded using the GetOperandSize function.
+The Imm uses two size setting, the first 4 bits are used for the Immediate actual adjustable sizes 8,16,32,64.
+---------------------------------------------------------------------------------------------------------------------------
+If BySize is false the SizeSetting is used numerically as a single size selection as
+0=8,1=16,2=32,3=64 by size setting value.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function DecodeImmediate( type, BySize, SizeSetting )
+{
+
+  /*-------------------------------------------------------------------------------------------------------------------------
+  Initialize V32, and V64 which will store the Immediate value.
+  JavaScript Float64 numbers can not accurately work with numbers 64 bit's long.
+  So numbers are split into two numbers that should never exceed an 32 bit value though calculation.
+  Numbers that are too big for the first 32 bit's are stored as the next 32 bit's in V64.
+  -------------------------------------------------------------------------------------------------------------------------*/
+
+  var V32 = 0, V64 = 0;
+
+  //*Initialize the Pad Size for V32, and V64 depending On the Immediate type Calculation they use.
+
+  var Pad32 = 0, Pad64 = 0;
+
+  //*Initialize the Sing value that is only set for Negative, or Positive Relative displacements.
+
+  var Sing = 0;
+
+  //*Initialize the Sing Extend variable size as 0 Some Immediate numbers Sing extend.
+
+  var Extend = 0;
+
+  //*The variable S is the size of the Immediate.
+
+  var S = SizeSetting & 0x0F;
+
+  //*Extend size.
+
+  Extend = SizeSetting >> 4;
+
+  //*If by Size attributes is set true.
+
+  if ( BySize )
+  {
+    S = GetOperandSize( S );
+
+    if ( Extend > 0 )
+    {
+      Extend = GetOperandSize( Extend );
+    }
+  }
+
+  /*-------------------------------------------------------------------------------------------------------------------------
+  The possible values of S (Calculated Size) are S=0 is IMM8, S=1 is IMM16, S=2 is IMM32, S=3 is IMM64.
+  Calculate how many bytes that are going to have to be read based on the value of S.
+  S=0 is 1 byte, S=1 is 2 bytes, S=2 is 4 bytes, S=3 is 8 bytes.
+  The Number of bytes to read is 2 to the power of S.
+  -------------------------------------------------------------------------------------------------------------------------*/
+
+  var n = 1 << S;
+
+  //Adjust Pad32, and Pad64.
+
+  Pad32 = Math.min( n, 4 ); ( n >= 8 ) && ( Pad64 = 8 );
+
+  //Store the first byte of the immediate because IMM8 can use different encodings.
+
+  IMMValue = BinCode[CodePos];
+
+  //*Loop and Move the Decoder to the next byte Code position to the number of bytes to read for V32, and V64.
+
+  for ( var i = 0, v = 1; i < Pad32; V32 += BinCode[CodePos] * v, i++, v *= 256, NextByte() );
+  for ( v = 1; i < Pad64; V64 += BinCode[CodePos] * v, i++, v *= 256, NextByte() );
+
+  //*Adjust Pad32 so it matches the length the Immediate should be in hex for number of bytes read.
+
+  Pad32 <<= 1; Pad64 <<= 1;
+
+  /*---------------------------------------------------------------------------------------------------------------------------
+  If the IMM type is used with an register operand on the upper four bit's then the IMM byte does not use the upper 4 bit's.
+  ---------------------------------------------------------------------------------------------------------------------------*/
+
+  if( type === 1 ) { V32 &= ( 1 << ( ( n << 3 ) - 4 ) ) - 1; }
+
+  /*---------------------------------------------------------------------------------------------------------------------------
+  If the Immediate is an relative address calculation.
+  ---------------------------------------------------------------------------------------------------------------------------*/
+
+  if ( type === 2 )
+  {
+    //Calculate the Padded size for at the end of the function an Relative is padded to the size of the address based on bit mode.
+
+    Pad32 = ( Math.min( BitMode, 1 ) << 2 ) + 4; Pad64 = Math.max( Math.min( BitMode, 2 ), 1 ) << 3;
+
+    //Add the 32 bit section to V32.
+
+    var C64 = 0; V32 += Pos32;
+
+    //If bit mode is 16 bits only the first 16 bits are used, or if Size Attribute is 16 bit.
+
+    ( BitMode <= 0 || SizeAttrSelect <= 0 ) && ( V32 &= 0xFFFF );
+
+    //Adjust the 32 bit relative address section if it was not cropped to 16 bit's.
+
+    ( C64 = ( ( V32 ) > 0xFFFFFFFF ) ) && ( V32 -= 0x100000000 );
+
+    //Add the 64 bit address section if in 64 bit mode, or higher.
+
+    ( BitMode >= 2 ) && ( ( V64 += Pos64 + C64 ) > 0xFFFFFFFF ) && ( V64 -= 0x100000000 );
+  }
+
+  /*---------------------------------------------------------------------------------------------------------------------------
+  If the Immediate is an displacement calculation.
+  ---------------------------------------------------------------------------------------------------------------------------*/
+
+  if ( type === 3 )
+  {
+    /*-------------------------------------------------------------------------------------------------------------------------
+    Calculate the displacement center point based on Immediate size.
+    -------------------------------------------------------------------------------------------------------------------------*/
+
+    //An displacement can not be bigger than 32 bit's, so Pad64 is set 0.
+
+    Pad64 = 0;
+
+    //Now calculate the Center Point.
+
+    var Center = 2 * ( 1 << ( n << 3 ) - 2 );
+
+    //By default the Sing is Positive.
+
+    Sing = 1;
+
+    /*-------------------------------------------------------------------------------------------------------------------------
+    Calculate the VSIB displacement size if it is a VSIB Disp8.
+    -------------------------------------------------------------------------------------------------------------------------*/
+
+    if ( VSIB && S === 0 )
+    {
+      var VScale = WidthBit | 2;
+      Center <<= VScale; V32 <<= VScale;
+    }
+
+    //When the value is higher than the center it is negative.
+
+    if ( V32 >= Center )
+    {
+      //Convert the number to the negative side of the center point.
+
+      V32 = Center * 2 - V32;
+
+      //The Sing is negative.
+
+      Sing = 2;
+    }
+  }
+
+  /*---------------------------------------------------------------------------------------------------------------------------
+  Pad Imm based on the calculated Immediate size, because when an value is converted to an number as text that can be displayed
+  the 0 digits to the left are removed. Think of this as like the number 000179 the actual length of the number is 6 digits,
+  but is displayed as 179, because the unused digits are not displayed, but they still exist in the memory.
+  ---------------------------------------------------------------------------------------------------------------------------*/
+
+  for( var Imm = V32.toString(16), L = Pad32; Imm.length < L; Imm = "0" + Imm );
+  if( Pad64 > 8 ) { for( Imm = V64.toString(16) + Imm, L = Pad64; Imm.length < L; Imm = "0" + Imm ); }
+
+  /*---------------------------------------------------------------------------------------------------------------------------
+  Extend Imm if it's extend size is bigger than the Current Imm size.
+  ---------------------------------------------------------------------------------------------------------------------------*/
+
+  if ( Extend !== S )
+  {
+    //Calculate number of bytes to Extend till by size.
+
+    Extend = Math.pow( 2, Extend ) * 2;
+
+    //Setup the Signified pad value.
+
+    var spd = "00"; ( ( ( parseInt( Imm.substring(0, 1), 16) & 8 ) >> 3 ) ) && ( spd = "FF" );
+
+    //Start padding.
+
+    for (; Imm.length < Extend; Imm = spd + Imm);
+  }
+
+  //*Return the Imm.
+
+  return ( ( Sing > 0 ? ( Sing > 1 ? "-" : "+" ) : "" ) + Imm.toUpperCase() );
+
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Decode registers by Size attributes, or a select register index.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function DecodeRegValue( RValue, BySize, Setting )
+{
+  //If the instruction is a Vector instruction, and no extension is active like EVEX, VEX Make sure Size attribute uses the default vector size.
+
+  if( Vect && Extension === 0 )
+  {
+    SizeAttrSelect = 0;
+  }
+
+  //If By size is true Use the Setting with the GetOperandSize
+
+  if ( BySize )
+  {
+    Setting = GetOperandSize( Setting ); //get decoded size value.
+
+    //Any Vector register smaller than 128 has to XMM because XMM is the smallest SIMD Vector register.
+
+    if( Vect && Setting < 4 ) { Setting = 4; }
+  }
+
+  //If XOP only vector 0 to 15 are usable.
+      
+  if( Opcode >= 0x400 ) { RValue &= 15; }
+
+  //Else If 16/32 bit mode in VEX/EVEX/MVEX vctor register can only go 0 though 7.
+
+  else if( BitMode <= 1 && Extension >= 1 ) { RValue &= 7; }
+
+  //If L1OM ZMM to V reg.
+
+  if ( Opcode >= 0x700 && Setting === 6 )
+  {
+    Setting = 16;
+  }
+
+  //Else if 8 bit high/low Registers
+
+  else if ( Setting === 0 )
+  {
+    return (REG[0][RexActive][ RValue ]);
+  }
+
+  //Return the Register.
+
+  return (REG[Setting][ RValue ]);
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Decode the ModR/M pointer, and Optional SIB if used.
+Note if by size attributes is false the lower four bits is the selected Memory pointer,
+and the higher four bits is the selected register.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function Decode_ModRM_SIB_Address( ModRM, BySize, Setting )
+{
+  var out = ""; //the variable out is what stores the decoded address pointer, or Register if Register mode.
+  var S_C = "{"; //L1OM, and K1OM {SSS,CCCCC} setting decoding, or EVEX broadcast round.
+
+  //-------------------------------------------------------------------------------------------------------------------------
+  //If the ModR/M is not in register mode decode it as an Effective address.
+  //-------------------------------------------------------------------------------------------------------------------------
+
+  if( ModRM[0] !== 3 )
+  {
+
+    //If the instruction is a Vector instruction, and no extension is active like EVEX, VEX Make sure Size attribute uses the default vector size.
+
+    if( Vect && Extension === 0 )
+    {
+      SizeAttrSelect = 0;
+    }
+
+    //-------------------------------------------------------------------------------------------------------------------------
+    //The Selected Size is setting unless BySize attribute is true.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    if ( BySize )
+    {
+      //-------------------------------------------------------------------------------------------------------------------------
+      //Check if it is not the non vectorized 128 which uses "Oword ptr".
+      //-------------------------------------------------------------------------------------------------------------------------
+
+      if ( Setting !== 16 || Vect )
+      {
+        Setting = ( GetOperandSize( Setting ) << 1 ) | FarPointer;
+      }
+
+      //-------------------------------------------------------------------------------------------------------------------------
+      //Non vectorized 128 uses "Oword ptr" alaises to "QWord ptr" in 32 bit mode, or lower.
+      //-------------------------------------------------------------------------------------------------------------------------
+
+      else if ( !Vect ) { Setting = 11 - ( ( BitMode <= 1 ) * 5 ); }
+    }
+
+    //-------------------------------------------------------------------------------------------------------------------------
+    //If By size attributes is false the selected Memory pointer is the first four bits of the size setting for all pointer indexes 0 to 15.
+    //Also if By size attribute is also true the selected by size index can not exceed 15 anyways which is the max combination the first four bits.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    Setting = Setting & 0x0F;
+
+    //If Vector extended then MM is changed to QWORD.
+
+    if( Extension !== 0 && Setting === 9 ){ Setting = 6; }
+
+    //Bround control, or 32/64 VSIB.
+
+    if ( ConversionMode === 1 || ConversionMode === 2 || VSIB ) { out += PTR[WidthBit > 0 ? 6 : 4]; }
+
+    //-------------------------------------------------------------------------------------------------------------------------
+    //Get the pointer size by Size setting.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    else{ out = PTR[Setting]; }
+
+    //Add the Segment override left address bracket if any segment override was used otherwise the SegOverride string should be just a normal left bracket.
+
+    out += SegOverride;
+
+    //-------------------------------------------------------------------------------------------------------------------------
+    //calculate the actual address size according to the Address override and the CPU bit mode.
+    //-------------------------------------------------------------------------------------------------------------------------
+    //AddressSize 1 is 16, AddressSize 2 is 32, AddressSize 3 is 64.
+    //The Bit mode is the address size except AddressOverride reacts differently in different bit modes.
+    //In 16 bit AddressOverride switches to the 32 bit ModR/M effective address system.
+    //In both 32/64 the Address size goes down by one is size.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    var AddressSize = BitMode + 1;
+
+    if (AddressOverride)
+    {
+      AddressSize = AddressSize - 1;
+
+      //the only time the address size is 0 is if the BitMode is 16 bit's and is subtracted by one resulting in 0.
+
+      if(AddressSize === 0)
+      {
+        AddressSize = 2; //set the address size to 32 bit from the 16 bit address mode.
+      }
+    }
+
+    /*-------------------------------------------------------------------------------------------------------------------------
+    The displacement size calculation.
+    ---------------------------------------------------------------------------------------------------------------------------
+    In 16/32/64 the mode setting 1 will always add a Displacement of 8 to the address.
+    In 16 the Mode setting 2 adds a displacement of 16 to the address.
+    In 32/64 the Mode Setting 2 for the effective address adds an displacement of 32 to the effective address.
+    -------------------------------------------------------------------------------------------------------------------------*/
+
+    var Disp = ModRM[0] - 1; //Let disp relate size to mode value of the ModR/M.
+
+    //if 32 bit and above, and if Mode is 2 then disp size is disp32.
+
+    if(AddressSize >= 2 && ModRM[0] === 2)
+    {
+      Disp += 1; //Only one more higher in size is 32.
+    }
+
+    /*-------------------------------------------------------------------------------------------------------------------------
+    End of calculation.
+    -------------------------------------------------------------------------------------------------------------------------*/
+    /*-------------------------------------------------------------------------------------------------------------------------
+    Normally the displacement type is an relative Immediate that is added ("+"),
+    or subtracted ("-") from the center point to the selected base register,
+    and the size depends on mode settings 1, and 2, and also Address bit mode (Displacement calculation).
+    Because the normal ModR/M format was limited to Relative addresses, and unfixed locations,
+    so some modes, and registers combinations where used for different Immediate displacements.
+    -------------------------------------------------------------------------------------------------------------------------*/
+
+    var DispType = 3; //by default the displacement size is added to the selected base register, or Index register if SIB byte combination is used.
+
+    //-------------------------------------------16 Bit ModR/M address decode logic-------------------------------------------
+
+    if( AddressSize === 1 )
+    {
+
+      //if ModR/M mode bits 0, and Base Register value is 6 then disp16 with DispType mode 0.
+
+      if(AddressSize === 1 && ModRM[0] === 0 && ModRM[2] === 6)
+      {
+        Disp = 1;
+        DispType = 0;
+      }
+
+      //BX , BP switch based on bit 2 of the Register value
+
+      if( ModRM[2] < 4 ){ out += REG[ AddressSize ][ 3 + ( ModRM[2] & 2 ) ] + "+"; }
+
+      //The first bit switches between Destination index, and source index
+
+      if( ModRM[2] < 6 ){ out += REG[ AddressSize ][ 6 + ( ModRM[2] & 1 ) ]; }
+
+      //[BP], and [BX] as long as Mode is not 0, and Register is not 6 which sets DispType 0.
+
+      else if ( DispType !== 0 ) { out += REG[ AddressSize ][ 17 - ( ModRM[2] << 1 ) ]; }
+    } //End of 16 bit ModR/M decode logic.
+
+    //-------------------------------------------Else 32/64 ModR/M-------------------------------------------
+
+    else
+    {
+
+      //if Mode is 0 and Base Register value is 5 then it uses an Relative (RIP) disp32.
+
+      if( ModRM[0] === 0 && ModRM[2] === 5 )
+      {
+        Disp = 2;
+        DispType = 2;
+      }
+
+      //check if Base Register is 4 which goes into the SIB address system
+
+      if( ModRM[2] === 4 )
+      {
+        //Decode the SIB byte.
+
+        var SIB = Decode_ModRM_SIB_Value();
+
+        //Calculate the Index register with it's Extended value because the index register will only cancel out if 4 in value.
+
+        var IndexReg = IndexExtend | SIB[1];
+
+        //check if the base register is 5 in value in the SIB without it's added extended value, and that the ModR/M Mode is 0 this activates Disp32
+
+        if ( ModRM[0] === 0 && SIB[2] === 5 && !VSIB )
+        {
+          Disp = 2; //Set Disp32
+
+          //check if the Index register is canceled out as well
+
+          if (IndexReg === 4) //if the Index is canceled out then
+          {
+            DispType = 0; //a regular IMM32 is used as the address.
+
+            //*if the Address size is 64 then the 32 bit Immediate must pad to the full 64 bit address.
+
+            if( AddressSize === 3 ) { Disp = 50; }
+          }
+        }
+
+        //Else Base register is not 5, and the Mode is not 0 then decode the base register normally.
+
+        else
+        {
+          out += REG[ AddressSize ][ BaseExtend & 8 | SIB[2] ];
+
+          //If the Index Register is not Canceled out (Note this is only reachable if base register was decoded and not canceled out)
+
+          if ( IndexReg !== 4 || VSIB )
+          {
+            out = out + "+"; //Then add the Plus in front of the Base register to add the index register
+          }
+        }
+
+        //if Index Register is not Canceled, and that it is not an Vector register then decode the Index with the possibility of the base register.
+
+        if ( IndexReg !== 4 && !VSIB )
+        {
+          out += REG[ AddressSize ][ IndexExtend | IndexReg ];
+
+          //add what the scale bits decode to the Index register by the value of the scale bits which select the name from the scale array.
+
+          out = out + scale[SIB[0]];
+        }
+        
+        //Else if it is an vector register.
+        
+        else if ( VSIB )
+        {
+          Setting = ( Setting < 8 ) ? 4 : Setting >> 1;
+
+          if( Opcode < 0x700 ) { IndexReg |= ( VectorRegister & 0x10 ); }
+
+          out += DecodeRegValue( IndexExtend | IndexReg, false, Setting ); //Decode Vector register by length setting and the V' extension.
+
+          //add what the scale bits decode to the Index register by the value of the scale bits which select the name from the scale array.
+
+          out = out + scale[SIB[0]];
+        }
+      } //END OF THE SIB BYTE ADDRESS DECODE.
+
+      //else Base register is not 4 and does not go into the SIB ADDRESS.
+      //Decode the Base register regularly plus it's Extended value if relative (RIP) disp32 is not used.
+
+      else if(DispType !== 2)
+      {
+        out += REG[ AddressSize ][ BaseExtend & 8 | ModRM[2] ];
+      }
+    }
+
+
+    //Finally the Immediate displacement is put into the Address last.
+
+    if( Disp >= 0 ) { out += DecodeImmediate( DispType, false, Disp ); }
+
+    //Put the right bracket on the address.
+
+    out += "]";
+
+    //----------------------L1OM/MVEX/EVEX memory conversion mode, or broadcast round-----------------------
+
+    if(
+        ( ConversionMode !== 0 ) && //Not used if set 0.
+       !(
+          ( ConversionMode === 3 && ( Opcode >= 0x700 || !( Opcode >= 0x700 ) && !Float ) ) || //If bad L1OM/K1OM float conversion.
+          ( !( Opcode >= 0x700 ) && ( VectS === 0 || ( ConversionMode === 5 && VectS === 5 ) || //If K1OM UNorm conversion L1OM only.
+          ( ConversionMode !== 1 && VectS === 1 ) ^ ( ConversionMode < 3 && !Swizzle ) ) ) //Or K1OM broadcast Swizzle, and special case {4to16} only.
+        )
+    )
+    {
+      //Calculate Conversion.
+
+      if( ConversionMode >= 4 ){ ConversionMode += 2; }
+      if( ConversionMode >= 8 ){ ConversionMode += 2; }
+
+      //If L1OM.
+
+      if( Opcode >= 0x700 )
+      {
+        //If L1OM without Swizzle.
+
+        if ( !Swizzle && ConversionMode > 2 ) { ConversionMode = 31; }
+
+        //L1OM Float adjust.
+
+        else if( Float )
+        {
+          if( ConversionMode === 7 ) { ConversionMode++; }
+          if( ConversionMode === 10 ) { ConversionMode = 3; }
+        }
+      }
+
+      //Set conversion. Note K1OM special case inverts width bit.
+
+      out += S_C + ConversionModes[ ( ConversionMode << 1 ) | ( WidthBit ^ ( !( Opcode >= 0x700 ) & VectS === 7 ) ) & 1 ]; S_C = ",";
+    }
+
+    //Else bad Conversion setting.
+
+    else if( ConversionMode !== 0 ) { out += S_C + "Error"; S_C = ","; }
+    
+    //--------------------------------END of memory Conversion control logic--------------------------------
+
+  } //End of Memory address Modes 00, 01, 10 decode.
+
+  //-----------------------------else the ModR/M mode bits are 11 register Mode-----------------------------
+
+  else
+  {
+    //-------------------------------------------------------------------------------------------------------------------------
+    //The Selected Size is setting unless BySize attribute is true.
+    //-------------------------------------------------------------------------------------------------------------------------
+    
+    //MVEX/EVEX round mode.
+ 
+    if ( ( Extension === 3 && HInt_ZeroMerg ) || ( Extension === 2 && ConversionMode === 1 ) )
+    {
+      RoundMode |= RoundingSetting;
+    }
+
+    //If the upper 4 bits are defined and by size is false then the upper four bits is the selected register.
+
+    if( ( ( Setting & 0xF0 ) > 0 ) && !BySize ) { Setting >>= 4; }
+
+    //Decode the register with Base expansion.
+
+    out = DecodeRegValue( BaseExtend | ModRM[2], BySize, Setting );
+    
+    //L1OM/K1OM Register swizzle modes.
+    
+    if( Opcode >= 0x700 || ( Extension === 3 && !HInt_ZeroMerg && Swizzle ) )
+    {
+      if( Opcode >= 0x700 && ConversionMode >= 3 ){ ConversionMode++; } //L1OM skips swizzle type DACB.
+      if( ConversionMode !== 0 ){ out += S_C + RegSwizzleModes[ ConversionMode ]; S_C = ","; }
+    }
+    if( Extension !== 2 ){ HInt_ZeroMerg = false; } //Cache memory control is not possible in Register mode.
+  }
+
+  //--------------------------------------------------L1OM.CCCCC conversions-------------------------------------------------
+
+  if( Opcode >= 0x700 )
+  {
+    //Swizzle Field control Int/Float, or Exponent adjustment.
+
+    if(Swizzle)
+    {
+      if( Opcode === 0x79A ) { out += S_C + ConversionModes[ ( 18 | ( VectorRegister & 3 ) ) << 1 ]; S_C = "}"; }
+      else if( Opcode === 0x79B ) { out += S_C + ConversionModes[ ( 22 + ( VectorRegister & 3 ) ) << 1 ]; S_C = "}"; }
+      else if( ( RoundingSetting & 8 ) === 8 ) { out += S_C + RoundModes [ 24 | ( VectorRegister & 7 ) ]; S_C = "}"; }
+    }
+
+    //Up/Down Conversion.
+
+    else if( VectorRegister !== 0 )
+    {
+      if( ( ( Up && VectorRegister !== 2 ) || //Up conversion "float16rz" is bad.
+        ( !Up && VectorRegister !== 3 && VectorRegister <= 15 ) ) //Down conversion "srgb8", and field control is bad.
+      ) { out += S_C + ConversionModes[ ( ( VectorRegister + 2 ) << 1 ) | WidthBit ]; S_C = "}"; }
+      else { out += S_C + "Error"; S_C = "}"; } //Else Invalid setting.
+    }
+  }
+  if ( S_C === "," ) { S_C = "}"; }
+
+  //Right bracket if any SSS,CCCCC conversion mode setting.
+
+  if( S_C === "}" ) { out += S_C; }
+
+  //------------------------------------------L1OM/K1OM Hint cache memory control--------------------------------------------
+
+  if( HInt_ZeroMerg )
+  {
+    if ( Extension === 3 ) { out += "{EH}"; }
+    else if ( Opcode >= 0x700 ) { out += "{NT}"; }
+  }
+
+  //-------------------------------------------Return the Register/Memory address--------------------------------------------
+
+  return (out);
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Decode Prefix Mnemonic codes. Prefixes are instruction codes that do not do an operation instead adjust
+controls in the CPU to be applied to an select instruction code that is not an Prefix instruction.
+---------------------------------------------------------------------------------------------------------------------------
+At the end of this function "Opcode" should not hold any prefix code, so then Opcode contains an operation code.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function DecodePrefixAdjustments()
+{
+  //-------------------------------------------------------------------------------------------------------------------------
+  Opcode = ( Opcode & 0x300 ) | BinCode[CodePos]; //Add 8 bit opcode while bits 9, and 10 are used for opcode map.
+  NextByte(); //Move to the next byte.
+  //-------------------------------------------------------------------------------------------------------------------------
+
+  //if 0F hex start at 256 for Opcode.
+
+  if(Opcode === 0x0F)
+  {
+    Opcode = 0x100; //By starting at 0x100 with binary bit 9 set one then adding the 8 bit opcode then Opcode goes 256 to 511.
+    return(DecodePrefixAdjustments()); //restart function decode more prefix settings that can effect the decode instruction.
+  }
+
+  //if 38 hex while using two byte opcode.
+
+  else if(Opcode === 0x138 && Mnemonics[0x138] === "")
+  {
+    Opcode = 0x200; //By starting at 0x200 with binary bit 10 set one then adding the 8 bit opcode then Opcode goes 512 to 767.
+    return(DecodePrefixAdjustments()); //restart function decode more prefix settings that can effect the decode instruction.
+  }
+
+  //if 3A hex while using two byte opcode go three byte opcodes.
+
+  else if(Opcode === 0x13A && Mnemonics[0x13A] === "")
+  {
+    Opcode = 0x300; //By starting at 0x300 hex and adding the 8 bit opcode then Opcode goes 768 to 1023.
+    return(DecodePrefixAdjustments()); //restart function decode more prefix settings that can effect the decode instruction.
+  }
+
+  //Rex prefix decodes only in 64 bit mode.
+
+  if( Opcode >= 0x40 & Opcode <= 0x4F && BitMode === 2 )
+  {
+    RexActive = 1; //Set Rex active uses 8 bit registers in lower order as 0 to 15.
+    BaseExtend = ( Opcode & 0x01 ) << 3; //Base Register extend setting.
+    IndexExtend = ( Opcode & 0x02 ) << 2; //Index Register extend setting.
+    RegExtend = ( Opcode & 0x04 ) << 1; //Register Extend Setting.
+    WidthBit = ( Opcode & 0x08 ) >> 3; //Set The Width Bit setting if active.
+    SizeAttrSelect = WidthBit ? 2 : 1; //The width Bit open all 64 bits.
+    return(DecodePrefixAdjustments()); //restart function decode more prefix settings that can effect the decode instruction.
+  }
+
+  //The VEX2 Operation code Extension to SSE settings decoding.
+
+  if( Opcode === 0xC5 && ( BinCode[CodePos] >= 0xC0 || BitMode === 2 ) )
+  {
+    Extension = 1;
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode = BinCode[CodePos]; //read VEX2 byte settings.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    //some bits are inverted, so uninvert them arithmetically.
+
+    Opcode ^= 0xF8;
+
+    //Decode bit settings.
+
+    if( BitMode === 2 )
+    {
+      RegExtend = ( Opcode & 0x80 ) >> 4; //Register Extend.
+      VectorRegister = ( Opcode & 0x78 ) >> 3; //The added in Vector register to SSE.
+    }
+
+    SizeAttrSelect = ( Opcode & 0x04 ) >> 2; //The L bit for 256 vector size.
+    SIMD = Opcode & 0x03; //The SIMD mode.
+
+    //Automatically uses the two byte opcode map starts at 256 goes to 511.
+
+    Opcode = 0x100;
+
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode = ( Opcode & 0x300 ) | BinCode[CodePos]; //read the opcode.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    //Stop decoding prefixes.
+
+    return(null);
+  }
+
+  //The VEX3 prefix settings decoding.
+
+  if( Opcode === 0xC4 && ( BinCode[CodePos] >= 0xC0 || BitMode === 2 ) )
+  {
+    Extension = 1;
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode = BinCode[CodePos]; //read VEX3 byte settings.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode |= ( BinCode[CodePos] << 8 ); //Read next VEX3 byte settings.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    //Some bits are inverted, so uninvert them arithmetically.
+
+    Opcode ^= 0x78E0;
+
+    //Decode bit settings.
+
+    if( BitMode === 2 )
+    {
+      RegExtend = ( Opcode & 0x0080 ) >> 4; //Extend Register Setting.
+      IndexExtend = ( Opcode & 0x0040 ) >> 3; //Extend Index register setting.
+      BaseExtend = ( Opcode & 0x0020 ) >> 2; //Extend base Register setting.
+    }
+
+    WidthBit = ( Opcode & 0x8000 ) >> 15; //The width bit works as a separator.
+    VectorRegister = ( Opcode & 0x7800 ) >> 11; //The added in Vector register to SSE.
+    SizeAttrSelect = ( Opcode & 0x0400 ) >> 10; //Vector length for 256 setting.
+    SIMD = ( Opcode & 0x0300 ) >> 8; //The SIMD mode.
+    Opcode = ( Opcode & 0x001F ) << 8; //Change Operation code map.
+
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode = ( Opcode & 0x300 ) | BinCode[CodePos]; //read the 8 bit opcode put them in the lower 8 bits away from opcode map bit's.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    return(null);
+  }
+
+  //The AMD XOP prefix.
+
+  if( Opcode === 0x8F )
+  {
+    //If XOP
+
+    var Code = BinCode[ CodePos ] & 0x0F;
+
+    if( Code >= 8 && Code <= 10 )
+    {
+      Extension = 1;
+      //-------------------------------------------------------------------------------------------------------------------------
+      Opcode = BinCode[CodePos]; //read XOP byte settings.
+      NextByte(); //Move to the next byte.
+      //-------------------------------------------------------------------------------------------------------------------------
+      Opcode |= ( BinCode[CodePos] << 8 ); //Read next XOP byte settings.
+      NextByte(); //Move to the next byte.
+      //-------------------------------------------------------------------------------------------------------------------------
+
+      //Some bits are inverted, so uninvert them arithmetically.
+
+      Opcode ^= 0x78E0;
+
+      //Decode bit settings.
+
+      RegExtend = ( Opcode & 0x0080 ) >> 4; //Extend Register Setting.
+      IndexExtend = ( Opcode & 0x0040 ) >> 3; //Extend Index register setting.
+      BaseExtend = ( Opcode & 0x0020 ) >> 2; //Extend base Register setting.
+      WidthBit = ( Opcode & 0x8000 ) >> 15; //The width bit works as a separator.
+      VectorRegister = ( Opcode & 0x7800 ) >> 11; //The added in Vector register to SSE.
+      SizeAttrSelect = ( Opcode & 0x0400 ) >> 10; //Vector length for 256 setting.
+      SIMD = ( Opcode & 0x0300 ) >> 8; //The SIMD mode.
+      if( SIMD > 0 ) { InvalidOp = true; } //If SIMD MODE is set anything other than 0 the instruction is invalid.
+      Opcode = 0x400 | ( ( Opcode & 0x0003 ) << 8 ); //Change Operation code map.
+
+      //-------------------------------------------------------------------------------------------------------------------------
+      Opcode = ( Opcode & 0x700 ) | BinCode[CodePos]; //read the 8 bit opcode put them in the lower 8 bits away from opcode map bit's.
+      NextByte(); //Move to the next byte.
+      //-------------------------------------------------------------------------------------------------------------------------
+
+      return(null);
+    }
+  }
+  
+  //The L1OM vector prefix settings decoding.
+
+  if( Opcode === 0xD6 )
+  {
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode = BinCode[CodePos]; //read L1OM byte settings.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode |= ( BinCode[CodePos] << 8 ); //Read next L1OM byte settings.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    WidthBit = SIMD & 1;
+    VectorRegister = ( Opcode & 0xF800 ) >> 11;
+    RoundMode = VectorRegister >> 3;
+    MaskRegister = ( Opcode & 0x0700 ) >> 8;
+    HInt_ZeroMerg = ( Opcode & 0x0080 ) >> 7;
+    ConversionMode = ( Opcode & 0x0070 ) >> 4;
+    RegExtend = ( Opcode & 0x000C ) << 1;
+    BaseExtend = ( Opcode & 0x0003 ) << 3;
+    IndexExtend = ( Opcode & 0x0002 ) << 2;
+
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode = 0x700 | BinCode[CodePos]; //read the 8 bit opcode.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    return(null);
+  }
+
+  //Only decode L1OM instead of MVEX/EVEX if L1OM compatibility mode is set.
+
+  if( Mnemonics[0x62] === "" && Opcode === 0x62 )
+  {
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode = BinCode[CodePos]; //read L1OM byte settings.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    Opcode ^= 0xF0;
+
+    IndexExtend = ( Opcode & 0x80 ) >> 4;
+    BaseExtend = ( Opcode & 0x40 ) >> 3;
+    RegExtend = ( Opcode & 0x20 ) >> 2;
+
+    if ( SIMD !== 1 ) { SizeAttrSelect = ( ( Opcode & 0x10 ) === 0x10 ) ? 2 : 1; } else { SIMD = 0; }
+
+    Opcode = 0x800 | ( ( Opcode & 0x30 ) >> 4 ) | ( ( Opcode & 0x0F ) << 2 );
+
+    return(null);
+  }
+
+  //The MVEX/EVEX prefix settings decoding.
+
+  if ( Opcode === 0x62 && ( BinCode[CodePos] >= 0xC0 || BitMode === 2 ) )
+  {
+    Extension = 2;
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode = BinCode[CodePos]; //read MVEX/EVEX byte settings.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode |= ( BinCode[CodePos] << 8 ); //read next MVEX/EVEX byte settings.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode |= ( BinCode[CodePos] << 16 ); //read next MVEX/EVEX byte settings.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    //Some bits are inverted, so uninvert them arithmetically.
+
+    Opcode ^= 0x0878F0;
+
+    //Check if Reserved bits are 0 if they are not 0 the MVEX/EVEX instruction is invalid.
+
+    InvalidOp = ( Opcode & 0x00000C ) > 0;
+
+    //Decode bit settings.
+    
+    if( BitMode === 2 )
+    {
+      RegExtend = ( ( Opcode & 0x80 ) >> 4 ) | ( Opcode & 0x10 ); //The Double R'R bit decode for Register Extension 0 to 32.
+      BaseExtend = ( Opcode & 0x60 ) >> 2; //The X bit, and B Bit base register extend combination 0 to 32.
+      IndexExtend = ( Opcode & 0x40 ) >> 3; //The X extends the SIB Index by 8.
+    }
+    
+    VectorRegister = ( ( Opcode & 0x7800 ) >> 11 ) | ( ( Opcode & 0x080000 ) >> 15 ); //The Added in Vector Register for SSE under MVEX/EVEX.
+    
+    WidthBit = ( Opcode & 0x8000 ) >> 15; //The width bit separator for MVEX/EVEX.
+    SIMD = ( Opcode & 0x0300 ) >> 8; //decode the SIMD mode setting.
+    HInt_ZeroMerg = ( Opcode & 0x800000 ) >> 23; //Zero Merge to destination control, or MVEX EH control.
+      
+    //EVEX option bits take the place of Vector length control.
+      
+    if ( ( Opcode & 0x0400 ) > 0 )
+    {
+      SizeAttrSelect = ( Opcode & 0x600000 ) >> 21; //The EVEX.L'L Size combination.
+      RoundMode = SizeAttrSelect | 4; //Rounding mode is Vector length if used.
+      ConversionMode = (Opcode & 0x100000 ) >> 20; //Broadcast Round Memory address system.
+    }
+      
+    //MVEX Vector Length, and Broadcast round.
+      
+    else
+    {
+      SizeAttrSelect = 2; //Max Size by default.
+      ConversionMode = ( Opcode & 0x700000 ) >> 20; //"MVEX.sss" Option bits.
+      RoundMode = ConversionMode; //Rounding mode selection is ConversionMode if used.
+      Extension = 3;
+    }
+
+    MaskRegister = ( Opcode & 0x070000 ) >> 16; //Mask to destination.
+    Opcode = ( Opcode & 0x03 ) << 8; //Change Operation code map.
+
+    //-------------------------------------------------------------------------------------------------------------------------
+    Opcode = ( Opcode & 0x300 ) | BinCode[CodePos]; //read the 8 bit opcode put them in the lower 8 bits away from opcode map extend bit's.
+    NextByte(); //Move to the next byte.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    //Stop decoding prefixes.
+
+    return(null);
+  }
+
+  //Segment overrides
+
+  if ( ( Opcode & 0x7E7 ) === 0x26 || ( Opcode & 0x7FE ) === 0x64 )
+  {
+    SegOverride = Mnemonics[ Opcode ]; //Set the Left Bracket for the ModR/M memory address.
+    return(DecodePrefixAdjustments()); //restart function decode more prefix settings that can effect the decode instruction.
+  }
+
+  //Operand override Prefix
+
+  if(Opcode === 0x66)
+  {
+    SIMD = 1; //sets SIMD mode 1 in case of SSE instruction opcode.
+    SizeAttrSelect = 0; //Adjust the size attribute setting for the size adjustment to the next instruction.
+    return(DecodePrefixAdjustments());  //restart function decode more prefix settings that can effect the decode instruction.
+  }
+
+  //Ram address size override.
+
+  if(Opcode === 0x67)
+  {
+    AddressOverride = true; //Set the setting active for the ModR/M address size.
+    return(DecodePrefixAdjustments()); //restart function decode more prefix settings that can effect the decode instruction.
+  }
+
+  //if repeat Prefixes F2 hex REP,or F3 hex RENP
+
+  if (Opcode === 0xF2 || Opcode === 0xF3)
+  {
+    SIMD = (Opcode & 0x02 )  |  ( 1 - Opcode & 0x01 ); //F2, and F3 change the SIMD mode during SSE instructions.
+    PrefixG1 = Mnemonics[ Opcode ]; //set the Prefix string.
+    HLEFlipG1G2 = true; //set Filp HLE in case this is the last prefix read, and LOCK was set in string G2 first for HLE.
+    return(DecodePrefixAdjustments()); //restart function decode more prefix settings that can effect the decode instruction.
+  }
+
+  //if the lock prefix note the lock prefix is separate
+
+  if (Opcode === 0xF0)
+  {
+    PrefixG2 = Mnemonics[ Opcode ]; //set the Prefix string
+    HLEFlipG1G2 = false; //set Flip HLE false in case this is the last prefix read, and REP, or REPNE was set in string G2 first for HLE.
+    return(DecodePrefixAdjustments()); //restart function decode more prefix settings that can effect the decode instruction.
+  }
+
+  //Before ending the function "DecodePrefixAdjustments()" some opcode combinations are invalid in 64 bit mode.
+
+  if ( BitMode === 2 )
+  {
+    InvalidOp |= ( ( ( Opcode & 0x07 ) >= 0x06 ) & ( Opcode <= 0x40 ) );
+    InvalidOp |= ( Opcode === 0x60 | Opcode === 0x61 );
+    InvalidOp |= ( Opcode === 0xD4 | Opcode === 0xD5 );
+    InvalidOp |= ( Opcode === 0x9A | Opcode === 0xEA );
+    InvalidOp |= ( Opcode === 0x82 );
+  }
+
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The Decode opcode function gives back the operation name, and what it uses for input.
+The input types are for example which registers it uses with the ModR/M, or which Immediate type is used.
+The input types are stored into an operand string. This function gives back the instruction name, And what the operands use.
+---------------------------------------------------------------------------------------------------------------------------
+This function is designed to be used after the Decode prefix adjustments function because the Opcode should contain an real instruction code.
+This is because the Decode prefix adjustments function will only end if the Opcode value is not a prefix adjustment code to the ModR/M etc.
+However DecodePrefixAdjustments can also prevent this function from being called next if the prefix settings are bad or an invalid instruction is
+used for the bit mode the CPU is in as it will set InvalidOp true.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function DecodeOpcode()
+{
+  //get the Operation name by the operations opcode.
+
+  Instruction = Mnemonics[Opcode];
+
+  //get the Operands for this opcode it follows the same array structure as Mnemonics array
+
+  InsOperands = Operands[Opcode];
+
+  //Some Opcodes use the next byte automatically for extended opcode selection. Or current SIMD mode.
+
+  var ModRMByte = BinCode[CodePos]; //Read the byte but do not move to the next byte.
+
+  //If the current Mnemonic is an array two in size then Register Mode, and memory mode are separate from each other.
+  //Used in combination with Grouped opcodes, and Static opcodes.
+
+  if(Instruction instanceof Array && Instruction.length == 2) { var bits = ( ModRMByte >> 6 ) & ( ModRMByte >> 7 ); Instruction = Instruction[bits]; InsOperands = InsOperands[bits]; }
+
+  //Arithmetic unit 8x8 combinational logic array combinations.
+  //If the current Mnemonic is an array 8 in length It is a group opcode instruction may repeat previous instructions in different forums.
+
+  if(Instruction instanceof Array && Instruction.length == 8) { var bits = ( ModRMByte & 0x38 ) >> 3; Instruction = Instruction[bits]; InsOperands = InsOperands[bits];
+
+    //if The select Group opcode is another array 8 in size it is a static opcode selection which makes the last three bits of the ModR/M byte combination.
+
+    if(Instruction instanceof Array && Instruction.length == 8) { var bits = ( ModRMByte & 0x07 ); Instruction = Instruction[bits]; InsOperands = InsOperands[bits]; NextByte(); } }
+
+  //Vector unit 4x4 combinational array logic.
+  //if the current Mnemonic is an array 4 in size it is an SIMD instruction with four possible modes N/A, 66, F3, F2.
+  //The mode is set to SIMD, it could have been set by the EVEX.pp, VEX.pp bit combination, or by prefixes N/A, 66, F3, F2.
+
+  if(Instruction instanceof Array && Instruction.length == 4)
+  {
+    Vect = true; //Set Vector Encoding true.
+
+    //Reset the prefix string G1 because prefix codes F2, and F3 are used with SSE which forum the repeat prefix.
+    //Some SSE instructions can use the REP, RENP prefixes.
+    //The Vectors that do support the repeat prefix uses Packed Single format.
+
+    if(Instruction[2] !== "" && Instruction[3] !== "") { PrefixG1 = ""; } else { SIMD = ( SIMD === 1 ) & 1; }
+    Instruction = Instruction[SIMD]; InsOperands = InsOperands[SIMD];
+
+    //If the SIMD instruction uses another array 4 in length in the Selected SIMD vector Instruction.
+    //Then each vector Extension is separate. The first extension is used if no extension is active for Regular instructions, and vector instruction septation.
+    //0=None. 1=VEX only. 2=EVEX only. 3=??? unused.
+
+    if(Instruction instanceof Array && Instruction.length == 4)
+    {
+      //Get the correct Instruction for the Active Extension type.
+
+      if(Instruction[Extension] !== "") { Instruction = Instruction[Extension]; InsOperands = InsOperands[Extension]; }
+      else{ Instruction = "???"; InsOperands = ""; }
+    }
+    else if( Extension === 3 ){ Instruction = "???"; InsOperands = ""; }
+  }
+  else if( Opcode >= 0x700 && SIMD > 0 ){ Instruction = "???"; InsOperands = ""; }
+
+  //if Any Mnemonic is an array 3 in size the instruction name goes by size.
+
+  if(Instruction instanceof Array && Instruction.length == 3)
+  {
+    var bits = ( Extension === 0 & BitMode !== 0 ) ^ ( SizeAttrSelect >= 1 ); //The first bit in SizeAttrSelect for size 32/16 Flips if 16 bit mode.
+    ( WidthBit ) && ( bits = 2 ); //Goes 64 using the Width bit.
+    ( Extension === 3 && HInt_ZeroMerg && Instruction[1] !== "" ) && ( HInt_ZeroMerg = false, bits = 1 ); //MVEX uses element 1 if MVEX.E is set for instruction that change name.
+
+    if (Instruction[bits] !== "") { Instruction = Instruction[bits]; InsOperands = InsOperands[bits]; }
+
+    //else no size prefix name then use the default size Mnemonic name.
+
+    else { Instruction = Instruction[0]; InsOperands = InsOperands[0]; }
+  }
+
+  //If Extension is not 0 then add the vector extend "V" to the instruction.
+  //During the decoding of the operands the instruction can be returned as invalid if it is an Arithmetic, or MM, ST instruction.
+  //Vector mask instructions start with K instead of V any instruction that starts with K and is an
+  //vector mask Instruction which starts with K instead of V.
+
+  if( Opcode <= 0x400 && Extension > 0 && Instruction.charAt(0) !== "K" && Instruction !== "???" ) { Instruction = "V" + Instruction; }
+
+  //In 32 bit mode, or bellow only one instruction MOVSXD is replaced with ARPL.
+
+  if( BitMode <= 1 && Instruction === "MOVSXD" ) { Instruction = "ARPL"; InsOperands = "06020A01"; }
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Read each operand in the Operand String then set the correct operand in the X86 decoder array.
+OpNum is the order the operands are read in the operand string. The Operand type is which operand will be set
+active along the X86Decoder. The OpNum is the order the decoded operands will be positioned after they are decoded
+in order along the X86 decoder. The order the operands display is different than the order they decode in sequence.
+---------------------------------------------------------------------------------------------------------------------------
+This function is used after the function ^DecodeOpcode()^ because the function ^DecodeOpcode()^ gives back the
+operand string for what the instruction takes as input.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function DecodeOperandString()
+{
+  //Variables that are used for decoding one operands across the operand string.
+
+  var OperandValue = 0, Code = 0, BySize = 0, Setting = 0;
+
+  //It does not matter which order the explicit operands decode as they do not require reading another byte.
+  //They start at 7 and are set in order, but the order they are displayed is the order they are read in the operand string because of OpNum.
+
+  var ExplicitOp = 8, ImmOp = 3;
+
+  //Each operand is 4 hex digits, and OpNum is added by one for each operand that is read per Iteration.
+
+  for( var i = 0, OpNum = 0; i < InsOperands.length; i+=4 ) //Iterate though operand string.
+  {
+    OperandValue = parseInt( InsOperands.substring(i, (i + 4) ), 16 ); //Convert the four hex digits to a 16 bit number value.
+    Code = ( OperandValue & 0xFE00 ) >> 9; //Get the operand Code.
+    BySize = ( OperandValue & 0x0100 ) >> 8; //Get it's by size attributes setting for if Setting is used as size attributes.
+    Setting = ( OperandValue & 0x00FF ); //Get the 8 bit Size setting.
+
+    //If code is 0 the next 8 bit value specifies which type of of prefix settings are active.
+
+    if( Code === 0 )
+    {
+      if(BySize) //Vector adjustment settings.
+      {
+        RoundingSetting = ( Setting & 0x03 ) << 3;
+        if( Opcode >= 0x700 && RoundingSetting >= 0x10 ){ RoundMode |= 0x10; }
+        VSIB = ( Setting >> 2 ) & 1;
+        IgnoresWidthbit = ( Setting >> 3 ) & 1;
+        VectS = ( Setting >> 4 ) & 7;
+        Swizzle = ( VectS >> 2 ) & 1;
+        Up = ( VectS >> 1 ) & 1;
+        Float = VectS & 1;
+        if( ( Setting & 0x80 ) == 0x80 ) { Vect = false; } //If Non vector instruction set Vect false.
+      }
+      else //Instruction Prefix types.
+      {
+        XRelease = Setting & 0x01;
+        XAcquire = ( Setting & 0x02 ) >> 1;
+        HT = ( Setting & 0x04 ) >> 2;
+        BND = ( Setting & 0x08 ) >> 3;
+      }
+    }
+
+    //if it is a opcode Reg Encoding then first element along the decoder is set as this has to be decode first, before moving to the
+    //byte for modR/M.
+
+    else if( Code === 1 )
+    {
+      X86Decoder[0].set( 0, BySize, Setting, OpNum++ );
+    }
+
+    //if it is a ModR/M, or Far pointer ModR/M, or Moffs address then second decoder element is set.
+
+    else if( Code >= 2 && Code <= 4 )
+    {
+      X86Decoder[1].set( ( Code - 2 ), BySize, Setting, OpNum++ );
+      if( Code == 4 ){ FarPointer = 1; } //If code is 4 it is a far pointer.
+    }
+
+    //The ModR/M Reg bit's are separated from the address system above. The ModR/M register can be used as a different register with a
+    //different address pointer. The Reg bits of the ModR/M decode next as it would be inefficient to read the register value if the
+    //decoder moves to the immediate.
+
+    else if( Code === 5 )
+    {
+      X86Decoder[2].set( 0, BySize, Setting, OpNum++ );
+    }
+
+    //Immediate input one. The immediate input is just a number input it is decoded last unless the instruction does not use a
+    //ModR/M encoding, or Reg Opcode.
+
+    else if( Code >= 6 && Code <= 8 && ImmOp <= 5 )
+    {
+      X86Decoder[ImmOp++].set( ( Code - 6 ), BySize, Setting, OpNum++ );
+    }
+
+    //Vector register. If the instruction uses this register it will not be decoded or displayed unless one of the vector extension codes are
+    //decoded by the function ^DecodePrefixAdjustments()^. The Vector extension codes also have a Vector register value that is stored into
+    //the variable VectorRegister. The variable VectorRegister is given to the function ^DecodeRegValue()^.
+
+    else if( Code === 9 && ( Extension > 0 || Opcode >= 0x700 ) )
+    {
+      X86Decoder[6].set( 0, BySize, Setting, OpNum++ );
+    }
+
+    //The upper four bits of the Immediate is used as an register. The variable IMM stores the last immediate byte that is read by ^DecodeImmediate()^.
+    //The upper four bits of the IMM is given to the function ^DecodeRegValue()^.
+
+    else if( Code === 10 )
+    {
+      X86Decoder[7].set( 0, BySize, Setting, OpNum++ );
+    }
+
+    //Else any other encoding type higher than 13 is an explicit operand selection.
+    //And also there can only be an max of four explicit operands.
+
+    else if( Code >= 11 && ExplicitOp <= 11)
+    {
+      X86Decoder[ExplicitOp].set( ( Code - 11 ), BySize, Setting, OpNum++ );
+      ExplicitOp++; //move to the next Explicit operand.
+    }
+  }
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+Decode each of the operands along the X86Decoder and deactivate them.
+This function is used after ^DecodeOperandString()^ which sets up the X86 Decoder for the instructions operands.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function DecodeOperands()
+{
+  //The Operands array is a string array in which the operand number is the element the decoded operand is positioned.
+
+  var out = [];
+
+  //This holds the decoded ModR/M byte from the "Decode_ModRM_SIB_Value()" function because the Register, and Address can decode differently.
+
+  var ModRMByte = [ -1, //Mode is set negative one used to check if the ModR/M has been decoded.
+    0, //The register value is decoded separately if used.
+    0 //the base register for the address location.
+  ];
+
+  //If no Immediate operand is used then the Immediate register encoding forces an IMM8 for the register even if the immediate is not used.
+
+  var IMM_Used = false; //This is set true for if any Immediate is read because the last Immediate byte is used as the register on the upper four bits.
+
+  //If reg opcode is active.
+
+  if( X86Decoder[0].Active )
+  {
+    out[ X86Decoder[0].OpNum ] = DecodeRegValue(
+      ( RegExtend | ( Opcode & 0x07 ) ), //Register value.
+      X86Decoder[0].BySizeAttrubute, //By size attribute or not.
+      X86Decoder[0].Size //Size settings.
+    );
+  }
+
+  //If ModR/M Address is active.
+
+  if( X86Decoder[1].Active )
+  {
+    //Decode the ModR/M byte Address which can end up reading another byte for SIB address, and including displacements.
+
+    if(X86Decoder[1].Type !== 0)
+    {
+      ModRMByte = Decode_ModRM_SIB_Value(); //Decode the ModR/M byte.
+      out[ X86Decoder[1].OpNum ] = Decode_ModRM_SIB_Address(
+        ModRMByte, //The ModR/M byte.
+        X86Decoder[1].BySizeAttrubute, //By size attribute or not.
+        X86Decoder[1].Size //Size settings.
+      );
+    }
+
+    //Else If the ModR/M type is 0 then it is a moffs address.
+
+    else
+    {
+      var s=0, AddrsSize = 0;
+      if( X86Decoder[1].BySizeAttrubute )
+      {
+        AddrsSize = ( Math.pow( 2, BitMode ) << 1 );
+        s = GetOperandSize( X86Decoder[1].Size, true ) << 1;
+      }
+      else
+      {
+        AddrsSize =  BitMode + 1;
+        s = X86Decoder[1].Size;
+      }
+      out[ X86Decoder[1].OpNum ] = PTR[ s ];
+      out[ X86Decoder[1].OpNum ] += SegOverride + DecodeImmediate( 0, X86Decoder[1].BySizeAttrubute, AddrsSize ) + "]";
+    }
+  }
+
+  //Decode the Register value of the ModR/M byte.
+
+  if( X86Decoder[2].Active )
+  {
+    //If the ModR/M address is not used, and ModR/M byte was not previously decoded then decode it.
+
+    if( ModRMByte[0] === -1 ){ ModRMByte = Decode_ModRM_SIB_Value(); }
+
+    //Decode only the Register Section of the ModR/M byte values.
+
+    out[ X86Decoder[2].OpNum ] = DecodeRegValue(
+      ( RegExtend | ( ModRMByte[1] & 0x07 ) ), //Register value.
+      X86Decoder[2].BySizeAttrubute, //By size attribute or not.
+      X86Decoder[2].Size //Size settings.
+    );
+  }
+
+  //First Immediate if used.
+
+  if( X86Decoder[3].Active )
+  {
+    var t = DecodeImmediate(
+      X86Decoder[3].Type, //Immediate input type.
+      X86Decoder[3].BySizeAttrubute, //By size attribute or not.
+      X86Decoder[3].Size //Size settings.
+    );
+	  
+    //Check if Instruction uses condition codes.
+
+    if( Instruction.slice(-1) === "," )
+    {
+      Instruction = Instruction.split(",");
+
+      if( ( Extension >= 1 && Extension <= 2 && Opcode <= 0x400 && IMMValue < 0x20 ) || IMMValue < 0x08 )
+      {
+        IMMValue |= ( ( ( Opcode > 0x400 ) & 1 ) << 5 ); //XOP adjust.
+        Instruction = Instruction[0] + ConditionCodes[ IMMValue ] + Instruction[1];
+      }
+      else { Instruction = Instruction[0] + Instruction[1]; out[ X86Decoder[3].OpNum ] = t; }
+    }
+
+    //else add the Immediate byte encoding to the decoded instruction operands.
+
+    else { out[ X86Decoder[3].OpNum ] = t; }
+    
+    IMM_Used = true; //Immediate byte is read.
+  }
+
+  //Second Immediate if used.
+
+  if( X86Decoder[4].Active )
+  {
+    out[ X86Decoder[4].OpNum ] = DecodeImmediate(
+      X86Decoder[4].Type, //Immediate input type.
+      X86Decoder[4].BySizeAttrubute, //By size attribute or not.
+      X86Decoder[4].Size //Size settings.
+    );
+  }
+
+  //Third Immediate if used.
+
+  if( X86Decoder[5].Active )
+  {
+    out[ X86Decoder[5].OpNum ] = DecodeImmediate(
+      X86Decoder[5].Type, //Immediate input type.
+      X86Decoder[5].BySizeAttrubute, //By size attribute or not.
+      X86Decoder[5].Size //Size settings.
+    );
+  }
+
+  //Vector register if used from an SIMD vector extended instruction.
+
+  if( X86Decoder[6].Active )
+  {
+      out[ X86Decoder[6].OpNum ] = DecodeRegValue(
+      VectorRegister, //Register value.
+      X86Decoder[6].BySizeAttrubute, //By size attribute or not.
+      X86Decoder[6].Size //Size settings.
+    );
+  }
+
+  //Immediate register encoding.
+
+  if( X86Decoder[7].Active )
+  {
+    if( !IMM_Used ) { DecodeImmediate(0, false, 0); } //forces IMM8 if no Immediate has been used.
+    out[ X86Decoder[7].OpNum ] = DecodeRegValue(
+      ( ( ( IMMValue & 0xF0 ) >> 4 ) | ( ( IMMValue & 0x08 ) << 1 ) ), //Register value.
+      X86Decoder[7].BySizeAttrubute, //By size attribute or not.
+      X86Decoder[7].Size //Size settings.
+    );
+  }
+
+  //-------------------------------------------------------------------------------------------------------------------------
+  //Iterate though the 4 possible Explicit operands The first operands that is not active ends the Iteration.
+  //-------------------------------------------------------------------------------------------------------------------------
+
+  for( var i = 8; i < 11; i++ )
+  {
+    //-------------------------------------------------------------------------------------------------------------------------
+    //if Active Type is used as which Explicit operand.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    if( X86Decoder[i].Active )
+    {
+      //General use registers value 0 though 4 there size can change by size setting but can not be extended or changed.
+
+      if( X86Decoder[i].Type <= 3 )
+      {
+        out[ X86Decoder[i].OpNum ] = DecodeRegValue(
+          X86Decoder[i].Type, //register by value for Explicit Registers A, C, D, B.
+          X86Decoder[i].BySizeAttrubute, //By size attribute or not.
+          X86Decoder[i].Size //Size attribute.
+        );
+      }
+
+      //RBX address Explicit Operands prefixes can extend the registers and change pointer size RegMode 0.
+
+      else if( X86Decoder[i].Type === 4 )
+      {
+        s = 3; //If 32, or 64 bit ModR/M.
+        if( ( BitMode === 0 && !AddressOverride ) || ( BitMode === 1 && AddressOverride ) ){ s = 7; } //If 16 bit ModR/M.
+        out[ X86Decoder[i].OpNum ] = Decode_ModRM_SIB_Address(
+          [ 0, 0, s ], //the RBX register only for the pointer.
+          X86Decoder[i].BySizeAttrubute, //By size attribute or not.
+          X86Decoder[i].Size //size attributes.
+        );
+      }
+
+      //source and destination address Explicit Operands prefixes can extend the registers and change pointer size.
+
+      else if( X86Decoder[i].Type === 5 | X86Decoder[i].Type === 6 )
+      {
+        s = 1; //If 32, or 64 bit ModR/M.
+        if( ( BitMode === 0 && !AddressOverride ) || ( BitMode === 1 & AddressOverride ) ) { s = -1; } //If 16 bit ModR/M.
+        out[ X86Decoder[i].OpNum ] = Decode_ModRM_SIB_Address(
+          [ 0, 0, ( X86Decoder[i].Type + s ) ], //source and destination pointer register by type value.
+          X86Decoder[i].BySizeAttrubute, //By size attribute or not.
+          X86Decoder[i].Size //size attributes.
+        );
+      }
+
+      //The ST only Operand, and FS, GS.
+
+      else if( X86Decoder[i].Type >= 7 )
+      {
+        out[ X86Decoder[i].OpNum ] = ["ST", "FS", "GS", "1", "3", "XMM0", "M10"][ ( X86Decoder[i].Type - 7 ) ];
+      }
+    }
+
+    //-------------------------------------------------------------------------------------------------------------------------
+    //else inactive end iteration.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    else { break; }
+
+  }
+
+  /*-------------------------------------------------------------------------------------------------------------------------
+  If the EVEX vector extension is active the Mask, and Zero merge control are inserted into operand 0 (Destination operand).
+  -------------------------------------------------------------------------------------------------------------------------*/
+
+  //Mask Register is used if it is not 0 in value.
+
+  if( MaskRegister !== 0 ){ out[0] += "{K" + MaskRegister + "}"; }
+  
+  //EVEX Zero Merge control.
+
+  if( Extension === 2 && HInt_ZeroMerg ) { out[0] += "{Z}"; }
+
+  //convert the operand array to a string and return it.
+
+  InsOperands = out.toString();
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+The main Instruction decode function plugs everything in together for the steps required to decode a full X86 instruction.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function DecodeInstruction()
+{
+  //Reset Prefix adjustments, and vector setting adjustments.
+
+  Reset();
+
+  var out = ""; //The instruction code that will be returned back from this function.
+
+  //Record the starting position.
+
+  InstructionPos = GetPosition();
+
+  //First read any opcodes (prefix) that act as adjustments to the main three operand decode functions ^DecodeRegValue()^,
+  //^Decode_ModRM_SIB_Address()^, and ^DecodeImmediate()^.
+
+  DecodePrefixAdjustments();
+
+  //Only continue if an invalid opcode is not read by DecodePrefixAdjustments() for cpu bit mode setting.
+
+  if( !InvalidOp )
+  {
+    //Decode the instruction.
+
+    DecodeOpcode();
+
+    //-------------------------------------------------------------------------------------------------------------------------
+    //Intel Larrabee CCCCC condition codes.
+    //-------------------------------------------------------------------------------------------------------------------------
+
+    if( Opcode >= 0x700 && Instruction.slice(-1) === "," )
+    {
+      Instruction = Instruction.split(",");
+
+      //CMP conditions.
+
+      if( Opcode >= 0x720 && Opcode <= 0x72F )
+      {
+        IMMValue = VectorRegister >> 2;
+
+        if( Float || ( IMMValue !== 3 && IMMValue !== 7 ) )
+        {
+          Instruction = Instruction[0] + ConditionCodes[IMMValue] + Instruction[1];
+        }
+        else { Instruction = Instruction[0] + Instruction[1]; }
+
+        IMMValue = 0; VectorRegister &= 0x03;
+      }
+
+      //Else High/Low.
+
+      else
+      {
+        Instruction = Instruction[0] + ( ( ( VectorRegister & 1 ) === 1 ) ? "H" : "L" ) + Instruction[1];
+      }
+    }
+
+    //Setup the X86 Decoder for which operands the instruction uses.
+
+    DecodeOperandString();
+
+    //Now only some instructions can vector extend, and that is only if the instruction is an SIMD Vector format instruction.
+
+    if( !Vect && Extension > 0 && Opcode <= 0x400 ) { InvalidOp = true; }
+
+    //The Width Bit setting must match the vector numbers size otherwise this create an invalid operation code in MVEX/EVEX unless the Width bit is ignored.
+
+    if( Vect && !IgnoresWidthbit && Extension >= 2 )
+    {
+      InvalidOp = ( ( SIMD & 1 ) !== ( WidthBit & 1 ) ); //Note use, and ignore width bit pastern EVEX.
+    }
+    if( Opcode >= 0x700 ) { WidthBit ^= IgnoresWidthbit; } //L1OM Width bit invert.
+  }
+
+  //If the instruction is invalid then set the instruction to "???"
+
+  if( InvalidOp )
+  {
+    out = "???" //set the returned instruction to invalid
+  }
+
+  //Else finish decoding the valid instruction.
+
+  else
+  {
+    //Decode each operand along the Decoder array in order, and deactivate them.
+
+    DecodeOperands();
+
+    /*-------------------------------------------------------------------------------------------------------------------------
+    3DNow Instruction name is encoded by the next byte after the ModR/M, and Reg operands.
+    -------------------------------------------------------------------------------------------------------------------------*/
+
+    if( Opcode === 0x10F )
+    {
+      //Lookup operation code.
+
+      Instruction = M3DNow[ BinCode[CodePos] ]; NextByte();
+
+      //If Invalid instruction.
+
+      if( Instruction === "" || Instruction == null )
+      {
+        Instruction = "???"; InsOperands = "";
+      }
+    }
+
+    /*-------------------------------------------------------------------------------------------------------------------------
+    Synthetic virtual machine operation codes.
+    -------------------------------------------------------------------------------------------------------------------------*/
+
+    else if( Instruction === "SSS" )
+    {
+      //The Next two bytes after the static opcode is the select synthetic virtual machine operation code.
+
+      var Code1 = BinCode[CodePos]; NextByte();
+      var Code2 = BinCode[CodePos]; NextByte();
+
+      //No operations exist past 4 in value for both bytes that combine to the operation code.
+
+      if( Code1 >= 5 || Code2 >= 5 ) { Instruction = "???"; }
+
+      //Else calculate the operation code in the 5x5 map.
+
+      else
+      {
+        Instruction = MSynthetic[ ( Code1 * 5 ) + Code2 ];
+
+        //If Invalid instruction.
+
+        if( Instruction === "" || Instruction == null )
+        {
+          Instruction = "???";
+        }
+      }
+    }
+
+    //32/16 bit instructions 9A, and EA use Segment, and offset with Immediate format.
+
+    if( Opcode === 0x9A || Opcode === 0xEA )
+    {
+      var t = InsOperands.split(",");
+      InsOperands = t[1] + ":" +t[0];
+    }
+
+    //**Depending on the operation different prefixes replace others for  HLE, or MPX, and branch prediction.
+    //if REP prefix, and LOCK prefix are used together, and the current decoded operation allows HLE XRELEASE.
+
+    if(PrefixG1 === Mnemonics[0xF3] && PrefixG2 === Mnemonics[0xF0] && XRelease)
+    {
+      PrefixG1 = "XRELEASE"; //Then change REP to XRELEASE.
+    }
+
+    //if REPNE prefix, and LOCK prefix are used together, and the current decoded operation allows HLE XACQUIRE.
+
+    if(PrefixG1 === Mnemonics[0xF2] && PrefixG2 === Mnemonics[0xF0] && XAcquire)
+    {
+      PrefixG1 = "XACQUIRE"; //Then change REP to XACQUIRE
+    }
+
+    //Depending on the order that the Repeat prefix, and Lock prefix is used flip Prefix G1, and G2 if HLEFlipG1G2 it is true.
+
+    if((PrefixG1 === "XRELEASE" || PrefixG1 === "XACQUIRE") && HLEFlipG1G2)
+    {
+      t = PrefixG1; PrefixG1 = PrefixG2; PrefixG2 = t;
+    }
+
+    //if HT is active then it is a jump instruction check and adjust for the HT,and HNT prefix.
+
+    if(HT)
+    {
+      if (SegOverride === Mnemonics[0x2E])
+      {
+        PrefixG1 = "HNT";
+      }
+      else if (SegOverride === Mnemonics[0x3E])
+      {
+        PrefixG1 = "HT";
+      }
+    }
+
+    //else if Prefix is REPNE switch it to BND if operation is a MPX instruction.
+
+    if(PrefixG1 === Mnemonics[0xF2] && BND)
+    {
+      PrefixG1 = "BND";
+    }
+
+    //Before the Instruction is put together check the length of the instruction if it is longer than 15 bytes the instruction is undefined.
+
+    if ( InstructionHex.length > 30 )
+    {
+      //Calculate how many bytes over.
+
+      var Dif32 = ( ( InstructionHex.length - 30 ) >> 1 );
+
+      //Limit the instruction hex output to 15 bytes.
+
+      InstructionHex = InstructionHex.substring( 0, 30 );
+
+      //Calculate the Difference between the Disassembler current position.
+
+      Dif32 = Pos32 - Dif32;
+
+      //Convert Dif to unsignified numbers.
+
+      if( Dif32 < 0 ) { Dif32 += 0x100000000; }
+
+      //Convert to strings.
+
+      for (var S32 = Dif32.toString(16) ; S32.length < 8; S32 = "0" + S32);
+      for (var S64 = Pos64.toString(16) ; S64.length < 8; S64 = "0" + S64);
+
+      //Go to the Calculated address right after the Instruction UD.
+
+      GotoPosition( S64 + S32 );
+
+      //Set prefixes, and operands to empty strings, and set Instruction to UD.
+
+      PrefixG1 = "";PrefixG2 = ""; Instruction = "???"; InsOperands = "";
+    }
+
+    //Put the Instruction sequence together.
+
+    out = PrefixG1 + " " + PrefixG2 + " " + Instruction + " " + InsOperands;
+
+    //Remove any trailing spaces because of unused prefixes.
+
+    out = out.replace(/^[ ]+|[ ]+$/g,'');
+
+    //Add error suppression if used.
+
+    if( Opcode >= 0x700 || RoundMode !== 0 )
+    {
+      out += RoundModes[ RoundMode ];
+    }
+
+    //Return the instruction.
+  }
+
+  return( out );
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+This function Resets the Decoder in case of error, or an full instruction has been decoded.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function Reset()
+{
+  //Reset Opcode, and Size attribute selector.
+
+  Opcode = 0; SizeAttrSelect = 1;
+  
+  //Reset Operands and instruction.
+  
+  Instruction = ""; InsOperands = "";
+
+  //Reset ModR/M.
+
+  RexActive = 0; RegExtend = 0; BaseExtend = 0; IndexExtend = 0;
+  SegOverride = "["; AddressOverride = false; FarPointer = 0;
+
+  //Reset Vector extensions controls.
+
+  Extension = 0; SIMD = 0; Vect = false; ConversionMode = 0; WidthBit = false;
+  VectorRegister = 0; MaskRegister = 0; HInt_ZeroMerg = false; RoundMode = 0x00;
+
+  //Reset vector format settings.
+
+  IgnoresWidthbit = false; VSIB = false; RoundingSetting = 0;
+  Swizzle = false; Up = false; Float = false; VectS = 0x00;
+
+  //Reset IMMValue used for Imm register encoding, and Condition codes.
+
+  IMMValue = 0;
+
+  //Reset instruction Prefixes.
+
+  PrefixG1 = "", PrefixG2 = "";
+  XRelease = false; XAcquire = false; HLEFlipG1G2 = false;
+  HT = false;
+  BND = false;
+
+  //Reset Invalid operation code.
+
+  InvalidOp = false;
+
+  //Reset instruction hex because it is used to check if the instruction is longer than 15 bytes which is impossible for the X86 Decoder Circuit.
+
+  InstructionHex = "";
+
+  //Deactivate all operands along the X86Decoder.
+
+  for( var i = 0; i < X86Decoder.length; X86Decoder[i++].Deactivate() );
+}
+
+/*-------------------------------------------------------------------------------------------------------------------------
+do an linear disassemble.
+-------------------------------------------------------------------------------------------------------------------------*/
+
+function LDisassemble()
+{
+  var Instruction = ""; //Stores the Decoded instruction.
+  var Out = "";  //The Disassemble output
+
+  //Disassemble binary code using an linear pass.
+
+  var len = BinCode.length;
+
+  //Backup the base address.
+
+  var BPos64 = Pos64, BPos32 = Pos32;
+
+  while( CodePos < len )
+  {
+    Instruction = DecodeInstruction();
+
+    //Add the 64 bit address of the output if ShowInstructionPos decoding is active.
+
+    if( ShowInstructionPos )
+    {
+      Out += InstructionPos + " ";
+    }
+
+    //Show Each byte that was read to decode the instruction if ShowInstructionHex decoding is active.
+
+    if(ShowInstructionHex)
+    {
+      InstructionHex = InstructionHex.toUpperCase();
+      for(; InstructionHex.length < 32; InstructionHex = InstructionHex + " " );
+      Out += InstructionHex + "";
+    }
+
+    //Put the decoded instruction into the output and make a new line.
+
+    Out += Instruction + "\r\n";
+
+    //Reset instruction Pos and Hex.
+
+    InstructionPos = ""; InstructionHex = "";
+  }
+
+  CodePos = 0; //Reset the Code position
+  Pos32 = BPos32; Pos64 = BPos64; //Reset Base address.
+
+  //return the decoded binary code
+
+  return(Out);
+
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * The following code has been added to expose public methods for use in CyberChef
+ */
+
+export default {
+  LoadBinCode: LoadBinCode,
+  LDisassemble: LDisassemble,
+  SetBasePosition: SetBasePosition,
+  CompatibilityMode: CompatibilityMode,
+
+  setBitMode: val => { BitMode = val; },
+  setShowInstructionHex: val => { ShowInstructionHex = val; },
+  setShowInstructionPos: val => { ShowInstructionPos = val; },
+};

+ 81 - 17
src/core/operations/BitwiseOp.js

@@ -1,5 +1,4 @@
 import Utils from "../Utils.js";
 import Utils from "../Utils.js";
-import CryptoJS from "crypto-js";
 
 
 
 
 /**
 /**
@@ -92,7 +91,7 @@ const BitwiseOp = {
      * @constant
      * @constant
      * @default
      * @default
      */
      */
-    XOR_BRUTE_KEY_LENGTH: ["1", "2"],
+    XOR_BRUTE_KEY_LENGTH: 1,
     /**
     /**
      * @constant
      * @constant
      * @default
      * @default
@@ -122,37 +121,62 @@ const BitwiseOp = {
      * @returns {string}
      * @returns {string}
      */
      */
     runXorBrute: function (input, args) {
     runXorBrute: function (input, args) {
-        const keyLength = parseInt(args[0], 10),
+        const keyLength = args[0],
             sampleLength = args[1],
             sampleLength = args[1],
             sampleOffset = args[2],
             sampleOffset = args[2],
             scheme = args[3],
             scheme = args[3],
             nullPreserving = args[4],
             nullPreserving = args[4],
             printKey = args[5],
             printKey = args[5],
             outputHex = args[6],
             outputHex = args[6],
-            crib = args[7];
+            crib = args[7].toLowerCase();
 
 
-        let output = "",
+        let output = [],
             result,
             result,
             resultUtf8,
             resultUtf8,
-            regex;
+            record = "";
 
 
         input = input.slice(sampleOffset, sampleOffset + sampleLength);
         input = input.slice(sampleOffset, sampleOffset + sampleLength);
 
 
-        if (crib !== "") {
-            regex = new RegExp(crib, "im");
-        }
-
+        if (ENVIRONMENT_IS_WORKER())
+            self.sendStatusMessage("Calculating " + Math.pow(256, keyLength) + " values...");
+
+        /**
+         * Converts an integer to an array of bytes expressing that number.
+         *
+         * @param {number} int
+         * @param {number} len - Length of the resulting array
+         * @returns {array}
+         */
+        const intToByteArray = (int, len) => {
+            let res = Array(len).fill(0);
+            for (let i = len - 1; i >= 0; i--) {
+                res[i] = int & 0xff;
+                int = int >>> 8;
+            }
+            return res;
+        };
 
 
         for (let key = 1, l = Math.pow(256, keyLength); key < l; key++) {
         for (let key = 1, l = Math.pow(256, keyLength); key < l; key++) {
-            result = BitwiseOp._bitOp(input, Utils.fromHex(key.toString(16)), BitwiseOp._xor, nullPreserving, scheme);
+            if (key % 10000 === 0 && ENVIRONMENT_IS_WORKER()) {
+                self.sendStatusMessage("Calculating " + l + " values... " + Math.floor(key / l * 100) + "%");
+            }
+
+            result = BitwiseOp._bitOp(input, intToByteArray(key, keyLength), BitwiseOp._xor, nullPreserving, scheme);
             resultUtf8 = Utils.byteArrayToUtf8(result);
             resultUtf8 = Utils.byteArrayToUtf8(result);
-            if (crib !== "" && resultUtf8.search(regex) === -1) continue;
-            if (printKey) output += "Key = " + Utils.hex(key, (2*keyLength)) + ": ";
-            if (outputHex) output += Utils.toHex(result) + "\n";
-            else output += Utils.printable(resultUtf8, false) + "\n";
-            if (printKey) output += "\n";
+            record = "";
+
+            if (crib && resultUtf8.toLowerCase().indexOf(crib) < 0) continue;
+            if (printKey) record += "Key = " + Utils.hex(key, (2*keyLength)) + ": ";
+            if (outputHex) {
+                record += Utils.toHex(result);
+            } else {
+                record += Utils.printable(resultUtf8, false);
+            }
+
+            output.push(record);
         }
         }
-        return output;
+
+        return output.join("\n");
     },
     },
 
 
 
 
@@ -228,6 +252,46 @@ const BitwiseOp = {
     },
     },
 
 
 
 
+    /**
+     * Bit shift left operation.
+     *
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    runBitShiftLeft: function(input, args) {
+        const amount = args[0];
+
+        return input.map(b => {
+            return (b << amount) & 0xff;
+        });
+    },
+
+
+    /**
+     * @constant
+     * @default
+     */
+    BIT_SHIFT_TYPE: ["Logical shift", "Arithmetic shift"],
+
+    /**
+     * Bit shift right operation.
+     *
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    runBitShiftRight: function(input, args) {
+        const amount = args[0],
+            type = args[1],
+            mask = type === "Logical shift" ? 0 : 0x80;
+
+        return input.map(b => {
+            return (b >>> amount) ^ (b & mask);
+        });
+    },
+
+
     /**
     /**
      * XOR bitwise calculation.
      * XOR bitwise calculation.
      *
      *

+ 6 - 11
src/core/operations/ByteRepr.js

@@ -1,4 +1,3 @@
-/* globals app */
 import Utils from "../Utils.js";
 import Utils from "../Utils.js";
 
 
 
 
@@ -119,11 +118,11 @@ const ByteRepr = {
                 else if (ordinal < 4294967296) padding = 8;
                 else if (ordinal < 4294967296) padding = 8;
                 else padding = 2;
                 else padding = 2;
 
 
-                if (padding > 2 && app) app.options.attemptHighlight = false;
+                if (padding > 2 && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
 
 
                 output += Utils.hex(ordinal, padding) + delim;
                 output += Utils.hex(ordinal, padding) + delim;
             } else {
             } else {
-                if (app) app.options.attemptHighlight = false;
+                if (ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
                 output += ordinal.toString(base) + delim;
                 output += ordinal.toString(base) + delim;
             }
             }
         }
         }
@@ -149,9 +148,7 @@ const ByteRepr = {
             throw "Error: Base argument must be between 2 and 36";
             throw "Error: Base argument must be between 2 and 36";
         }
         }
 
 
-        if (base !== 16 && app) {
-            app.options.attemptHighlight = false;
-        }
+        if (base !== 16 && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
 
 
         // Split into groups of 2 if the whole string is concatenated and
         // Split into groups of 2 if the whole string is concatenated and
         // too long to be a single character
         // too long to be a single character
@@ -196,7 +193,7 @@ const ByteRepr = {
 
 
 
 
     /**
     /**
-     * Highlight to hex
+     * Highlight from hex
      *
      *
      * @param {Object[]} pos
      * @param {Object[]} pos
      * @param {number} pos[].start
      * @param {number} pos[].start
@@ -288,10 +285,8 @@ const ByteRepr = {
      * @returns {byteArray}
      * @returns {byteArray}
      */
      */
     runFromBinary: function(input, args) {
     runFromBinary: function(input, args) {
-        if (args[0] !== "None") {
-            const delimRegex = Utils.regexRep[args[0] || "Space"];
-            input = input.replace(delimRegex, "");
-        }
+        const delimRegex = Utils.regexRep[args[0] || "Space"];
+        input = input.replace(delimRegex, "");
 
 
         const output = [];
         const output = [];
         const byteLen = 8;
         const byteLen = 8;

+ 0 - 2
src/core/operations/CharEnc.js

@@ -1,6 +1,4 @@
 import cptable from "../lib/js-codepage/cptable.js";
 import cptable from "../lib/js-codepage/cptable.js";
-import Utils from "../Utils.js";
-import CryptoJS from "crypto-js";
 
 
 
 
 /**
 /**

+ 13 - 29
src/core/operations/Checksum.js

@@ -1,3 +1,4 @@
+import * as CRC from "js-crc";
 import Utils from "../Utils.js";
 import Utils from "../Utils.js";
 
 
 
 
@@ -119,19 +120,24 @@ const Checksum = {
     /**
     /**
      * CRC-32 Checksum operation.
      * CRC-32 Checksum operation.
      *
      *
-     * @param {byteArray} input
+     * @param {string} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
     runCRC32: function(input, args) {
     runCRC32: function(input, args) {
-        let crcTable = global.crcTable || (global.crcTable = Checksum._genCRCTable()),
-            crc = 0 ^ (-1);
+        return CRC.crc32(input);
+    },
 
 
-        for (let i = 0; i < input.length; i++) {
-            crc = (crc >>> 8) ^ crcTable[(crc ^ input[i]) & 0xff];
-        }
 
 
-        return Utils.hex((crc ^ (-1)) >>> 0);
+    /**
+     * CRC-16 Checksum operation.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runCRC16: function(input, args) {
+        return CRC.crc16(input);
     },
     },
 
 
 
 
@@ -168,28 +174,6 @@ const Checksum = {
         return Utils.hex(0xffff - csum);
         return Utils.hex(0xffff - csum);
     },
     },
 
 
-
-    /**
-     * Generates a CRC table for use with CRC checksums.
-     *
-     * @private
-     * @returns {array}
-     */
-    _genCRCTable: function() {
-        let c,
-            crcTable = [];
-
-        for (let n = 0; n < 256; n++) {
-            c = n;
-            for (let k = 0; k < 8; k++) {
-                c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
-            }
-            crcTable[n] = c;
-        }
-
-        return crcTable;
-    },
-
 };
 };
 
 
 export default Checksum;
 export default Checksum;

+ 264 - 343
src/core/operations/DateTime.js

@@ -1,5 +1,3 @@
-import {BigInteger} from "jsbn";
-
 /**
 /**
  * Date and time operations.
  * Date and time operations.
  *
  *
@@ -80,85 +78,6 @@ const DateTime = {
     },
     },
 
 
 
 
-    /**
-     * Windows Filetime to Unix Timestamp operation.
-     *
-     * @author bwhitn [brian.m.whitney@outlook.com]
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runFromFiletimeToUnix: function(input, args) {
-        let units = args[0],
-            format = args[1];
-
-        if (format === "Hex") {
-            input = new BigInteger(input, 16);
-        } else {
-            input = new BigInteger(input);
-        }
-
-        input = input.subtract(new BigInteger("116444736000000000"));
-
-        if (units === "Seconds (s)"){
-            input = input.divide(new BigInteger("10000000"));
-        } else if (units === "Milliseconds (ms)") {
-            input = input.divide(new BigInteger("10000"));
-        } else if (units === "Microseconds (μs)") {
-            input = input.divide(new BigInteger("10"));
-        } else if (units === "Nanoseconds (ns)") {
-            input = input.multiply(new BigInteger("100"));
-        } else {
-            throw "Unrecognised unit";
-        }
-
-        return input.toString();
-    },
-
-
-    /**
-     * Unix Timestamp to Windows Filetime operation.
-     *
-     * @author bwhitn [brian.m.whitney@outlook.com]
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runToFiletimeFromUnix: function(input, args) {
-        let units = args[0],
-            format = args[1];
-
-        input = new BigInteger(input);
-
-        if (units === "Seconds (s)"){
-            input = input.multiply(new BigInteger("10000000"));
-        } else if (units === "Milliseconds (ms)") {
-            input = input.multiply(new BigInteger("10000"));
-        } else if (units === "Microseconds (μs)") {
-            input = input.multiply(new BigInteger("10"));
-        } else if (units === "Nanoseconds (ns)") {
-            input = input.divide(new BigInteger("100"));
-        } else {
-            throw "Unrecognised unit";
-        }
-
-        input = input.add(new BigInteger("116444736000000000"));
-
-        if (format === "Hex"){
-            return input.toString(16);
-        } else {
-            return input.toString();
-        }
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    FILETIME_FORMATS: ["Decimal", "Hex"],
-
-
     /**
     /**
      * @constant
      * @constant
      * @default
      * @default
@@ -273,268 +192,270 @@ const DateTime = {
     /**
     /**
      * @constant
      * @constant
      */
      */
-    FORMAT_EXAMPLES: "Format string tokens:\n\n\
-<table class='table table-striped table-hover table-condensed table-bordered' style='font-family: sans-serif'>\
-  <thead>\
-    <tr>\
-      <th>Category</th>\
-      <th>Token</th>\
-      <th>Output</th>\
-    </tr>\
-  </thead>\
-  <tbody>\
-    <tr>\
-      <td><b>Month</b></td>\
-      <td>M</td>\
-      <td>1 2 ... 11 12</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>Mo</td>\
-      <td>1st 2nd ... 11th 12th</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>MM</td>\
-      <td>01 02 ... 11 12</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>MMM</td>\
-      <td>Jan Feb ... Nov Dec</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>MMMM</td>\
-      <td>January February ... November December</td>\
-    </tr>\
-    <tr>\
-      <td><b>Quarter</b></td>\
-      <td>Q</td>\
-      <td>1 2 3 4</td>\
-    </tr>\
-    <tr>\
-      <td><b>Day of Month</b></td>\
-      <td>D</td>\
-      <td>1 2 ... 30 31</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>Do</td>\
-      <td>1st 2nd ... 30th 31st</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>DD</td>\
-      <td>01 02 ... 30 31</td>\
-    </tr>\
-    <tr>\
-      <td><b>Day of Year</b></td>\
-      <td>DDD</td>\
-      <td>1 2 ... 364 365</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>DDDo</td>\
-      <td>1st 2nd ... 364th 365th</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>DDDD</td>\
-      <td>001 002 ... 364 365</td>\
-    </tr>\
-    <tr>\
-      <td><b>Day of Week</b></td>\
-      <td>d</td>\
-      <td>0 1 ... 5 6</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>do</td>\
-      <td>0th 1st ... 5th 6th</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>dd</td>\
-      <td>Su Mo ... Fr Sa</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>ddd</td>\
-      <td>Sun Mon ... Fri Sat</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>dddd</td>\
-      <td>Sunday Monday ... Friday Saturday</td>\
-    </tr>\
-    <tr>\
-      <td><b>Day of Week (Locale)</b></td>\
-      <td>e</td>\
-      <td>0 1 ... 5 6</td>\
-    </tr>\
-    <tr>\
-      <td><b>Day of Week (ISO)</b></td>\
-      <td>E</td>\
-      <td>1 2 ... 6 7</td>\
-    </tr>\
-    <tr>\
-      <td><b>Week of Year</b></td>\
-      <td>w</td>\
-      <td>1 2 ... 52 53</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>wo</td>\
-      <td>1st 2nd ... 52nd 53rd</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>ww</td>\
-      <td>01 02 ... 52 53</td>\
-    </tr>\
-    <tr>\
-      <td><b>Week of Year (ISO)</b></td>\
-      <td>W</td>\
-      <td>1 2 ... 52 53</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>Wo</td>\
-      <td>1st 2nd ... 52nd 53rd</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>WW</td>\
-      <td>01 02 ... 52 53</td>\
-    </tr>\
-    <tr>\
-      <td><b>Year</b></td>\
-      <td>YY</td>\
-      <td>70 71 ... 29 30</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>YYYY</td>\
-      <td>1970 1971 ... 2029 2030</td>\
-    </tr>\
-    <tr>\
-      <td><b>Week Year</b></td>\
-      <td>gg</td>\
-      <td>70 71 ... 29 30</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>gggg</td>\
-      <td>1970 1971 ... 2029 2030</td>\
-    </tr>\
-    <tr>\
-      <td><b>Week Year (ISO)</b></td>\
-      <td>GG</td>\
-      <td>70 71 ... 29 30</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>GGGG</td>\
-      <td>1970 1971 ... 2029 2030</td>\
-    </tr>\
-    <tr>\
-      <td><b>AM/PM</b></td>\
-      <td>A</td>\
-      <td>AM PM</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>a</td>\
-      <td>am pm</td>\
-    </tr>\
-    <tr>\
-      <td><b>Hour</b></td>\
-      <td>H</td>\
-      <td>0 1 ... 22 23</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>HH</td>\
-      <td>00 01 ... 22 23</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>h</td>\
-      <td>1 2 ... 11 12</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>hh</td>\
-      <td>01 02 ... 11 12</td>\
-    </tr>\
-    <tr>\
-      <td><b>Minute</b></td>\
-      <td>m</td>\
-      <td>0 1 ... 58 59</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>mm</td>\
-      <td>00 01 ... 58 59</td>\
-    </tr>\
-    <tr>\
-      <td><b>Second</b></td>\
-      <td>s</td>\
-      <td>0 1 ... 58 59</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>ss</td>\
-      <td>00 01 ... 58 59</td>\
-    </tr>\
-    <tr>\
-      <td><b>Fractional Second</b></td>\
-      <td>S</td>\
-      <td>0 1 ... 8 9</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>SS</td>\
-      <td>00 01 ... 98 99</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>SSS</td>\
-      <td>000 001 ... 998 999</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>SSSS ... SSSSSSSSS</td>\
-      <td>000[0..] 001[0..] ... 998[0..] 999[0..]</td>\
-    </tr>\
-    <tr>\
-      <td><b>Timezone</b></td>\
-      <td>z or zz</td>\
-      <td>EST CST ... MST PST</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>Z</td>\
-      <td>-07:00 -06:00 ... +06:00 +07:00</td>\
-    </tr>\
-    <tr>\
-      <td></td>\
-      <td>ZZ</td>\
-      <td>-0700 -0600 ... +0600 +0700</td>\
-    </tr>\
-    <tr>\
-      <td><b>Unix Timestamp</b></td>\
-      <td>X</td>\
-      <td>1360013296</td>\
-    </tr>\
-    <tr>\
-      <td><b>Unix Millisecond Timestamp</b></td>\
-      <td>x</td>\
-      <td>1360013296123</td>\
-    </tr>\
-  </tbody>\
-</table>",
+    FORMAT_EXAMPLES: `Format string tokens:
+
+
+<table class="table table-striped table-hover table-condensed table-bordered" style="font-family: sans-serif">
+  <thead>
+    <tr>
+      <th>Category</th>
+      <th>Token</th>
+      <th>Output</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td><b>Month</b></td>
+      <td>M</td>
+      <td>1 2 ... 11 12</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>Mo</td>
+      <td>1st 2nd ... 11th 12th</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>MM</td>
+      <td>01 02 ... 11 12</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>MMM</td>
+      <td>Jan Feb ... Nov Dec</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>MMMM</td>
+      <td>January February ... November December</td>
+    </tr>
+    <tr>
+      <td><b>Quarter</b></td>
+      <td>Q</td>
+      <td>1 2 3 4</td>
+    </tr>
+    <tr>
+      <td><b>Day of Month</b></td>
+      <td>D</td>
+      <td>1 2 ... 30 31</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>Do</td>
+      <td>1st 2nd ... 30th 31st</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>DD</td>
+      <td>01 02 ... 30 31</td>
+    </tr>
+    <tr>
+      <td><b>Day of Year</b></td>
+      <td>DDD</td>
+      <td>1 2 ... 364 365</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>DDDo</td>
+      <td>1st 2nd ... 364th 365th</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>DDDD</td>
+      <td>001 002 ... 364 365</td>
+    </tr>
+    <tr>
+      <td><b>Day of Week</b></td>
+      <td>d</td>
+      <td>0 1 ... 5 6</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>do</td>
+      <td>0th 1st ... 5th 6th</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>dd</td>
+      <td>Su Mo ... Fr Sa</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>ddd</td>
+      <td>Sun Mon ... Fri Sat</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>dddd</td>
+      <td>Sunday Monday ... Friday Saturday</td>
+    </tr>
+    <tr>
+      <td><b>Day of Week (Locale)</b></td>
+      <td>e</td>
+      <td>0 1 ... 5 6</td>
+    </tr>
+    <tr>
+      <td><b>Day of Week (ISO)</b></td>
+      <td>E</td>
+      <td>1 2 ... 6 7</td>
+    </tr>
+    <tr>
+      <td><b>Week of Year</b></td>
+      <td>w</td>
+      <td>1 2 ... 52 53</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>wo</td>
+      <td>1st 2nd ... 52nd 53rd</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>ww</td>
+      <td>01 02 ... 52 53</td>
+    </tr>
+    <tr>
+      <td><b>Week of Year (ISO)</b></td>
+      <td>W</td>
+      <td>1 2 ... 52 53</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>Wo</td>
+      <td>1st 2nd ... 52nd 53rd</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>WW</td>
+      <td>01 02 ... 52 53</td>
+    </tr>
+    <tr>
+      <td><b>Year</b></td>
+      <td>YY</td>
+      <td>70 71 ... 29 30</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>YYYY</td>
+      <td>1970 1971 ... 2029 2030</td>
+    </tr>
+    <tr>
+      <td><b>Week Year</b></td>
+      <td>gg</td>
+      <td>70 71 ... 29 30</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>gggg</td>
+      <td>1970 1971 ... 2029 2030</td>
+    </tr>
+    <tr>
+      <td><b>Week Year (ISO)</b></td>
+      <td>GG</td>
+      <td>70 71 ... 29 30</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>GGGG</td>
+      <td>1970 1971 ... 2029 2030</td>
+    </tr>
+    <tr>
+      <td><b>AM/PM</b></td>
+      <td>A</td>
+      <td>AM PM</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>a</td>
+      <td>am pm</td>
+    </tr>
+    <tr>
+      <td><b>Hour</b></td>
+      <td>H</td>
+      <td>0 1 ... 22 23</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>HH</td>
+      <td>00 01 ... 22 23</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>h</td>
+      <td>1 2 ... 11 12</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>hh</td>
+      <td>01 02 ... 11 12</td>
+    </tr>
+    <tr>
+      <td><b>Minute</b></td>
+      <td>m</td>
+      <td>0 1 ... 58 59</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>mm</td>
+      <td>00 01 ... 58 59</td>
+    </tr>
+    <tr>
+      <td><b>Second</b></td>
+      <td>s</td>
+      <td>0 1 ... 58 59</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>ss</td>
+      <td>00 01 ... 58 59</td>
+    </tr>
+    <tr>
+      <td><b>Fractional Second</b></td>
+      <td>S</td>
+      <td>0 1 ... 8 9</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>SS</td>
+      <td>00 01 ... 98 99</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>SSS</td>
+      <td>000 001 ... 998 999</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>SSSS ... SSSSSSSSS</td>
+      <td>000[0..] 001[0..] ... 998[0..] 999[0..]</td>
+    </tr>
+    <tr>
+      <td><b>Timezone</b></td>
+      <td>z or zz</td>
+      <td>EST CST ... MST PST</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>Z</td>
+      <td>-07:00 -06:00 ... +06:00 +07:00</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>ZZ</td>
+      <td>-0700 -0600 ... +0600 +0700</td>
+    </tr>
+    <tr>
+      <td><b>Unix Timestamp</b></td>
+      <td>X</td>
+      <td>1360013296</td>
+    </tr>
+    <tr>
+      <td><b>Unix Millisecond Timestamp</b></td>
+      <td>x</td>
+      <td>1360013296123</td>
+    </tr>
+  </tbody>
+</table>`,
 
 
 };
 };
 
 

+ 94 - 0
src/core/operations/Diff.js

@@ -0,0 +1,94 @@
+import Utils from "../Utils.js";
+import * as JsDiff from "diff";
+
+
+/**
+ * Diff operations.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ *
+ * @namespace
+ */
+const Diff = {
+
+    /**
+     * @constant
+     * @default
+     */
+    DIFF_SAMPLE_DELIMITER: "\\n\\n",
+    /**
+     * @constant
+     * @default
+     */
+    DIFF_BY: ["Character", "Word", "Line", "Sentence", "CSS", "JSON"],
+
+    /**
+     * Diff operation.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {html}
+     */
+    runDiff: function(input, args) {
+        let sampleDelim = args[0],
+            diffBy = args[1],
+            showAdded = args[2],
+            showRemoved = args[3],
+            ignoreWhitespace = args[4],
+            samples = input.split(sampleDelim),
+            output = "",
+            diff;
+
+        if (!samples || samples.length !== 2) {
+            return "Incorrect number of samples, perhaps you need to modify the sample delimiter or add more samples?";
+        }
+
+        switch (diffBy) {
+            case "Character":
+                diff = JsDiff.diffChars(samples[0], samples[1]);
+                break;
+            case "Word":
+                if (ignoreWhitespace) {
+                    diff = JsDiff.diffWords(samples[0], samples[1]);
+                } else {
+                    diff = JsDiff.diffWordsWithSpace(samples[0], samples[1]);
+                }
+                break;
+            case "Line":
+                if (ignoreWhitespace) {
+                    diff = JsDiff.diffTrimmedLines(samples[0], samples[1]);
+                } else {
+                    diff = JsDiff.diffLines(samples[0], samples[1]);
+                }
+                break;
+            case "Sentence":
+                diff = JsDiff.diffSentences(samples[0], samples[1]);
+                break;
+            case "CSS":
+                diff = JsDiff.diffCss(samples[0], samples[1]);
+                break;
+            case "JSON":
+                diff = JsDiff.diffJson(samples[0], samples[1]);
+                break;
+            default:
+                return "Invalid 'Diff by' option.";
+        }
+
+        for (let i = 0; i < diff.length; i++) {
+            if (diff[i].added) {
+                if (showAdded) output += "<span class='hl5'>" + Utils.escapeHtml(diff[i].value) + "</span>";
+            } else if (diff[i].removed) {
+                if (showRemoved) output += "<span class='hl3'>" + Utils.escapeHtml(diff[i].value) + "</span>";
+            } else {
+                output += Utils.escapeHtml(diff[i].value);
+            }
+        }
+
+        return output;
+    },
+
+};
+
+export default Diff;

+ 2 - 38
src/core/operations/Extract.js

@@ -187,11 +187,8 @@ const Extract = {
      * @returns {string}
      * @returns {string}
      */
      */
     runDomains: function(input, args) {
     runDomains: function(input, args) {
-        let displayTotal = args[0],
-            protocol = "https?://",
-            hostname = "[-\\w\\.]+",
-            tld = "\\.(?:com|net|org|biz|info|co|uk|onion|int|mobi|name|edu|gov|mil|eu|ac|ae|af|de|ca|ch|cn|cy|es|gb|hk|il|in|io|tv|me|nl|no|nz|ro|ru|tr|us|az|ir|kz|uz|pk)+",
-            regex = new RegExp("(?:" + protocol + ")?" + hostname + tld, "ig");
+        const displayTotal = args[0],
+            regex = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/ig;
 
 
         return Extract._search(input, regex, null, displayTotal);
         return Extract._search(input, regex, null, displayTotal);
     },
     },
@@ -261,39 +258,6 @@ const Extract = {
         return Extract._search(input, regex, null, displayTotal);
         return Extract._search(input, regex, null, displayTotal);
     },
     },
 
 
-
-    /**
-     * Extract all identifiers operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runAllIdents: function(input, args) {
-        let output = "";
-        output += "IP addresses\n";
-        output += Extract.runIp(input, [true, true, false]);
-
-        output += "\nEmail addresses\n";
-        output += Extract.runEmail(input, []);
-
-        output += "\nMAC addresses\n";
-        output += Extract.runMac(input, []);
-
-        output += "\nURLs\n";
-        output += Extract.runUrls(input, []);
-
-        output += "\nDomain names\n";
-        output += Extract.runDomains(input, []);
-
-        output += "\nFile paths\n";
-        output += Extract.runFilePaths(input, [true, true]);
-
-        output += "\nDates\n";
-        output += Extract.runDates(input, []);
-        return output;
-    },
-
 };
 };
 
 
 export default Extract;
 export default Extract;

+ 99 - 0
src/core/operations/Filetime.js

@@ -0,0 +1,99 @@
+import {BigInteger} from "jsbn";
+
+/**
+ * Windows Filetime operations.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ *
+ * @namespace
+ */
+const Filetime = {
+
+    /**
+     * @constant
+     * @default
+     */
+    UNITS: ["Seconds (s)", "Milliseconds (ms)", "Microseconds (μs)", "Nanoseconds (ns)"],
+
+    /**
+     * @constant
+     * @default
+     */
+    FILETIME_FORMATS: ["Decimal", "Hex"],
+
+    /**
+     * Windows Filetime to Unix Timestamp operation.
+     *
+     * @author bwhitn [brian.m.whitney@outlook.com]
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runFromFiletimeToUnix: function(input, args) {
+        let units = args[0],
+            format = args[1];
+
+        if (format === "Hex") {
+            input = new BigInteger(input, 16);
+        } else {
+            input = new BigInteger(input);
+        }
+
+        input = input.subtract(new BigInteger("116444736000000000"));
+
+        if (units === "Seconds (s)"){
+            input = input.divide(new BigInteger("10000000"));
+        } else if (units === "Milliseconds (ms)") {
+            input = input.divide(new BigInteger("10000"));
+        } else if (units === "Microseconds (μs)") {
+            input = input.divide(new BigInteger("10"));
+        } else if (units === "Nanoseconds (ns)") {
+            input = input.multiply(new BigInteger("100"));
+        } else {
+            throw "Unrecognised unit";
+        }
+
+        return input.toString();
+    },
+
+
+    /**
+     * Unix Timestamp to Windows Filetime operation.
+     *
+     * @author bwhitn [brian.m.whitney@outlook.com]
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runToFiletimeFromUnix: function(input, args) {
+        let units = args[0],
+            format = args[1];
+
+        input = new BigInteger(input);
+
+        if (units === "Seconds (s)"){
+            input = input.multiply(new BigInteger("10000000"));
+        } else if (units === "Milliseconds (ms)") {
+            input = input.multiply(new BigInteger("10000"));
+        } else if (units === "Microseconds (μs)") {
+            input = input.multiply(new BigInteger("10"));
+        } else if (units === "Nanoseconds (ns)") {
+            input = input.divide(new BigInteger("100"));
+        } else {
+            throw "Unrecognised unit";
+        }
+
+        input = input.add(new BigInteger("116444736000000000"));
+
+        if (format === "Hex"){
+            return input.toString(16);
+        } else {
+            return input.toString();
+        }
+    },
+
+};
+
+export default Filetime;

+ 20 - 20
src/core/operations/HTML.js

@@ -225,26 +225,26 @@ const HTML = {
             cmyk = "cmyk(" + c + ", " + m + ", " + y + ", " + k + ")";
             cmyk = "cmyk(" + c + ", " + m + ", " + y + ", " + k + ")";
 
 
         // Generate output
         // Generate output
-        return "<div id='colorpicker' style='display: inline-block'></div>" +
-            "Hex:  " + hex + "\n" +
-            "RGB:  " + rgb + "\n" +
-            "RGBA: " + rgba + "\n" +
-            "HSL:  " + hsl + "\n" +
-            "HSLA: " + hsla + "\n" +
-            "CMYK: " + cmyk +
-            "<script>\
-                $('#colorpicker').colorpicker({\
-                    format: 'rgba',\
-                    color: '" + rgba + "',\
-                    container: true,\
-                    inline: true,\
-                }).on('changeColor', function(e) {\
-                    var color = e.color.toRGB();\
-                    document.getElementById('input-text').value = 'rgba(' +\
-                        color.r + ', ' + color.g + ', ' + color.b + ', ' + color.a + ')';\
-                    window.app.autoBake();\
-                });\
-            </script>";
+        return `<div id="colorpicker" style="display: inline-block"></div>
+Hex:  ${hex}
+RGB:  ${rgb}
+RGBA: ${rgba}
+HSL:  ${hsl}
+HSLA: ${hsla}
+CMYK: ${cmyk}
+<script>
+    $('#colorpicker').colorpicker({
+        format: 'rgba',
+        color: '${rgba}',
+        container: true,
+        inline: true,
+    }).on('changeColor', function(e) {
+        var color = e.color.toRGB();
+        document.getElementById('input-text').value = 'rgba(' +
+            color.r + ', ' + color.g + ', ' + color.b + ', ' + color.a + ')';
+        window.app.autoBake();
+    });
+</script>`;
     },
     },
 
 
 
 

+ 255 - 57
src/core/operations/Hash.js

@@ -1,6 +1,7 @@
 import Utils from "../Utils.js";
 import Utils from "../Utils.js";
-import CryptoJS from "crypto-js";
 import CryptoApi from "crypto-api";
 import CryptoApi from "crypto-api";
+import MD6 from "node-md6";
+import * as SHA3 from "js-sha3";
 import Checksum from "./Checksum.js";
 import Checksum from "./Checksum.js";
 
 
 
 
@@ -15,6 +16,22 @@ import Checksum from "./Checksum.js";
  */
  */
 const Hash = {
 const Hash = {
 
 
+    /**
+     * Generic hash function.
+     *
+     * @param {string} name
+     * @param {string} input
+     * @returns {string}
+     */
+    runHash: function(name, input) {
+        const hasher = CryptoApi.hasher(name);
+        hasher.state.message = input;
+        hasher.state.length += input.length;
+        hasher.process();
+        return hasher.finalize().stringify("hex");
+    },
+
+
     /**
     /**
      * MD2 operation.
      * MD2 operation.
      *
      *
@@ -23,7 +40,7 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runMD2: function (input, args) {
     runMD2: function (input, args) {
-        return Utils.toHexFast(CryptoApi.hash("md2", input, {}));
+        return Hash.runHash("md2", input);
     },
     },
 
 
 
 
@@ -35,7 +52,7 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runMD4: function (input, args) {
     runMD4: function (input, args) {
-        return Utils.toHexFast(CryptoApi.hash("md4", input, {}));
+        return Hash.runHash("md4", input);
     },
     },
 
 
 
 
@@ -47,8 +64,39 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runMD5: function (input, args) {
     runMD5: function (input, args) {
-        input = CryptoJS.enc.Latin1.parse(input); // Cast to WordArray
-        return CryptoJS.MD5(input).toString(CryptoJS.enc.Hex);
+        return Hash.runHash("md5", input);
+    },
+
+
+    /**
+     * @constant
+     * @default
+     */
+    MD6_SIZE: 256,
+    /**
+     * @constant
+     * @default
+     */
+    MD6_LEVELS: 64,
+
+    /**
+     * MD6 operation.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runMD6: function (input, args) {
+        const size = args[0],
+            levels = args[1],
+            key = args[2];
+
+        if (size < 0 || size > 512)
+            return "Size must be between 0 and 512";
+        if (levels < 0)
+            return "Levels must be greater than 0";
+
+        return MD6.getHashOfText(input, size, key, levels);
     },
     },
 
 
 
 
@@ -60,7 +108,7 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runSHA0: function (input, args) {
     runSHA0: function (input, args) {
-        return Utils.toHexFast(CryptoApi.hash("sha0", input, {}));
+        return Hash.runHash("sha0", input);
     },
     },
 
 
 
 
@@ -72,60 +120,174 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runSHA1: function (input, args) {
     runSHA1: function (input, args) {
-        input = CryptoJS.enc.Latin1.parse(input);
-        return CryptoJS.SHA1(input).toString(CryptoJS.enc.Hex);
+        return Hash.runHash("sha1", input);
+    },
+
+
+    /**
+     * @constant
+     * @default
+     */
+    SHA2_SIZE: ["512", "256", "384", "224", "512/256", "512/224"],
+
+    /**
+     * SHA2 operation.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runSHA2: function (input, args) {
+        const size = args[0];
+        return Hash.runHash("sha" + size, input);
+    },
+
+
+    /**
+     * @constant
+     * @default
+     */
+    SHA3_SIZE: ["512", "384", "256", "224"],
+
+    /**
+     * SHA3 operation.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runSHA3: function (input, args) {
+        const size = parseInt(args[0], 10);
+        let algo;
+
+        switch (size) {
+            case 224:
+                algo = SHA3.sha3_224;
+                break;
+            case 384:
+                algo = SHA3.sha3_384;
+                break;
+            case 256:
+                algo = SHA3.sha3_256;
+                break;
+            case 512:
+                algo = SHA3.sha3_512;
+                break;
+            default:
+                return "Invalid size";
+        }
+
+        return algo(input);
     },
     },
 
 
 
 
     /**
     /**
-     * SHA224 operation.
+     * @constant
+     * @default
+     */
+    KECCAK_SIZE: ["512", "384", "256", "224"],
+
+    /**
+     * Keccak operation.
      *
      *
      * @param {string} input
      * @param {string} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
-    runSHA224: function (input, args) {
-        input = CryptoJS.enc.Latin1.parse(input);
-        return CryptoJS.SHA224(input).toString(CryptoJS.enc.Hex);
+    runKeccak: function (input, args) {
+        const size = parseInt(args[0], 10);
+        let algo;
+
+        switch (size) {
+            case 224:
+                algo = SHA3.keccak224;
+                break;
+            case 384:
+                algo = SHA3.keccak384;
+                break;
+            case 256:
+                algo = SHA3.keccak256;
+                break;
+            case 512:
+                algo = SHA3.keccak512;
+                break;
+            default:
+                return "Invalid size";
+        }
+
+        return algo(input);
     },
     },
 
 
 
 
     /**
     /**
-     * SHA256 operation.
+     * @constant
+     * @default
+     */
+    SHAKE_CAPACITY: ["256", "128"],
+    /**
+     * @constant
+     * @default
+     */
+    SHAKE_SIZE: 512,
+
+    /**
+     * Shake operation.
      *
      *
      * @param {string} input
      * @param {string} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
-    runSHA256: function (input, args) {
-        input = CryptoJS.enc.Latin1.parse(input);
-        return CryptoJS.SHA256(input).toString(CryptoJS.enc.Hex);
+    runShake: function (input, args) {
+        const capacity = parseInt(args[0], 10),
+            size = args[1];
+        let algo;
+
+        if (size < 0)
+            return "Size must be greater than 0";
+
+        switch (capacity) {
+            case 128:
+                algo = SHA3.shake128;
+                break;
+            case 256:
+                algo = SHA3.shake256;
+                break;
+            default:
+                return "Invalid size";
+        }
+
+        return algo(input, size);
     },
     },
 
 
 
 
     /**
     /**
-     * SHA384 operation.
+     * @constant
+     * @default
+     */
+    RIPEMD_SIZE: ["320", "256", "160", "128"],
+
+    /**
+     * RIPEMD operation.
      *
      *
      * @param {string} input
      * @param {string} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
-    runSHA384: function (input, args) {
-        input = CryptoJS.enc.Latin1.parse(input);
-        return CryptoJS.SHA384(input).toString(CryptoJS.enc.Hex);
+    runRIPEMD: function (input, args) {
+        const size = args[0];
+        return Hash.runHash("ripemd" + size, input);
     },
     },
 
 
 
 
     /**
     /**
-     * SHA512 operation.
+     * HAS-160 operation.
      *
      *
      * @param {string} input
      * @param {string} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
-    runSHA512: function (input, args) {
-        input = CryptoJS.enc.Latin1.parse(input);
-        return CryptoJS.SHA512(input).toString(CryptoJS.enc.Hex);
+    runHAS: function (input, args) {
+        return Hash.runHash("has160", input);
     },
     },
 
 
 
 
@@ -133,35 +295,43 @@ const Hash = {
      * @constant
      * @constant
      * @default
      * @default
      */
      */
-    SHA3_LENGTH: ["512", "384", "256", "224"],
+    WHIRLPOOL_VARIANT: ["Whirlpool", "Whirlpool-T", "Whirlpool-0"],
 
 
     /**
     /**
-     * SHA3 operation.
+     * Whirlpool operation.
      *
      *
      * @param {string} input
      * @param {string} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
-    runSHA3: function (input, args) {
-        input = CryptoJS.enc.Latin1.parse(input);
-        let sha3Length = args[0],
-            options = {
-                outputLength: parseInt(sha3Length, 10)
-            };
-        return CryptoJS.SHA3(input, options).toString(CryptoJS.enc.Hex);
+    runWhirlpool: function (input, args) {
+        const variant = args[0].toLowerCase();
+        return Hash.runHash(variant, input);
     },
     },
 
 
 
 
     /**
     /**
-     * RIPEMD-160 operation.
+     * @constant
+     * @default
+     */
+    SNEFRU_ROUNDS: ["8", "4", "2"],
+    /**
+     * @constant
+     * @default
+     */
+    SNEFRU_SIZE: ["256", "128"],
+
+    /**
+     * Snefru operation.
      *
      *
      * @param {string} input
      * @param {string} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
-    runRIPEMD160: function (input, args) {
-        input = CryptoJS.enc.Latin1.parse(input);
-        return CryptoJS.RIPEMD160(input).toString(CryptoJS.enc.Hex);
+    runSnefru: function (input, args) {
+        const rounds = args[0],
+            size = args[1];
+        return Hash.runHash(`snefru-${rounds}-${size}`, input);
     },
     },
 
 
 
 
@@ -169,7 +339,27 @@ const Hash = {
      * @constant
      * @constant
      * @default
      * @default
      */
      */
-    HMAC_FUNCTIONS: ["MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "RIPEMD-160"],
+    HMAC_FUNCTIONS: [
+        "MD2",
+        "MD4",
+        "MD5",
+        "SHA0",
+        "SHA1",
+        "SHA224",
+        "SHA256",
+        "SHA384",
+        "SHA512",
+        "SHA512/224",
+        "SHA512/256",
+        "RIPEMD128",
+        "RIPEMD160",
+        "RIPEMD256",
+        "RIPEMD320",
+        "HAS160",
+        "Whirlpool",
+        "Whirlpool-0",
+        "Whirlpool-T"
+    ],
 
 
     /**
     /**
      * HMAC operation.
      * HMAC operation.
@@ -179,19 +369,12 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runHMAC: function (input, args) {
     runHMAC: function (input, args) {
-        const hashFunc = args[1];
-        input = CryptoJS.enc.Latin1.parse(input);
-        const execute = {
-            "MD5": CryptoJS.HmacMD5(input, args[0]),
-            "SHA1": CryptoJS.HmacSHA1(input, args[0]),
-            "SHA224": CryptoJS.HmacSHA224(input, args[0]),
-            "SHA256": CryptoJS.HmacSHA256(input, args[0]),
-            "SHA384": CryptoJS.HmacSHA384(input, args[0]),
-            "SHA512": CryptoJS.HmacSHA512(input, args[0]),
-            "SHA3": CryptoJS.HmacSHA3(input, args[0]),
-            "RIPEMD-160": CryptoJS.HmacRIPEMD160(input, args[0]),
-        };
-        return execute[hashFunc].toString(CryptoJS.enc.Hex);
+        const password = args[0],
+            hashFunc = args[1].toLowerCase(),
+            hmac = CryptoApi.mac("hmac", password, hashFunc, {});
+
+        hmac.update(input);
+        return hmac.finalize().stringify("hex");
     },
     },
 
 
 
 
@@ -207,24 +390,39 @@ const Hash = {
             output = "MD2:         " + Hash.runMD2(input, []) +
             output = "MD2:         " + Hash.runMD2(input, []) +
                 "\nMD4:         " + Hash.runMD4(input, []) +
                 "\nMD4:         " + Hash.runMD4(input, []) +
                 "\nMD5:         " + Hash.runMD5(input, []) +
                 "\nMD5:         " + Hash.runMD5(input, []) +
+                "\nMD6:         " + Hash.runMD6(input, []) +
                 "\nSHA0:        " + Hash.runSHA0(input, []) +
                 "\nSHA0:        " + Hash.runSHA0(input, []) +
                 "\nSHA1:        " + Hash.runSHA1(input, []) +
                 "\nSHA1:        " + Hash.runSHA1(input, []) +
-                "\nSHA2 224:    " + Hash.runSHA224(input, []) +
-                "\nSHA2 256:    " + Hash.runSHA256(input, []) +
-                "\nSHA2 384:    " + Hash.runSHA384(input, []) +
-                "\nSHA2 512:    " + Hash.runSHA512(input, []) +
+                "\nSHA2 224:    " + Hash.runSHA2(input, ["224"]) +
+                "\nSHA2 256:    " + Hash.runSHA2(input, ["256"]) +
+                "\nSHA2 384:    " + Hash.runSHA2(input, ["384"]) +
+                "\nSHA2 512:    " + Hash.runSHA2(input, ["512"]) +
                 "\nSHA3 224:    " + Hash.runSHA3(input, ["224"]) +
                 "\nSHA3 224:    " + Hash.runSHA3(input, ["224"]) +
                 "\nSHA3 256:    " + Hash.runSHA3(input, ["256"]) +
                 "\nSHA3 256:    " + Hash.runSHA3(input, ["256"]) +
                 "\nSHA3 384:    " + Hash.runSHA3(input, ["384"]) +
                 "\nSHA3 384:    " + Hash.runSHA3(input, ["384"]) +
                 "\nSHA3 512:    " + Hash.runSHA3(input, ["512"]) +
                 "\nSHA3 512:    " + Hash.runSHA3(input, ["512"]) +
-                "\nRIPEMD-160:  " + Hash.runRIPEMD160(input, []) +
+                "\nKeccak 224:  " + Hash.runKeccak(input, ["224"]) +
+                "\nKeccak 256:  " + Hash.runKeccak(input, ["256"]) +
+                "\nKeccak 384:  " + Hash.runKeccak(input, ["384"]) +
+                "\nKeccak 512:  " + Hash.runKeccak(input, ["512"]) +
+                "\nShake 128:   " + Hash.runShake(input, ["128", 256]) +
+                "\nShake 256:   " + Hash.runShake(input, ["256", 512]) +
+                "\nRIPEMD-128:  " + Hash.runRIPEMD(input, ["128"]) +
+                "\nRIPEMD-160:  " + Hash.runRIPEMD(input, ["160"]) +
+                "\nRIPEMD-256:  " + Hash.runRIPEMD(input, ["256"]) +
+                "\nRIPEMD-320:  " + Hash.runRIPEMD(input, ["320"]) +
+                "\nHAS-160:     " + Hash.runHAS(input, []) +
+                "\nWhirlpool-0: " + Hash.runWhirlpool(input, ["Whirlpool-0"]) +
+                "\nWhirlpool-T: " + Hash.runWhirlpool(input, ["Whirlpool-T"]) +
+                "\nWhirlpool:   " + Hash.runWhirlpool(input, ["Whirlpool"]) +
                 "\n\nChecksums:" +
                 "\n\nChecksums:" +
                 "\nFletcher-8:  " + Checksum.runFletcher8(byteArray, []) +
                 "\nFletcher-8:  " + Checksum.runFletcher8(byteArray, []) +
                 "\nFletcher-16: " + Checksum.runFletcher16(byteArray, []) +
                 "\nFletcher-16: " + Checksum.runFletcher16(byteArray, []) +
                 "\nFletcher-32: " + Checksum.runFletcher32(byteArray, []) +
                 "\nFletcher-32: " + Checksum.runFletcher32(byteArray, []) +
                 "\nFletcher-64: " + Checksum.runFletcher64(byteArray, []) +
                 "\nFletcher-64: " + Checksum.runFletcher64(byteArray, []) +
                 "\nAdler-32:    " + Checksum.runAdler32(byteArray, []) +
                 "\nAdler-32:    " + Checksum.runAdler32(byteArray, []) +
-                "\nCRC-32:      " + Checksum.runCRC32(byteArray, []);
+                "\nCRC-16:      " + Checksum.runCRC16(input, []) +
+                "\nCRC-32:      " + Checksum.runCRC32(input, []);
 
 
         return output;
         return output;
     },
     },

+ 1 - 2
src/core/operations/Hexdump.js

@@ -1,4 +1,3 @@
-/* globals app */
 import Utils from "../Utils.js";
 import Utils from "../Utils.js";
 
 
 
 
@@ -92,7 +91,7 @@ const Hexdump = {
         const w = (width - 13) / 4;
         const w = (width - 13) / 4;
         // w should be the specified width of the hexdump and therefore a round number
         // w should be the specified width of the hexdump and therefore a round number
         if (Math.floor(w) !== w || input.indexOf("\r") !== -1 || output.indexOf(13) !== -1) {
         if (Math.floor(w) !== w || input.indexOf("\r") !== -1 || output.indexOf(13) !== -1) {
-            if (app) app.options.attemptHighlight = false;
+            if (ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
         }
         }
         return output;
         return output;
     },
     },

+ 213 - 0
src/core/operations/MS.js

@@ -0,0 +1,213 @@
+/**
+ * Microsoft operations. 
+ *
+ * @author bmwhitn [brian.m.whitney@outlook.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ *
+ * @namespace
+ */
+const MS = {
+
+    /**
+     * @constant
+     * @default
+     */
+    D_DECODE: [
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "\x57\x6E\x7B",
+        "\x4A\x4C\x41",
+        "\x0B\x0B\x0B",
+        "\x0C\x0C\x0C",
+        "\x4A\x4C\x41",
+        "\x0E\x0E\x0E",
+        "\x0F\x0F\x0F",
+        "\x10\x10\x10",
+        "\x11\x11\x11",
+        "\x12\x12\x12",
+        "\x13\x13\x13",
+        "\x14\x14\x14",
+        "\x15\x15\x15",
+        "\x16\x16\x16",
+        "\x17\x17\x17",
+        "\x18\x18\x18",
+        "\x19\x19\x19",
+        "\x1A\x1A\x1A",
+        "\x1B\x1B\x1B",
+        "\x1C\x1C\x1C",
+        "\x1D\x1D\x1D",
+        "\x1E\x1E\x1E",
+        "\x1F\x1F\x1F",
+        "\x2E\x2D\x32",
+        "\x47\x75\x30",
+        "\x7A\x52\x21",
+        "\x56\x60\x29",
+        "\x42\x71\x5B",
+        "\x6A\x5E\x38",
+        "\x2F\x49\x33",
+        "\x26\x5C\x3D",
+        "\x49\x62\x58",
+        "\x41\x7D\x3A",
+        "\x34\x29\x35",
+        "\x32\x36\x65",
+        "\x5B\x20\x39",
+        "\x76\x7C\x5C",
+        "\x72\x7A\x56",
+        "\x43\x7F\x73",
+        "\x38\x6B\x66",
+        "\x39\x63\x4E",
+        "\x70\x33\x45",
+        "\x45\x2B\x6B",
+        "\x68\x68\x62",
+        "\x71\x51\x59",
+        "\x4F\x66\x78",
+        "\x09\x76\x5E",
+        "\x62\x31\x7D",
+        "\x44\x64\x4A",
+        "\x23\x54\x6D",
+        "\x75\x43\x71",
+        "\x4A\x4C\x41",
+        "\x7E\x3A\x60",
+        "\x4A\x4C\x41",
+        "\x5E\x7E\x53",
+        "\x40\x4C\x40",
+        "\x77\x45\x42",
+        "\x4A\x2C\x27",
+        "\x61\x2A\x48",
+        "\x5D\x74\x72",
+        "\x22\x27\x75",
+        "\x4B\x37\x31",
+        "\x6F\x44\x37",
+        "\x4E\x79\x4D",
+        "\x3B\x59\x52",
+        "\x4C\x2F\x22",
+        "\x50\x6F\x54",
+        "\x67\x26\x6A",
+        "\x2A\x72\x47",
+        "\x7D\x6A\x64",
+        "\x74\x39\x2D",
+        "\x54\x7B\x20",
+        "\x2B\x3F\x7F",
+        "\x2D\x38\x2E",
+        "\x2C\x77\x4C",
+        "\x30\x67\x5D",
+        "\x6E\x53\x7E",
+        "\x6B\x47\x6C",
+        "\x66\x34\x6F",
+        "\x35\x78\x79",
+        "\x25\x5D\x74",
+        "\x21\x30\x43",
+        "\x64\x23\x26",
+        "\x4D\x5A\x76",
+        "\x52\x5B\x25",
+        "\x63\x6C\x24",
+        "\x3F\x48\x2B",
+        "\x7B\x55\x28",
+        "\x78\x70\x23",
+        "\x29\x69\x41",
+        "\x28\x2E\x34",
+        "\x73\x4C\x09",
+        "\x59\x21\x2A",
+        "\x33\x24\x44",
+        "\x7F\x4E\x3F",
+        "\x6D\x50\x77",
+        "\x55\x09\x3B",
+        "\x53\x56\x55",
+        "\x7C\x73\x69",
+        "\x3A\x35\x61",
+        "\x5F\x61\x63",
+        "\x65\x4B\x50",
+        "\x46\x58\x67",
+        "\x58\x3B\x51",
+        "\x31\x57\x49",
+        "\x69\x22\x4F",
+        "\x6C\x6D\x46",
+        "\x5A\x4D\x68",
+        "\x48\x25\x7C",
+        "\x27\x28\x36",
+        "\x5C\x46\x70",
+        "\x3D\x4A\x6E",
+        "\x24\x32\x7A",
+        "\x79\x41\x2F",
+        "\x37\x3D\x5F",
+        "\x60\x5F\x4B",
+        "\x51\x4F\x5A",
+        "\x20\x42\x2C",
+        "\x36\x65\x57"
+    ],
+
+    /**
+     * @constant
+     * @default
+     */
+    D_COMBINATION: [
+        0, 1, 2, 0, 1, 2, 1, 2, 2, 1, 2, 1, 0, 2, 1, 2, 0, 2, 1, 2, 0, 0, 1, 2, 2, 1, 0, 2, 1, 2, 2, 1,
+        0, 0, 2, 1, 2, 1, 2, 0, 2, 0, 0, 1, 2, 0, 2, 1, 0, 2, 1, 2, 0, 0, 1, 2, 2, 0, 0, 1, 2, 0, 2, 1
+    ],
+
+
+    /**
+     * Decodes Microsoft Encoded Script files that can be read and executed by cscript.exe/wscript.exe.
+     * This is a conversion of a Python script that was originally created by Didier Stevens
+     * (https://DidierStevens.com).
+     *
+     * @private
+     * @param {string} data
+     * @returns {string}
+     */
+    _decode: function (data) {
+        let result = [];
+        let index = -1;
+        data = data.replace(/@&/g, String.fromCharCode(10))
+            .replace(/@#/g, String.fromCharCode(13))
+            .replace(/@\*/g, ">")
+            .replace(/@!/g, "<")
+            .replace(/@\$/g, "@");
+
+        for (let i = 0; i < data.length; i++) {
+            let byte = data.charCodeAt(i);
+            let char = data.charAt(i);
+            if (byte < 128) {
+                index++;
+            }
+
+            if ((byte === 9 || byte > 31 && byte < 128) &&
+                byte !== 60 &&
+                byte !== 62 &&
+                byte !== 64) {
+                char = MS.D_DECODE[byte].charAt(MS.D_COMBINATION[index % 64]);
+            }
+            result.push(char);
+        }
+        return result.join("");
+    },
+
+
+    /**
+     * Microsoft Script Decoder operation.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runDecodeScript: function (input, args) {
+        let matcher = /#@~\^.{6}==(.+).{6}==\^#~@/;
+        let encodedData = matcher.exec(input);
+        if (encodedData){
+            return MS._decode(encodedData[1]);
+        } else {
+            return "";
+        }
+    }
+
+};
+
+export default MS;

+ 55 - 0
src/core/operations/OTP.js

@@ -0,0 +1,55 @@
+import otp from "otp";
+import Base64 from "./Base64.js";
+
+/**
+ * One-Time Password operations.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ *
+ * @namespace
+ */
+const OTP = {
+
+    /**
+     * Generate TOTP operation.
+     *
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runTOTP: function(input, args) {
+        const otpObj = otp({
+            name: args[0],
+            keySize: args[1],
+            codeLength: args[2],
+            secret: Base64.runTo32(input, []),
+            epoch: args[3],
+            timeSlice: args[4]
+        });
+        return `URI: ${otpObj.totpURL}\n\nPassword: ${otpObj.totp()}`;
+    },
+
+
+    /**
+     * Generate HOTP operation.
+     *
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runHOTP: function(input, args) {
+        const otpObj = otp({
+            name: args[0],
+            keySize: args[1],
+            codeLength: args[2],
+            secret: Base64.runTo32(input, []),
+        });
+        const counter = args[3];
+        return `URI: ${otpObj.hotpURL}\n\nPassword: ${otpObj.hotp(counter)}`;
+    },
+
+};
+
+export default OTP;

+ 0 - 699
src/core/operations/PublicKey.js

@@ -341,702 +341,3 @@ ${extensions}`;
 };
 };
 
 
 export default PublicKey;
 export default PublicKey;
-
-
-/**
- * Overwrite DN attribute lookup in jsrasign library with a much more complete version from
- * https://github.com/nfephp-org/nfephp/blob/master/libs/Common/Certificate/Oids.php
- *
- * Various duplicates commented out.
- *
- * @constant
- */
-r.X509.DN_ATTRHEX = {
-    "0603550403": "commonName",
-    "0603550404": "surname",
-    "0603550406": "countryName",
-    "0603550407": "localityName",
-    "0603550408": "stateOrProvinceName",
-    "0603550409": "streetAddress",
-    "060355040a": "organizationName",
-    "060355040b": "organizationalUnitName",
-    "060355040c": "title",
-    "0603550414": "telephoneNumber",
-    "060355042a": "givenName",
-    // "0603551d0e" : "id-ce-subjectKeyIdentifier",
-    // "0603551d0f" : "id-ce-keyUsage",
-    // "0603551d11" : "id-ce-subjectAltName",
-    // "0603551d13" : "id-ce-basicConstraints",
-    // "0603551d14" : "id-ce-cRLNumber",
-    // "0603551d1f" : "id-ce-CRLDistributionPoints",
-    // "0603551d20" : "id-ce-certificatePolicies",
-    // "0603551d23" : "id-ce-authorityKeyIdentifier",
-    // "0603551d25" : "id-ce-extKeyUsage",
-    // "06032a864886f70d010901" : "Email",
-    // "06032a864886f70d010101" : "RSAEncryption",
-    // "06032a864886f70d010102" : "md2WithRSAEncryption",
-    // "06032a864886f70d010104" : "md5withRSAEncryption",
-    // "06032a864886f70d010105" : "SHA-1WithRSAEncryption",
-    // "06032a8648ce380403" : "id-dsa-with-sha-1",
-    // "06032b06010505070302" : "idKpClientAuth",
-    // "06032b06010505070304" : "idKpSecurityemail",
-    "06032b06010505070201": "idCertificatePolicies",
-    "06036086480186f8420101": "netscape-cert-type",
-    "06036086480186f8420102": "netscape-base-url",
-    "06036086480186f8420103": "netscape-revocation-url",
-    "06036086480186f8420104": "netscape-ca-revocation-url",
-    "06036086480186f8420107": "netscape-cert-renewal-url",
-    "06036086480186f8420108": "netscape-ca-policy-url",
-    "06036086480186f842010c": "netscape-ssl-server-name",
-    "06036086480186f842010d": "netscape-comment",
-    "0603604c010201": "A1",
-    "0603604c010203": "A3",
-    "0603604c01020110": "Certification Practice Statement pointer",
-    "0603604c010301": "Dados do cert parte 1",
-    "0603604c010305": "Dados do cert parte 2",
-    "0603604c010306": "Dados do cert parte 3",
-    "06030992268993f22c640119": "domainComponent",
-    "06032a24a0f2a07d01010a": "Signet pilot",
-    "06032a24a0f2a07d01010b": "Signet intraNet",
-    "06032a24a0f2a07d010102": "Signet personal",
-    "06032a24a0f2a07d010114": "Signet securityPolicy",
-    "06032a24a0f2a07d010103": "Signet business",
-    "06032a24a0f2a07d010104": "Signet legal",
-    "06032a24a497a35301640101": "Certificates Australia policyIdentifier",
-    "06032a85702201": "seis-cp",
-    "06032a8570220101": "SEIS certificatePolicy-s10",
-    "06032a85702202": "SEIS pe",
-    "06032a85702203": "SEIS at",
-    "06032a8570220301": "SEIS at-personalIdentifier",
-    "06032a8648ce380201": "holdinstruction-none",
-    "06032a8648ce380202": "holdinstruction-callissuer",
-    "06032a8648ce380203": "holdinstruction-reject",
-    "06032a8648ce380401": "dsa",
-    "06032a8648ce380403": "dsaWithSha1",
-    "06032a8648ce3d01": "fieldType",
-    "06032a8648ce3d0101": "prime-field",
-    "06032a8648ce3d0102": "characteristic-two-field",
-    "06032a8648ce3d010201": "ecPublicKey",
-    "06032a8648ce3d010203": "characteristic-two-basis",
-    "06032a8648ce3d01020301": "onBasis",
-    "06032a8648ce3d01020302": "tpBasis",
-    "06032a8648ce3d01020303": "ppBasis",
-    "06032a8648ce3d02": "publicKeyType",
-    "06032a8648ce3d0201": "ecPublicKey",
-    "06032a8648ce3e0201": "dhPublicNumber",
-    "06032a864886f67d07": "nsn",
-    "06032a864886f67d0741": "nsn-ce",
-    "06032a864886f67d074100": "entrustVersInfo",
-    "06032a864886f67d0742": "nsn-alg",
-    "06032a864886f67d07420a": "cast5CBC",
-    "06032a864886f67d07420b": "cast5MAC",
-    "06032a864886f67d07420c": "pbeWithMD5AndCAST5-CBC",
-    "06032a864886f67d07420d": "passwordBasedMac",
-    "06032a864886f67d074203": "cast3CBC",
-    "06032a864886f67d0743": "nsn-oc",
-    "06032a864886f67d074300": "entrustUser",
-    "06032a864886f67d0744": "nsn-at",
-    "06032a864886f67d074400": "entrustCAInfo",
-    "06032a864886f67d07440a": "attributeCertificate",
-    "06032a864886f70d0101": "pkcs-1",
-    "06032a864886f70d010101": "rsaEncryption",
-    "06032a864886f70d010102": "md2withRSAEncryption",
-    "06032a864886f70d010103": "md4withRSAEncryption",
-    "06032a864886f70d010104": "md5withRSAEncryption",
-    "06032a864886f70d010105": "sha1withRSAEncryption",
-    "06032a864886f70d010106": "rsaOAEPEncryptionSET",
-    "06032a864886f70d010910020b": "SMIMEEncryptionKeyPreference",
-    "06032a864886f70d010c": "pkcs-12",
-    "06032a864886f70d010c01": "pkcs-12-PbeIds",
-    "06032a864886f70d010c0101": "pbeWithSHAAnd128BitRC4",
-    "06032a864886f70d010c0102": "pbeWithSHAAnd40BitRC4",
-    "06032a864886f70d010c0103": "pbeWithSHAAnd3-KeyTripleDES-CBC",
-    "06032a864886f70d010c0104": "pbeWithSHAAnd2-KeyTripleDES-CBC",
-    "06032a864886f70d010c0105": "pbeWithSHAAnd128BitRC2-CBC",
-    "06032a864886f70d010c0106": "pbeWithSHAAnd40BitRC2-CBC",
-    "06032a864886f70d010c0a": "pkcs-12Version1",
-    "06032a864886f70d010c0a01": "pkcs-12BadIds",
-    "06032a864886f70d010c0a0101": "pkcs-12-keyBag",
-    "06032a864886f70d010c0a0102": "pkcs-12-pkcs-8ShroudedKeyBag",
-    "06032a864886f70d010c0a0103": "pkcs-12-certBag",
-    "06032a864886f70d010c0a0104": "pkcs-12-crlBag",
-    "06032a864886f70d010c0a0105": "pkcs-12-secretBag",
-    "06032a864886f70d010c0a0106": "pkcs-12-safeContentsBag",
-    "06032a864886f70d010c02": "pkcs-12-ESPVKID",
-    "06032a864886f70d010c0201": "pkcs-12-PKCS8KeyShrouding",
-    "06032a864886f70d010c03": "pkcs-12-BagIds",
-    "06032a864886f70d010c0301": "pkcs-12-keyBagId",
-    "06032a864886f70d010c0302": "pkcs-12-certAndCRLBagId",
-    "06032a864886f70d010c0303": "pkcs-12-secretBagId",
-    "06032a864886f70d010c0304": "pkcs-12-safeContentsId",
-    "06032a864886f70d010c0305": "pkcs-12-pkcs-8ShroudedKeyBagId",
-    "06032a864886f70d010c04": "pkcs-12-CertBagID",
-    "06032a864886f70d010c0401": "pkcs-12-X509CertCRLBagID",
-    "06032a864886f70d010c0402": "pkcs-12-SDSICertBagID",
-    "06032a864886f70d010c05": "pkcs-12-OID",
-    "06032a864886f70d010c0501": "pkcs-12-PBEID",
-    "06032a864886f70d010c050101": "pkcs-12-PBEWithSha1And128BitRC4",
-    "06032a864886f70d010c050102": "pkcs-12-PBEWithSha1And40BitRC4",
-    "06032a864886f70d010c050103": "pkcs-12-PBEWithSha1AndTripleDESCBC",
-    "06032a864886f70d010c050104": "pkcs-12-PBEWithSha1And128BitRC2CBC",
-    "06032a864886f70d010c050105": "pkcs-12-PBEWithSha1And40BitRC2CBC",
-    "06032a864886f70d010c050106": "pkcs-12-PBEWithSha1AndRC4",
-    "06032a864886f70d010c050107": "pkcs-12-PBEWithSha1AndRC2CBC",
-    "06032a864886f70d010c0502": "pkcs-12-EnvelopingID",
-    "06032a864886f70d010c050201": "pkcs-12-RSAEncryptionWith128BitRC4",
-    "06032a864886f70d010c050202": "pkcs-12-RSAEncryptionWith40BitRC4",
-    "06032a864886f70d010c050203": "pkcs-12-RSAEncryptionWithTripleDES",
-    "06032a864886f70d010c0503": "pkcs-12-SignatureID",
-    "06032a864886f70d010c050301": "pkcs-12-RSASignatureWithSHA1Digest",
-    "06032a864886f70d0103": "pkcs-3",
-    "06032a864886f70d010301": "dhKeyAgreement",
-    "06032a864886f70d0105": "pkcs-5",
-    "06032a864886f70d010501": "pbeWithMD2AndDES-CBC",
-    "06032a864886f70d01050a": "pbeWithSHAAndDES-CBC",
-    "06032a864886f70d010503": "pbeWithMD5AndDES-CBC",
-    "06032a864886f70d010504": "pbeWithMD2AndRC2-CBC",
-    "06032a864886f70d010506": "pbeWithMD5AndRC2-CBC",
-    "06032a864886f70d010509": "pbeWithMD5AndXOR",
-    "06032a864886f70d0107": "pkcs-7",
-    "06032a864886f70d010701": "data",
-    "06032a864886f70d010702": "signedData",
-    "06032a864886f70d010703": "envelopedData",
-    "06032a864886f70d010704": "signedAndEnvelopedData",
-    "06032a864886f70d010705": "digestData",
-    "06032a864886f70d010706": "encryptedData",
-    "06032a864886f70d010707": "dataWithAttributes",
-    "06032a864886f70d010708": "encryptedPrivateKeyInfo",
-    "06032a864886f70d0109": "pkcs-9",
-    "06032a864886f70d010901": "emailAddress",
-    "06032a864886f70d01090a": "issuerAndSerialNumber",
-    "06032a864886f70d01090b": "passwordCheck",
-    "06032a864886f70d01090c": "publicKey",
-    "06032a864886f70d01090d": "signingDescription",
-    "06032a864886f70d01090e": "extensionReq",
-    "06032a864886f70d01090f": "sMIMECapabilities",
-    "06032a864886f70d01090f01": "preferSignedData",
-    "06032a864886f70d01090f02": "canNotDecryptAny",
-    "06032a864886f70d01090f03": "receiptRequest",
-    "06032a864886f70d01090f04": "receipt",
-    "06032a864886f70d01090f05": "contentHints",
-    "06032a864886f70d01090f06": "mlExpansionHistory",
-    "06032a864886f70d010910": "id-sMIME",
-    "06032a864886f70d01091000": "id-mod",
-    "06032a864886f70d0109100001": "id-mod-cms",
-    "06032a864886f70d0109100002": "id-mod-ess",
-    "06032a864886f70d01091001": "id-ct",
-    "06032a864886f70d0109100101": "id-ct-receipt",
-    "06032a864886f70d01091002": "id-aa",
-    "06032a864886f70d0109100201": "id-aa-receiptRequest",
-    "06032a864886f70d0109100202": "id-aa-securityLabel",
-    "06032a864886f70d0109100203": "id-aa-mlExpandHistory",
-    "06032a864886f70d0109100204": "id-aa-contentHint",
-    "06032a864886f70d010902": "unstructuredName",
-    "06032a864886f70d010914": "friendlyName",
-    "06032a864886f70d010915": "localKeyID",
-    "06032a864886f70d010916": "certTypes",
-    "06032a864886f70d01091601": "x509Certificate",
-    "06032a864886f70d01091602": "sdsiCertificate",
-    "06032a864886f70d010917": "crlTypes",
-    "06032a864886f70d01091701": "x509Crl",
-    "06032a864886f70d010903": "contentType",
-    "06032a864886f70d010904": "messageDigest",
-    "06032a864886f70d010905": "signingTime",
-    "06032a864886f70d010906": "countersignature",
-    "06032a864886f70d010907": "challengePassword",
-    "06032a864886f70d010908": "unstructuredAddress",
-    "06032a864886f70d010909": "extendedCertificateAttributes",
-    "06032a864886f70d02": "digestAlgorithm",
-    "06032a864886f70d0202": "md2",
-    "06032a864886f70d0204": "md4",
-    "06032a864886f70d0205": "md5",
-    "06032a864886f70d03": "encryptionAlgorithm",
-    "06032a864886f70d030a": "desCDMF",
-    "06032a864886f70d0302": "rc2CBC",
-    "06032a864886f70d0303": "rc2ECB",
-    "06032a864886f70d0304": "rc4",
-    "06032a864886f70d0305": "rc4WithMAC",
-    "06032a864886f70d0306": "DESX-CBC",
-    "06032a864886f70d0307": "DES-EDE3-CBC",
-    "06032a864886f70d0308": "RC5CBC",
-    "06032a864886f70d0309": "RC5-CBCPad",
-    "06032a864886f7140403": "microsoftExcel",
-    "06032a864886f7140404": "titledWithOID",
-    "06032a864886f7140405": "microsoftPowerPoint",
-    "06032b81051086480954": "x9-84",
-    "06032b8105108648095400": "x9-84-Module",
-    "06032b810510864809540001": "x9-84-Biometrics",
-    "06032b810510864809540002": "x9-84-CMS",
-    "06032b810510864809540003": "x9-84-Identifiers",
-    "06032b8105108648095401": "biometric",
-    "06032b810510864809540100": "id-unknown-Type",
-    "06032b810510864809540101": "id-body-Odor",
-    "06032b81051086480954010a": "id-palm",
-    "06032b81051086480954010b": "id-retina",
-    "06032b81051086480954010c": "id-signature",
-    "06032b81051086480954010d": "id-speech-Pattern",
-    "06032b81051086480954010e": "id-thermal-Image",
-    "06032b81051086480954010f": "id-vein-Pattern",
-    "06032b810510864809540110": "id-thermal-Face-Image",
-    "06032b810510864809540111": "id-thermal-Hand-Image",
-    "06032b810510864809540112": "id-lip-Movement",
-    "06032b810510864809540113": "id-gait",
-    "06032b810510864809540102": "id-dna",
-    "06032b810510864809540103": "id-ear-Shape",
-    "06032b810510864809540104": "id-facial-Features",
-    "06032b810510864809540105": "id-finger-Image",
-    "06032b810510864809540106": "id-finger-Geometry",
-    "06032b810510864809540107": "id-hand-Geometry",
-    "06032b810510864809540108": "id-iris-Features",
-    "06032b810510864809540109": "id-keystroke-Dynamics",
-    "06032b8105108648095402": "processing-algorithm",
-    "06032b8105108648095403": "matching-method",
-    "06032b8105108648095404": "format-Owner",
-    "06032b810510864809540400": "cbeff-Owner",
-    "06032b810510864809540401": "ibia-Owner",
-    "06032b81051086480954040101": "id-ibia-SAFLINK",
-    "06032b8105108648095404010a": "id-ibia-SecuGen",
-    "06032b8105108648095404010b": "id-ibia-PreciseBiometric",
-    "06032b8105108648095404010c": "id-ibia-Identix",
-    "06032b8105108648095404010d": "id-ibia-DERMALOG",
-    "06032b8105108648095404010e": "id-ibia-LOGICO",
-    "06032b8105108648095404010f": "id-ibia-NIST",
-    "06032b81051086480954040110": "id-ibia-A3Vision",
-    "06032b81051086480954040111": "id-ibia-NEC",
-    "06032b81051086480954040112": "id-ibia-STMicroelectronics",
-    "06032b81051086480954040102": "id-ibia-Bioscrypt",
-    "06032b81051086480954040103": "id-ibia-Visionics",
-    "06032b81051086480954040104": "id-ibia-InfineonTechnologiesAG",
-    "06032b81051086480954040105": "id-ibia-IridianTechnologies",
-    "06032b81051086480954040106": "id-ibia-Veridicom",
-    "06032b81051086480954040107": "id-ibia-CyberSIGN",
-    "06032b81051086480954040108": "id-ibia-eCryp.",
-    "06032b81051086480954040109": "id-ibia-FingerprintCardsAB",
-    "06032b810510864809540402": "x9-Owner",
-    "06032b0e021a05": "sha",
-    "06032b0e03020101": "rsa",
-    "06032b0e03020a": "desMAC",
-    "06032b0e03020b": "rsaSignature",
-    "06032b0e03020c": "dsa",
-    "06032b0e03020d": "dsaWithSHA",
-    "06032b0e03020e": "mdc2WithRSASignature",
-    "06032b0e03020f": "shaWithRSASignature",
-    "06032b0e030210": "dhWithCommonModulus",
-    "06032b0e030211": "desEDE",
-    "06032b0e030212": "sha",
-    "06032b0e030213": "mdc-2",
-    "06032b0e030202": "md4WitRSA",
-    "06032b0e03020201": "sqmod-N",
-    "06032b0e030214": "dsaCommon",
-    "06032b0e030215": "dsaCommonWithSHA",
-    "06032b0e030216": "rsaKeyTransport",
-    "06032b0e030217": "keyed-hash-seal",
-    "06032b0e030218": "md2WithRSASignature",
-    "06032b0e030219": "md5WithRSASignature",
-    "06032b0e03021a": "sha1",
-    "06032b0e03021b": "dsaWithSHA1",
-    "06032b0e03021c": "dsaWithCommonSHA1",
-    "06032b0e03021d": "sha-1WithRSAEncryption",
-    "06032b0e030203": "md5WithRSA",
-    "06032b0e03020301": "sqmod-NwithRSA",
-    "06032b0e030204": "md4WithRSAEncryption",
-    "06032b0e030206": "desECB",
-    "06032b0e030207": "desCBC",
-    "06032b0e030208": "desOFB",
-    "06032b0e030209": "desCFB",
-    "06032b0e030301": "simple-strong-auth-mechanism",
-    "06032b0e07020101": "ElGamal",
-    "06032b0e07020301": "md2WithRSA",
-    "06032b0e07020302": "md2WithElGamal",
-    "06032b2403": "algorithm",
-    "06032b240301": "encryptionAlgorithm",
-    "06032b24030101": "des",
-    "06032b240301010101": "desECBPad",
-    "06032b24030101010101": "desECBPadISO",
-    "06032b240301010201": "desCBCPad",
-    "06032b24030101020101": "desCBCPadISO",
-    "06032b24030102": "idea",
-    "06032b2403010201": "ideaECB",
-    "06032b240301020101": "ideaECBPad",
-    "06032b24030102010101": "ideaECBPadISO",
-    "06032b2403010202": "ideaCBC",
-    "06032b240301020201": "ideaCBCPad",
-    "06032b24030102020101": "ideaCBCPadISO",
-    "06032b2403010203": "ideaOFB",
-    "06032b2403010204": "ideaCFB",
-    "06032b24030103": "des-3",
-    "06032b240301030101": "des-3ECBPad",
-    "06032b24030103010101": "des-3ECBPadISO",
-    "06032b240301030201": "des-3CBCPad",
-    "06032b24030103020101": "des-3CBCPadISO",
-    "06032b240302": "hashAlgorithm",
-    "06032b24030201": "ripemd160",
-    "06032b24030202": "ripemd128",
-    "06032b24030203": "ripemd256",
-    "06032b24030204": "mdc2singleLength",
-    "06032b24030205": "mdc2doubleLength",
-    "06032b240303": "signatureAlgorithm",
-    "06032b24030301": "rsa",
-    "06032b2403030101": "rsaMitSHA-1",
-    "06032b2403030102": "rsaMitRIPEMD160",
-    "06032b24030302": "ellipticCurve",
-    "06032b240304": "signatureScheme",
-    "06032b24030401": "iso9796-1",
-    "06032b2403040201": "iso9796-2",
-    "06032b2403040202": "iso9796-2rsa",
-    "06032b2404": "attribute",
-    "06032b2405": "policy",
-    "06032b2406": "api",
-    "06032b240601": "manufacturerSpecific",
-    "06032b240602": "functionalitySpecific",
-    "06032b2407": "api",
-    "06032b240701": "keyAgreement",
-    "06032b240702": "keyTransport",
-    "06032b06010401927c0a0101": "UNINETT policyIdentifier",
-    "06032b0601040195180a": "ICE-TEL policyIdentifier",
-    "06032b0601040197552001": "cryptlibEnvelope",
-    "06032b0601040197552002": "cryptlibPrivateKey",
-    "060a2b060104018237": "Microsoft OID",
-    "060a2b0601040182370a": "Crypto 2.0",
-    "060a2b0601040182370a01": "certTrustList",
-    "060a2b0601040182370a0101": "szOID_SORTED_CTL",
-    "060a2b0601040182370a0a": "Microsoft CMC OIDs",
-    "060a2b0601040182370a0a01": "szOID_CMC_ADD_ATTRIBUTES",
-    "060a2b0601040182370a0b": "Microsoft certificate property OIDs",
-    "060a2b0601040182370a0b01": "szOID_CERT_PROP_ID_PREFIX",
-    "060a2b0601040182370a0c": "CryptUI",
-    "060a2b0601040182370a0c01": "szOID_ANY_APPLICATION_POLICY",
-    "060a2b0601040182370a02": "nextUpdateLocation",
-    "060a2b0601040182370a0301": "certTrustListSigning",
-    "060a2b0601040182370a030a": "szOID_KP_QUALIFIED_SUBORDINATION",
-    "060a2b0601040182370a030b": "szOID_KP_KEY_RECOVERY",
-    "060a2b0601040182370a030c": "szOID_KP_DOCUMENT_SIGNING",
-    "060a2b0601040182370a0302": "timeStampSigning",
-    "060a2b0601040182370a0303": "serverGatedCrypto",
-    "060a2b0601040182370a030301": "szOID_SERIALIZED",
-    "060a2b0601040182370a0304": "encryptedFileSystem",
-    "060a2b0601040182370a030401": "szOID_EFS_RECOVERY",
-    "060a2b0601040182370a0305": "szOID_WHQL_CRYPTO",
-    "060a2b0601040182370a0306": "szOID_NT5_CRYPTO",
-    "060a2b0601040182370a0307": "szOID_OEM_WHQL_CRYPTO",
-    "060a2b0601040182370a0308": "szOID_EMBEDDED_NT_CRYPTO",
-    "060a2b0601040182370a0309": "szOID_ROOT_LIST_SIGNER",
-    "060a2b0601040182370a0401": "yesnoTrustAttr",
-    "060a2b0601040182370a0501": "szOID_DRM",
-    "060a2b0601040182370a0502": "szOID_DRM_INDIVIDUALIZATION",
-    "060a2b0601040182370a0601": "szOID_LICENSES",
-    "060a2b0601040182370a0602": "szOID_LICENSE_SERVER",
-    "060a2b0601040182370a07": "szOID_MICROSOFT_RDN_PREFIX",
-    "060a2b0601040182370a0701": "szOID_KEYID_RDN",
-    "060a2b0601040182370a0801": "szOID_REMOVE_CERTIFICATE",
-    "060a2b0601040182370a0901": "szOID_CROSS_CERT_DIST_POINTS",
-    "060a2b0601040182370c": "Catalog",
-    "060a2b0601040182370c0101": "szOID_CATALOG_LIST",
-    "060a2b0601040182370c0102": "szOID_CATALOG_LIST_MEMBER",
-    "060a2b0601040182370c0201": "CAT_NAMEVALUE_OBJID",
-    "060a2b0601040182370c0202": "CAT_MEMBERINFO_OBJID",
-    "060a2b0601040182370d": "Microsoft PKCS10 OIDs",
-    "060a2b0601040182370d01": "szOID_RENEWAL_CERTIFICATE",
-    "060a2b0601040182370d0201": "szOID_ENROLLMENT_NAME_VALUE_PAIR",
-    "060a2b0601040182370d0202": "szOID_ENROLLMENT_CSP_PROVIDER",
-    "060a2b0601040182370d0203": "OS Version",
-    "060a2b0601040182370f": "Microsoft Java",
-    "060a2b06010401823710": "Microsoft Outlook/Exchange",
-    "060a2b0601040182371004": "Outlook Express",
-    "060a2b06010401823711": "Microsoft PKCS12 attributes",
-    "060a2b0601040182371101": "szOID_LOCAL_MACHINE_KEYSET",
-    "060a2b06010401823712": "Microsoft Hydra",
-    "060a2b06010401823713": "Microsoft ISPU Test",
-    "060a2b06010401823702": "Authenticode",
-    "060a2b06010401823702010a": "spcAgencyInfo",
-    "060a2b06010401823702010b": "spcStatementType",
-    "060a2b06010401823702010c": "spcSpOpusInfo",
-    "060a2b06010401823702010e": "certExtensions",
-    "060a2b06010401823702010f": "spcPelmageData",
-    "060a2b060104018237020112": "SPC_RAW_FILE_DATA_OBJID",
-    "060a2b060104018237020113": "SPC_STRUCTURED_STORAGE_DATA_OBJID",
-    "060a2b060104018237020114": "spcLink",
-    "060a2b060104018237020115": "individualCodeSigning",
-    "060a2b060104018237020116": "commercialCodeSigning",
-    "060a2b060104018237020119": "spcLink",
-    "060a2b06010401823702011a": "spcMinimalCriteriaInfo",
-    "060a2b06010401823702011b": "spcFinancialCriteriaInfo",
-    "060a2b06010401823702011c": "spcLink",
-    "060a2b06010401823702011d": "SPC_HASH_INFO_OBJID",
-    "060a2b06010401823702011e": "SPC_SIPINFO_OBJID",
-    "060a2b060104018237020104": "spcIndirectDataContext",
-    "060a2b0601040182370202": "CTL for Software Publishers Trusted CAs",
-    "060a2b060104018237020201": "szOID_TRUSTED_CODESIGNING_CA_LIST",
-    "060a2b060104018237020202": "szOID_TRUSTED_CLIENT_AUTH_CA_LIST",
-    "060a2b060104018237020203": "szOID_TRUSTED_SERVER_AUTH_CA_LIST",
-    "060a2b06010401823714": "Microsoft Enrollment Infrastructure",
-    "060a2b0601040182371401": "szOID_AUTO_ENROLL_CTL_USAGE",
-    "060a2b0601040182371402": "szOID_ENROLL_CERTTYPE_EXTENSION",
-    "060a2b060104018237140201": "szOID_ENROLLMENT_AGENT",
-    "060a2b060104018237140202": "szOID_KP_SMARTCARD_LOGON",
-    "060a2b060104018237140203": "szOID_NT_PRINCIPAL_NAME",
-    "060a2b0601040182371403": "szOID_CERT_MANIFOLD",
-    "06092b06010401823715": "Microsoft CertSrv Infrastructure",
-    "06092b0601040182371501": "szOID_CERTSRV_CA_VERSION",
-    "06092b0601040182371514": "Client Information",
-    "060a2b06010401823719": "Microsoft Directory Service",
-    "060a2b0601040182371901": "szOID_NTDS_REPLICATION",
-    "060a2b06010401823703": "Time Stamping",
-    "060a2b060104018237030201": "SPC_TIME_STAMP_REQUEST_OBJID",
-    "060a2b0601040182371e": "IIS",
-    "060a2b0601040182371f": "Windows updates and service packs",
-    "060a2b0601040182371f01": "szOID_PRODUCT_UPDATE",
-    "060a2b06010401823704": "Permissions",
-    "060a2b06010401823728": "Fonts",
-    "060a2b06010401823729": "Microsoft Licensing and Registration",
-    "060a2b0601040182372a": "Microsoft Corporate PKI (ITG)",
-    "060a2b06010401823758": "CAPICOM",
-    "060a2b0601040182375801": "szOID_CAPICOM_VERSION",
-    "060a2b0601040182375802": "szOID_CAPICOM_ATTRIBUTE",
-    "060a2b060104018237580201": "szOID_CAPICOM_DOCUMENT_NAME",
-    "060a2b060104018237580202": "szOID_CAPICOM_DOCUMENT_DESCRIPTION",
-    "060a2b0601040182375803": "szOID_CAPICOM_ENCRYPTED_DATA",
-    "060a2b060104018237580301": "szOID_CAPICOM_ENCRYPTED_CONTENT",
-    "06032b0601050507": "pkix",
-    "06032b060105050701": "privateExtension",
-    "06032b06010505070101": "authorityInfoAccess",
-    "06032b06010505070c02": "CMC Data",
-    "06032b060105050702": "policyQualifierIds",
-    // "06032b06010505070201" : "cps",
-    "06032b06010505070202": "unotice",
-    "06032b060105050703": "keyPurpose",
-    "06032b06010505070301": "serverAuth",
-    "06032b06010505070302": "clientAuth",
-    "06032b06010505070303": "codeSigning",
-    "06032b06010505070304": "emailProtection",
-    "06032b06010505070305": "ipsecEndSystem",
-    "06032b06010505070306": "ipsecTunnel",
-    "06032b06010505070307": "ipsecUser",
-    "06032b06010505070308": "timeStamping",
-    "06032b060105050704": "cmpInformationTypes",
-    "06032b06010505070401": "caProtEncCert",
-    "06032b06010505070402": "signKeyPairTypes",
-    "06032b06010505070403": "encKeyPairTypes",
-    "06032b06010505070404": "preferredSymmAlg",
-    "06032b06010505070405": "caKeyUpdateInfo",
-    "06032b06010505070406": "currentCRL",
-    "06032b06010505073001": "ocsp",
-    "06032b06010505073002": "caIssuers",
-    "06032b06010505080101": "HMAC-MD5",
-    "06032b06010505080102": "HMAC-SHA",
-    "060360864801650201010a": "mosaicKeyManagementAlgorithm",
-    "060360864801650201010b": "sdnsKMandSigAlgorithm",
-    "060360864801650201010c": "mosaicKMandSigAlgorithm",
-    "060360864801650201010d": "SuiteASignatureAlgorithm",
-    "060360864801650201010e": "SuiteAConfidentialityAlgorithm",
-    "060360864801650201010f": "SuiteAIntegrityAlgorithm",
-    "06036086480186f84201": "cert-extension",
-    // "06036086480186f8420101" : "netscape-cert-type",
-    "06036086480186f842010a": "EntityLogo",
-    "06036086480186f842010b": "UserPicture",
-    // "06036086480186f842010c" : "netscape-ssl-server-name",
-    // "06036086480186f842010d" : "netscape-comment",
-    // "06036086480186f8420102" : "netscape-base-url",
-    // "06036086480186f8420103" : "netscape-revocation-url",
-    // "06036086480186f8420104" : "netscape-ca-revocation-url",
-    // "06036086480186f8420107" : "netscape-cert-renewal-url",
-    // "06036086480186f8420108" : "netscape-ca-policy-url",
-    "06036086480186f8420109": "HomePage-url",
-    "06036086480186f84202": "data-type",
-    "06036086480186f8420201": "GIF",
-    "06036086480186f8420202": "JPEG",
-    "06036086480186f8420203": "URL",
-    "06036086480186f8420204": "HTML",
-    "06036086480186f8420205": "netscape-cert-sequence",
-    "06036086480186f8420206": "netscape-cert-url",
-    "06036086480186f84203": "directory",
-    "06036086480186f8420401": "serverGatedCrypto",
-    "06036086480186f845010603": "Unknown Verisign extension",
-    "06036086480186f845010606": "Unknown Verisign extension",
-    "06036086480186f84501070101": "Verisign certificatePolicy",
-    "06036086480186f8450107010101": "Unknown Verisign policy qualifier",
-    "06036086480186f8450107010102": "Unknown Verisign policy qualifier",
-    "0603678105": "TCPA",
-    "060367810501": "tcpaSpecVersion",
-    "060367810502": "tcpaAttribute",
-    "06036781050201": "tcpaAtTpmManufacturer",
-    "0603678105020a": "tcpaAtSecurityQualities",
-    "0603678105020b": "tcpaAtTpmProtectionProfile",
-    "0603678105020c": "tcpaAtTpmSecurityTarget",
-    "0603678105020d": "tcpaAtFoundationProtectionProfile",
-    "0603678105020e": "tcpaAtFoundationSecurityTarget",
-    "0603678105020f": "tcpaAtTpmIdLabel",
-    "06036781050202": "tcpaAtTpmModel",
-    "06036781050203": "tcpaAtTpmVersion",
-    "06036781050204": "tcpaAtPlatformManufacturer",
-    "06036781050205": "tcpaAtPlatformModel",
-    "06036781050206": "tcpaAtPlatformVersion",
-    "06036781050207": "tcpaAtComponentManufacturer",
-    "06036781050208": "tcpaAtComponentModel",
-    "06036781050209": "tcpaAtComponentVersion",
-    "060367810503": "tcpaProtocol",
-    "06036781050301": "tcpaPrttTpmIdProtocol",
-    "0603672a00": "contentType",
-    "0603672a0000": "PANData",
-    "0603672a0001": "PANToken",
-    "0603672a0002": "PANOnly",
-    "0603672a01": "msgExt",
-    "0603672a0a": "national",
-    "0603672a0a8140": "Japan",
-    "0603672a02": "field",
-    "0603672a0200": "fullName",
-    "0603672a0201": "givenName",
-    "0603672a020a": "amount",
-    "0603672a0202": "familyName",
-    "0603672a0203": "birthFamilyName",
-    "0603672a0204": "placeName",
-    "0603672a0205": "identificationNumber",
-    "0603672a0206": "month",
-    "0603672a0207": "date",
-    "0603672a02070b": "accountNumber",
-    "0603672a02070c": "passPhrase",
-    "0603672a0208": "address",
-    "0603672a0209": "telephone",
-    "0603672a03": "attribute",
-    "0603672a0300": "cert",
-    "0603672a030000": "rootKeyThumb",
-    "0603672a030001": "additionalPolicy",
-    "0603672a04": "algorithm",
-    "0603672a05": "policy",
-    "0603672a0500": "root",
-    "0603672a06": "module",
-    "0603672a07": "certExt",
-    "0603672a0700": "hashedRootKey",
-    "0603672a0701": "certificateType",
-    "0603672a0702": "merchantData",
-    "0603672a0703": "cardCertRequired",
-    "0603672a0704": "tunneling",
-    "0603672a0705": "setExtensions",
-    "0603672a0706": "setQualifier",
-    "0603672a08": "brand",
-    "0603672a0801": "IATA-ATA",
-    "0603672a081e": "Diners",
-    "0603672a0822": "AmericanExpress",
-    "0603672a0804": "VISA",
-    "0603672a0805": "MasterCard",
-    "0603672a08ae7b": "Novus",
-    "0603672a09": "vendor",
-    "0603672a0900": "GlobeSet",
-    "0603672a0901": "IBM",
-    "0603672a090a": "Griffin",
-    "0603672a090b": "Certicom",
-    "0603672a090c": "OSS",
-    "0603672a090d": "TenthMountain",
-    "0603672a090e": "Antares",
-    "0603672a090f": "ECC",
-    "0603672a0910": "Maithean",
-    "0603672a0911": "Netscape",
-    "0603672a0912": "Verisign",
-    "0603672a0913": "BlueMoney",
-    "0603672a0902": "CyberCash",
-    "0603672a0914": "Lacerte",
-    "0603672a0915": "Fujitsu",
-    "0603672a0916": "eLab",
-    "0603672a0917": "Entrust",
-    "0603672a0918": "VIAnet",
-    "0603672a0919": "III",
-    "0603672a091a": "OpenMarket",
-    "0603672a091b": "Lexem",
-    "0603672a091c": "Intertrader",
-    "0603672a091d": "Persimmon",
-    "0603672a0903": "Terisa",
-    "0603672a091e": "NABLE",
-    "0603672a091f": "espace-net",
-    "0603672a0920": "Hitachi",
-    "0603672a0921": "Microsoft",
-    "0603672a0922": "NEC",
-    "0603672a0923": "Mitsubishi",
-    "0603672a0924": "NCR",
-    "0603672a0925": "e-COMM",
-    "0603672a0926": "Gemplus",
-    "0603672a0904": "RSADSI",
-    "0603672a0905": "VeriFone",
-    "0603672a0906": "TrinTech",
-    "0603672a0907": "BankGate",
-    "0603672a0908": "GTE",
-    "0603672a0909": "CompuSource",
-    "0603551d01": "authorityKeyIdentifier",
-    "0603551d0a": "basicConstraints",
-    "0603551d0b": "nameConstraints",
-    "0603551d0c": "policyConstraints",
-    "0603551d0d": "basicConstraints",
-    "0603551d0e": "subjectKeyIdentifier",
-    "0603551d0f": "keyUsage",
-    "0603551d10": "privateKeyUsagePeriod",
-    "0603551d11": "subjectAltName",
-    "0603551d12": "issuerAltName",
-    "0603551d13": "basicConstraints",
-    "0603551d02": "keyAttributes",
-    "0603551d14": "cRLNumber",
-    "0603551d15": "cRLReason",
-    "0603551d16": "expirationDate",
-    "0603551d17": "instructionCode",
-    "0603551d18": "invalidityDate",
-    "0603551d1a": "issuingDistributionPoint",
-    "0603551d1b": "deltaCRLIndicator",
-    "0603551d1c": "issuingDistributionPoint",
-    "0603551d1d": "certificateIssuer",
-    "0603551d03": "certificatePolicies",
-    "0603551d1e": "nameConstraints",
-    "0603551d1f": "cRLDistributionPoints",
-    "0603551d20": "certificatePolicies",
-    "0603551d21": "policyMappings",
-    "0603551d22": "policyConstraints",
-    "0603551d23": "authorityKeyIdentifier",
-    "0603551d24": "policyConstraints",
-    "0603551d25": "extKeyUsage",
-    "0603551d04": "keyUsageRestriction",
-    "0603551d05": "policyMapping",
-    "0603551d06": "subtreesConstraint",
-    "0603551d07": "subjectAltName",
-    "0603551d08": "issuerAltName",
-    "0603551d09": "subjectDirectoryAttributes",
-    "0603550400": "objectClass",
-    "0603550401": "aliasObjectName",
-    // "060355040c" : "title",
-    "060355040d": "description",
-    "060355040e": "searchGuide",
-    "060355040f": "businessCategory",
-    "0603550410": "postalAddress",
-    "0603550411": "postalCode",
-    "0603550412": "postOfficeBox",
-    "0603550413": "physicalDeliveryOfficeName",
-    "0603550402": "knowledgeInformation",
-    // "0603550414" : "telephoneNumber",
-    "0603550415": "telexNumber",
-    "0603550416": "teletexTerminalIdentifier",
-    "0603550417": "facsimileTelephoneNumber",
-    "0603550418": "x121Address",
-    "0603550419": "internationalISDNNumber",
-    "060355041a": "registeredAddress",
-    "060355041b": "destinationIndicator",
-    "060355041c": "preferredDeliveryMehtod",
-    "060355041d": "presentationAddress",
-    "060355041e": "supportedApplicationContext",
-    "060355041f": "member",
-    "0603550420": "owner",
-    "0603550421": "roleOccupant",
-    "0603550422": "seeAlso",
-    "0603550423": "userPassword",
-    "0603550424": "userCertificate",
-    "0603550425": "caCertificate",
-    "0603550426": "authorityRevocationList",
-    "0603550427": "certificateRevocationList",
-    "0603550428": "crossCertificatePair",
-    "0603550429": "givenName",
-    // "060355042a" : "givenName",
-    "0603550405": "serialNumber",
-    "0603550434": "supportedAlgorithms",
-    "0603550435": "deltaRevocationList",
-    "060355043a": "crossCertificatePair",
-    // "0603550409" : "streetAddress",
-    "06035508": "X.500-Algorithms",
-    "0603550801": "X.500-Alg-Encryption",
-    "060355080101": "rsa",
-    "0603604c0101": "DPC"
-};

+ 5 - 5
src/core/operations/Rotate.js

@@ -20,7 +20,7 @@ const Rotate = {
      * @constant
      * @constant
      * @default
      * @default
      */
      */
-    ROTATE_WHOLE: false,
+    ROTATE_CARRY: false,
 
 
     /**
     /**
      * Runs rotation operations across the input data.
      * Runs rotation operations across the input data.
@@ -53,7 +53,7 @@ const Rotate = {
      */
      */
     runRotr: function(input, args) {
     runRotr: function(input, args) {
         if (args[1]) {
         if (args[1]) {
-            return Rotate._rotrWhole(input, args[0]);
+            return Rotate._rotrCarry(input, args[0]);
         } else {
         } else {
             return Rotate._rot(input, args[0], Rotate._rotr);
             return Rotate._rot(input, args[0], Rotate._rotr);
         }
         }
@@ -69,7 +69,7 @@ const Rotate = {
      */
      */
     runRotl: function(input, args) {
     runRotl: function(input, args) {
         if (args[1]) {
         if (args[1]) {
-            return Rotate._rotlWhole(input, args[0]);
+            return Rotate._rotlCarry(input, args[0]);
         } else {
         } else {
             return Rotate._rot(input, args[0], Rotate._rotl);
             return Rotate._rot(input, args[0], Rotate._rotl);
         }
         }
@@ -197,7 +197,7 @@ const Rotate = {
      * @param {number} amount
      * @param {number} amount
      * @returns {byteArray}
      * @returns {byteArray}
      */
      */
-    _rotrWhole: function(data, amount) {
+    _rotrCarry: function(data, amount) {
         let carryBits = 0,
         let carryBits = 0,
             newByte,
             newByte,
             result = [];
             result = [];
@@ -223,7 +223,7 @@ const Rotate = {
      * @param {number} amount
      * @param {number} amount
      * @returns {byteArray}
      * @returns {byteArray}
      */
      */
-    _rotlWhole: function(data, amount) {
+    _rotlCarry: function(data, amount) {
         let carryBits = 0,
         let carryBits = 0,
             newByte,
             newByte,
             result = [];
             result = [];

+ 1 - 1
src/core/operations/SeqUtils.js

@@ -249,7 +249,7 @@ const SeqUtils = {
             }
             }
         }
         }
 
 
-        return 0;
+        return a.localeCompare(b);
     },
     },
 
 
 };
 };

+ 96 - 0
src/core/operations/Shellcode.js

@@ -0,0 +1,96 @@
+import disassemble from "../lib/DisassembleX86-64.js";
+
+
+/**
+ * Shellcode operations.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ *
+ * @namespace
+ */
+const Shellcode = {
+
+    /**
+     * @constant
+     * @default
+     */
+    MODE: ["64", "32", "16"],
+    /**
+     * @constant
+     * @default
+     */
+    COMPATIBILITY: [
+        "Full x86 architecture",
+        "Knights Corner",
+        "Larrabee",
+        "Cyrix",
+        "Geode",
+        "Centaur",
+        "X86/486"
+    ],
+
+    /**
+     * Disassemble x86 operation.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runDisassemble: function(input, args) {
+        const mode = args[0],
+            compatibility = args[1],
+            codeSegment = args[2],
+            offset = args[3],
+            showInstructionHex = args[4],
+            showInstructionPos = args[5];
+
+        switch (mode) {
+            case "64":
+                disassemble.setBitMode(2);
+                break;
+            case "32":
+                disassemble.setBitMode(1);
+                break;
+            case "16":
+                disassemble.setBitMode(0);
+                break;
+            default:
+                throw "Invalid mode value";
+        }
+
+        switch (compatibility) {
+            case "Full x86 architecture":
+                disassemble.CompatibilityMode(0);
+                break;
+            case "Knights Corner":
+                disassemble.CompatibilityMode(1);
+                break;
+            case "Larrabee":
+                disassemble.CompatibilityMode(2);
+                break;
+            case "Cyrix":
+                disassemble.CompatibilityMode(3);
+                break;
+            case "Geode":
+                disassemble.CompatibilityMode(4);
+                break;
+            case "Centaur":
+                disassemble.CompatibilityMode(5);
+                break;
+            case "X86/486":
+                disassemble.CompatibilityMode(6);
+                break;
+        }
+
+        disassemble.SetBasePosition(codeSegment + ":" + offset);
+        disassemble.setShowInstructionHex(showInstructionHex);
+        disassemble.setShowInstructionPos(showInstructionPos);
+        disassemble.LoadBinCode(input.replace(/\s/g, ""));
+        return disassemble.LDisassemble();
+    },
+
+};
+
+export default Shellcode;

+ 1 - 79
src/core/operations/StrUtils.js

@@ -1,5 +1,4 @@
 import Utils from "../Utils.js";
 import Utils from "../Utils.js";
-import * as JsDiff from "diff";
 
 
 
 
 /**
 /**
@@ -40,7 +39,7 @@ const StrUtils = {
         },
         },
         {
         {
             name: "Domain",
             name: "Domain",
-            value: "(?:(https?):\\/\\/)?([-\\w.]+)\\.(com|net|org|biz|info|co|uk|onion|int|mobi|name|edu|gov|mil|eu|ac|ae|af|de|ca|ch|cn|cy|es|gb|hk|il|in|io|tv|me|nl|no|nz|ro|ru|tr|us|az|ir|kz|uz|pk)+"
+            value: "\\b((?=[a-z0-9-]{1,63}\\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,63}\\b"
         },
         },
         {
         {
             name: "Windows file path",
             name: "Windows file path",
@@ -294,83 +293,6 @@ const StrUtils = {
     },
     },
 
 
 
 
-    /**
-     * @constant
-     * @default
-     */
-    DIFF_SAMPLE_DELIMITER: "\\n\\n",
-    /**
-     * @constant
-     * @default
-     */
-    DIFF_BY: ["Character", "Word", "Line", "Sentence", "CSS", "JSON"],
-
-    /**
-     * Diff operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {html}
-     */
-    runDiff: function(input, args) {
-        let sampleDelim = args[0],
-            diffBy = args[1],
-            showAdded = args[2],
-            showRemoved = args[3],
-            ignoreWhitespace = args[4],
-            samples = input.split(sampleDelim),
-            output = "",
-            diff;
-
-        if (!samples || samples.length !== 2) {
-            return "Incorrect number of samples, perhaps you need to modify the sample delimiter or add more samples?";
-        }
-
-        switch (diffBy) {
-            case "Character":
-                diff = JsDiff.diffChars(samples[0], samples[1]);
-                break;
-            case "Word":
-                if (ignoreWhitespace) {
-                    diff = JsDiff.diffWords(samples[0], samples[1]);
-                } else {
-                    diff = JsDiff.diffWordsWithSpace(samples[0], samples[1]);
-                }
-                break;
-            case "Line":
-                if (ignoreWhitespace) {
-                    diff = JsDiff.diffTrimmedLines(samples[0], samples[1]);
-                } else {
-                    diff = JsDiff.diffLines(samples[0], samples[1]);
-                }
-                break;
-            case "Sentence":
-                diff = JsDiff.diffSentences(samples[0], samples[1]);
-                break;
-            case "CSS":
-                diff = JsDiff.diffCss(samples[0], samples[1]);
-                break;
-            case "JSON":
-                diff = JsDiff.diffJson(samples[0], samples[1]);
-                break;
-            default:
-                return "Invalid 'Diff by' option.";
-        }
-
-        for (let i = 0; i < diff.length; i++) {
-            if (diff[i].added) {
-                if (showAdded) output += "<span class='hl5'>" + Utils.escapeHtml(diff[i].value) + "</span>";
-            } else if (diff[i].removed) {
-                if (showRemoved) output += "<span class='hl3'>" + Utils.escapeHtml(diff[i].value) + "</span>";
-            } else {
-                output += Utils.escapeHtml(diff[i].value);
-            }
-        }
-
-        return output;
-    },
-
-
     /**
     /**
      * @constant
      * @constant
      * @default
      * @default

+ 27 - 46
src/core/operations/URL.js

@@ -1,5 +1,6 @@
 /* globals unescape */
 /* globals unescape */
 import Utils from "../Utils.js";
 import Utils from "../Utils.js";
+import url from "url";
 
 
 
 
 /**
 /**
@@ -58,56 +59,36 @@ const URL_ = {
      * @returns {string}
      * @returns {string}
      */
      */
     runParse: function(input, args) {
     runParse: function(input, args) {
-        if (!document) {
-            throw "This operation only works in a browser.";
-        }
-
-        const a = document.createElement("a");
-
-        // Overwrite base href which will be the current CyberChef URL to reduce confusion.
-        a.href = "http://example.com/";
-        a.href = input;
-
-        if (a.protocol) {
-            let output = "";
-            if (a.hostname !== window.location.hostname) {
-                output = "Protocol:\t" + a.protocol + "\n";
-                if (a.hostname) output += "Hostname:\t" + a.hostname + "\n";
-                if (a.port) output += "Port:\t\t" + a.port + "\n";
-            }
-
-            if (a.pathname && a.pathname !== window.location.pathname) {
-                let pathname = a.pathname;
-                if (pathname.indexOf(window.location.pathname) === 0)
-                    pathname = pathname.replace(window.location.pathname, "");
-                if (pathname)
-                    output += "Path name:\t" + pathname + "\n";
-            }
-
-            if (a.hash && a.hash !== window.location.hash) {
-                output += "Hash:\t\t" + a.hash + "\n";
-            }
-
-            if (a.search && a.search !== window.location.search) {
-                output += "Arguments:\n";
-                const args_ = (a.search.slice(1, a.search.length)).split("&");
-                let splitArgs = [], padding = 0, i;
-                for (i = 0; i < args_.length; i++) {
-                    splitArgs.push(args_[i].split("="));
-                    padding = (splitArgs[i][0].length > padding) ? splitArgs[i][0].length : padding;
-                }
-                for (i = 0; i < splitArgs.length; i++) {
-                    output += "\t" + Utils.padRight(splitArgs[i][0], padding);
-                    if (splitArgs[i].length > 1 && splitArgs[i][1].length)
-                        output += " = " + splitArgs[i][1] + "\n";
-                    else output += "\n";
+        const uri = url.parse(input, true);
+
+        let output = "";
+
+        if (uri.protocol) output += "Protocol:\t" + uri.protocol + "\n";
+        if (uri.auth) output += "Auth:\t\t" + uri.auth + "\n";
+        if (uri.hostname) output += "Hostname:\t" + uri.hostname + "\n";
+        if (uri.port) output += "Port:\t\t" + uri.port + "\n";
+        if (uri.pathname) output += "Path name:\t" + uri.pathname + "\n";
+        if (uri.query) {
+            let keys = Object.keys(uri.query),
+                padding = 0;
+
+            keys.forEach(k => {
+                padding = (k.length > padding) ? k.length : padding;
+            });
+
+            output += "Arguments:\n";
+            for (let key in uri.query) {
+                output += "\t" + Utils.padRight(key, padding);
+                if (uri.query[key].length) {
+                    output += " = " + uri.query[key] + "\n";
+                } else {
+                    output += "\n";
                 }
                 }
             }
             }
-
-            return output;
         }
         }
+        if (uri.hash) output += "Hash:\t\t" + uri.hash + "\n";
 
 
-        return "Invalid URI";
+        return output;
     },
     },
 
 
 
 

+ 3 - 1
src/node/index.js

@@ -9,7 +9,7 @@ require("babel-polyfill");
 
 
 const Chef = require("../core/Chef.js").default;
 const Chef = require("../core/Chef.js").default;
 
 
-const CyberChef = module.exports = {
+const CyberChef = {
 
 
     bake: function(input, recipeConfig) {
     bake: function(input, recipeConfig) {
         this.chef = new Chef();
         this.chef = new Chef();
@@ -23,3 +23,5 @@ const CyberChef = module.exports = {
     }
     }
 
 
 };
 };
+
+module.exports = CyberChef;

+ 87 - 95
src/web/App.js

@@ -1,5 +1,4 @@
 import Utils from "../core/Utils.js";
 import Utils from "../core/Utils.js";
-import Chef from "../core/Chef.js";
 import Manager from "./Manager.js";
 import Manager from "./Manager.js";
 import HTMLCategory from "./HTMLCategory.js";
 import HTMLCategory from "./HTMLCategory.js";
 import HTMLOperation from "./HTMLOperation.js";
 import HTMLOperation from "./HTMLOperation.js";
@@ -27,7 +26,6 @@ const App = function(categories, operations, defaultFavourites, defaultOptions)
     this.doptions      = defaultOptions;
     this.doptions      = defaultOptions;
     this.options       = Utils.extend({}, defaultOptions);
     this.options       = Utils.extend({}, defaultOptions);
 
 
-    this.chef          = new Chef();
     this.manager       = new Manager(this);
     this.manager       = new Manager(this);
 
 
     this.baking        = false;
     this.baking        = false;
@@ -35,8 +33,6 @@ const App = function(categories, operations, defaultFavourites, defaultOptions)
     this.autoBakePause = false;
     this.autoBakePause = false;
     this.progress      = 0;
     this.progress      = 0;
     this.ingId         = 0;
     this.ingId         = 0;
-
-    window.chef        = this.chef;
 };
 };
 
 
 
 
@@ -54,6 +50,8 @@ App.prototype.setup = function() {
     this.resetLayout();
     this.resetLayout();
     this.setCompileMessage();
     this.setCompileMessage();
     this.loadURIParams();
     this.loadURIParams();
+
+    this.appLoaded = true;
     this.loaded();
     this.loaded();
 };
 };
 
 
@@ -64,6 +62,11 @@ App.prototype.setup = function() {
  * @fires Manager#apploaded
  * @fires Manager#apploaded
  */
  */
 App.prototype.loaded = function() {
 App.prototype.loaded = function() {
+    // Check that both the app and the worker have loaded successfully, and that
+    // we haven't already loaded before attempting to remove the loading screen.
+    if (!this.workerLoaded || !this.appLoaded ||
+        !document.getElementById("loader-wrapper")) return;
+
     // Trigger CSS animations to remove preloader
     // Trigger CSS animations to remove preloader
     document.body.classList.add("loaded");
     document.body.classList.add("loaded");
 
 
@@ -85,85 +88,34 @@ App.prototype.loaded = function() {
  * An error handler for displaying the error to the user.
  * An error handler for displaying the error to the user.
  *
  *
  * @param {Error} err
  * @param {Error} err
+ * @param {boolean} [logToConsole=false]
  */
  */
-App.prototype.handleError = function(err) {
-    console.error(err);
+App.prototype.handleError = function(err, logToConsole) {
+    if (logToConsole) console.error(err);
     const msg = err.displayStr || err.toString();
     const msg = err.displayStr || err.toString();
     this.alert(msg, "danger", this.options.errorTimeout, !this.options.showErrors);
     this.alert(msg, "danger", this.options.errorTimeout, !this.options.showErrors);
 };
 };
 
 
 
 
 /**
 /**
- * Updates the UI to show if baking is in process or not.
- *
- * @param {bakingStatus}
- */
-App.prototype.setBakingStatus = function(bakingStatus) {
-    this.baking = bakingStatus;
-
-    let inputLoadingIcon = document.querySelector("#input .title .loading-icon"),
-        outputLoadingIcon = document.querySelector("#output .title .loading-icon"),
-        outputElement = document.querySelector("#output-text");
-
-    if (bakingStatus) {
-        inputLoadingIcon.style.display = "inline-block";
-        outputLoadingIcon.style.display = "inline-block";
-        outputElement.classList.add("disabled");
-        outputElement.disabled = true;
-    } else {
-        inputLoadingIcon.style.display = "none";
-        outputLoadingIcon.style.display = "none";
-        outputElement.classList.remove("disabled");
-        outputElement.disabled = false;
-    }
-};
-
-
-/**
- * Calls the Chef to bake the current input using the current recipe.
+ * Asks the ChefWorker to bake the current input using the current recipe.
  *
  *
  * @param {boolean} [step] - Set to true if we should only execute one operation instead of the
  * @param {boolean} [step] - Set to true if we should only execute one operation instead of the
  *   whole recipe.
  *   whole recipe.
  */
  */
-App.prototype.bake = async function(step) {
-    let response;
-
+App.prototype.bake = function(step) {
     if (this.baking) return;
     if (this.baking) return;
 
 
-    this.setBakingStatus(true);
-
-    try {
-        response = await this.chef.bake(
-            this.getInput(),          // The user's input
-            this.getRecipeConfig(),   // The configuration of the recipe
-            this.options,             // Options set by the user
-            this.progress,            // The current position in the recipe
-            step                      // Whether or not to take one step or execute the whole recipe
-        );
-    } catch (err) {
-        this.handleError(err);
-    }
-
-    this.setBakingStatus(false);
-
-    if (!response) return;
-
-    if (response.error) {
-        this.handleError(response.error);
-    }
+    // Reset attemptHighlight flag
+    this.options.attemptHighlight = true;
 
 
-    this.options  = response.options;
-    this.dishStr  = response.type === "html" ? Utils.stripHtmlTags(response.result, true) : response.result;
-    this.progress = response.progress;
-    this.manager.recipe.updateBreakpointIndicator(response.progress);
-    this.manager.output.set(response.result, response.type, response.duration);
-
-    // If baking took too long, disable auto-bake
-    if (response.duration > this.options.autoBakeThreshold && this.autoBake_) {
-        this.manager.controls.setAutoBake(false);
-        this.alert("Baking took longer than " + this.options.autoBakeThreshold +
-            "ms, Auto Bake has been disabled.", "warning", 5000);
-    }
+    this.manager.worker.bake(
+        this.getInput(),        // The user's input
+        this.getRecipeConfig(), // The configuration of the recipe
+        this.options,           // Options set by the user
+        this.progress,          // The current position in the recipe
+        step                    // Whether or not to take one step or execute the whole recipe
+    );
 };
 };
 
 
 
 
@@ -171,30 +123,36 @@ App.prototype.bake = async function(step) {
  * Runs Auto Bake if it is set.
  * Runs Auto Bake if it is set.
  */
  */
 App.prototype.autoBake = function() {
 App.prototype.autoBake = function() {
-    if (this.autoBake_ && !this.autoBakePause) {
+    // If autoBakePause is set, we are loading a full recipe (and potentially input), so there is no
+    // need to set the staleness indicator. Just exit and wait until auto bake is called after loading
+    // has completed.
+    if (this.autoBakePause) return false;
+
+    if (this.autoBake_ && !this.baking) {
         this.bake();
         this.bake();
+    } else {
+        this.manager.controls.showStaleIndicator();
     }
     }
 };
 };
 
 
 
 
 /**
 /**
- * Runs a silent bake forcing the browser to load and cache all the relevant JavaScript code needed
+ * Runs a silent bake, forcing the browser to load and cache all the relevant JavaScript code needed
  * to do a real bake.
  * to do a real bake.
  *
  *
- * The output will not be modified (hence "silent" bake). This will only actually execute the
- * recipe if auto-bake is enabled, otherwise it will just load the recipe, ingredients and dish.
- *
- * @returns {number} - The number of miliseconds it took to run the silent bake.
+ * The output will not be modified (hence "silent" bake). This will only actually execute the recipe
+ * if auto-bake is enabled, otherwise it will just wake up the ChefWorker with an empty recipe.
  */
  */
 App.prototype.silentBake = function() {
 App.prototype.silentBake = function() {
-    let startTime = new Date().getTime(),
-        recipeConfig = this.getRecipeConfig();
+    let recipeConfig = [];
 
 
     if (this.autoBake_) {
     if (this.autoBake_) {
-        this.chef.silentBake(recipeConfig);
+        // If auto-bake is not enabled we don't want to actually run the recipe as it may be disabled
+        // for a good reason.
+        recipeConfig = this.getRecipeConfig();
     }
     }
 
 
-    return new Date().getTime() - startTime;
+    this.manager.worker.silentBake(recipeConfig);
 };
 };
 
 
 
 
@@ -264,7 +222,7 @@ App.prototype.populateOperationsList = function() {
 App.prototype.initialiseSplitter = function() {
 App.prototype.initialiseSplitter = function() {
     this.columnSplitter = Split(["#operations", "#recipe", "#IO"], {
     this.columnSplitter = Split(["#operations", "#recipe", "#IO"], {
         sizes: [20, 30, 50],
         sizes: [20, 30, 50],
-        minSize: [240, 325, 440],
+        minSize: [240, 325, 450],
         gutterSize: 4,
         gutterSize: 4,
         onDrag: function() {
         onDrag: function() {
             this.manager.controls.adjustWidth();
             this.manager.controls.adjustWidth();
@@ -288,7 +246,7 @@ App.prototype.initialiseSplitter = function() {
 App.prototype.loadLocalStorage = function() {
 App.prototype.loadLocalStorage = function() {
     // Load options
     // Load options
     let lOptions;
     let lOptions;
-    if (localStorage.options !== undefined) {
+    if (this.isLocalStorageAvailable() && localStorage.options !== undefined) {
         lOptions = JSON.parse(localStorage.options);
         lOptions = JSON.parse(localStorage.options);
     }
     }
     this.manager.options.load(lOptions);
     this.manager.options.load(lOptions);
@@ -304,13 +262,17 @@ App.prototype.loadLocalStorage = function() {
  * If the user currently has no saved favourites, the defaults from the view constructor are used.
  * If the user currently has no saved favourites, the defaults from the view constructor are used.
  */
  */
 App.prototype.loadFavourites = function() {
 App.prototype.loadFavourites = function() {
-    let favourites = localStorage.favourites &&
-        localStorage.favourites.length > 2 ?
-        JSON.parse(localStorage.favourites) :
-        this.dfavourites;
-
-    favourites = this.validFavourites(favourites);
-    this.saveFavourites(favourites);
+    let favourites;
+
+    if (this.isLocalStorageAvailable()) {
+        favourites = localStorage.favourites && localStorage.favourites.length > 2 ?
+            JSON.parse(localStorage.favourites) :
+            this.dfavourites;
+        favourites = this.validFavourites(favourites);
+        this.saveFavourites(favourites);
+    } else {
+        favourites = this.dfavourites;
+    }
 
 
     const favCat = this.categories.filter(function(c) {
     const favCat = this.categories.filter(function(c) {
         return c.name === "Favourites";
         return c.name === "Favourites";
@@ -354,6 +316,15 @@ App.prototype.validFavourites = function(favourites) {
  * @param {string[]} favourites - A list of the user's favourite operations
  * @param {string[]} favourites - A list of the user's favourite operations
  */
  */
 App.prototype.saveFavourites = function(favourites) {
 App.prototype.saveFavourites = function(favourites) {
+    if (!this.isLocalStorageAvailable()) {
+        this.alert(
+            "Your security settings do not allow access to local storage so your favourites cannot be saved.",
+            "danger",
+            5000
+        );
+        return false;
+    }
+
     localStorage.setItem("favourites", JSON.stringify(this.validFavourites(favourites)));
     localStorage.setItem("favourites", JSON.stringify(this.validFavourites(favourites)));
 };
 };
 
 
@@ -404,10 +375,6 @@ App.prototype.loadURIParams = function() {
         window.location.hash;
         window.location.hash;
     this.uriParams = Utils.parseURIParams(params);
     this.uriParams = Utils.parseURIParams(params);
 
 
-    // Pause auto-bake while loading but don't modify `this.autoBake_`
-    // otherwise `manualBake` cannot trigger.
-    this.autoBakePause = true;
-
     // Read in recipe from URI params
     // Read in recipe from URI params
     if (this.uriParams.recipe) {
     if (this.uriParams.recipe) {
         try {
         try {
@@ -436,14 +403,16 @@ App.prototype.loadURIParams = function() {
 
 
     // Read in input data from URI params
     // Read in input data from URI params
     if (this.uriParams.input) {
     if (this.uriParams.input) {
+        this.autoBakePause = true;
         try {
         try {
             const inputData = Utils.fromBase64(this.uriParams.input);
             const inputData = Utils.fromBase64(this.uriParams.input);
             this.setInput(inputData);
             this.setInput(inputData);
-        } catch (err) {}
+        } catch (err) {
+        } finally {
+            this.autoBakePause = false;
+        }
     }
     }
 
 
-    // Unpause auto-bake
-    this.autoBakePause = false;
     this.autoBake();
     this.autoBake();
 };
 };
 
 
@@ -476,6 +445,10 @@ App.prototype.getRecipeConfig = function() {
 App.prototype.setRecipeConfig = function(recipeConfig) {
 App.prototype.setRecipeConfig = function(recipeConfig) {
     document.getElementById("rec-list").innerHTML = null;
     document.getElementById("rec-list").innerHTML = null;
 
 
+    // Pause auto-bake while loading but don't modify `this.autoBake_`
+    // otherwise `manualBake` cannot trigger.
+    this.autoBakePause = true;
+
     for (let i = 0; i < recipeConfig.length; i++) {
     for (let i = 0; i < recipeConfig.length; i++) {
         const item = this.manager.recipe.addOperation(recipeConfig[i].op);
         const item = this.manager.recipe.addOperation(recipeConfig[i].op);
 
 
@@ -508,6 +481,9 @@ App.prototype.setRecipeConfig = function(recipeConfig) {
 
 
         this.progress = 0;
         this.progress = 0;
     }
     }
+
+    // Unpause auto bake
+    this.autoBakePause = false;
 };
 };
 
 
 
 
@@ -551,6 +527,22 @@ App.prototype.setCompileMessage = function() {
 };
 };
 
 
 
 
+/**
+ * Determines whether the browser supports Local Storage and if it is accessible.
+ * 
+ * @returns {boolean}
+ */
+App.prototype.isLocalStorageAvailable = function() {
+    try {
+        if (!localStorage) return false;
+        return true;
+    } catch (err) {
+        // Access to LocalStorage is denied
+        return false;
+    }
+};
+
+
 /**
 /**
  * Pops up a message to the user and writes it to the console log.
  * Pops up a message to the user and writes it to the console log.
  *
  *

+ 217 - 0
src/web/BindingsWaiter.js

@@ -0,0 +1,217 @@
+/**
+ * Waiter to handle keybindings to CyberChef functions (i.e. Bake, Step, Save, Load etc.)
+ *
+ * @author Matt C [matt@artemisbot.uk]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ *
+ * @constructor
+ * @param {App} app - The main view object for CyberChef.
+ * @param {Manager} manager - The CyberChef event manager.
+ */
+const BindingsWaiter = function (app, manager) {
+    this.app = app;
+    this.manager = manager;
+};
+
+
+/**
+ * Handler for all keydown events
+ * Checks whether valid keyboard shortcut has been instated
+ *
+ * @fires Manager#statechange
+ * @param {event} e
+ */
+BindingsWaiter.prototype.parseInput = function(e) {
+    const modKey = this.app.options.useMetaKey ? e.metaKey : e.altKey;
+
+    if (e.ctrlKey && modKey) {
+        let elem;
+        switch (e.code) {
+            case "KeyF": // Focus search
+                e.preventDefault();
+                document.getElementById("search").focus();
+                break;
+            case "KeyI": // Focus input
+                e.preventDefault();
+                document.getElementById("input-text").focus();
+                break;
+            case "KeyO": // Focus output
+                e.preventDefault();
+                document.getElementById("output-text").focus();
+                break;
+            case "Period": // Focus next operation
+                e.preventDefault();
+                try {
+                    elem = document.activeElement.closest(".operation") || document.querySelector("#rec-list .operation");
+                    if (elem.parentNode.lastChild === elem) {
+                        // If operation is last in recipe, loop around to the top operation's first argument
+                        elem.parentNode.firstChild.querySelectorAll(".arg")[0].focus();
+                    } else {
+                        // Focus first argument of next operation
+                        elem.nextSibling.querySelectorAll(".arg")[0].focus();
+                    }
+                } catch (e) {
+                    // do nothing, just don't throw an error
+                }
+                break;
+            case "KeyB": // Set breakpoint
+                e.preventDefault();
+                try {
+                    elem = document.activeElement.closest(".operation").querySelectorAll(".breakpoint")[0];
+                    if (elem.getAttribute("break") === "false") {
+                        elem.setAttribute("break", "true"); // add break point if not already enabled
+                        elem.classList.add("breakpoint-selected");
+                    } else {
+                        elem.setAttribute("break", "false"); // remove break point if already enabled
+                        elem.classList.remove("breakpoint-selected");
+                    }
+                    window.dispatchEvent(this.manager.statechange);
+                } catch (e) {
+                    // do nothing, just don't throw an error
+                }
+                break;
+            case "KeyD": // Disable operation
+                e.preventDefault();
+                try {
+                    elem = document.activeElement.closest(".operation").querySelectorAll(".disable-icon")[0];
+                    if (elem.getAttribute("disabled") === "false") {
+                        elem.setAttribute("disabled", "true"); // disable operation if enabled
+                        elem.classList.add("disable-elem-selected");
+                        elem.parentNode.parentNode.classList.add("disabled");
+                    } else {
+                        elem.setAttribute("disabled", "false"); // enable operation if disabled
+                        elem.classList.remove("disable-elem-selected");
+                        elem.parentNode.parentNode.classList.remove("disabled");
+                    }
+                    this.app.progress = 0;
+                    window.dispatchEvent(this.manager.statechange);
+                } catch (e) {
+                    // do nothing, just don't throw an error
+                }
+                break;
+            case "Space": // Bake
+                e.preventDefault();
+                this.app.bake();
+                break;
+            case "Quote": // Step through
+                e.preventDefault();
+                this.app.bake(true);
+                break;
+            case "KeyC": // Clear recipe
+                e.preventDefault();
+                this.manager.recipe.clearRecipe();
+                break;
+            case "KeyS": // Save output to file
+                e.preventDefault();
+                this.manager.output.saveClick();
+                break;
+            case "KeyL": // Load recipe
+                e.preventDefault();
+                this.manager.controls.loadClick();
+                break;
+            case "KeyM": // Switch input and output
+                e.preventDefault();
+                this.manager.output.switchClick();
+                break;
+            default:
+                if (e.code.match(/Digit[0-9]/g)) { // Select nth operation
+                    e.preventDefault();
+                    try {
+                        // Select the first argument of the operation corresponding to the number pressed
+                        document.querySelector(`li:nth-child(${e.code.substr(-1)}) .arg`).focus();
+                    } catch (e) {
+                        // do nothing, just don't throw an error
+                    }
+                }
+                break;
+        }
+    }
+};
+
+
+/**
+ * Updates keybinding list when metaKey option is toggled
+ *
+ */
+BindingsWaiter.prototype.updateKeybList = function() {
+    let modWinLin = "Alt";
+    let modMac = "Opt";
+    if (this.app.options.useMetaKey) {
+        modWinLin = "Win";
+        modMac = "Cmd";
+    }
+    document.getElementById("keybList").innerHTML = `
+    <tr>
+        <td><b>Command</b></td>
+        <td><b>Shortcut (Win/Linux)</b></td>
+        <td><b>Shortcut (Mac)</b></td>
+    </tr>
+    <tr>
+        <td>Place cursor in search field</td>
+        <td>Ctrl+${modWinLin}+f</td>
+        <td>Ctrl+${modMac}+f</td>
+    <tr>
+        <td>Place cursor in input box</td>
+        <td>Ctrl+${modWinLin}+i</td>
+        <td>Ctrl+${modMac}+i</td>
+    </tr>
+    <tr>
+        <td>Place cursor in output box</td>
+        <td>Ctrl+${modWinLin}+o</td>
+        <td>Ctrl+${modMac}+o</td>
+    </tr>
+    <tr>
+        <td>Place cursor in first argument field of the next operation in the recipe</td>
+        <td>Ctrl+${modWinLin}+.</td>
+        <td>Ctrl+${modMac}+.</td>
+    </tr>
+    <tr>
+        <td>Place cursor in first argument field of the nth operation in the recipe</td>
+        <td>Ctrl+${modWinLin}+[1-9]</td>
+        <td>Ctrl+${modMac}+[1-9]</td>
+    </tr>
+    <tr>
+        <td>Disable current operation</td>
+        <td>Ctrl+${modWinLin}+d</td>
+        <td>Ctrl+${modMac}+d</td>
+    </tr>
+    <tr>
+        <td>Set/clear breakpoint</td>
+        <td>Ctrl+${modWinLin}+b</td>
+        <td>Ctrl+${modMac}+b</td>
+    </tr>
+    <tr>
+        <td>Bake</td>
+        <td>Ctrl+${modWinLin}+Space</td>
+        <td>Ctrl+${modMac}+Space</td>
+    </tr>
+    <tr>
+        <td>Step</td>
+        <td>Ctrl+${modWinLin}+'</td>
+        <td>Ctrl+${modMac}+'</td>
+    </tr>
+    <tr>
+        <td>Clear recipe</td>
+        <td>Ctrl+${modWinLin}+c</td>
+        <td>Ctrl+${modMac}+c</td>
+    </tr>
+    <tr>
+        <td>Save to file</td>
+        <td>Ctrl+${modWinLin}+s</td>
+        <td>Ctrl+${modMac}+s</td>
+    </tr>
+    <tr>
+        <td>Load recipe</td>
+        <td>Ctrl+${modWinLin}+l</td>
+        <td>Ctrl+${modMac}+l</td>
+    </tr>
+    <tr>
+        <td>Move output to input</td>
+        <td>Ctrl+${modWinLin}+m</td>
+        <td>Ctrl+${modMac}+m</td>
+    </tr>
+    `;
+};
+
+export default BindingsWaiter;

+ 66 - 7
src/web/ControlsWaiter.js

@@ -78,10 +78,11 @@ ControlsWaiter.prototype.setAutoBake = function(value) {
  * Handler to trigger baking.
  * Handler to trigger baking.
  */
  */
 ControlsWaiter.prototype.bakeClick = function() {
 ControlsWaiter.prototype.bakeClick = function() {
-    this.app.bake();
-    const outputText = document.getElementById("output-text");
-    outputText.focus();
-    outputText.setSelectionRange(0, 0);
+    if (document.getElementById("bake").textContent.indexOf("Bake") > 0) {
+        this.app.bake();
+    } else {
+        this.manager.worker.cancelBake();
+    }
 };
 };
 
 
 
 
@@ -90,9 +91,6 @@ ControlsWaiter.prototype.bakeClick = function() {
  */
  */
 ControlsWaiter.prototype.stepClick = function() {
 ControlsWaiter.prototype.stepClick = function() {
     this.app.bake(true);
     this.app.bake(true);
-    const outputText = document.getElementById("output-text");
-    outputText.focus();
-    outputText.setSelectionRange(0, 0);
 };
 };
 
 
 
 
@@ -256,6 +254,15 @@ ControlsWaiter.prototype.loadClick = function() {
  * Saves the recipe specified in the save textarea to local storage.
  * Saves the recipe specified in the save textarea to local storage.
  */
  */
 ControlsWaiter.prototype.saveButtonClick = function() {
 ControlsWaiter.prototype.saveButtonClick = function() {
+    if (!this.app.isLocalStorageAvailable()) {
+        this.app.alert(
+            "Your security settings do not allow access to local storage so your recipe cannot be saved.",
+            "danger",
+            5000
+        );
+        return false;
+    }
+
     const recipeName = Utils.escapeHtml(document.getElementById("save-name").value);
     const recipeName = Utils.escapeHtml(document.getElementById("save-name").value);
     const recipeStr  = document.querySelector("#save-texts .tab-pane.active textarea").value;
     const recipeStr  = document.querySelector("#save-texts .tab-pane.active textarea").value;
 
 
@@ -285,6 +292,8 @@ ControlsWaiter.prototype.saveButtonClick = function() {
  * Populates the list of saved recipes in the load dialog box from local storage.
  * Populates the list of saved recipes in the load dialog box from local storage.
  */
  */
 ControlsWaiter.prototype.populateLoadRecipesList = function() {
 ControlsWaiter.prototype.populateLoadRecipesList = function() {
+    if (!this.app.isLocalStorageAvailable()) return false;
+
     const loadNameEl = document.getElementById("load-name");
     const loadNameEl = document.getElementById("load-name");
 
 
     // Remove current recipes from select
     // Remove current recipes from select
@@ -315,6 +324,8 @@ ControlsWaiter.prototype.populateLoadRecipesList = function() {
  * Removes the currently selected recipe from local storage.
  * Removes the currently selected recipe from local storage.
  */
  */
 ControlsWaiter.prototype.loadDeleteClick = function() {
 ControlsWaiter.prototype.loadDeleteClick = function() {
+    if (!this.app.isLocalStorageAvailable()) return false;
+
     const id = parseInt(document.getElementById("load-name").value, 10);
     const id = parseInt(document.getElementById("load-name").value, 10);
     const rawSavedRecipes = localStorage.savedRecipes ?
     const rawSavedRecipes = localStorage.savedRecipes ?
         JSON.parse(localStorage.savedRecipes) : [];
         JSON.parse(localStorage.savedRecipes) : [];
@@ -330,6 +341,8 @@ ControlsWaiter.prototype.loadDeleteClick = function() {
  * Displays the selected recipe in the load text box.
  * Displays the selected recipe in the load text box.
  */
  */
 ControlsWaiter.prototype.loadNameChange = function(e) {
 ControlsWaiter.prototype.loadNameChange = function(e) {
+    if (!this.app.isLocalStorageAvailable()) return false;
+
     const el = e.target;
     const el = e.target;
     const savedRecipes = localStorage.savedRecipes ?
     const savedRecipes = localStorage.savedRecipes ?
         JSON.parse(localStorage.savedRecipes) : [];
         JSON.parse(localStorage.savedRecipes) : [];
@@ -348,6 +361,7 @@ ControlsWaiter.prototype.loadButtonClick = function() {
     try {
     try {
         const recipeConfig = Utils.parseRecipeConfig(document.getElementById("load-text").value);
         const recipeConfig = Utils.parseRecipeConfig(document.getElementById("load-text").value);
         this.app.setRecipeConfig(recipeConfig);
         this.app.setRecipeConfig(recipeConfig);
+        this.app.autoBake();
 
 
         $("#rec-list [data-toggle=popover]").popover();
         $("#rec-list [data-toggle=popover]").popover();
     } catch (e) {
     } catch (e) {
@@ -375,4 +389,49 @@ ControlsWaiter.prototype.supportButtonClick = function(e) {
     }
     }
 };
 };
 
 
+
+/**
+ * Shows the stale indicator to show that the input or recipe has changed
+ * since the last bake.
+ */
+ControlsWaiter.prototype.showStaleIndicator = function() {
+    const staleIndicator = document.getElementById("stale-indicator");
+
+    staleIndicator.style.visibility = "visible";
+    staleIndicator.style.opacity = 1;
+};
+
+
+/**
+ * Hides the stale indicator to show that the input or recipe has not changed
+ * since the last bake.
+ */
+ControlsWaiter.prototype.hideStaleIndicator = function() {
+    const staleIndicator = document.getElementById("stale-indicator");
+
+    staleIndicator.style.opacity = 0;
+    staleIndicator.style.visibility = "hidden";
+};
+
+
+/**
+ * Switches the Bake button between 'Bake' and 'Cancel' functions.
+ *
+ * @param {boolean} cancel - Whether to change to cancel or not
+ */
+ControlsWaiter.prototype.toggleBakeButtonFunction = function(cancel) {
+    const bakeButton = document.getElementById("bake"),
+        btnText = bakeButton.querySelector("span");
+
+    if (cancel) {
+        btnText.innerText = "Cancel";
+        bakeButton.classList.remove("btn-success");
+        bakeButton.classList.add("btn-danger");
+    } else {
+        btnText.innerText = "Bake!";
+        bakeButton.classList.remove("btn-danger");
+        bakeButton.classList.add("btn-success");
+    }
+};
+
 export default ControlsWaiter;
 export default ControlsWaiter;

+ 22 - 70
src/web/HighlighterWaiter.js

@@ -10,9 +10,11 @@ import Utils from "../core/Utils.js";
  *
  *
  * @constructor
  * @constructor
  * @param {App} app - The main view object for CyberChef.
  * @param {App} app - The main view object for CyberChef.
+ * @param {Manager} manager - The CyberChef event manager.
  */
  */
-const HighlighterWaiter = function(app) {
+const HighlighterWaiter = function(app, manager) {
     this.app = app;
     this.app = app;
+    this.manager = manager;
 
 
     this.mouseButtonDown = false;
     this.mouseButtonDown = false;
     this.mouseTarget = null;
     this.mouseTarget = null;
@@ -329,41 +331,6 @@ HighlighterWaiter.prototype.removeHighlights = function() {
 };
 };
 
 
 
 
-/**
- * Generates a list of all the highlight functions assigned to operations in the recipe, if the
- * entire recipe supports highlighting.
- *
- * @returns {Object[]} highlights
- * @returns {function} highlights[].f
- * @returns {function} highlights[].b
- * @returns {Object[]} highlights[].args
- */
-HighlighterWaiter.prototype.generateHighlightList = function() {
-    const recipeConfig = this.app.getRecipeConfig();
-    const highlights = [];
-
-    for (let i = 0; i < recipeConfig.length; i++) {
-        if (recipeConfig[i].disabled) continue;
-
-        // If any breakpoints are set, do not attempt to highlight
-        if (recipeConfig[i].breakpoint) return false;
-
-        const op = this.app.operations[recipeConfig[i].op];
-
-        // If any of the operations do not support highlighting, fail immediately.
-        if (op.highlight === false || op.highlight === undefined) return false;
-
-        highlights.push({
-            f: op.highlight,
-            b: op.highlightReverse,
-            args: recipeConfig[i].args
-        });
-    }
-
-    return highlights;
-};
-
-
 /**
 /**
  * Highlights the given offsets in the output.
  * Highlights the given offsets in the output.
  * We will only highlight if:
  * We will only highlight if:
@@ -376,26 +343,8 @@ HighlighterWaiter.prototype.generateHighlightList = function() {
  * @param {number} pos.end - The end offset.
  * @param {number} pos.end - The end offset.
  */
  */
 HighlighterWaiter.prototype.highlightOutput = function(pos) {
 HighlighterWaiter.prototype.highlightOutput = function(pos) {
-    const highlights = this.generateHighlightList();
-
-    if (!highlights || !this.app.autoBake_) {
-        return false;
-    }
-
-    for (let i = 0; i < highlights.length; i++) {
-        // Remove multiple highlights before processing again
-        pos = [pos[0]];
-
-        if (typeof highlights[i].f == "function") {
-            pos = highlights[i].f(pos, highlights[i].args);
-        }
-    }
-
-    document.getElementById("output-selection-info").innerHTML = this.selectionInfo(pos[0].start, pos[0].end);
-    this.highlight(
-        document.getElementById("output-text"),
-        document.getElementById("output-highlighter"),
-        pos);
+    if (!this.app.autoBake_ || this.app.baking) return false;
+    this.manager.worker.highlight(this.app.getRecipeConfig(), "forward", pos);
 };
 };
 
 
 
 
@@ -411,25 +360,28 @@ HighlighterWaiter.prototype.highlightOutput = function(pos) {
  * @param {number} pos.end - The end offset.
  * @param {number} pos.end - The end offset.
  */
  */
 HighlighterWaiter.prototype.highlightInput = function(pos) {
 HighlighterWaiter.prototype.highlightInput = function(pos) {
-    const highlights = this.generateHighlightList();
+    if (!this.app.autoBake_ || this.app.baking) return false;
+    this.manager.worker.highlight(this.app.getRecipeConfig(), "reverse", pos);
+};
 
 
-    if (!highlights || !this.app.autoBake_) {
-        return false;
-    }
 
 
-    for (let i = 0; i < highlights.length; i++) {
-        // Remove multiple highlights before processing again
-        pos = [pos[0]];
+/**
+ * Displays highlight offsets sent back from the Chef.
+ *
+ * @param {Object} pos - The position object for the highlight.
+ * @param {number} pos.start - The start offset.
+ * @param {number} pos.end - The end offset.
+ * @param {string} direction
+ */
+HighlighterWaiter.prototype.displayHighlights = function(pos, direction) {
+    if (!pos) return;
 
 
-        if (typeof highlights[i].b == "function") {
-            pos = highlights[i].b(pos, highlights[i].args);
-        }
-    }
+    const io = direction === "forward" ? "output" : "input";
 
 
-    document.getElementById("input-selection-info").innerHTML = this.selectionInfo(pos[0].start, pos[0].end);
+    document.getElementById(io + "-selection-info").innerHTML = this.selectionInfo(pos[0].start, pos[0].end);
     this.highlight(
     this.highlight(
-        document.getElementById("input-text"),
-        document.getElementById("input-highlighter"),
+        document.getElementById(io + "-text"),
+        document.getElementById(io + "-highlighter"),
         pos);
         pos);
 };
 };
 
 

+ 2 - 6
src/web/InputWaiter.js

@@ -158,18 +158,14 @@ InputWaiter.prototype.inputDrop = function(e) {
     const CHUNK_SIZE = 20480; // 20KB
     const CHUNK_SIZE = 20480; // 20KB
 
 
     const setInput = function() {
     const setInput = function() {
-        if (inputCharcode.length > 100000 && this.app.autoBake_) {
-            this.manager.controls.setAutoBake(false);
-            this.app.alert("Turned off Auto Bake as the input is large", "warning", 5000);
-        }
-
-        this.set(inputCharcode);
         const recipeConfig = this.app.getRecipeConfig();
         const recipeConfig = this.app.getRecipeConfig();
         if (!recipeConfig[0] || recipeConfig[0].op !== "From Hex") {
         if (!recipeConfig[0] || recipeConfig[0].op !== "From Hex") {
             recipeConfig.unshift({op: "From Hex", args: ["Space"]});
             recipeConfig.unshift({op: "From Hex", args: ["Space"]});
             this.app.setRecipeConfig(recipeConfig);
             this.app.setRecipeConfig(recipeConfig);
         }
         }
 
 
+        this.set(inputCharcode);
+
         el.classList.remove("loadingFile");
         el.classList.remove("loadingFile");
     }.bind(this);
     }.bind(this);
 
 

+ 12 - 3
src/web/Manager.js

@@ -1,3 +1,4 @@
+import WorkerWaiter from "./WorkerWaiter.js";
 import WindowWaiter from "./WindowWaiter.js";
 import WindowWaiter from "./WindowWaiter.js";
 import ControlsWaiter from "./ControlsWaiter.js";
 import ControlsWaiter from "./ControlsWaiter.js";
 import RecipeWaiter from "./RecipeWaiter.js";
 import RecipeWaiter from "./RecipeWaiter.js";
@@ -7,6 +8,7 @@ import OutputWaiter from "./OutputWaiter.js";
 import OptionsWaiter from "./OptionsWaiter.js";
 import OptionsWaiter from "./OptionsWaiter.js";
 import HighlighterWaiter from "./HighlighterWaiter.js";
 import HighlighterWaiter from "./HighlighterWaiter.js";
 import SeasonalWaiter from "./SeasonalWaiter.js";
 import SeasonalWaiter from "./SeasonalWaiter.js";
+import BindingsWaiter from "./BindingsWaiter.js";
 
 
 
 
 /**
 /**
@@ -49,6 +51,7 @@ const Manager = function(app) {
     this.statechange = new CustomEvent("statechange", {bubbles: true});
     this.statechange = new CustomEvent("statechange", {bubbles: true});
 
 
     // Define Waiter objects to handle various areas
     // Define Waiter objects to handle various areas
+    this.worker      = new WorkerWaiter(this.app, this);
     this.window      = new WindowWaiter(this.app);
     this.window      = new WindowWaiter(this.app);
     this.controls    = new ControlsWaiter(this.app, this);
     this.controls    = new ControlsWaiter(this.app, this);
     this.recipe      = new RecipeWaiter(this.app, this);
     this.recipe      = new RecipeWaiter(this.app, this);
@@ -56,8 +59,9 @@ const Manager = function(app) {
     this.input       = new InputWaiter(this.app, this);
     this.input       = new InputWaiter(this.app, this);
     this.output      = new OutputWaiter(this.app, this);
     this.output      = new OutputWaiter(this.app, this);
     this.options     = new OptionsWaiter(this.app);
     this.options     = new OptionsWaiter(this.app);
-    this.highlighter = new HighlighterWaiter(this.app);
+    this.highlighter = new HighlighterWaiter(this.app, this);
     this.seasonal    = new SeasonalWaiter(this.app, this);
     this.seasonal    = new SeasonalWaiter(this.app, this);
+    this.bindings    = new BindingsWaiter(this.app, this);
 
 
     // Object to store dynamic handlers to fire on elements that may not exist yet
     // Object to store dynamic handlers to fire on elements that may not exist yet
     this.dynamicHandlers = {};
     this.dynamicHandlers = {};
@@ -70,8 +74,10 @@ const Manager = function(app) {
  * Sets up the various components and listeners.
  * Sets up the various components and listeners.
  */
  */
 Manager.prototype.setup = function() {
 Manager.prototype.setup = function() {
+    this.worker.registerChefWorker();
     this.recipe.initialiseOperationDragNDrop();
     this.recipe.initialiseOperationDragNDrop();
     this.controls.autoBakeChange();
     this.controls.autoBakeChange();
+    this.bindings.updateKeybList();
     this.seasonal.load();
     this.seasonal.load();
 };
 };
 
 
@@ -116,8 +122,8 @@ Manager.prototype.initialiseEventListeners = function() {
     this.addDynamicListener("li.operation", "operationadd", this.recipe.opAdd.bind(this.recipe));
     this.addDynamicListener("li.operation", "operationadd", this.recipe.opAdd.bind(this.recipe));
 
 
     // Recipe
     // Recipe
-    this.addDynamicListener(".arg", "keyup", this.recipe.ingChange, this.recipe);
-    this.addDynamicListener(".arg", "change", this.recipe.ingChange, this.recipe);
+    this.addDynamicListener(".arg:not(select)", "input", this.recipe.ingChange, this.recipe);
+    this.addDynamicListener(".arg[type=checkbox], .arg[type=radio], select.arg", "change", this.recipe.ingChange, this.recipe);
     this.addDynamicListener(".disable-icon", "click", this.recipe.disableClick, this.recipe);
     this.addDynamicListener(".disable-icon", "click", this.recipe.disableClick, this.recipe);
     this.addDynamicListener(".breakpoint", "click", this.recipe.breakpointClick, this.recipe);
     this.addDynamicListener(".breakpoint", "click", this.recipe.breakpointClick, this.recipe);
     this.addDynamicListener("#rec-list li.operation", "dblclick", this.recipe.operationDblclick, this.recipe);
     this.addDynamicListener("#rec-list li.operation", "dblclick", this.recipe.operationDblclick, this.recipe);
@@ -139,6 +145,7 @@ Manager.prototype.initialiseEventListeners = function() {
 
 
     // Output
     // Output
     document.getElementById("save-to-file").addEventListener("click", this.output.saveClick.bind(this.output));
     document.getElementById("save-to-file").addEventListener("click", this.output.saveClick.bind(this.output));
+    document.getElementById("copy-output").addEventListener("click", this.output.copyClick.bind(this.output));
     document.getElementById("switch").addEventListener("click", this.output.switchClick.bind(this.output));
     document.getElementById("switch").addEventListener("click", this.output.switchClick.bind(this.output));
     document.getElementById("undo-switch").addEventListener("click", this.output.undoSwitchClick.bind(this.output));
     document.getElementById("undo-switch").addEventListener("click", this.output.undoSwitchClick.bind(this.output));
     document.getElementById("maximise-output").addEventListener("click", this.output.maximiseOutputClick.bind(this.output));
     document.getElementById("maximise-output").addEventListener("click", this.output.maximiseOutputClick.bind(this.output));
@@ -156,12 +163,14 @@ Manager.prototype.initialiseEventListeners = function() {
     document.getElementById("reset-options").addEventListener("click", this.options.resetOptionsClick.bind(this.options));
     document.getElementById("reset-options").addEventListener("click", this.options.resetOptionsClick.bind(this.options));
     $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.switchChange.bind(this.options));
     $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.switchChange.bind(this.options));
     $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.setWordWrap.bind(this.options));
     $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.setWordWrap.bind(this.options));
+    $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox#useMetaKey", this.bindings.updateKeybList.bind(this.bindings));
     this.addDynamicListener(".option-item input[type=number]", "keyup", this.options.numberChange, this.options);
     this.addDynamicListener(".option-item input[type=number]", "keyup", this.options.numberChange, this.options);
     this.addDynamicListener(".option-item input[type=number]", "change", this.options.numberChange, this.options);
     this.addDynamicListener(".option-item input[type=number]", "change", this.options.numberChange, this.options);
     this.addDynamicListener(".option-item select", "change", this.options.selectChange, this.options);
     this.addDynamicListener(".option-item select", "change", this.options.selectChange, this.options);
     document.getElementById("theme").addEventListener("change", this.options.themeChange.bind(this.options));
     document.getElementById("theme").addEventListener("change", this.options.themeChange.bind(this.options));
 
 
     // Misc
     // Misc
+    window.addEventListener("keydown", this.bindings.parseInput.bind(this.bindings));
     document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app));
     document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app));
 };
 };
 
 

+ 1 - 3
src/web/OperationsWaiter.js

@@ -38,7 +38,6 @@ OperationsWaiter.prototype.searchOperations = function(e) {
             selected = this.getSelectedOp(ops);
             selected = this.getSelectedOp(ops);
             if (selected > -1) {
             if (selected > -1) {
                 this.manager.recipe.addOperation(ops[selected].innerHTML);
                 this.manager.recipe.addOperation(ops[selected].innerHTML);
-                this.app.autoBake();
             }
             }
         }
         }
     }
     }
@@ -197,7 +196,6 @@ OperationsWaiter.prototype.operationDblclick = function(e) {
     const li = e.target;
     const li = e.target;
 
 
     this.manager.recipe.addOperation(li.textContent);
     this.manager.recipe.addOperation(li.textContent);
-    this.app.autoBake();
 };
 };
 
 
 
 
@@ -231,7 +229,7 @@ OperationsWaiter.prototype.editFavouritesClick = function(e) {
         filter: ".remove-icon",
         filter: ".remove-icon",
         onFilter: function (evt) {
         onFilter: function (evt) {
             const el = editableList.closest(evt.item);
             const el = editableList.closest(evt.item);
-            if (el) {
+            if (el && el.parentNode) {
                 $(el).popover("destroy");
                 $(el).popover("destroy");
                 el.parentNode.removeChild(el);
                 el.parentNode.removeChild(el);
             }
             }

+ 9 - 3
src/web/OptionsWaiter.js

@@ -87,7 +87,9 @@ OptionsWaiter.prototype.switchChange = function(e, state) {
     const option = el.getAttribute("option");
     const option = el.getAttribute("option");
 
 
     this.app.options[option] = state;
     this.app.options[option] = state;
-    localStorage.setItem("options", JSON.stringify(this.app.options));
+
+    if (this.app.isLocalStorageAvailable())
+        localStorage.setItem("options", JSON.stringify(this.app.options));
 };
 };
 
 
 
 
@@ -102,7 +104,9 @@ OptionsWaiter.prototype.numberChange = function(e) {
     const option = el.getAttribute("option");
     const option = el.getAttribute("option");
 
 
     this.app.options[option] = parseInt(el.value, 10);
     this.app.options[option] = parseInt(el.value, 10);
-    localStorage.setItem("options", JSON.stringify(this.app.options));
+
+    if (this.app.isLocalStorageAvailable())
+        localStorage.setItem("options", JSON.stringify(this.app.options));
 };
 };
 
 
 
 
@@ -117,7 +121,9 @@ OptionsWaiter.prototype.selectChange = function(e) {
     const option = el.getAttribute("option");
     const option = el.getAttribute("option");
 
 
     this.app.options[option] = el.value;
     this.app.options[option] = el.value;
-    localStorage.setItem("options", JSON.stringify(this.app.options));
+
+    if (this.app.isLocalStorageAvailable())
+        localStorage.setItem("options", JSON.stringify(this.app.options));
 };
 };
 
 
 
 

+ 81 - 0
src/web/OutputWaiter.js

@@ -105,17 +105,20 @@ OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) {
 OutputWaiter.prototype.adjustWidth = function() {
 OutputWaiter.prototype.adjustWidth = function() {
     const output         = document.getElementById("output");
     const output         = document.getElementById("output");
     const saveToFile     = document.getElementById("save-to-file");
     const saveToFile     = document.getElementById("save-to-file");
+    const copyOutput     = document.getElementById("copy-output");
     const switchIO       = document.getElementById("switch");
     const switchIO       = document.getElementById("switch");
     const undoSwitch     = document.getElementById("undo-switch");
     const undoSwitch     = document.getElementById("undo-switch");
     const maximiseOutput = document.getElementById("maximise-output");
     const maximiseOutput = document.getElementById("maximise-output");
 
 
     if (output.clientWidth < 680) {
     if (output.clientWidth < 680) {
         saveToFile.childNodes[1].nodeValue = "";
         saveToFile.childNodes[1].nodeValue = "";
+        copyOutput.childNodes[1].nodeValue = "";
         switchIO.childNodes[1].nodeValue = "";
         switchIO.childNodes[1].nodeValue = "";
         undoSwitch.childNodes[1].nodeValue = "";
         undoSwitch.childNodes[1].nodeValue = "";
         maximiseOutput.childNodes[1].nodeValue = "";
         maximiseOutput.childNodes[1].nodeValue = "";
     } else {
     } else {
         saveToFile.childNodes[1].nodeValue = " Save to file";
         saveToFile.childNodes[1].nodeValue = " Save to file";
+        copyOutput.childNodes[1].nodeValue = " Copy output";
         switchIO.childNodes[1].nodeValue = " Move output to input";
         switchIO.childNodes[1].nodeValue = " Move output to input";
         undoSwitch.childNodes[1].nodeValue = " Undo";
         undoSwitch.childNodes[1].nodeValue = " Undo";
         maximiseOutput.childNodes[1].nodeValue =
         maximiseOutput.childNodes[1].nodeValue =
@@ -147,6 +150,44 @@ OutputWaiter.prototype.saveClick = function() {
 };
 };
 
 
 
 
+/**
+ * Handler for copy click events.
+ * Copies the output to the clipboard.
+ */
+OutputWaiter.prototype.copyClick = function() {
+    // Create invisible textarea to populate with the raw dishStr (not the printable version that
+    // contains dots instead of the actual bytes)
+    const textarea = document.createElement("textarea");
+    textarea.style.position = "fixed";
+    textarea.style.top = 0;
+    textarea.style.left = 0;
+    textarea.style.width = 0;
+    textarea.style.height = 0;
+    textarea.style.border = "none";
+
+    textarea.value = this.app.dishStr;
+    document.body.appendChild(textarea);
+
+    // Select and copy the contents of this textarea
+    let success = false;
+    try {
+        textarea.select();
+        success = document.execCommand("copy");
+    } catch (err) {
+        success = false;
+    }
+
+    if (success) {
+        this.app.alert("Copied raw output successfully.", "success", 2000);
+    } else {
+        this.app.alert("Sorry, the output could not be copied.", "danger", 2000);
+    }
+
+    // Clean up
+    document.body.removeChild(textarea);
+};
+
+
 /**
 /**
  * Handler for switch click events.
  * Handler for switch click events.
  * Moves the current output into the input textarea.
  * Moves the current output into the input textarea.
@@ -201,4 +242,44 @@ OutputWaiter.prototype.maximiseOutputClick = function(e) {
     }
     }
 };
 };
 
 
+
+/**
+ * Shows or hides the loading icon.
+ *
+ * @param {boolean} value
+ */
+OutputWaiter.prototype.toggleLoader = function(value) {
+    const outputLoader = document.getElementById("output-loader"),
+        outputElement = document.getElementById("output-text");
+
+    if (value) {
+        this.manager.controls.hideStaleIndicator();
+        this.bakingStatusTimeout = setTimeout(function() {
+            outputElement.disabled = true;
+            outputLoader.style.visibility = "visible";
+            outputLoader.style.opacity = 1;
+            this.manager.controls.toggleBakeButtonFunction(true);
+        }.bind(this), 200);
+    } else {
+        clearTimeout(this.bakingStatusTimeout);
+        outputElement.disabled = false;
+        outputLoader.style.opacity = 0;
+        outputLoader.style.visibility = "hidden";
+        this.manager.controls.toggleBakeButtonFunction(false);
+        this.setStatusMsg("");
+    }
+};
+
+
+/**
+ * Sets the baking status message value.
+ *
+ * @param {string} msg
+ */
+OutputWaiter.prototype.setStatusMsg = function(msg) {
+    const el = document.querySelector("#output-loader .loading-msg");
+
+    el.textContent = msg;
+};
+
 export default OutputWaiter;
 export default OutputWaiter;

+ 28 - 1
src/web/RecipeWaiter.js

@@ -1,5 +1,6 @@
 import HTMLOperation from "./HTMLOperation.js";
 import HTMLOperation from "./HTMLOperation.js";
 import Sortable from "sortablejs";
 import Sortable from "sortablejs";
+import Utils from "../core/Utils.js";
 
 
 
 
 /**
 /**
@@ -191,7 +192,7 @@ RecipeWaiter.prototype.favDrop = function(e) {
  *
  *
  * @fires Manager#statechange
  * @fires Manager#statechange
  */
  */
-RecipeWaiter.prototype.ingChange = function() {
+RecipeWaiter.prototype.ingChange = function(e) {
     window.dispatchEvent(this.manager.statechange);
     window.dispatchEvent(this.manager.statechange);
 };
 };
 
 
@@ -435,4 +436,30 @@ RecipeWaiter.prototype.opRemove = function(e) {
     window.dispatchEvent(this.manager.statechange);
     window.dispatchEvent(this.manager.statechange);
 };
 };
 
 
+
+/**
+ * Sets register values.
+ *
+ * @param {number} opIndex
+ * @param {number} numPrevRegisters
+ * @param {string[]} registers
+ */
+RecipeWaiter.prototype.setRegisters = function(opIndex, numPrevRegisters, registers) {
+    const op = document.querySelector(`#rec-list .operation:nth-child(${opIndex + 1})`),
+        prevRegList = op.querySelector(".register-list");
+
+    // Remove previous div
+    if (prevRegList) prevRegList.remove();
+
+    let registerList = [];
+    for (let i = 0; i < registers.length; i++) {
+        registerList.push(`$R${numPrevRegisters + i} = ${Utils.escapeHtml(Utils.truncate(Utils.printable(registers[i]), 100))}`);
+    }
+    const registerListEl = `<div class="register-list">
+            ${registerList.join("<br>")}
+        </div>`;
+
+    op.insertAdjacentHTML("beforeend", registerListEl);
+};
+
 export default RecipeWaiter;
 export default RecipeWaiter;

+ 183 - 0
src/web/WorkerWaiter.js

@@ -0,0 +1,183 @@
+import Utils from "../core/Utils.js";
+import ChefWorker from "worker-loader?inline&fallback=false!../core/ChefWorker.js";
+
+/**
+ * Waiter to handle conversations with the ChefWorker.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ *
+ * @constructor
+ * @param {App} app - The main view object for CyberChef.
+ * @param {Manager} manager - The CyberChef event manager.
+ */
+const WorkerWaiter = function(app, manager) {
+    this.app = app;
+    this.manager = manager;
+};
+
+
+/**
+ * Sets up the ChefWorker and associated listeners.
+ */
+WorkerWaiter.prototype.registerChefWorker = function() {
+    this.chefWorker = new ChefWorker();
+    this.chefWorker.addEventListener("message", this.handleChefMessage.bind(this));
+
+    let docURL = document.location.href.split(/[#?]/)[0];
+    const index = docURL.lastIndexOf("/");
+    if (index > 0) {
+        docURL = docURL.substring(0, index);
+    }
+    this.chefWorker.postMessage({"action": "docURL", "data": docURL});
+};
+
+
+/**
+ * Handler for messages sent back by the ChefWorker.
+ *
+ * @param {MessageEvent} e
+ */
+WorkerWaiter.prototype.handleChefMessage = function(e) {
+    const r = e.data;
+    switch (r.action) {
+        case "bakeSuccess":
+            this.bakingComplete(r.data);
+            break;
+        case "bakeError":
+            this.app.handleError(r.data);
+            this.setBakingStatus(false);
+            break;
+        case "silentBakeComplete":
+            break;
+        case "workerLoaded":
+            this.app.workerLoaded = true;
+            this.app.loaded();
+            break;
+        case "statusMessage":
+            this.manager.output.setStatusMsg(r.data);
+            break;
+        case "optionUpdate":
+            this.app.options[r.data.option] = r.data.value;
+            break;
+        case "setRegisters":
+            this.manager.recipe.setRegisters(r.data.opIndex, r.data.numPrevRegisters, r.data.registers);
+            break;
+        case "highlightsCalculated":
+            this.manager.highlighter.displayHighlights(r.data.pos, r.data.direction);
+            break;
+        default:
+            console.error("Unrecognised message from ChefWorker", e);
+            break;
+    }
+};
+
+
+/**
+ * Updates the UI to show if baking is in process or not.
+ *
+ * @param {bakingStatus}
+ */
+WorkerWaiter.prototype.setBakingStatus = function(bakingStatus) {
+    this.app.baking = bakingStatus;
+
+    this.manager.output.toggleLoader(bakingStatus);
+};
+
+
+/**
+ * Cancels the current bake by terminating the ChefWorker and creating a new one.
+ */
+WorkerWaiter.prototype.cancelBake = function() {
+    this.chefWorker.terminate();
+    this.registerChefWorker();
+    this.setBakingStatus(false);
+    this.manager.controls.showStaleIndicator();
+};
+
+
+/**
+ * Handler for completed bakes.
+ *
+ * @param {Object} response
+ */
+WorkerWaiter.prototype.bakingComplete = function(response) {
+    this.setBakingStatus(false);
+
+    if (!response) return;
+
+    if (response.error) {
+        this.app.handleError(response.error);
+    }
+
+    this.app.dishStr  = response.type === "html" ? Utils.stripHtmlTags(response.result, true) : response.result;
+    this.app.progress = response.progress;
+    this.manager.recipe.updateBreakpointIndicator(response.progress);
+    this.manager.output.set(response.result, response.type, response.duration);
+};
+
+
+/**
+ * Asks the ChefWorker to bake the current input using the current recipe.
+ *
+ * @param {string} input
+ * @param {Object[]} recipeConfig
+ * @param {Object} options
+ * @param {number} progress
+ * @param {boolean} step
+ */
+WorkerWaiter.prototype.bake = function(input, recipeConfig, options, progress, step) {
+    this.setBakingStatus(true);
+
+    this.chefWorker.postMessage({
+        action: "bake",
+        data: {
+            input: input,
+            recipeConfig: recipeConfig,
+            options: options,
+            progress: progress,
+            step: step
+        }
+    });
+};
+
+
+/**
+ * Asks the ChefWorker to run a silent bake, forcing the browser to load and cache all the relevant
+ * JavaScript code needed to do a real bake.
+ *
+ * @param {Objectp[]} [recipeConfig]
+ */
+WorkerWaiter.prototype.silentBake = function(recipeConfig) {
+    this.chefWorker.postMessage({
+        action: "silentBake",
+        data: {
+            recipeConfig: recipeConfig
+        }
+    });
+};
+
+
+/**
+ * Asks the ChefWorker to calculate highlight offsets if possible.
+ *
+ * @param {Object[]} recipeConfig
+ * @param {string} direction
+ * @param {Object} pos - The position object for the highlight.
+ * @param {number} pos.start - The start offset.
+ * @param {number} pos.end - The end offset.
+ */
+WorkerWaiter.prototype.highlight = function(recipeConfig, direction, pos) {
+    this.chefWorker.postMessage({
+        action: "highlight",
+        data: {
+            recipeConfig: recipeConfig,
+            direction: direction,
+            pos: pos
+        }
+    });
+};
+
+
+export default WorkerWaiter;

+ 56 - 35
src/web/html/index.html

@@ -1,17 +1,17 @@
 <!-- htmlmin:ignore --><!--
 <!-- htmlmin:ignore --><!--
     CyberChef - The Cyber Swiss Army Knife
     CyberChef - The Cyber Swiss Army Knife
-    
+
     @copyright Crown Copyright 2016
     @copyright Crown Copyright 2016
     @license Apache-2.0
     @license Apache-2.0
-    
+
       Copyright 2016 Crown Copyright
       Copyright 2016 Crown Copyright
-    
+
     Licensed under the Apache License, Version 2.0 (the "License");
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
     You may obtain a copy of the License at
-    
+
         http://www.apache.org/licenses/LICENSE-2.0
         http://www.apache.org/licenses/LICENSE-2.0
-    
+
     Unless required by applicable law or agreed to in writing, software
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,7 +24,7 @@
     <head>
     <head>
         <meta charset="UTF-8">
         <meta charset="UTF-8">
         <title>CyberChef</title>
         <title>CyberChef</title>
-        
+
         <meta name="copyright" content="Crown Copyright 2016" />
         <meta name="copyright" content="Crown Copyright 2016" />
         <meta name="description" content="The Cyber Swiss Army Knife - a web app for encryption, encoding, compression and data analysis" />
         <meta name="description" content="The Cyber Swiss Army Knife - a web app for encryption, encoding, compression and data analysis" />
         <meta name="keywords" content="base64, hex, decode, encode, encrypt, decrypt, compress, decompress, regex, regular expressions, hash, crypt, hexadecimal, user agent, url, certificate, x.509, parser, JSON, gzip,  md5, sha1, aes, des, blowfish, xor" />
         <meta name="keywords" content="base64, hex, decode, encode, encrypt, decrypt, compress, decompress, regex, regular expressions, hash, crypt, hexadecimal, user agent, url, certificate, x.509, parser, JSON, gzip,  md5, sha1, aes, des, blowfish, xor" />
@@ -36,8 +36,10 @@
 
 
             // Load theme before the preloader is shown
             // Load theme before the preloader is shown
             try {
             try {
-                document.querySelector(":root").className = JSON.parse(localStorage.getItem("options")).theme;
-            } catch (e) {}
+                document.querySelector(":root").className = (JSON.parse(localStorage.getItem("options")) || {}).theme;
+            } catch (err) {
+                // LocalStorage access is denied by security settings
+            }
 
 
             // Define loading messages
             // Define loading messages
             const loadingMsgs = [
             const loadingMsgs = [
@@ -73,7 +75,8 @@
                 loadingMsgs.push(msg);
                 loadingMsgs.push(msg);
                 try {
                 try {
                     const el = document.getElementById("preloader-msg");
                     const el = document.getElementById("preloader-msg");
-                    el.className = "loading"; // Causes CSS transition on first message
+                    if (!el.classList.contains("loading"))
+                        el.classList.add("loading"); // Causes CSS transition on first message
                     el.innerHTML = msg;
                     el.innerHTML = msg;
                 } catch (err) {} // Ignore errors if DOM not yet ready
                 } catch (err) {} // Ignore errors if DOM not yet ready
             }
             }
@@ -90,8 +93,8 @@
     <body>
     <body>
         <!-- Preloader overlay -->
         <!-- Preloader overlay -->
         <div id="loader-wrapper">
         <div id="loader-wrapper">
-            <div id="preloader"></div>
-            <div id="preloader-msg"></div>
+            <div id="preloader" class="loader"></div>
+            <div id="preloader-msg" class="loading-msg"></div>
         </div>
         </div>
         <!-- End preloader overlay -->
         <!-- End preloader overlay -->
         <span id="edit-favourites" class="btn btn-default btn-sm"><img aria-hidden="true" src="<%- require('../static/images/favourite-16x16.png') %>" alt="Star Icon"/> Edit</span>
         <span id="edit-favourites" class="btn btn-default btn-sm"><img aria-hidden="true" src="<%- require('../static/images/favourite-16x16.png') %>" alt="Star Icon"/> Edit</span>
@@ -132,30 +135,30 @@
                     <ul id="search-results" class="op-list"></ul>
                     <ul id="search-results" class="op-list"></ul>
                     <div id="categories" class="panel-group no-select"></div>
                     <div id="categories" class="panel-group no-select"></div>
                 </div>
                 </div>
-                
+
                 <div id="recipe" class="split split-horizontal no-select">
                 <div id="recipe" class="split split-horizontal no-select">
                     <div class="title no-select">Recipe</div>
                     <div class="title no-select">Recipe</div>
                     <ul id="rec-list" class="list-area no-select"></ul>
                     <ul id="rec-list" class="list-area no-select"></ul>
-                    
+
                     <div id="controls" class="no-select">
                     <div id="controls" class="no-select">
                         <div id="operational-controls">
                         <div id="operational-controls">
                             <div id="bake-group">
                             <div id="bake-group">
                                 <button type="button" class="btn btn-success btn-lg" id="bake">
                                 <button type="button" class="btn btn-success btn-lg" id="bake">
                                     <img aria-hidden="true" src="<%- require('../static/images/cook_male-32x32.png') %>" alt="Chef Icon"/>
                                     <img aria-hidden="true" src="<%- require('../static/images/cook_male-32x32.png') %>" alt="Chef Icon"/>
-                                    Bake!
+                                    <span>Bake!</span>
                                 </button>
                                 </button>
                                 <label class="btn btn-success btn-lg" id="auto-bake-label" for="auto-bake">
                                 <label class="btn btn-success btn-lg" id="auto-bake-label" for="auto-bake">
                                     <input type="checkbox" checked="checked" id="auto-bake">
                                     <input type="checkbox" checked="checked" id="auto-bake">
                                     <div>Auto Bake</div>
                                     <div>Auto Bake</div>
                                 </label>
                                 </label>
                             </div>
                             </div>
-                            
+
                             <div class="btn-group" style="padding-top: 10px;">
                             <div class="btn-group" style="padding-top: 10px;">
                                 <button type="button" class="btn btn-default" id="step"><img aria-hidden="true" src="<%- require('../static/images/step-16x16.png') %>" alt="Footstep Icon"/> Step through</button>
                                 <button type="button" class="btn btn-default" id="step"><img aria-hidden="true" src="<%- require('../static/images/step-16x16.png') %>" alt="Footstep Icon"/> Step through</button>
                                 <button type="button" class="btn btn-default" id="clr-breaks"><img aria-hidden="true" src="<%- require('../static/images/erase-16x16.png') %>" alt="Eraser Icon"/> Clear breakpoints</button>
                                 <button type="button" class="btn btn-default" id="clr-breaks"><img aria-hidden="true" src="<%- require('../static/images/erase-16x16.png') %>" alt="Eraser Icon"/> Clear breakpoints</button>
                             </div>
                             </div>
                         </div>
                         </div>
-                        
+
                         <div class="btn-group-vertical" id="extra-controls">
                         <div class="btn-group-vertical" id="extra-controls">
                             <button type="button" class="btn btn-default" id="save"><img aria-hidden="true" src="<%- require('../static/images/save-16x16.png') %>" alt="Save Icon"/> Save recipe</button>
                             <button type="button" class="btn btn-default" id="save"><img aria-hidden="true" src="<%- require('../static/images/save-16x16.png') %>" alt="Save Icon"/> Save recipe</button>
                             <button type="button" class="btn btn-default" id="load"><img aria-hidden="true" src="<%- require('../static/images/open_yellow-16x16.png') %>" alt="Open Icon"/> Load recipe</button>
                             <button type="button" class="btn btn-default" id="load"><img aria-hidden="true" src="<%- require('../static/images/open_yellow-16x16.png') %>" alt="Open Icon"/> Load recipe</button>
@@ -163,12 +166,11 @@
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
-                
+
                 <div class="split split-horizontal" id="IO">
                 <div class="split split-horizontal" id="IO">
                     <div id="input" class="split no-select">
                     <div id="input" class="split no-select">
                         <div class="title no-select">
                         <div class="title no-select">
                             <label for="input-text">Input</label>
                             <label for="input-text">Input</label>
-                            <div class="loading-icon" style="display: none"></div>
                             <div class="btn-group io-btn-group">
                             <div class="btn-group io-btn-group">
                                 <button type="button" class="btn btn-default btn-sm" id="clr-io"><img aria-hidden="true" src="<%- require('../static/images/recycle-16x16.png') %>" alt="Recycle Icon"/> Clear I/O</button>
                                 <button type="button" class="btn btn-default btn-sm" id="clr-io"><img aria-hidden="true" src="<%- require('../static/images/recycle-16x16.png') %>" alt="Recycle Icon"/> Clear I/O</button>
                                 <button type="button" class="btn btn-default btn-sm" id="reset-layout"><img aria-hidden="true" src="<%- require('../static/images/layout-16x16.png') %>" alt="Grid Icon"/> Reset layout</button>
                                 <button type="button" class="btn btn-default btn-sm" id="reset-layout"><img aria-hidden="true" src="<%- require('../static/images/layout-16x16.png') %>" alt="Grid Icon"/> Reset layout</button>
@@ -181,30 +183,35 @@
                             <textarea id="input-text"></textarea>
                             <textarea id="input-text"></textarea>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div id="output" class="split">
                     <div id="output" class="split">
                         <div class="title no-select">
                         <div class="title no-select">
                             <label for="output-text">Output</label>
                             <label for="output-text">Output</label>
-                            <div class="loading-icon" style="display: none"></div>
                             <div class="btn-group io-btn-group">
                             <div class="btn-group io-btn-group">
                                 <button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img aria-hidden="true" src="<%- require('../static/images/save_as-16x16.png') %>" alt="Save Icon"/> Save to file</button>
                                 <button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img aria-hidden="true" src="<%- require('../static/images/save_as-16x16.png') %>" alt="Save Icon"/> Save to file</button>
+                                <button type="button" class="btn btn-default btn-sm" id="copy-output" title="Copy output"><img aria-hidden="true" src="<%- require('../static/images/copy-16x16.png') %>" alt="Copy Icon"/> Copy raw output</button>
                                 <button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img aria-hidden="true" src="<%- require('../static/images/switch-16x16.png') %>" alt="Switch Icon"/> Move output to input</button>
                                 <button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img aria-hidden="true" src="<%- require('../static/images/switch-16x16.png') %>" alt="Switch Icon"/> Move output to input</button>
                                 <button type="button" class="btn btn-default btn-sm" id="undo-switch" title="Undo move" disabled="disabled"><img aria-hidden="true" src="<%- require('../static/images/undo-16x16.png') %>" alt="Undo Icon"/> Undo</button>
                                 <button type="button" class="btn btn-default btn-sm" id="undo-switch" title="Undo move" disabled="disabled"><img aria-hidden="true" src="<%- require('../static/images/undo-16x16.png') %>" alt="Undo Icon"/> Undo</button>
                                 <button type="button" class="btn btn-default btn-sm" id="maximise-output" title="Maximise"><img aria-hidden="true" src="<%- require('../static/images/maximise-16x16.png') %>" alt="Maximise Icon"/> Max</button>
                                 <button type="button" class="btn btn-default btn-sm" id="maximise-output" title="Maximise"><img aria-hidden="true" src="<%- require('../static/images/maximise-16x16.png') %>" alt="Maximise Icon"/> Max</button>
                             </div>
                             </div>
                             <div class="io-info" id="output-info"></div>
                             <div class="io-info" id="output-info"></div>
                             <div class="io-info" id="output-selection-info"></div>
                             <div class="io-info" id="output-selection-info"></div>
+                            <span id="stale-indicator" title="The output is stale.&#10;The input or recipe has changed since this output was generated. Bake again to get the new value.">&#x1F551;</span>
                         </div>
                         </div>
                         <div class="textarea-wrapper">
                         <div class="textarea-wrapper">
                             <div id="output-highlighter" class="no-select"></div>
                             <div id="output-highlighter" class="no-select"></div>
                             <div id="output-html"></div>
                             <div id="output-html"></div>
                             <textarea id="output-text" readonly="readonly"></textarea>
                             <textarea id="output-text" readonly="readonly"></textarea>
+                            <div id="output-loader">
+                                <div class="loader"></div>
+                                <div class="loading-msg"></div>
+                            </div>
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="save-modal" tabindex="-1" role="dialog">
         <div class="modal" id="save-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -255,7 +262,7 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="load-modal" tabindex="-1" role="dialog">
         <div class="modal" id="load-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -281,7 +288,7 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="options-modal" tabindex="-1" role="dialog">
         <div class="modal" id="options-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -320,12 +327,12 @@
                             <label for="showErrors"> Operation error reporting (recommended) </label>
                             <label for="showErrors"> Operation error reporting (recommended) </label>
                         </div>
                         </div>
                         <div class="option-item">
                         <div class="option-item">
-                            <input type="number" option="errorTimeout" id="errorTimeout" />
-                            <label for="errorTimeout"> Operation error timeout in ms (0 for never) </label>
+                            <input type="checkbox" option="useMetaKey" id="useMetaKey" />
+                            <label for="useMetaKey"> Use meta key for keybindings (Windows ⊞/Command ⌘) </label>
                         </div>
                         </div>
                         <div class="option-item">
                         <div class="option-item">
-                            <input type="number" option="autoBakeThreshold" id="autoBakeThreshold"/>
-                            <label for="autoBakeThreshold"> Auto Bake threshold in ms </label>
+                            <input type="number" option="errorTimeout" id="errorTimeout" />
+                            <label for="errorTimeout"> Operation error timeout in ms (0 for never) </label>
                         </div>
                         </div>
                     </div>
                     </div>
                     <div class="modal-footer">
                     <div class="modal-footer">
@@ -335,7 +342,7 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="favourites-modal" tabindex="-1" role="dialog">
         <div class="modal" id="favourites-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -362,7 +369,7 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="support-modal" tabindex="-1" role="dialog">
         <div class="modal" id="support-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -378,6 +385,11 @@
                         </p>
                         </p>
                         <p>&copy; Crown Copyright 2016.</p>
                         <p>&copy; Crown Copyright 2016.</p>
                         <p>Released under the Apache Licence, Version 2.0.</p>
                         <p>Released under the Apache Licence, Version 2.0.</p>
+                        <p>
+                            <a href="https://gitter.im/gchq/CyberChef">
+                                <img src="<%- require('../static/images/gitter-badge.svg') %>">
+                            </a>
+                        </p>
                         <br>
                         <br>
                         <br>
                         <br>
                         <div>
                         <div>
@@ -394,6 +406,10 @@
                                     <img aria-hidden="true" src="<%- require('../static/images/speech-16x16.png') %>" alt="Speech Balloon Icon"/>
                                     <img aria-hidden="true" src="<%- require('../static/images/speech-16x16.png') %>" alt="Speech Balloon Icon"/>
                                     About
                                     About
                                 </a></li>
                                 </a></li>
+                                <li role="presentation"><a href="#keybindings" aria-controls="messages" role="tab" data-toggle="tab">
+                                    <img aria-hidden="true" src="<%- require('../static/images/code-16x16.png') %>" alt="List Icon"/>
+                                    Keybindings
+                                </a></li>
                             </ul>
                             </ul>
                             <div class="tab-content">
                             <div class="tab-content">
                                 <div role="tabpanel" class="tab-pane active" id="faqs">
                                 <div role="tabpanel" class="tab-pane active" id="faqs">
@@ -410,8 +426,10 @@
                                             <li><a href="#recipe=Translate_DateTime_Format('Standard%20date%20and%20time','DD/MM/YYYY%20HH:mm:ss','UTC','dddd%20Do%20MMMM%20YYYY%20HH:mm:ss%20Z%20z','Australia/Queensland')&input=MTUvMDYvMjAxNSAyMDo0NTowMA">Convert a date and time to a different time zone</a></li>
                                             <li><a href="#recipe=Translate_DateTime_Format('Standard%20date%20and%20time','DD/MM/YYYY%20HH:mm:ss','UTC','dddd%20Do%20MMMM%20YYYY%20HH:mm:ss%20Z%20z','Australia/Queensland')&input=MTUvMDYvMjAxNSAyMDo0NTowMA">Convert a date and time to a different time zone</a></li>
                                             <li><a href="#recipe=Parse_IPv6_address()&input=MjAwMTowMDAwOjQxMzY6ZTM3ODo4MDAwOjYzYmY6M2ZmZjpmZGQy">Parse a Teredo IPv6 address</a></li>
                                             <li><a href="#recipe=Parse_IPv6_address()&input=MjAwMTowMDAwOjQxMzY6ZTM3ODo4MDAwOjYzYmY6M2ZmZjpmZGQy">Parse a Teredo IPv6 address</a></li>
                                             <li><a href="#recipe=From_Hexdump()Gunzip()&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu/y7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb/3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw">Convert data from a hexdump, then decompress</a></li>
                                             <li><a href="#recipe=From_Hexdump()Gunzip()&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu/y7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb/3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw">Convert data from a hexdump, then decompress</a></li>
+                                            <li><a href="#recipe=RC4(%7B'option':'UTF8','string':'secret'%7D,'Hex','Hex')Disassemble_x86('64','Full%20x86%20architecture',16,0,true,true)&input=MjFkZGQyNTQwMTYwZWU2NWZlMDc3NzEwM2YyYTM5ZmJlNWJjYjZhYTBhYWJkNDE0ZjkwYzZjYWY1MzEyNzU0YWY3NzRiNzZiM2JiY2QxOTNjYjNkZGZkYmM1YTI2NTMzYTY4NmI1OWI4ZmVkNGQzODBkNDc0NDIwMWFlYzIwNDA1MDcxMzhlMmZlMmIzOTUwNDQ2ZGIzMWQyYmM2MjliZTRkM2YyZWIwMDQzYzI5M2Q3YTVkMjk2MmMwMGZlNmRhMzAwNzJkOGM1YTZiNGZlN2Q4NTlhMDQwZWVhZjI5OTczMzYzMDJmNWEwZWMxOQ">Decrypt and disassemble shellcode</a></li>
                                             <li><a href="#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA">Display multiple timestamps as full dates</a></li>
                                             <li><a href="#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA">Display multiple timestamps as full dates</a></li>
                                             <li><a href="#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',2,10)To_Hex('Space')Return()To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA">Carry out different operations on data of different types</a></li>
                                             <li><a href="#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',2,10)To_Hex('Space')Return()To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA">Carry out different operations on data of different types</a></li>
+                                            <li><a href="#recipe=Register('key%3D(%5B%5C%5Cda-f%5D*)',true,false)Find_/_Replace(%7B'option':'Regex','string':'.*data%3D(.*)'%7D,'$1',true,false,true)RC4(%7B'option':'Hex','string':'$R0'%7D,'Hex','Latin1')&input=aHR0cDovL21hbHdhcmV6LmJpei9iZWFjb24ucGhwP2tleT0wZTkzMmE1YyZkYXRhPThkYjdkNWViZTM4NjYzYTU0ZWNiYjMzNGUzZGIxMQ">Use parts of the input as arguments to operations</a></li>
                                         </ul>
                                         </ul>
                                     </div>
                                     </div>
                                     <blockquote>
                                     <blockquote>
@@ -445,20 +463,20 @@
                                 <div role="tabpanel" class="tab-pane" id="about" style="padding: 20px;">
                                 <div role="tabpanel" class="tab-pane" id="about" style="padding: 20px;">
                                     <h5><strong>What</strong></h5>
                                     <h5><strong>What</strong></h5>
                                     <p>A simple, intuitive web app for analysing and decoding data without having to deal with complex tools or programming languages. CyberChef encourages both technical and non-technical people to explore data formats, encryption and compression.</p><br>
                                     <p>A simple, intuitive web app for analysing and decoding data without having to deal with complex tools or programming languages. CyberChef encourages both technical and non-technical people to explore data formats, encryption and compression.</p><br>
-                                    
+
                                     <h5><strong>Why</strong></h5>
                                     <h5><strong>Why</strong></h5>
                                     <p>Digital data comes in all shapes, sizes and formats in the modern world – CyberChef helps to make sense of this data all on one easy-to-use platform.</p><br>
                                     <p>Digital data comes in all shapes, sizes and formats in the modern world – CyberChef helps to make sense of this data all on one easy-to-use platform.</p><br>
 
 
-                                    
+
                                     <h5><strong>How</strong></h5>
                                     <h5><strong>How</strong></h5>
                                     <p>The interface is designed with simplicity at its heart. Complex techniques are now as trivial as drag-and-drop. Simple functions can be combined to build up a "recipe", potentially resulting in complex analysis, which can be shared with other users and used with their input.</p>
                                     <p>The interface is designed with simplicity at its heart. Complex techniques are now as trivial as drag-and-drop. Simple functions can be combined to build up a "recipe", potentially resulting in complex analysis, which can be shared with other users and used with their input.</p>
                                     <p>For those comfortable writing code, CyberChef is a quick and efficient way to prototype solutions to a problem which can then be scripted once proven to work.</p><br>
                                     <p>For those comfortable writing code, CyberChef is a quick and efficient way to prototype solutions to a problem which can then be scripted once proven to work.</p><br>
 
 
-                                    
+
                                     <h5><strong>Who</strong></h5>
                                     <h5><strong>Who</strong></h5>
                                     <p>It is expected that CyberChef will be useful for cybersecurity and antivirus companies. It should also appeal to the academic world and any individuals or companies involved in the analysis of digital data, be that software developers, analysts, mathematicians or casual puzzle solvers.</p><br>
                                     <p>It is expected that CyberChef will be useful for cybersecurity and antivirus companies. It should also appeal to the academic world and any individuals or companies involved in the analysis of digital data, be that software developers, analysts, mathematicians or casual puzzle solvers.</p><br>
 
 
-                                    
+
                                     <h5><strong>Aim</strong></h5>
                                     <h5><strong>Aim</strong></h5>
                                     <p>It is hoped that by releasing CyberChef through <a href="https://github.com/gchq/CyberChef">GitHub</a>, contributions can be added which can be rolled out into future versions of the tool.</p><br>
                                     <p>It is hoped that by releasing CyberChef through <a href="https://github.com/gchq/CyberChef">GitHub</a>, contributions can be added which can be rolled out into future versions of the tool.</p><br>
 
 
@@ -467,6 +485,9 @@
                                     <p>There are around 150 useful operations in CyberChef for anyone working on anything vaguely Internet-related, whether you just want to convert a timestamp to a different format, decompress gzipped data, create a SHA3 hash, or parse an X.509 certificate to find out who issued it.</p>
                                     <p>There are around 150 useful operations in CyberChef for anyone working on anything vaguely Internet-related, whether you just want to convert a timestamp to a different format, decompress gzipped data, create a SHA3 hash, or parse an X.509 certificate to find out who issued it.</p>
                                     <p>It’s the Cyber Swiss Army Knife.</p>
                                     <p>It’s the Cyber Swiss Army Knife.</p>
                                 </div>
                                 </div>
+                                <div role="tabpanel" class="tab-pane" id="keybindings" style="padding: 20px;">
+                                    <table class="table table-condensed table-bordered table-hover" id="keybList"></table>
+                                </div>
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>
@@ -479,7 +500,7 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="confirm-modal" tabindex="-1" role="dialog">
         <div class="modal" id="confirm-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -500,6 +521,6 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
     </body>
     </body>
 </html>
 </html>

+ 2 - 2
src/web/index.js

@@ -17,7 +17,7 @@ import CanvasComponents from "../core/lib/canvascomponents.js";
 // CyberChef
 // CyberChef
 import App from "./App.js";
 import App from "./App.js";
 import Categories from "../core/config/Categories.js";
 import Categories from "../core/config/Categories.js";
-import OperationConfig from "../core/config/OperationConfig.js";
+import OperationConfig from "../core/config/MetaConfig.js";
 
 
 
 
 /**
 /**
@@ -44,9 +44,9 @@ function main() {
         wordWrap:          true,
         wordWrap:          true,
         showErrors:        true,
         showErrors:        true,
         errorTimeout:      4000,
         errorTimeout:      4000,
-        autoBakeThreshold: 200,
         attemptHighlight:  true,
         attemptHighlight:  true,
         theme:             "classic",
         theme:             "classic",
+        useMetaKey:        false
     };
     };
 
 
     document.removeEventListener("DOMContentLoaded", main, false);
     document.removeEventListener("DOMContentLoaded", main, false);

BIN
src/web/static/images/breakpoint-16x16.png


BIN
src/web/static/images/bug-16x16.png


BIN
src/web/static/images/clean-16x16.png


BIN
src/web/static/images/code-16x16.png


BIN
src/web/static/images/cook_female-32x32.png


BIN
src/web/static/images/cook_male-32x32.png


BIN
src/web/static/images/copy-16x16.png


BIN
src/web/static/images/cyberchef-128x128.png


BIN
src/web/static/images/cyberchef-16x16.png


BIN
src/web/static/images/cyberchef-256x256.png


BIN
src/web/static/images/cyberchef-32x32.png


BIN
src/web/static/images/cyberchef-512x512.png


BIN
src/web/static/images/cyberchef-64x64.png


BIN
src/web/static/images/disable_deselected-16x16.png


BIN
src/web/static/images/disable_selected-16x16.png


BIN
src/web/static/images/download-24x24.png


BIN
src/web/static/images/erase-16x16.png


BIN
src/web/static/images/favourite-16x16.png


BIN
src/web/static/images/favourite-24x24.png


BIN
src/web/static/images/fork_me.png


+ 1 - 0
src/web/static/images/gitter-badge.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="92" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="92" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h34v20H0z"/><path fill="#46BC99" d="M34 0h58v20H34z"/><path fill="url(#b)" d="M0 0h92v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="17" y="15" fill="#010101" fill-opacity=".3">chat</text><text x="17" y="14">chat</text><text x="62" y="15" fill="#010101" fill-opacity=".3">on gitter</text><text x="62" y="14">on gitter</text></g></svg>

BIN
src/web/static/images/help-16x16.png


BIN
src/web/static/images/help-22x22.png


BIN
src/web/static/images/info-16x16.png


BIN
src/web/static/images/layout-16x16.png


BIN
src/web/static/images/mail-16x16.png


BIN
src/web/static/images/maximise-16x16.png


BIN
src/web/static/images/open_yellow-16x16.png


BIN
src/web/static/images/open_yellow-24x24.png


BIN
src/web/static/images/recycle-16x16.png


BIN
src/web/static/images/remove-16x16.png


BIN
src/web/static/images/restore-16x16.png


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است