Restructured and fixed inliner.

This commit is contained in:
n1474335 2017-03-27 16:08:36 +01:00
parent d37bc4ab08
commit 97d41fd50a
24 changed files with 378 additions and 5720 deletions

View File

@ -1,5 +1,7 @@
var webpack = require("webpack"),
ExtractTextPlugin = require("extract-text-webpack-plugin");
ExtractTextPlugin = require("extract-text-webpack-plugin"),
HtmlWebpackPlugin = require("html-webpack-plugin"),
Inliner = require("web-resource-inliner");
module.exports = function (grunt) {
grunt.file.defaultEncoding = "utf8";
@ -8,7 +10,7 @@ module.exports = function (grunt) {
// Tasks
grunt.registerTask("dev",
"A persistent task which creates a development build whenever source files are modified.",
["clean:dev", "copy:htmlDev", "copy:staticDev", "chmod:build", "webpack:webDev", "watch"]);
["clean:dev", "webpack:webDev"]);
grunt.registerTask("node",
"Compiles CyberChef into a single NodeJS module.",
@ -16,17 +18,16 @@ module.exports = function (grunt) {
grunt.registerTask("test",
"A task which runs all the tests in test/tests.",
["clean:test", "webpack:tests", "chmod:build", "execute:test"]);
grunt.registerTask("prod",
"Creates a production-ready build. Use the --msg flag to add a compile message.",
["eslint", "test", "exec:stats", "clean", "jsdoc", "webpack:webProd", "copy:htmlDev", "copy:htmlProd", "copy:htmlInline",
"copy:staticDev", "copy:staticProd", "cssmin", "inline", "htmlmin", "chmod"]);
["clean:test", "webpack:tests", "execute:test"]);
grunt.registerTask("docs",
"Compiles documentation in the /docs directory.",
["clean:docs", "jsdoc", "chmod:docs"]);
grunt.registerTask("prod",
"Creates a production-ready build. Use the --msg flag to add a compile message.",
["eslint", "test", "clean:prod", "clean:docs", "jsdoc", "exec:stats", "webpack:webProd", "inline", "chmod"]);
grunt.registerTask("stats",
"Provides statistics about the code base such as how many lines there are as well as details of file sizes before and after compression.",
["webpack:webDev", "webpack:webProd", "exec:stats", "exec:repoSize", "exec:displayStats"]);
@ -39,6 +40,10 @@ module.exports = function (grunt) {
"Lints the code base and shows stats",
["eslint", "exec:stats", "exec:displayStats"]);
grunt.registerTask("inline",
"Compiles a production build of CyberChef into a single, portable web page.",
runInliner);
grunt.registerTask("doc", "docs");
grunt.registerTask("tests", "test");
grunt.registerTask("lint", "eslint");
@ -46,20 +51,18 @@ module.exports = function (grunt) {
// Load tasks provided by each plugin
grunt.loadNpmTasks("grunt-eslint");
grunt.loadNpmTasks("grunt-webpack");
grunt.loadNpmTasks("grunt-jsdoc");
grunt.loadNpmTasks("grunt-contrib-clean");
grunt.loadNpmTasks("grunt-webpack");
grunt.loadNpmTasks("grunt-contrib-copy");
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-htmlmin");
grunt.loadNpmTasks("grunt-inline-alt");
grunt.loadNpmTasks("grunt-chmod");
grunt.loadNpmTasks("grunt-exec");
grunt.loadNpmTasks("grunt-execute");
grunt.loadNpmTasks("grunt-contrib-watch");
// Project configuration
var compileTime = grunt.template.today("dd/mm/yyyy HH:MM:ss") + " UTC",
codebaseStats = grunt.file.read("src/web/static/stats.txt").split("\n").join("<br>"),
banner = "/**\n" +
"* CyberChef - The Cyber Swiss Army Knife\n" +
"*\n" +
@ -81,16 +84,39 @@ module.exports = function (grunt) {
"* limitations under the License.\n" +
"*/\n";
var templateOptions = {
data: {
compileTime: compileTime,
compileMsg: grunt.option("compile-msg") || grunt.option("msg") || "",
codebaseStats: grunt.file.read("src/web/static/stats.txt").split("\n").join("<br>")
}
};
/**
* Compiles a production build of CyberChef into a single, portable web page.
*/
function runInliner() {
var inlinerError = false;
Inliner.html({
relativeTo: "build/prod/",
fileContent: grunt.file.read("build/prod/cyberchef.htm"),
images: true,
svgs: true,
scripts: true,
links: true,
strict: true
}, function(error, result) {
if (error) {
console.log(error);
inlinerError = true;
return false;
}
grunt.file.write("build/prod/cyberchef.htm", result);
});
return !inlinerError;
}
// Project configuration
grunt.initConfig({
clean: {
dev: ["build/dev/*"],
prod: ["build/prod/*"],
test: ["build/test/*"],
node: ["build/node/*"],
docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico"],
},
eslint: {
options: {
configFile: "src/.eslintrc.json"
@ -116,13 +142,6 @@ module.exports = function (grunt) {
],
}
},
clean: {
dev: ["build/dev/*"],
prod: ["build/prod/*"],
test: ["build/test/*"],
node: ["build/node/*"],
docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico"],
},
webpack: {
options: {
plugins: [
@ -132,9 +151,9 @@ module.exports = function (grunt) {
moment: "moment-timezone"
}),
new webpack.BannerPlugin({
"banner": banner,
"raw": true,
"entryOnly": true
banner: banner,
raw: true,
entryOnly: true
}),
new webpack.DefinePlugin({
COMPILE_TIME: JSON.stringify(compileTime),
@ -148,37 +167,54 @@ module.exports = function (grunt) {
}
},
module: {
loaders: [
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader?compact=false"
}
],
rules: [
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: "css-loader"
use: "css-loader?minimize"
})
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
use: [
{ loader: "css-loader" },
{ loader: "css-loader?minimize" },
{ loader: "less-loader" }
]
})
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
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
}
},
webDev: {
@ -187,7 +223,16 @@ module.exports = function (grunt) {
output: {
filename: "scripts.js",
path: "build/dev"
}
},
plugins: [
new HtmlWebpackPlugin({
filename: "index.html",
template: "./src/web/html/index.html",
compileTime: compileTime,
codebaseStats: codebaseStats
})
],
watch: true
},
webProd: {
target: "web",
@ -206,8 +251,66 @@ module.exports = function (grunt) {
},
comments: false,
}),
new HtmlWebpackPlugin({ // Main version
filename: "index.html",
template: "./src/web/html/index.html",
compileTime: compileTime,
codebaseStats: codebaseStats,
minify: {
removeComments: true,
collapseWhitespace: true,
minifyJS: true,
minifyCSS: true
}
}),
new HtmlWebpackPlugin({ // Inline version
filename: "cyberchef.htm",
template: "./src/web/html/index.html",
compileTime: compileTime,
codebaseStats: codebaseStats,
inline: true,
minify: {
removeComments: true,
collapseWhitespace: true,
minifyJS: true,
minifyCSS: true
}
}),
]
},
// webInline: {
// target: "web",
// entry: "./src/web/index.js",
// output: {
// filename: "scripts.js",
// path: "build/prod"
// },
// plugins: [
// new webpack.optimize.UglifyJsPlugin({
// compress: {
// "screw_ie8": true,
// "dead_code": true,
// "unused": true,
// "warnings": false
// },
// comments: false,
// }),
// new HtmlWebpackPlugin({
// filename: "cyberchef.htm",
// template: "./src/web/html/index.html",
// compileTime: compileTime,
// codebaseStats: codebaseStats,
// inline: true,
// minify: {
// removeComments: true,
// collapseWhitespace: true,
// minifyJS: true,
// minifyCSS: true
// }
// }),
// new StyleExtHtmlWebpackPlugin()
// ]
// },
tests: {
target: "node",
entry: "./test/index.js",
@ -228,134 +331,37 @@ module.exports = function (grunt) {
}
},
copy: {
htmlDev: {
options: {
process: function (content, srcpath) {
return grunt.template.process(content, templateOptions);
}
},
src: "src/web/html/index.html",
dest: "build/dev/index.html"
},
htmlProd: {
options: {
process: function (content, srcpath) {
return grunt.template.process(content, templateOptions);
}
},
src: "src/web/html/index.html",
dest: "build/prod/index.html"
},
htmlInline: {
options: {
process: function (content, srcpath) {
// TODO: Do all this in Jade
content = content.replace(
'<a href="cyberchef.htm" style="float: left; margin-left: 10px; margin-right: 80px;" download>Download CyberChef<img src="images/download-24x24.png" /></a>',
'<span style="float: left; margin-left: 10px;">Compile time: ' + grunt.template.today("dd/mm/yyyy HH:MM:ss") + " UTC</span>");
return grunt.template.process(content, templateOptions);
}
},
src: "src/web/html/index.html",
dest: "build/prod/cyberchef.htm"
},
staticDev: {
files: [
{
expand: true,
cwd: "src/web/static/",
src: [
"**/*",
"**/.*",
"!stats.txt",
"!ga.html"
],
dest: "build/dev/"
}
]
},
staticProd: {
files: [
{
expand: true,
cwd: "src/web/static/",
src: [
"**/*",
"**/.*",
"!stats.txt",
"!ga.html"
],
dest: "build/prod/"
}
]
},
ghPages: {
options: {
process: function (content, srcpath) {
// Add Google Analytics code to index.html
content = content.replace("</body></html>",
grunt.file.read("src/static/ga.html") + "</body></html>");
return grunt.template.process(content, templateOptions);
return grunt.template.process(content);
}
},
src: "build/prod/index.html",
dest: "build/prod/index.html"
}
},
cssmin: {
prod: {
src: "build/dev/styles.css",
dest: "build/prod/styles.css"
}
},
htmlmin: {
prod: {
options: {
removeComments: true,
collapseWhitespace: true,
minifyJS: true,
minifyCSS: true
},
src: "build/prod/index.html",
dest: "build/prod/index.html"
},
inline: {
options: {
removeComments: true,
collapseWhitespace: true,
minifyJS: false,
minifyCSS: false
},
src: "build/prod/cyberchef.htm",
dest: "build/prod/cyberchef.htm"
}
},
inline: {
options: {
tag: "",
inlineTagAttributes: {
js: "type='application/javascript'",
css: "type='text/css'"
}
},
compiled: {
src: "build/prod/cyberchef.htm",
dest: "build/prod/cyberchef.htm"
},
prod: {
options: {
tag: "__inline"
},
src: "build/prod/index.html",
dest: "build/prod/index.html"
}
},
// inline: {
// options: {
// tag: "",
// inlineTagAttributes: {
// js: "type='application/javascript'",
// css: "type='text/css'"
// }
// },
// compiled: {
// src: "build/prod/cyberchef.htm"
// }
// },
chmod: {
build: {
options: {
mode: "755",
},
src: ["build/**/*", "build/**/.htaccess", "build/"]
src: ["build/**/*", "build/"]
},
docs: {
options: {
@ -412,28 +418,6 @@ module.exports = function (grunt) {
execute: {
test: "build/test/index.js"
},
watch: {
css: {
files: ["src/web/css/**/*.css", "src/web/css/**/*.less"],
tasks: ["webpack:webDev", "chmod:build"]
},
js: {
files: "src/**/*.js",
tasks: ["webpack:webDev", "chmod:build"]
},
html: {
files: "src/web/html/**/*.html",
tasks: ["copy:htmlDev", "chmod:build"]
},
static: {
files: ["src/web/static/**/*", "src/web/static/**/.*"],
tasks: ["copy:staticDev", "chmod:build"]
},
grunt: {
files: "Gruntfile.js",
tasks: ["clean:dev", "webpack:webDev", "copy:htmlDev", "copy:staticDev", "chmod:build"]
}
},
});
};

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -38,23 +38,19 @@
"grunt-chmod": "~1.1.1",
"grunt-contrib-clean": "~1.0.0",
"grunt-contrib-copy": "~1.0.0",
"grunt-contrib-cssmin": "~1.0.2",
"grunt-contrib-htmlmin": "~2.0.0",
"grunt-contrib-watch": "~1.0.0",
"grunt-eslint": "^19.0.0",
"grunt-exec": "~1.0.1",
"grunt-execute": "^0.2.2",
"grunt-inline-alt": "~0.3.10",
"grunt-jsdoc": "^2.1.0",
"grunt-webpack": "^2.0.1",
"import-loader": "^1.0.1",
"html-webpack-plugin": "^2.28.0",
"imports-loader": "^0.7.1",
"ink-docstrap": "^1.1.4",
"less": "^2.7.2",
"less-loader": "^4.0.2",
"phantomjs-prebuilt": "^2.1.14",
"style-loader": "^0.15.0",
"url-loader": "^0.5.8",
"web-resource-inliner": "^4.1.0",
"webpack": "^2.2.1"
},
"dependencies": {

View File

@ -29,18 +29,21 @@
<meta name="description" content="The Cyber Swiss Army Knife" />
<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" />
<link rel="icon" type="image/png" href="images/favicon.ico?__inline" />
<link href="styles.css" rel="stylesheet" />
<link rel="icon" type="image/ico" href="<%- require('../static/images/favicon.ico') %>" />
</head>
<body>
<span id="edit-favourites" class="btn btn-default btn-sm"><img src="images/favourite-16x16.png" /> Edit</span>
<span id="edit-favourites" class="btn btn-default btn-sm"><img src="<%- require('../static/images/favourite-16x16.png') %>" /> Edit</span>
<div id="alert" class="alert alert-danger">
<button type="button" class="close" id="alert-close">&times;</button>
<span id="alert-content"></span>
</div>
<div id="content-wrapper">
<div id="banner" class="green">
<a href="cyberchef.htm" style="float: left; margin-left: 10px; margin-right: 80px;" download>Download CyberChef<img src="images/download-24x24.png" /></a>
<% if (htmlWebpackPlugin.options.inline) { %>
<span style="float: left; margin-left: 10px;">Compile time: <%= htmlWebpackPlugin.options.compileTime %></span>
<% } else { %>
<a href="cyberchef.htm" style="float: left; margin-left: 10px; margin-right: 80px;" download>Download CyberChef<img src="<%- require('../static/images/download-24x24.png') %>" /></a>
<% } %>
<span id="notice">
<script type="text/javascript">
// Must be text/javascript rather than application/javascript otherwise IE won't recognise it...
@ -51,8 +54,8 @@
</script>
<noscript>JavaScript is not enabled. Good luck.</noscript>
</span>
<a href="#" id="support" class="banner-right" data-toggle="modal" data-target="#support-modal">About / Support<img src="images/help-22x22.png" /></a>
<a href="#" id="options" class="banner-right">Options<img src="images/settings-22x22.png" /></a>
<a href="#" id="support" class="banner-right" data-toggle="modal" data-target="#support-modal">About / Support<img src="<%- require('../static/images/help-22x22.png') %>" /></a>
<a href="#" id="options" class="banner-right">Options<img src="<%- require('../static/images/settings-22x22.png') %>" /></a>
</div>
<div id="wrapper">
<div id="operations" class="split split-horizontal no-select">
@ -70,7 +73,7 @@
<div id="operational-controls">
<div id="bake-group">
<button type="button" class="btn btn-success btn-lg" id="bake">
<img src="images/cook_male-32x32.png" />
<img src="<%- require('../static/images/cook_male-32x32.png') %>" />
Bake!
</button>
<label class="btn btn-success btn-lg" id="auto-bake-label">
@ -80,15 +83,15 @@
</div>
<div class="btn-group" style="padding-top: 10px;">
<button type="button" class="btn btn-default" id="step"><img src="images/step-16x16.png" /> Step through</button>
<button type="button" class="btn btn-default" id="clr-breaks"><img src="images/erase-16x16.png" /> Clear breakpoints</button>
<button type="button" class="btn btn-default" id="step"><img src="<%- require('../static/images/step-16x16.png') %>" /> Step through</button>
<button type="button" class="btn btn-default" id="clr-breaks"><img src="<%- require('../static/images/erase-16x16.png') %>" /> Clear breakpoints</button>
</div>
</div>
<div class="btn-group-vertical" id="extra-controls">
<button type="button" class="btn btn-default" id="save"><img src="images/save-16x16.png" /> Save recipe</button>
<button type="button" class="btn btn-default" id="load"><img src="images/open_yellow-16x16.png" /> Load recipe</button>
<button type="button" class="btn btn-default" id="clr-recipe"><img src="images/clean-16x16.png" /> Clear recipe</button>
<button type="button" class="btn btn-default" id="save"><img src="<%- require('../static/images/save-16x16.png') %>" /> Save recipe</button>
<button type="button" class="btn btn-default" id="load"><img src="<%- require('../static/images/open_yellow-16x16.png') %>" /> Load recipe</button>
<button type="button" class="btn btn-default" id="clr-recipe"><img src="<%- require('../static/images/clean-16x16.png') %>" /> Clear recipe</button>
</div>
</div>
</div>
@ -98,8 +101,8 @@
<div class="title no-select">
Input
<div class="btn-group io-btn-group">
<button type="button" class="btn btn-default btn-sm" id="clr-io"><img src="images/recycle-16x16.png" /> Clear I/O</button>
<button type="button" class="btn btn-default btn-sm" id="reset-layout"><img src="images/layout-16x16.png" /> Reset layout</button>
<button type="button" class="btn btn-default btn-sm" id="clr-io"><img src="<%- require('../static/images/recycle-16x16.png') %>" /> Clear I/O</button>
<button type="button" class="btn btn-default btn-sm" id="reset-layout"><img src="<%- require('../static/images/layout-16x16.png') %>" /> Reset layout</button>
</div>
<div class="io-info" id="input-info"></div>
<div class="io-info" id="input-selection-info"></div>
@ -114,10 +117,10 @@
<div class="title no-select">
Output
<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 src="images/save_as-16x16.png" /> Save to file</button>
<button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img src="images/switch-16x16.png" /> Move output to input</button>
<button type="button" class="btn btn-default btn-sm" id="undo-switch" title="Undo move" disabled="disabled"><img src="images/undo-16x16.png" /> Undo</button>
<button type="button" class="btn btn-default btn-sm" id="maximise-output" title="Maximise"><img src="images/maximise-16x16.png" /> Max</button>
<button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img src="<%- require('../static/images/save_as-16x16.png') %>" /> Save to file</button>
<button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img src="<%- require('../static/images/switch-16x16.png') %>" /> Move output to input</button>
<button type="button" class="btn btn-default btn-sm" id="undo-switch" title="Undo move" disabled="disabled"><img src="<%- require('../static/images/undo-16x16.png') %>" /> Undo</button>
<button type="button" class="btn btn-default btn-sm" id="maximise-output" title="Maximise"><img src="<%- require('../static/images/maximise-16x16.png') %>" /> Max</button>
</div>
<div class="io-info" id="output-info"></div>
<div class="io-info" id="output-selection-info"></div>
@ -136,7 +139,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<img class="pull-right" src="images/save-22x22.png" />
<img class="pull-right" src="<%- require('../static/images/save-22x22.png') %>" />
<h4 class="modal-title">Save recipe</h4>
</div>
<div class="modal-body">
@ -171,7 +174,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<img class="pull-right" src="images/open_yellow-24x24.png" />
<img class="pull-right" src="<%- require('../static/images/open_yellow-24x24.png') %>" />
<h4 class="modal-title">Load recipe</h4>
</div>
<div class="modal-body">
@ -196,7 +199,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<img class="pull-right" src="images/settings-22x22.png" />
<img class="pull-right" src="<%- require('../static/images/settings-22x22.png') %>" />
<h4 class="modal-title">Options</h4>
</div>
<div class="modal-body" id="options-body">
@ -242,7 +245,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<img class="pull-right" src="images/favourite-24x24.png" />
<img class="pull-right" src="<%- require('../static/images/favourite-24x24.png') %>" />
<h4 class="modal-title">Edit Favourites</h4>
</div>
<div class="modal-body" id="options-body">
@ -269,44 +272,44 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<img class="pull-right" src="images/help-22x22.png" />
<img class="pull-right" src="<%- require('../static/images/help-22x22.png') %>" />
<h4 class="modal-title">CyberChef - The Cyber Swiss Army Knife</h4>
</div>
<div class="modal-body">
<img class="about-img-left" src="images/cyberchef-128x128.png" />
<p class="subtext">Compile time: <%= compileTime %></p>
<img class="about-img-left" src="<%- require('../static/images/cyberchef-128x128.png') %>" />
<p class="subtext">Compile time: <%= htmlWebpackPlugin.options.compileTime %></p>
<p>&copy Crown Copyright 2016.</p>
<p>Licenced under the Apache Licence, Version 2.0.</p>
<br>
<br>
<div>
<ul class='nav nav-tabs' role='tablist'>
<li role='presentation' class='active'><a href='#faqs' aria-controls='profile' role='tab' data-toggle='tab'>
<img src='images/help-16x16.png' />
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#faqs" aria-controls="profile" role="tab" data-toggle="tab">
<img src="<%- require('../static/images/help-16x16.png') %>" />
FAQs
</a></li>
<li role='presentation'><a href='#report-bug' aria-controls='messages' role='tab' data-toggle='tab'>
<img src='images/bug-16x16.png' />
<li role="presentation"><a href="#report-bug" aria-controls="messages" role="tab" data-toggle="tab">
<img src="<%- require('../static/images/bug-16x16.png') %>" />
Report a bug
</a></li>
<li role='presentation'><a href='#stats' aria-controls='messages' role='tab' data-toggle='tab'>
<img src='images/stats-16x16.png' />
<li role="presentation"><a href="#stats" aria-controls="messages" role="tab" data-toggle="tab">
<img src="<%- require('../static/images/stats-16x16.png') %>" />
Stats
</a></li>
<li role='presentation'><a href='#about' aria-controls='messages' role='tab' data-toggle='tab'>
<img src='images/speech-16x16.png' />
<li role="presentation"><a href="#about" aria-controls="messages" role="tab" data-toggle="tab">
<img src="<%- require('../static/images/speech-16x16.png') %>" />
About
</a></li>
</ul>
<div class='tab-content'>
<div role='tabpanel' class='tab-pane active' id='faqs'>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="faqs">
<br>
<blockquote>
<a data-toggle='collapse' data-target='#faq-examples'>
<a data-toggle="collapse" data-target="#faq-examples">
What sort of things can I do with CyberChef?
</a>
</blockquote>
<div class='collapse' id='faq-examples'>
<div class="collapse" id="faq-examples">
<p>There are well over 100 operations in CyberChef allowing you to carry simple and complex tasks easily. Here are some examples:</p>
<ul>
<li><a href="?recipe=%5B%7B%22op%22%3A%22From%20Base64%22%2C%22args%22%3A%5B%22A-Za-z0-9%2B%2F%3D%22%2Ctrue%5D%7D%5D&input=VTI4Z2JHOXVaeUJoYm1RZ2RHaGhibXR6SUdadmNpQmhiR3dnZEdobElHWnBjMmd1">Decode a Base64-encoded string</a></li>
@ -318,39 +321,39 @@
</ul>
</div>
<blockquote>
<a data-toggle='collapse' data-target='#faq-load-files'>
<a data-toggle="collapse" data-target="#faq-load-files">
Can I load input directly from files?
</a>
</blockquote>
<div class='collapse' id='faq-load-files'>
<div class="collapse" id="faq-load-files">
<p>Yes! Just drag your file over the input box and drop it. The contents of the file will be converted into hexadecimal and the 'From Hex' operation will be added to the beginning of the recipe (if it's not already there). This is so that special characters like carriage returns aren't removed by your browser.</p>
<p>Please note that loading large files is likely to cause a crash. There's not a lot that can be done about this - browsers just aren't very good at handling and displaying large amounts of data.</p>
</div>
<blockquote>
<a data-toggle='collapse' data-target='#faq-fork'>
<a data-toggle="collapse" data-target="#faq-fork">
How do I run operation X over multiple inputs at once?
</a>
</blockquote>
<div class='collapse' id='faq-fork'>
<div class="collapse" id="faq-fork">
<p>Maybe you have 10 timestamps that you want to parse or 16 encoded strings that all have the same key.</p>
<p>The 'Fork' operation (found in the 'Flow control' category) splits up the input line by line and runs all subsequent operations on each line separately. Each output is then displayed on a separate line. These delimiters can be changed, so if your inputs are separated by commas, you can change the split delimiter to a comma instead.</p>
<p><a href='?recipe=%5B%7B"op"%3A"Fork"%2C"args"%3A%5B"%5C%5Cn"%2C"%5C%5Cn"%5D%7D%2C%7B"op"%3A"From%20UNIX%20Timestamp"%2C"args"%3A%5B"Seconds%20(s)"%5D%7D%5D&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA%3D%3D'>Click here</a> for an example.</p>
</div>
</div>
<div role='tabpanel' class='tab-pane' id='report-bug'>
<div role="tabpanel" class="tab-pane" id="report-bug">
<br>
<p>If you find a bug in CyberChef, please raise an issue in our GitHub repository explaining it in as much detail as possible. Copy and include the following information if relevant.</p>
<br>
<pre id='report-bug-info'></pre>
<pre id="report-bug-info"></pre>
<br>
<a class="btn btn-primary" href="https://github.com/gchq/CyberChef/issues/new" role="button">Raise issue on GitHub</a>
</div>
<div role='tabpanel' class='tab-pane' id='stats'>
<div role="tabpanel" class="tab-pane" id="stats">
<br>
<p>If you're a nerd like me, you might find statistics really fun! Here's some about the CyberChef code base:</p>
<br><pre><%= codebaseStats %></pre>
<br><pre><%= htmlWebpackPlugin.options.codebaseStats %></pre>
</div>
<div role='tabpanel' class='tab-pane' id='about' style="padding: 20px;">
<div role="tabpanel" class="tab-pane" id="about" style="padding: 20px;">
<h4>What</h4>
<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>
@ -378,7 +381,7 @@
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
<a href="https://github.com/gchq/CyberChef">
<img style="position: absolute; top: 0; right: 0; border: 0;" src="images/fork_me.png" alt="Fork me on GitHub">
<img style="position: absolute; top: 0; right: 0; border: 0;" src="<%- require('../static/images/fork_me.png') %>" alt="Fork me on GitHub">
</a>
</div>
</div>
@ -393,11 +396,11 @@
<div class="modal-body" id="confirm-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-success" id="confirm-yes">
<img src="images/thumb_up-16x16.png" />
<img src="<%- require('../static/images/thumb_up-16x16.png') %>" />
Yes
</button>
<button type="button" class="btn btn-danger" id="confirm-no" data-dismiss="modal">
<img src="images/thumb_down-16x16.png" />
<img src="<%- require('../static/images/thumb_down-16x16.png') %>" />
No
</button>
</div>
@ -405,6 +408,5 @@
</div>
</div>
<script type="application/javascript" src="scripts.js"></script>
</body>
</html>

View File

@ -1,50 +0,0 @@
# Serve up .htm files as binary files rather than text/html.
# This allows cyberchef.htm to be downloaded rather than opened in the browser.
AddType application/octet-stream .htm
# Fix Apache bug #45023 where "-gzip" is appended to all ETags, preventing 304 responses
<IfModule mod_headers.c>
RequestHeader edit "If-None-Match" "^\"(.*)-gzip\"$" "\"$1\""
Header edit "ETag" "^\"(.*[^g][^z][^i][^p])\"$" "\"$1-gzip\""
</IfModule>
# Set gzip compression on all resources that support it
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
</IfModule>
# Set Expires headers on various resources
<IfModule mod_expires.c>
ExpiresActive On
# 10 minutes
ExpiresDefault "access plus 600 seconds"
# 30 days
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
# 7 days
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 604800 seconds"
ExpiresByType application/javascript "access plus 604800 seconds"
ExpiresByType text/html "access plus 604800 seconds"
</IfModule>
# Set Cache-Control headers on various resources
<IfModule mod_headers.c>
<FilesMatch "\\.(ico|jpe?g|png|gif)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\\.(css)$">
Header set Cache-Control "max-age=600, public"
</FilesMatch>
<FilesMatch "\\.(js)$">
Header set Cache-Control "max-age=600, private, must-revalidate"
</FilesMatch>
<FilesMatch "\\.(x?html?)$">
Header set Cache-Control "max-age=600, private, must-revalidate"
</FilesMatch>
</IfModule>

View File

@ -1,13 +1,13 @@
128 source files
49068 lines
129 source files
49149 lines
1.9M size
63 JavaScript source files
20841 lines
20966 lines
788K size
4.7M uncompressed JavaScript size
2.6M compressed JavaScript size
uncompressed JavaScript size
compressed JavaScript size
15 categories
177 operations