mirror of
https://github.com/hugo-fixit/FixIt.git
synced 2026-09-03 12:12:39 +00:00
Merge branch 'feature/encryption' (#123)
This commit is contained in:
@@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
|
||||
> Add hugo new features support.
|
||||
> Snapshot:
|
||||
|
||||
- :tada: Feat: add content encryption of pages ([#123](https://github.com/Lruihao/FixIt/issues/123))
|
||||
- :sparkles: Feat: add total word count feature in section and remove from footer ([#124](https://github.com/Lruihao/FixIt/issues/124))
|
||||
- :sparkles: Feat: enhance auto toc feature ([#104](https://github.com/Lruihao/FixIt/issues/104) [#136](https://github.com/Lruihao/FixIt/issues/136))
|
||||
- :sparkles: Feat(SEO): add options to make output baidu_urls.txt file ([#138](https://github.com/Lruihao/FixIt/issues/138))
|
||||
|
||||
@@ -248,6 +248,7 @@ Thanks to the authors of following resources included in the theme:
|
||||
* [Twikoo](https://twikoo.js.org/)
|
||||
* [github-corners](https://github.com/tholman/github-corners)
|
||||
* [giscus](https://giscus.app/)
|
||||
* [crypto-js](https://github.com/brix/crypto-js)
|
||||
|
||||
## Author
|
||||
|
||||
|
||||
@@ -247,6 +247,7 @@ FixIt 主题中用到了以下项目,感谢它们的作者:
|
||||
* [Twikoo](https://twikoo.js.org/)
|
||||
* [github-corners](https://github.com/tholman/github-corners)
|
||||
* [giscus](https://giscus.app/zh-CN)
|
||||
* [crypto-js](https://github.com/brix/crypto-js)
|
||||
|
||||
## 作者
|
||||
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.d-none,
|
||||
.d-none {
|
||||
display: none !important;
|
||||
}
|
||||
.d-none-desktop {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@import '../_partial/_single/toc';
|
||||
@import '../_partial/_single/fixit-decryptor';
|
||||
|
||||
.single {
|
||||
.single-title {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
.fixit-decryptor-container {
|
||||
font-family: $global-font-family;
|
||||
text-align: center;
|
||||
margin-top: 3rem;
|
||||
|
||||
#fixit-decryptor-input,
|
||||
.fixit-encryptor-btn {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
color: $global-font-color;
|
||||
background-color: $global-background-color;
|
||||
border: 1px solid darken($global-border-color, 15%);
|
||||
border-radius: $global-border-radius;
|
||||
transition: 0.1s;
|
||||
box-shadow: 0px 0px 5px 0px darken($global-border-color, 15%);
|
||||
|
||||
&:active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: darken($global-link-hover-color, 6%);
|
||||
border-color: $global-link-hover-color;
|
||||
box-shadow: 0px 0px 5px 0px lighten($global-link-hover-color, 20%);
|
||||
|
||||
[theme='dark'] & {
|
||||
color: lighten($global-link-hover-color-dark, 6%);
|
||||
border-color: $global-link-hover-color-dark;
|
||||
box-shadow: 0px 0px 5px 0px darken($global-link-hover-color-dark, 20%);
|
||||
}
|
||||
}
|
||||
|
||||
[theme='dark'] & {
|
||||
color: $global-font-color-dark;
|
||||
border-color: lighten($global-border-color-dark, 15%);
|
||||
background-color: $global-background-color-dark;
|
||||
box-shadow: 0px 0px 5px 0px lighten($global-border-color-dark, 15%);
|
||||
}
|
||||
}
|
||||
|
||||
#fixit-decryptor-input {
|
||||
width: clamp(50%, 400px, 100%);
|
||||
height: 3rem;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.fixit-encryptor-btn {
|
||||
cursor: pointer;
|
||||
transition: 0.1s;
|
||||
padding: 0.6rem 1rem;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
# Tip: remove sourceMappingURL of local libraries to avoid source map 404 error.
|
||||
# See https://github.com/Lruihao/FixIt/issues/67
|
||||
# TODO https://unpkg.com/ cdn support
|
||||
|
||||
prefix:
|
||||
libFiles: https://cdn.jsdelivr.net/npm/
|
||||
# simple-icons@6.3.0 https://github.com/simple-icons/simple-icons
|
||||
@@ -20,6 +24,11 @@ libFiles:
|
||||
# cookieconsent@3.1.1 https://github.com/osano/cookieconsent
|
||||
cookieconsentCSS: cookieconsent@3.1.1/build/cookieconsent.min.css
|
||||
cookieconsentJS: cookieconsent@3.1.1/build/cookieconsent.min.js
|
||||
# crypto-js@4.1.1 https://github.com/brix/crypto-js
|
||||
cryptoCoreJS: crypto-js@4.1.1/core.js
|
||||
cryptoEncBase64JS: crypto-js@4.1.1/enc-base64.js
|
||||
cryptoMd5JS: crypto-js@4.1.1/md5.js
|
||||
cryptoSha256JS: crypto-js@4.1.1/sha256.js
|
||||
# echarts@5.2.2 https://github.com/apache/echarts
|
||||
echartsJS: echarts@5.3.2/dist/echarts.min.js
|
||||
echartsMacaronsJS: echarts@5.3.2/theme/macarons.min.js
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* FixIt decryptor for encrypted pages
|
||||
* @param {Object} options
|
||||
* @param {Function} [options.decrypted] handler after decrypting
|
||||
* @param {Function} [options.reset] handler after encrypting again
|
||||
* @param {Number} [options.duration=86400] number of seconds to cache decryption statistics. unit: s
|
||||
* @author @Lruihao https://lruihao.cn
|
||||
* @since v0.2.15
|
||||
*/
|
||||
FixItDecryptor = function (options = {}) {
|
||||
var _proto = FixItDecryptor.prototype;
|
||||
this.options = options || {};
|
||||
this.options.duration = this.options.duration || 24 * 60 * 60; // default cache one day
|
||||
this.decryptedEventSet = new Set();
|
||||
this.resetEventSet = new Set();
|
||||
this.$el = document.querySelector('.fixit-decryptor-container');
|
||||
|
||||
/**
|
||||
* decrypt content
|
||||
* @param {String} base64EncodeContent encrypted content
|
||||
*/
|
||||
var _decryptContent = (base64EncodeContent) => {
|
||||
try {
|
||||
this.$el.querySelector('#fixit-decryptor-input').classList.add('d-none');
|
||||
this.$el.querySelector('.fixit-encryptor-btn').classList.remove('d-none');
|
||||
document.querySelector('#content').insertAdjacentHTML(
|
||||
'afterbegin',
|
||||
CryptoJS.enc.Base64.parse(base64EncodeContent).toString(CryptoJS.enc.Utf8)
|
||||
);
|
||||
} catch (err) {
|
||||
return console.error(err);
|
||||
}
|
||||
// decrypted hook
|
||||
for (const event of this.decryptedEventSet) {
|
||||
event();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* initialize FixIt decryptor
|
||||
*/
|
||||
_proto.init = () => {
|
||||
this.addEventListener('decrypted', this.options?.decrypted);
|
||||
this.addEventListener('reset', this.options?.reset);
|
||||
this.validateCache();
|
||||
|
||||
const _decryptor = this;
|
||||
this.$el.querySelector('#fixit-decryptor-input')?.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
const $content = document.querySelector('#content');
|
||||
const password = $content.getAttribute('data-password');
|
||||
const input = this.value.trim();
|
||||
const saltLen = input.length % 2 ? input.length : input.length + 1;
|
||||
const inputMd5 = CryptoJS.MD5(input).toString();
|
||||
const inputSha256 = CryptoJS.SHA256(input).toString();
|
||||
|
||||
this.value = '';
|
||||
if (!input) {
|
||||
alert('Please enter the correct password!');
|
||||
return console.warn('Please enter the correct password!');
|
||||
}
|
||||
if (inputMd5 !== password) {
|
||||
alert(`Password error: ${input} not the correct password!`);
|
||||
return console.warn(`Password error: ${input} not the correct password!`);
|
||||
}
|
||||
// cache decryption statistics
|
||||
window.localStorage.setItem(
|
||||
`fixit-decryptor/#${location.pathname}`,
|
||||
JSON.stringify({
|
||||
expiration: Math.ceil(Date.now() / 1000) + _decryptor.options.duration,
|
||||
md5: inputMd5,
|
||||
sha256: inputSha256.slice(saltLen)
|
||||
})
|
||||
);
|
||||
_decryptContent($content.getAttribute('data-content').replace(inputSha256.slice(saltLen), ''));
|
||||
}
|
||||
});
|
||||
|
||||
this.$el.querySelector('.fixit-encryptor-btn')?.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
this.classList.add('d-none')
|
||||
_decryptor.$el.querySelector('#fixit-decryptor-input').classList.remove('d-none');
|
||||
document.querySelector('#content').innerHTML = '';
|
||||
document.querySelector('#content').insertAdjacentElement(
|
||||
'afterbegin',
|
||||
_decryptor.$el
|
||||
);
|
||||
window.localStorage.removeItem(`fixit-decryptor/#${location.pathname}`);
|
||||
// reset hook
|
||||
for (const event of _decryptor.resetEventSet) {
|
||||
event();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* validate the cached decryption statistics in localStorage
|
||||
*/
|
||||
_proto.validateCache = () => {
|
||||
const $content = document.querySelector('#content');
|
||||
const password = $content.getAttribute('data-password');
|
||||
const cachedStat = JSON.parse(window.localStorage.getItem(`fixit-decryptor/#${location.pathname}`));
|
||||
|
||||
if (!cachedStat) {
|
||||
return this.$el.querySelector('#fixit-decryptor-input').classList.remove('d-none');
|
||||
}
|
||||
if (cachedStat?.md5 !== password || Number(cachedStat?.expiration) < Math.ceil(Date.now() / 1000)) {
|
||||
this.$el.querySelector('#fixit-decryptor-input').classList.remove('d-none');
|
||||
window.localStorage.removeItem(`fixit-decryptor/#${location.pathname}`);
|
||||
return console.warn('The password has expired, please re-enter!');
|
||||
}
|
||||
_decryptContent($content.getAttribute('data-content').replace(cachedStat.sha256, ''));
|
||||
};
|
||||
|
||||
/**
|
||||
* add event listener for FixIt Decryptor
|
||||
* @param {String} event
|
||||
* @param {Function} listener event handler
|
||||
* @returns {FixItDecryptor}
|
||||
*/
|
||||
_proto.addEventListener = (event, listener) => {
|
||||
if (typeof listener !== 'function') {
|
||||
return this;
|
||||
}
|
||||
switch (event) {
|
||||
case 'decrypted':
|
||||
this.decryptedEventSet.add(listener);
|
||||
break;
|
||||
case 'reset':
|
||||
this.resetEventSet.add(listener);
|
||||
break;
|
||||
default:
|
||||
console.warn(`Event ${event} not found in FixIt Decryptor!`);
|
||||
break;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* remove event listener for FixIt Decryptor
|
||||
* @param {String} event
|
||||
* @param {Function} listener event handler
|
||||
* @returns {FixItDecryptor}
|
||||
*/
|
||||
_proto.removeEventListener = (event, listener) => {
|
||||
if (typeof listener !== 'function') {
|
||||
return this;
|
||||
}
|
||||
switch (event) {
|
||||
case 'decrypted':
|
||||
this.decryptedEventSet.delete(listener);
|
||||
break;
|
||||
case 'reset':
|
||||
this.resetEventSet.delete(listener);
|
||||
break;
|
||||
default:
|
||||
console.warn(`Event ${event} not found in FixIt Decryptor!`);
|
||||
break;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
};
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -5,6 +5,7 @@ artalk@2.2.12 https://github.com/ArtalkJS/Artalk
|
||||
autocomplete.js@0.38.1 https://github.com/algolia/autocomplete.js
|
||||
cell-watermark@1.0.3 https://github.com/Lruihao/watermark
|
||||
cookieconsent@3.1.1 https://github.com/osano/cookieconsent
|
||||
crypto-js@4.1.1 https://github.com/brix/crypto-js
|
||||
echarts@5.3.2 https://github.com/apache/echarts
|
||||
fontawesome-free@6.1.1 https://github.com/FortAwesome/Font-Awesome
|
||||
gitalk@1.7.2 https://github.com/gitalk/gitalk
|
||||
|
||||
@@ -0,0 +1,807 @@
|
||||
;(function (root, factory) {
|
||||
if (typeof exports === "object") {
|
||||
// CommonJS
|
||||
module.exports = exports = factory();
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
// AMD
|
||||
define([], factory);
|
||||
}
|
||||
else {
|
||||
// Global (browser)
|
||||
root.CryptoJS = factory();
|
||||
}
|
||||
}(this, function () {
|
||||
|
||||
/*globals window, global, require*/
|
||||
|
||||
/**
|
||||
* CryptoJS core components.
|
||||
*/
|
||||
var CryptoJS = CryptoJS || (function (Math, undefined) {
|
||||
|
||||
var crypto;
|
||||
|
||||
// Native crypto from window (Browser)
|
||||
if (typeof window !== 'undefined' && window.crypto) {
|
||||
crypto = window.crypto;
|
||||
}
|
||||
|
||||
// Native crypto in web worker (Browser)
|
||||
if (typeof self !== 'undefined' && self.crypto) {
|
||||
crypto = self.crypto;
|
||||
}
|
||||
|
||||
// Native crypto from worker
|
||||
if (typeof globalThis !== 'undefined' && globalThis.crypto) {
|
||||
crypto = globalThis.crypto;
|
||||
}
|
||||
|
||||
// Native (experimental IE 11) crypto from window (Browser)
|
||||
if (!crypto && typeof window !== 'undefined' && window.msCrypto) {
|
||||
crypto = window.msCrypto;
|
||||
}
|
||||
|
||||
// Native crypto from global (NodeJS)
|
||||
if (!crypto && typeof global !== 'undefined' && global.crypto) {
|
||||
crypto = global.crypto;
|
||||
}
|
||||
|
||||
// Native crypto import via require (NodeJS)
|
||||
if (!crypto && typeof require === 'function') {
|
||||
try {
|
||||
crypto = require('crypto');
|
||||
} catch (err) {}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cryptographically secure pseudorandom number generator
|
||||
*
|
||||
* As Math.random() is cryptographically not safe to use
|
||||
*/
|
||||
var cryptoSecureRandomInt = function () {
|
||||
if (crypto) {
|
||||
// Use getRandomValues method (Browser)
|
||||
if (typeof crypto.getRandomValues === 'function') {
|
||||
try {
|
||||
return crypto.getRandomValues(new Uint32Array(1))[0];
|
||||
} catch (err) {}
|
||||
}
|
||||
|
||||
// Use randomBytes method (NodeJS)
|
||||
if (typeof crypto.randomBytes === 'function') {
|
||||
try {
|
||||
return crypto.randomBytes(4).readInt32LE();
|
||||
} catch (err) {}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Native crypto module could not be used to get secure random number.');
|
||||
};
|
||||
|
||||
/*
|
||||
* Local polyfill of Object.create
|
||||
|
||||
*/
|
||||
var create = Object.create || (function () {
|
||||
function F() {}
|
||||
|
||||
return function (obj) {
|
||||
var subtype;
|
||||
|
||||
F.prototype = obj;
|
||||
|
||||
subtype = new F();
|
||||
|
||||
F.prototype = null;
|
||||
|
||||
return subtype;
|
||||
};
|
||||
}());
|
||||
|
||||
/**
|
||||
* CryptoJS namespace.
|
||||
*/
|
||||
var C = {};
|
||||
|
||||
/**
|
||||
* Library namespace.
|
||||
*/
|
||||
var C_lib = C.lib = {};
|
||||
|
||||
/**
|
||||
* Base object for prototypal inheritance.
|
||||
*/
|
||||
var Base = C_lib.Base = (function () {
|
||||
|
||||
|
||||
return {
|
||||
/**
|
||||
* Creates a new object that inherits from this object.
|
||||
*
|
||||
* @param {Object} overrides Properties to copy into the new object.
|
||||
*
|
||||
* @return {Object} The new object.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var MyType = CryptoJS.lib.Base.extend({
|
||||
* field: 'value',
|
||||
*
|
||||
* method: function () {
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
extend: function (overrides) {
|
||||
// Spawn
|
||||
var subtype = create(this);
|
||||
|
||||
// Augment
|
||||
if (overrides) {
|
||||
subtype.mixIn(overrides);
|
||||
}
|
||||
|
||||
// Create default initializer
|
||||
if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
|
||||
subtype.init = function () {
|
||||
subtype.$super.init.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
// Initializer's prototype is the subtype object
|
||||
subtype.init.prototype = subtype;
|
||||
|
||||
// Reference supertype
|
||||
subtype.$super = this;
|
||||
|
||||
return subtype;
|
||||
},
|
||||
|
||||
/**
|
||||
* Extends this object and runs the init method.
|
||||
* Arguments to create() will be passed to init().
|
||||
*
|
||||
* @return {Object} The new object.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var instance = MyType.create();
|
||||
*/
|
||||
create: function () {
|
||||
var instance = this.extend();
|
||||
instance.init.apply(instance, arguments);
|
||||
|
||||
return instance;
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes a newly created object.
|
||||
* Override this method to add some logic when your objects are created.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var MyType = CryptoJS.lib.Base.extend({
|
||||
* init: function () {
|
||||
* // ...
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
init: function () {
|
||||
},
|
||||
|
||||
/**
|
||||
* Copies properties into this object.
|
||||
*
|
||||
* @param {Object} properties The properties to mix in.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* MyType.mixIn({
|
||||
* field: 'value'
|
||||
* });
|
||||
*/
|
||||
mixIn: function (properties) {
|
||||
for (var propertyName in properties) {
|
||||
if (properties.hasOwnProperty(propertyName)) {
|
||||
this[propertyName] = properties[propertyName];
|
||||
}
|
||||
}
|
||||
|
||||
// IE won't copy toString using the loop above
|
||||
if (properties.hasOwnProperty('toString')) {
|
||||
this.toString = properties.toString;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a copy of this object.
|
||||
*
|
||||
* @return {Object} The clone.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var clone = instance.clone();
|
||||
*/
|
||||
clone: function () {
|
||||
return this.init.prototype.extend(this);
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
||||
/**
|
||||
* An array of 32-bit words.
|
||||
*
|
||||
* @property {Array} words The array of 32-bit words.
|
||||
* @property {number} sigBytes The number of significant bytes in this word array.
|
||||
*/
|
||||
var WordArray = C_lib.WordArray = Base.extend({
|
||||
/**
|
||||
* Initializes a newly created word array.
|
||||
*
|
||||
* @param {Array} words (Optional) An array of 32-bit words.
|
||||
* @param {number} sigBytes (Optional) The number of significant bytes in the words.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var wordArray = CryptoJS.lib.WordArray.create();
|
||||
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
|
||||
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
|
||||
*/
|
||||
init: function (words, sigBytes) {
|
||||
words = this.words = words || [];
|
||||
|
||||
if (sigBytes != undefined) {
|
||||
this.sigBytes = sigBytes;
|
||||
} else {
|
||||
this.sigBytes = words.length * 4;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts this word array to a string.
|
||||
*
|
||||
* @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
|
||||
*
|
||||
* @return {string} The stringified word array.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var string = wordArray + '';
|
||||
* var string = wordArray.toString();
|
||||
* var string = wordArray.toString(CryptoJS.enc.Utf8);
|
||||
*/
|
||||
toString: function (encoder) {
|
||||
return (encoder || Hex).stringify(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Concatenates a word array to this word array.
|
||||
*
|
||||
* @param {WordArray} wordArray The word array to append.
|
||||
*
|
||||
* @return {WordArray} This word array.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* wordArray1.concat(wordArray2);
|
||||
*/
|
||||
concat: function (wordArray) {
|
||||
// Shortcuts
|
||||
var thisWords = this.words;
|
||||
var thatWords = wordArray.words;
|
||||
var thisSigBytes = this.sigBytes;
|
||||
var thatSigBytes = wordArray.sigBytes;
|
||||
|
||||
// Clamp excess bits
|
||||
this.clamp();
|
||||
|
||||
// Concat
|
||||
if (thisSigBytes % 4) {
|
||||
// Copy one byte at a time
|
||||
for (var i = 0; i < thatSigBytes; i++) {
|
||||
var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
||||
thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
|
||||
}
|
||||
} else {
|
||||
// Copy one word at a time
|
||||
for (var j = 0; j < thatSigBytes; j += 4) {
|
||||
thisWords[(thisSigBytes + j) >>> 2] = thatWords[j >>> 2];
|
||||
}
|
||||
}
|
||||
this.sigBytes += thatSigBytes;
|
||||
|
||||
// Chainable
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes insignificant bits.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* wordArray.clamp();
|
||||
*/
|
||||
clamp: function () {
|
||||
// Shortcuts
|
||||
var words = this.words;
|
||||
var sigBytes = this.sigBytes;
|
||||
|
||||
// Clamp
|
||||
words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
|
||||
words.length = Math.ceil(sigBytes / 4);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a copy of this word array.
|
||||
*
|
||||
* @return {WordArray} The clone.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var clone = wordArray.clone();
|
||||
*/
|
||||
clone: function () {
|
||||
var clone = Base.clone.call(this);
|
||||
clone.words = this.words.slice(0);
|
||||
|
||||
return clone;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a word array filled with random bytes.
|
||||
*
|
||||
* @param {number} nBytes The number of random bytes to generate.
|
||||
*
|
||||
* @return {WordArray} The random word array.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var wordArray = CryptoJS.lib.WordArray.random(16);
|
||||
*/
|
||||
random: function (nBytes) {
|
||||
var words = [];
|
||||
|
||||
for (var i = 0; i < nBytes; i += 4) {
|
||||
words.push(cryptoSecureRandomInt());
|
||||
}
|
||||
|
||||
return new WordArray.init(words, nBytes);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Encoder namespace.
|
||||
*/
|
||||
var C_enc = C.enc = {};
|
||||
|
||||
/**
|
||||
* Hex encoding strategy.
|
||||
*/
|
||||
var Hex = C_enc.Hex = {
|
||||
/**
|
||||
* Converts a word array to a hex string.
|
||||
*
|
||||
* @param {WordArray} wordArray The word array.
|
||||
*
|
||||
* @return {string} The hex string.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var hexString = CryptoJS.enc.Hex.stringify(wordArray);
|
||||
*/
|
||||
stringify: function (wordArray) {
|
||||
// Shortcuts
|
||||
var words = wordArray.words;
|
||||
var sigBytes = wordArray.sigBytes;
|
||||
|
||||
// Convert
|
||||
var hexChars = [];
|
||||
for (var i = 0; i < sigBytes; i++) {
|
||||
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
||||
hexChars.push((bite >>> 4).toString(16));
|
||||
hexChars.push((bite & 0x0f).toString(16));
|
||||
}
|
||||
|
||||
return hexChars.join('');
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts a hex string to a word array.
|
||||
*
|
||||
* @param {string} hexStr The hex string.
|
||||
*
|
||||
* @return {WordArray} The word array.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var wordArray = CryptoJS.enc.Hex.parse(hexString);
|
||||
*/
|
||||
parse: function (hexStr) {
|
||||
// Shortcut
|
||||
var hexStrLength = hexStr.length;
|
||||
|
||||
// Convert
|
||||
var words = [];
|
||||
for (var i = 0; i < hexStrLength; i += 2) {
|
||||
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
|
||||
}
|
||||
|
||||
return new WordArray.init(words, hexStrLength / 2);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Latin1 encoding strategy.
|
||||
*/
|
||||
var Latin1 = C_enc.Latin1 = {
|
||||
/**
|
||||
* Converts a word array to a Latin1 string.
|
||||
*
|
||||
* @param {WordArray} wordArray The word array.
|
||||
*
|
||||
* @return {string} The Latin1 string.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
|
||||
*/
|
||||
stringify: function (wordArray) {
|
||||
// Shortcuts
|
||||
var words = wordArray.words;
|
||||
var sigBytes = wordArray.sigBytes;
|
||||
|
||||
// Convert
|
||||
var latin1Chars = [];
|
||||
for (var i = 0; i < sigBytes; i++) {
|
||||
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
||||
latin1Chars.push(String.fromCharCode(bite));
|
||||
}
|
||||
|
||||
return latin1Chars.join('');
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts a Latin1 string to a word array.
|
||||
*
|
||||
* @param {string} latin1Str The Latin1 string.
|
||||
*
|
||||
* @return {WordArray} The word array.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
|
||||
*/
|
||||
parse: function (latin1Str) {
|
||||
// Shortcut
|
||||
var latin1StrLength = latin1Str.length;
|
||||
|
||||
// Convert
|
||||
var words = [];
|
||||
for (var i = 0; i < latin1StrLength; i++) {
|
||||
words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
|
||||
}
|
||||
|
||||
return new WordArray.init(words, latin1StrLength);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* UTF-8 encoding strategy.
|
||||
*/
|
||||
var Utf8 = C_enc.Utf8 = {
|
||||
/**
|
||||
* Converts a word array to a UTF-8 string.
|
||||
*
|
||||
* @param {WordArray} wordArray The word array.
|
||||
*
|
||||
* @return {string} The UTF-8 string.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
|
||||
*/
|
||||
stringify: function (wordArray) {
|
||||
try {
|
||||
return decodeURIComponent(escape(Latin1.stringify(wordArray)));
|
||||
} catch (e) {
|
||||
throw new Error('Malformed UTF-8 data');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts a UTF-8 string to a word array.
|
||||
*
|
||||
* @param {string} utf8Str The UTF-8 string.
|
||||
*
|
||||
* @return {WordArray} The word array.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
|
||||
*/
|
||||
parse: function (utf8Str) {
|
||||
return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract buffered block algorithm template.
|
||||
*
|
||||
* The property blockSize must be implemented in a concrete subtype.
|
||||
*
|
||||
* @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
|
||||
*/
|
||||
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
|
||||
/**
|
||||
* Resets this block algorithm's data buffer to its initial state.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* bufferedBlockAlgorithm.reset();
|
||||
*/
|
||||
reset: function () {
|
||||
// Initial values
|
||||
this._data = new WordArray.init();
|
||||
this._nDataBytes = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds new data to this block algorithm's buffer.
|
||||
*
|
||||
* @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* bufferedBlockAlgorithm._append('data');
|
||||
* bufferedBlockAlgorithm._append(wordArray);
|
||||
*/
|
||||
_append: function (data) {
|
||||
// Convert string to WordArray, else assume WordArray already
|
||||
if (typeof data == 'string') {
|
||||
data = Utf8.parse(data);
|
||||
}
|
||||
|
||||
// Append
|
||||
this._data.concat(data);
|
||||
this._nDataBytes += data.sigBytes;
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes available data blocks.
|
||||
*
|
||||
* This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
|
||||
*
|
||||
* @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
|
||||
*
|
||||
* @return {WordArray} The processed data.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var processedData = bufferedBlockAlgorithm._process();
|
||||
* var processedData = bufferedBlockAlgorithm._process(!!'flush');
|
||||
*/
|
||||
_process: function (doFlush) {
|
||||
var processedWords;
|
||||
|
||||
// Shortcuts
|
||||
var data = this._data;
|
||||
var dataWords = data.words;
|
||||
var dataSigBytes = data.sigBytes;
|
||||
var blockSize = this.blockSize;
|
||||
var blockSizeBytes = blockSize * 4;
|
||||
|
||||
// Count blocks ready
|
||||
var nBlocksReady = dataSigBytes / blockSizeBytes;
|
||||
if (doFlush) {
|
||||
// Round up to include partial blocks
|
||||
nBlocksReady = Math.ceil(nBlocksReady);
|
||||
} else {
|
||||
// Round down to include only full blocks,
|
||||
// less the number of blocks that must remain in the buffer
|
||||
nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
|
||||
}
|
||||
|
||||
// Count words ready
|
||||
var nWordsReady = nBlocksReady * blockSize;
|
||||
|
||||
// Count bytes ready
|
||||
var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
|
||||
|
||||
// Process blocks
|
||||
if (nWordsReady) {
|
||||
for (var offset = 0; offset < nWordsReady; offset += blockSize) {
|
||||
// Perform concrete-algorithm logic
|
||||
this._doProcessBlock(dataWords, offset);
|
||||
}
|
||||
|
||||
// Remove processed words
|
||||
processedWords = dataWords.splice(0, nWordsReady);
|
||||
data.sigBytes -= nBytesReady;
|
||||
}
|
||||
|
||||
// Return processed words
|
||||
return new WordArray.init(processedWords, nBytesReady);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a copy of this object.
|
||||
*
|
||||
* @return {Object} The clone.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var clone = bufferedBlockAlgorithm.clone();
|
||||
*/
|
||||
clone: function () {
|
||||
var clone = Base.clone.call(this);
|
||||
clone._data = this._data.clone();
|
||||
|
||||
return clone;
|
||||
},
|
||||
|
||||
_minBufferSize: 0
|
||||
});
|
||||
|
||||
/**
|
||||
* Abstract hasher template.
|
||||
*
|
||||
* @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
|
||||
*/
|
||||
var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
|
||||
/**
|
||||
* Configuration options.
|
||||
*/
|
||||
cfg: Base.extend(),
|
||||
|
||||
/**
|
||||
* Initializes a newly created hasher.
|
||||
*
|
||||
* @param {Object} cfg (Optional) The configuration options to use for this hash computation.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var hasher = CryptoJS.algo.SHA256.create();
|
||||
*/
|
||||
init: function (cfg) {
|
||||
// Apply config defaults
|
||||
this.cfg = this.cfg.extend(cfg);
|
||||
|
||||
// Set initial values
|
||||
this.reset();
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets this hasher to its initial state.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* hasher.reset();
|
||||
*/
|
||||
reset: function () {
|
||||
// Reset data buffer
|
||||
BufferedBlockAlgorithm.reset.call(this);
|
||||
|
||||
// Perform concrete-hasher logic
|
||||
this._doReset();
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates this hasher with a message.
|
||||
*
|
||||
* @param {WordArray|string} messageUpdate The message to append.
|
||||
*
|
||||
* @return {Hasher} This hasher.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* hasher.update('message');
|
||||
* hasher.update(wordArray);
|
||||
*/
|
||||
update: function (messageUpdate) {
|
||||
// Append
|
||||
this._append(messageUpdate);
|
||||
|
||||
// Update the hash
|
||||
this._process();
|
||||
|
||||
// Chainable
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Finalizes the hash computation.
|
||||
* Note that the finalize operation is effectively a destructive, read-once operation.
|
||||
*
|
||||
* @param {WordArray|string} messageUpdate (Optional) A final message update.
|
||||
*
|
||||
* @return {WordArray} The hash.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var hash = hasher.finalize();
|
||||
* var hash = hasher.finalize('message');
|
||||
* var hash = hasher.finalize(wordArray);
|
||||
*/
|
||||
finalize: function (messageUpdate) {
|
||||
// Final message update
|
||||
if (messageUpdate) {
|
||||
this._append(messageUpdate);
|
||||
}
|
||||
|
||||
// Perform concrete-hasher logic
|
||||
var hash = this._doFinalize();
|
||||
|
||||
return hash;
|
||||
},
|
||||
|
||||
blockSize: 512/32,
|
||||
|
||||
/**
|
||||
* Creates a shortcut function to a hasher's object interface.
|
||||
*
|
||||
* @param {Hasher} hasher The hasher to create a helper for.
|
||||
*
|
||||
* @return {Function} The shortcut function.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
|
||||
*/
|
||||
_createHelper: function (hasher) {
|
||||
return function (message, cfg) {
|
||||
return new hasher.init(cfg).finalize(message);
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param {Hasher} hasher The hasher to use in this HMAC helper.
|
||||
*
|
||||
* @return {Function} The shortcut function.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
|
||||
*/
|
||||
_createHmacHelper: function (hasher) {
|
||||
return function (message, key) {
|
||||
return new C_algo.HMAC.init(hasher, key).finalize(message);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Algorithm namespace.
|
||||
*/
|
||||
var C_algo = C.algo = {};
|
||||
|
||||
return C;
|
||||
}(Math));
|
||||
|
||||
|
||||
return CryptoJS;
|
||||
|
||||
}));
|
||||
@@ -0,0 +1,136 @@
|
||||
;(function (root, factory) {
|
||||
if (typeof exports === "object") {
|
||||
// CommonJS
|
||||
module.exports = exports = factory(require("./core"));
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
// AMD
|
||||
define(["./core"], factory);
|
||||
}
|
||||
else {
|
||||
// Global (browser)
|
||||
factory(root.CryptoJS);
|
||||
}
|
||||
}(this, function (CryptoJS) {
|
||||
|
||||
(function () {
|
||||
// Shortcuts
|
||||
var C = CryptoJS;
|
||||
var C_lib = C.lib;
|
||||
var WordArray = C_lib.WordArray;
|
||||
var C_enc = C.enc;
|
||||
|
||||
/**
|
||||
* Base64 encoding strategy.
|
||||
*/
|
||||
var Base64 = C_enc.Base64 = {
|
||||
/**
|
||||
* Converts a word array to a Base64 string.
|
||||
*
|
||||
* @param {WordArray} wordArray The word array.
|
||||
*
|
||||
* @return {string} The Base64 string.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var base64String = CryptoJS.enc.Base64.stringify(wordArray);
|
||||
*/
|
||||
stringify: function (wordArray) {
|
||||
// Shortcuts
|
||||
var words = wordArray.words;
|
||||
var sigBytes = wordArray.sigBytes;
|
||||
var map = this._map;
|
||||
|
||||
// Clamp excess bits
|
||||
wordArray.clamp();
|
||||
|
||||
// Convert
|
||||
var base64Chars = [];
|
||||
for (var i = 0; i < sigBytes; i += 3) {
|
||||
var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
||||
var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
|
||||
var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
|
||||
|
||||
var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
|
||||
|
||||
for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
|
||||
base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
|
||||
}
|
||||
}
|
||||
|
||||
// Add padding
|
||||
var paddingChar = map.charAt(64);
|
||||
if (paddingChar) {
|
||||
while (base64Chars.length % 4) {
|
||||
base64Chars.push(paddingChar);
|
||||
}
|
||||
}
|
||||
|
||||
return base64Chars.join('');
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts a Base64 string to a word array.
|
||||
*
|
||||
* @param {string} base64Str The Base64 string.
|
||||
*
|
||||
* @return {WordArray} The word array.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var wordArray = CryptoJS.enc.Base64.parse(base64String);
|
||||
*/
|
||||
parse: function (base64Str) {
|
||||
// Shortcuts
|
||||
var base64StrLength = base64Str.length;
|
||||
var map = this._map;
|
||||
var reverseMap = this._reverseMap;
|
||||
|
||||
if (!reverseMap) {
|
||||
reverseMap = this._reverseMap = [];
|
||||
for (var j = 0; j < map.length; j++) {
|
||||
reverseMap[map.charCodeAt(j)] = j;
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore padding
|
||||
var paddingChar = map.charAt(64);
|
||||
if (paddingChar) {
|
||||
var paddingIndex = base64Str.indexOf(paddingChar);
|
||||
if (paddingIndex !== -1) {
|
||||
base64StrLength = paddingIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert
|
||||
return parseLoop(base64Str, base64StrLength, reverseMap);
|
||||
|
||||
},
|
||||
|
||||
_map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
|
||||
};
|
||||
|
||||
function parseLoop(base64Str, base64StrLength, reverseMap) {
|
||||
var words = [];
|
||||
var nBytes = 0;
|
||||
for (var i = 0; i < base64StrLength; i++) {
|
||||
if (i % 4) {
|
||||
var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);
|
||||
var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);
|
||||
var bitsCombined = bits1 | bits2;
|
||||
words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8);
|
||||
nBytes++;
|
||||
}
|
||||
}
|
||||
return WordArray.create(words, nBytes);
|
||||
}
|
||||
}());
|
||||
|
||||
|
||||
return CryptoJS.enc.Base64;
|
||||
|
||||
}));
|
||||
@@ -0,0 +1,268 @@
|
||||
;(function (root, factory) {
|
||||
if (typeof exports === "object") {
|
||||
// CommonJS
|
||||
module.exports = exports = factory(require("./core"));
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
// AMD
|
||||
define(["./core"], factory);
|
||||
}
|
||||
else {
|
||||
// Global (browser)
|
||||
factory(root.CryptoJS);
|
||||
}
|
||||
}(this, function (CryptoJS) {
|
||||
|
||||
(function (Math) {
|
||||
// Shortcuts
|
||||
var C = CryptoJS;
|
||||
var C_lib = C.lib;
|
||||
var WordArray = C_lib.WordArray;
|
||||
var Hasher = C_lib.Hasher;
|
||||
var C_algo = C.algo;
|
||||
|
||||
// Constants table
|
||||
var T = [];
|
||||
|
||||
// Compute constants
|
||||
(function () {
|
||||
for (var i = 0; i < 64; i++) {
|
||||
T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;
|
||||
}
|
||||
}());
|
||||
|
||||
/**
|
||||
* MD5 hash algorithm.
|
||||
*/
|
||||
var MD5 = C_algo.MD5 = Hasher.extend({
|
||||
_doReset: function () {
|
||||
this._hash = new WordArray.init([
|
||||
0x67452301, 0xefcdab89,
|
||||
0x98badcfe, 0x10325476
|
||||
]);
|
||||
},
|
||||
|
||||
_doProcessBlock: function (M, offset) {
|
||||
// Swap endian
|
||||
for (var i = 0; i < 16; i++) {
|
||||
// Shortcuts
|
||||
var offset_i = offset + i;
|
||||
var M_offset_i = M[offset_i];
|
||||
|
||||
M[offset_i] = (
|
||||
(((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
|
||||
(((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
|
||||
);
|
||||
}
|
||||
|
||||
// Shortcuts
|
||||
var H = this._hash.words;
|
||||
|
||||
var M_offset_0 = M[offset + 0];
|
||||
var M_offset_1 = M[offset + 1];
|
||||
var M_offset_2 = M[offset + 2];
|
||||
var M_offset_3 = M[offset + 3];
|
||||
var M_offset_4 = M[offset + 4];
|
||||
var M_offset_5 = M[offset + 5];
|
||||
var M_offset_6 = M[offset + 6];
|
||||
var M_offset_7 = M[offset + 7];
|
||||
var M_offset_8 = M[offset + 8];
|
||||
var M_offset_9 = M[offset + 9];
|
||||
var M_offset_10 = M[offset + 10];
|
||||
var M_offset_11 = M[offset + 11];
|
||||
var M_offset_12 = M[offset + 12];
|
||||
var M_offset_13 = M[offset + 13];
|
||||
var M_offset_14 = M[offset + 14];
|
||||
var M_offset_15 = M[offset + 15];
|
||||
|
||||
// Working varialbes
|
||||
var a = H[0];
|
||||
var b = H[1];
|
||||
var c = H[2];
|
||||
var d = H[3];
|
||||
|
||||
// Computation
|
||||
a = FF(a, b, c, d, M_offset_0, 7, T[0]);
|
||||
d = FF(d, a, b, c, M_offset_1, 12, T[1]);
|
||||
c = FF(c, d, a, b, M_offset_2, 17, T[2]);
|
||||
b = FF(b, c, d, a, M_offset_3, 22, T[3]);
|
||||
a = FF(a, b, c, d, M_offset_4, 7, T[4]);
|
||||
d = FF(d, a, b, c, M_offset_5, 12, T[5]);
|
||||
c = FF(c, d, a, b, M_offset_6, 17, T[6]);
|
||||
b = FF(b, c, d, a, M_offset_7, 22, T[7]);
|
||||
a = FF(a, b, c, d, M_offset_8, 7, T[8]);
|
||||
d = FF(d, a, b, c, M_offset_9, 12, T[9]);
|
||||
c = FF(c, d, a, b, M_offset_10, 17, T[10]);
|
||||
b = FF(b, c, d, a, M_offset_11, 22, T[11]);
|
||||
a = FF(a, b, c, d, M_offset_12, 7, T[12]);
|
||||
d = FF(d, a, b, c, M_offset_13, 12, T[13]);
|
||||
c = FF(c, d, a, b, M_offset_14, 17, T[14]);
|
||||
b = FF(b, c, d, a, M_offset_15, 22, T[15]);
|
||||
|
||||
a = GG(a, b, c, d, M_offset_1, 5, T[16]);
|
||||
d = GG(d, a, b, c, M_offset_6, 9, T[17]);
|
||||
c = GG(c, d, a, b, M_offset_11, 14, T[18]);
|
||||
b = GG(b, c, d, a, M_offset_0, 20, T[19]);
|
||||
a = GG(a, b, c, d, M_offset_5, 5, T[20]);
|
||||
d = GG(d, a, b, c, M_offset_10, 9, T[21]);
|
||||
c = GG(c, d, a, b, M_offset_15, 14, T[22]);
|
||||
b = GG(b, c, d, a, M_offset_4, 20, T[23]);
|
||||
a = GG(a, b, c, d, M_offset_9, 5, T[24]);
|
||||
d = GG(d, a, b, c, M_offset_14, 9, T[25]);
|
||||
c = GG(c, d, a, b, M_offset_3, 14, T[26]);
|
||||
b = GG(b, c, d, a, M_offset_8, 20, T[27]);
|
||||
a = GG(a, b, c, d, M_offset_13, 5, T[28]);
|
||||
d = GG(d, a, b, c, M_offset_2, 9, T[29]);
|
||||
c = GG(c, d, a, b, M_offset_7, 14, T[30]);
|
||||
b = GG(b, c, d, a, M_offset_12, 20, T[31]);
|
||||
|
||||
a = HH(a, b, c, d, M_offset_5, 4, T[32]);
|
||||
d = HH(d, a, b, c, M_offset_8, 11, T[33]);
|
||||
c = HH(c, d, a, b, M_offset_11, 16, T[34]);
|
||||
b = HH(b, c, d, a, M_offset_14, 23, T[35]);
|
||||
a = HH(a, b, c, d, M_offset_1, 4, T[36]);
|
||||
d = HH(d, a, b, c, M_offset_4, 11, T[37]);
|
||||
c = HH(c, d, a, b, M_offset_7, 16, T[38]);
|
||||
b = HH(b, c, d, a, M_offset_10, 23, T[39]);
|
||||
a = HH(a, b, c, d, M_offset_13, 4, T[40]);
|
||||
d = HH(d, a, b, c, M_offset_0, 11, T[41]);
|
||||
c = HH(c, d, a, b, M_offset_3, 16, T[42]);
|
||||
b = HH(b, c, d, a, M_offset_6, 23, T[43]);
|
||||
a = HH(a, b, c, d, M_offset_9, 4, T[44]);
|
||||
d = HH(d, a, b, c, M_offset_12, 11, T[45]);
|
||||
c = HH(c, d, a, b, M_offset_15, 16, T[46]);
|
||||
b = HH(b, c, d, a, M_offset_2, 23, T[47]);
|
||||
|
||||
a = II(a, b, c, d, M_offset_0, 6, T[48]);
|
||||
d = II(d, a, b, c, M_offset_7, 10, T[49]);
|
||||
c = II(c, d, a, b, M_offset_14, 15, T[50]);
|
||||
b = II(b, c, d, a, M_offset_5, 21, T[51]);
|
||||
a = II(a, b, c, d, M_offset_12, 6, T[52]);
|
||||
d = II(d, a, b, c, M_offset_3, 10, T[53]);
|
||||
c = II(c, d, a, b, M_offset_10, 15, T[54]);
|
||||
b = II(b, c, d, a, M_offset_1, 21, T[55]);
|
||||
a = II(a, b, c, d, M_offset_8, 6, T[56]);
|
||||
d = II(d, a, b, c, M_offset_15, 10, T[57]);
|
||||
c = II(c, d, a, b, M_offset_6, 15, T[58]);
|
||||
b = II(b, c, d, a, M_offset_13, 21, T[59]);
|
||||
a = II(a, b, c, d, M_offset_4, 6, T[60]);
|
||||
d = II(d, a, b, c, M_offset_11, 10, T[61]);
|
||||
c = II(c, d, a, b, M_offset_2, 15, T[62]);
|
||||
b = II(b, c, d, a, M_offset_9, 21, T[63]);
|
||||
|
||||
// Intermediate hash value
|
||||
H[0] = (H[0] + a) | 0;
|
||||
H[1] = (H[1] + b) | 0;
|
||||
H[2] = (H[2] + c) | 0;
|
||||
H[3] = (H[3] + d) | 0;
|
||||
},
|
||||
|
||||
_doFinalize: function () {
|
||||
// Shortcuts
|
||||
var data = this._data;
|
||||
var dataWords = data.words;
|
||||
|
||||
var nBitsTotal = this._nDataBytes * 8;
|
||||
var nBitsLeft = data.sigBytes * 8;
|
||||
|
||||
// Add padding
|
||||
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
|
||||
|
||||
var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
|
||||
var nBitsTotalL = nBitsTotal;
|
||||
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (
|
||||
(((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) |
|
||||
(((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00)
|
||||
);
|
||||
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
|
||||
(((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) |
|
||||
(((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00)
|
||||
);
|
||||
|
||||
data.sigBytes = (dataWords.length + 1) * 4;
|
||||
|
||||
// Hash final blocks
|
||||
this._process();
|
||||
|
||||
// Shortcuts
|
||||
var hash = this._hash;
|
||||
var H = hash.words;
|
||||
|
||||
// Swap endian
|
||||
for (var i = 0; i < 4; i++) {
|
||||
// Shortcut
|
||||
var H_i = H[i];
|
||||
|
||||
H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) |
|
||||
(((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
|
||||
}
|
||||
|
||||
// Return final computed hash
|
||||
return hash;
|
||||
},
|
||||
|
||||
clone: function () {
|
||||
var clone = Hasher.clone.call(this);
|
||||
clone._hash = this._hash.clone();
|
||||
|
||||
return clone;
|
||||
}
|
||||
});
|
||||
|
||||
function FF(a, b, c, d, x, s, t) {
|
||||
var n = a + ((b & c) | (~b & d)) + x + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
}
|
||||
|
||||
function GG(a, b, c, d, x, s, t) {
|
||||
var n = a + ((b & d) | (c & ~d)) + x + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
}
|
||||
|
||||
function HH(a, b, c, d, x, s, t) {
|
||||
var n = a + (b ^ c ^ d) + x + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
}
|
||||
|
||||
function II(a, b, c, d, x, s, t) {
|
||||
var n = a + (c ^ (b | ~d)) + x + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut function to the hasher's object interface.
|
||||
*
|
||||
* @param {WordArray|string} message The message to hash.
|
||||
*
|
||||
* @return {WordArray} The hash.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var hash = CryptoJS.MD5('message');
|
||||
* var hash = CryptoJS.MD5(wordArray);
|
||||
*/
|
||||
C.MD5 = Hasher._createHelper(MD5);
|
||||
|
||||
/**
|
||||
* Shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param {WordArray|string} message The message to hash.
|
||||
* @param {WordArray|string} key The secret key.
|
||||
*
|
||||
* @return {WordArray} The HMAC.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var hmac = CryptoJS.HmacMD5(message, key);
|
||||
*/
|
||||
C.HmacMD5 = Hasher._createHmacHelper(MD5);
|
||||
}(Math));
|
||||
|
||||
|
||||
return CryptoJS.MD5;
|
||||
|
||||
}));
|
||||
@@ -0,0 +1,199 @@
|
||||
;(function (root, factory) {
|
||||
if (typeof exports === "object") {
|
||||
// CommonJS
|
||||
module.exports = exports = factory(require("./core"));
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
// AMD
|
||||
define(["./core"], factory);
|
||||
}
|
||||
else {
|
||||
// Global (browser)
|
||||
factory(root.CryptoJS);
|
||||
}
|
||||
}(this, function (CryptoJS) {
|
||||
|
||||
(function (Math) {
|
||||
// Shortcuts
|
||||
var C = CryptoJS;
|
||||
var C_lib = C.lib;
|
||||
var WordArray = C_lib.WordArray;
|
||||
var Hasher = C_lib.Hasher;
|
||||
var C_algo = C.algo;
|
||||
|
||||
// Initialization and round constants tables
|
||||
var H = [];
|
||||
var K = [];
|
||||
|
||||
// Compute constants
|
||||
(function () {
|
||||
function isPrime(n) {
|
||||
var sqrtN = Math.sqrt(n);
|
||||
for (var factor = 2; factor <= sqrtN; factor++) {
|
||||
if (!(n % factor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getFractionalBits(n) {
|
||||
return ((n - (n | 0)) * 0x100000000) | 0;
|
||||
}
|
||||
|
||||
var n = 2;
|
||||
var nPrime = 0;
|
||||
while (nPrime < 64) {
|
||||
if (isPrime(n)) {
|
||||
if (nPrime < 8) {
|
||||
H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));
|
||||
}
|
||||
K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));
|
||||
|
||||
nPrime++;
|
||||
}
|
||||
|
||||
n++;
|
||||
}
|
||||
}());
|
||||
|
||||
// Reusable object
|
||||
var W = [];
|
||||
|
||||
/**
|
||||
* SHA-256 hash algorithm.
|
||||
*/
|
||||
var SHA256 = C_algo.SHA256 = Hasher.extend({
|
||||
_doReset: function () {
|
||||
this._hash = new WordArray.init(H.slice(0));
|
||||
},
|
||||
|
||||
_doProcessBlock: function (M, offset) {
|
||||
// Shortcut
|
||||
var H = this._hash.words;
|
||||
|
||||
// Working variables
|
||||
var a = H[0];
|
||||
var b = H[1];
|
||||
var c = H[2];
|
||||
var d = H[3];
|
||||
var e = H[4];
|
||||
var f = H[5];
|
||||
var g = H[6];
|
||||
var h = H[7];
|
||||
|
||||
// Computation
|
||||
for (var i = 0; i < 64; i++) {
|
||||
if (i < 16) {
|
||||
W[i] = M[offset + i] | 0;
|
||||
} else {
|
||||
var gamma0x = W[i - 15];
|
||||
var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
|
||||
((gamma0x << 14) | (gamma0x >>> 18)) ^
|
||||
(gamma0x >>> 3);
|
||||
|
||||
var gamma1x = W[i - 2];
|
||||
var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
|
||||
((gamma1x << 13) | (gamma1x >>> 19)) ^
|
||||
(gamma1x >>> 10);
|
||||
|
||||
W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
|
||||
}
|
||||
|
||||
var ch = (e & f) ^ (~e & g);
|
||||
var maj = (a & b) ^ (a & c) ^ (b & c);
|
||||
|
||||
var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));
|
||||
var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25));
|
||||
|
||||
var t1 = h + sigma1 + ch + K[i] + W[i];
|
||||
var t2 = sigma0 + maj;
|
||||
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = (d + t1) | 0;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = (t1 + t2) | 0;
|
||||
}
|
||||
|
||||
// Intermediate hash value
|
||||
H[0] = (H[0] + a) | 0;
|
||||
H[1] = (H[1] + b) | 0;
|
||||
H[2] = (H[2] + c) | 0;
|
||||
H[3] = (H[3] + d) | 0;
|
||||
H[4] = (H[4] + e) | 0;
|
||||
H[5] = (H[5] + f) | 0;
|
||||
H[6] = (H[6] + g) | 0;
|
||||
H[7] = (H[7] + h) | 0;
|
||||
},
|
||||
|
||||
_doFinalize: function () {
|
||||
// Shortcuts
|
||||
var data = this._data;
|
||||
var dataWords = data.words;
|
||||
|
||||
var nBitsTotal = this._nDataBytes * 8;
|
||||
var nBitsLeft = data.sigBytes * 8;
|
||||
|
||||
// Add padding
|
||||
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
|
||||
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
|
||||
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
|
||||
data.sigBytes = dataWords.length * 4;
|
||||
|
||||
// Hash final blocks
|
||||
this._process();
|
||||
|
||||
// Return final computed hash
|
||||
return this._hash;
|
||||
},
|
||||
|
||||
clone: function () {
|
||||
var clone = Hasher.clone.call(this);
|
||||
clone._hash = this._hash.clone();
|
||||
|
||||
return clone;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Shortcut function to the hasher's object interface.
|
||||
*
|
||||
* @param {WordArray|string} message The message to hash.
|
||||
*
|
||||
* @return {WordArray} The hash.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var hash = CryptoJS.SHA256('message');
|
||||
* var hash = CryptoJS.SHA256(wordArray);
|
||||
*/
|
||||
C.SHA256 = Hasher._createHelper(SHA256);
|
||||
|
||||
/**
|
||||
* Shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param {WordArray|string} message The message to hash.
|
||||
* @param {WordArray|string} key The secret key.
|
||||
*
|
||||
* @return {WordArray} The HMAC.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var hmac = CryptoJS.HmacSHA256(message, key);
|
||||
*/
|
||||
C.HmacSHA256 = Hasher._createHmacHelper(SHA256);
|
||||
}(Math));
|
||||
|
||||
|
||||
return CryptoJS.SHA256;
|
||||
|
||||
}));
|
||||
@@ -1004,7 +1004,9 @@ enableEmoji = true
|
||||
[params.pangu]
|
||||
# For Chinese writing
|
||||
# 适用于中文写作用户
|
||||
enable = false
|
||||
enable = true
|
||||
# TODO 为空则全局生效
|
||||
selector = ''
|
||||
|
||||
# Watermark config since v0.2.12
|
||||
# Detail config see https://github.com/Lruihao/watermark#readme
|
||||
|
||||
@@ -129,4 +129,5 @@ Thanks to the authors of following resources included in the theme:
|
||||
* [Waline](https://waline.js.org/)
|
||||
* [Twikoo](https://twikoo.js.org/)
|
||||
* [github-corners](https://github.com/tholman/github-corners)
|
||||
* [giscus](https://giscus.app/)
|
||||
* [giscus](https://giscus.app/)
|
||||
* [crypto-js](https://github.com/brix/crypto-js)
|
||||
|
||||
@@ -130,3 +130,4 @@ FixIt 主题中用到了以下项目,感谢它们的作者:
|
||||
* [Twikoo](https://twikoo.js.org/)
|
||||
* [github-corners](https://github.com/tholman/github-corners)
|
||||
* [giscus](https://giscus.app/zh-CN)
|
||||
* [crypto-js](https://github.com/brix/crypto-js)
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
---
|
||||
title: "Encrypt Test"
|
||||
date: 2022-05-21T22:31:22+08:00
|
||||
description: "Test for encrypting content"
|
||||
type: 'posts'
|
||||
draft: true
|
||||
password: 1212
|
||||
message: Password is 1212
|
||||
|
||||
lightgallery: true
|
||||
|
||||
math:
|
||||
enable: true
|
||||
|
||||
twemoji: true
|
||||
|
||||
tags:
|
||||
- Test
|
||||
- Encryption
|
||||
categories:
|
||||
- Test
|
||||
|
||||
menu:
|
||||
main:
|
||||
title: "Test for encrypting content"
|
||||
parent: "tests"
|
||||
pre: "<i class='fa-solid fa-vial fa-fw fa-sm'></i>"
|
||||
---
|
||||
|
||||
I was shy, so I hid.
|
||||
|
||||
<!--more-->
|
||||
|
||||

|
||||
|
||||
## Encrypted Content
|
||||
|
||||
### twemoji
|
||||
<!-- ### emoji -->
|
||||
|
||||
coffee ☕
|
||||
|
||||
Gone camping! :tent: Be back soon.
|
||||
|
||||
That is so funny! :joy:
|
||||
|
||||
### pangu
|
||||
|
||||
```
|
||||
與PM戰鬥的人,應當小心自己不要成為PM
|
||||
```
|
||||
|
||||
與PM戰鬥的人,應當小心自己不要成為PM
|
||||
|
||||
### ruby
|
||||
[Hugo]^(An open-source static site generator)
|
||||
|
||||
### math
|
||||
$$ \ce{CO2 + C -> 2 CO} $$
|
||||
|
||||
$$ \ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-} $$
|
||||
|
||||
## Shortcodes in Encrypted Content
|
||||
|
||||
### 1 style
|
||||
|
||||
{{< style "text-align:right; strong{color:#00b1ff;}" >}}
|
||||
This is a **right-aligned** paragraph.
|
||||
{{< /style >}}
|
||||
|
||||
### 2 link
|
||||
|
||||
{{< link "https://github.com/upstage/" Upstage "Visit Upstage!" >}}
|
||||
|
||||
{{< link "https://github.com/Lruihao/FixIt" "FixIt Theme" "source of FixIt Theme" true >}}
|
||||
|
||||
{{< link href="/music/Wavelength.mp3" content="Wavelength.mp3" title="Download Wavelength.mp3" download="Wavelength.mp3" >}}
|
||||
|
||||
{{< link href="/music/Wavelength.mp3" content="Wavelength.mp3" title="Download Wavelength.mp3" download="Wavelength.mp3" card=true >}}
|
||||
|
||||
### 3 image
|
||||
|
||||
{{< image src="/images/lighthouse.jpg" caption="Lighthouse (`image`)" src_s="/images/lighthouse-small.jpg" src_l="/images/lighthouse-large.jpg" >}}
|
||||
|
||||
### 4 admonition
|
||||
|
||||
{{< admonition tip "This is a tip" false >}}
|
||||
A **tip** banner
|
||||
{{< /admonition >}}
|
||||
|
||||
### 5 mermaid
|
||||
|
||||
{{< mermaid >}}
|
||||
graph LR;
|
||||
A[Hard edge] -->|Link text| B(Round edge)
|
||||
B --> C{Decision}
|
||||
C -->|One| D[Result one]
|
||||
C -->|Two| E[Result two]
|
||||
{{< /mermaid >}}
|
||||
|
||||
### 6 echarts
|
||||
|
||||
{{< echarts >}}
|
||||
title:
|
||||
text: Summary Line Chart
|
||||
top: 2%
|
||||
left: center
|
||||
tooltip:
|
||||
trigger: axis
|
||||
legend:
|
||||
data:
|
||||
- Email Marketing
|
||||
- Affiliate Advertising
|
||||
- Video Advertising
|
||||
- Direct View
|
||||
- Search Engine
|
||||
top: 10%
|
||||
grid:
|
||||
left: 5%
|
||||
right: 5%
|
||||
bottom: 5%
|
||||
top: 20%
|
||||
containLabel: true
|
||||
toolbox:
|
||||
feature:
|
||||
saveAsImage:
|
||||
title: Save as Image
|
||||
xAxis:
|
||||
type: category
|
||||
boundaryGap: false
|
||||
data:
|
||||
- Monday
|
||||
- Tuesday
|
||||
- Wednesday
|
||||
- Thursday
|
||||
- Friday
|
||||
- Saturday
|
||||
- Sunday
|
||||
yAxis:
|
||||
type: value
|
||||
series:
|
||||
- name: Email Marketing
|
||||
type: line
|
||||
stack: Total
|
||||
data:
|
||||
- 120
|
||||
- 132
|
||||
- 101
|
||||
- 134
|
||||
- 90
|
||||
- 230
|
||||
- 210
|
||||
- name: Affiliate Advertising
|
||||
type: line
|
||||
stack: Total
|
||||
data:
|
||||
- 220
|
||||
- 182
|
||||
- 191
|
||||
- 234
|
||||
- 290
|
||||
- 330
|
||||
- 310
|
||||
- name: Video Advertising
|
||||
type: line
|
||||
stack: Total
|
||||
data:
|
||||
- 150
|
||||
- 232
|
||||
- 201
|
||||
- 154
|
||||
- 190
|
||||
- 330
|
||||
- 410
|
||||
- name: Direct View
|
||||
type: line
|
||||
stack: Total
|
||||
data:
|
||||
- 320
|
||||
- 332
|
||||
- 301
|
||||
- 334
|
||||
- 390
|
||||
- 330
|
||||
- 320
|
||||
- name: Search Engine
|
||||
type: line
|
||||
stack: Total
|
||||
data:
|
||||
- 820
|
||||
- 932
|
||||
- 901
|
||||
- 934
|
||||
- 1290
|
||||
- 1330
|
||||
- 1320
|
||||
{{< /echarts >}}
|
||||
|
||||
### 7 mapbox
|
||||
|
||||
{{< mapbox 113.953277 22.559102 11 >}}
|
||||
|
||||
### 8 music
|
||||
|
||||
{{< music url="/music/Wavelength.mp3" name=Wavelength artist=oldmanyoung cover="/images/Wavelength.jpg" >}}
|
||||
|
||||
### 9 bilibili
|
||||
|
||||
{{< bilibili BV1Sx411T7QQ >}}
|
||||
|
||||
### 10 typeit
|
||||
|
||||
{{< typeit code=javascript >}}
|
||||
console.log('before decrypting');
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
fixit.decryptor.addEventListener('decrypted', function() {
|
||||
console.log('after decrypting')
|
||||
})
|
||||
});
|
||||
{{< /typeit >}}
|
||||
|
||||
### 11 script
|
||||
|
||||
```go-html-template
|
||||
{{</* script */>}}
|
||||
console.log('before decrypting');
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
fixit.theme.decryptor.addEventListener('decrypted', function() {
|
||||
console.log('after decrypting')
|
||||
})
|
||||
});
|
||||
{{</* /script */>}}
|
||||
```
|
||||
|
||||
You can see the output in the console of the developer tool.
|
||||
|
||||
{{< script >}}
|
||||
console.log('before decrypting');
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
fixit.decryptor.addEventListener('decrypted', function() {
|
||||
console.log('after decrypting')
|
||||
})
|
||||
});
|
||||
{{< /script >}}
|
||||
|
||||
### 12 details
|
||||
|
||||
{{< details "**Copyright** 2022." >}}
|
||||
*All pages and graphics on this web site are the property of FixIt.*
|
||||
{{< /details >}}
|
||||
|
||||
### 13 center-quote
|
||||
|
||||
{{% center-quote %}}
|
||||
**hello** *world*
|
||||
this is a center-quote shortcode example.
|
||||
{{% /center-quote %}}
|
||||
@@ -189,6 +189,18 @@ other = "Mehr lesen"
|
||||
|
||||
[expirationReminder]
|
||||
other = "Dieser Artikel wurde zuletzt auf {{ .Date }} aktualisiert, der Inhalt kann veraltet sein."
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[encryptedMessage]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[password]
|
||||
other = "Passwort"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "" # waitting for translation
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -185,6 +185,18 @@ other = "Read More"
|
||||
|
||||
[expirationReminder]
|
||||
other = "This article was last updated on {{ .Date }}, the content may be out of date."
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "This article has been encrypted, so its raw content is invisible!"
|
||||
|
||||
[encryptedMessage]
|
||||
other = "Please enter the password"
|
||||
|
||||
[password]
|
||||
other = "Password"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "Encrypt again"
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -189,6 +189,18 @@ other = "Leer más"
|
||||
|
||||
[expirationReminder]
|
||||
other = "Este artículo se actualizó por última vez el {{ .Date }}, es posible que el contenido no esté actualizado."
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[encryptedMessage]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[password]
|
||||
other = "Contraseña"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "" # waitting for translation
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -186,6 +186,18 @@ other = "Accueil"
|
||||
|
||||
[readMore]
|
||||
other = "En savoir plus"
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[encryptedMessage]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[password]
|
||||
other = "Mot de passe"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "" # waitting for translation
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -189,6 +189,18 @@ other = "Leggi di più"
|
||||
|
||||
[expirationReminder]
|
||||
other = "Questo articolo è stato aggiornato l'ultima volta il {{ .Date }}, il contenuto potrebbe non essere aggiornato."
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[encryptedMessage]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[password]
|
||||
other = "Password"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "" # waitting for translation
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -186,6 +186,18 @@ other = "Czytaj więcej"
|
||||
|
||||
[expirationReminder]
|
||||
other = "Ten artykuł był ostatnio aktualizowany {{ .Date }}, jego treść może być nieaktualna."
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[encryptedMessage]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[password]
|
||||
other = "Hasło"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "" # waitting for translation
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -189,6 +189,18 @@ other = "Leia mais"
|
||||
|
||||
[expirationReminder]
|
||||
other = "Este artigo foi atualizado pela última vez em {{ .Date }}, o conteúdo pode estar desatualizado."
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[encryptedMessage]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[password]
|
||||
other = "Contrasinha"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "" # waitting for translation
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -189,6 +189,18 @@ other = "Citește mai mult"
|
||||
|
||||
[expirationReminder]
|
||||
other = "Acest articol a fost actualizat ultima dată pe {{ .Date }}, conținutul poate fi depășit."
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[encryptedMessage]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[password]
|
||||
other = "Parolă"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "" # waitting for translation
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -189,6 +189,18 @@ other = "Читать больше"
|
||||
|
||||
[expirationReminder]
|
||||
other = "Эта статья последний раз обновлялась {{ .Date }}, содержание может быть устаревшим."
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[encryptedMessage]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[password]
|
||||
other = "арготизм"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "" # waitting for translation
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -186,6 +186,18 @@ other = "Прочитај више"
|
||||
|
||||
[expirationReminder]
|
||||
other = "Овај чланак је последњи пут ажуриран {{ .Date }}, садржај је можда застарео."
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[encryptedMessage]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[password]
|
||||
other = "Паролица"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "" # waitting for translation
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -188,6 +188,18 @@ other = "Đọc thêm"
|
||||
|
||||
[expirationReminder]
|
||||
other = "Bài viết này được cập nhật lần cuối vào {{ .Date }}, nội dung có thể đã lỗi thời."
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[encryptedMessage]
|
||||
other = "" # waitting for translation
|
||||
|
||||
[password]
|
||||
other = "Mật khẩu"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "" # waitting for translation
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -189,6 +189,18 @@ other = "阅读全文"
|
||||
|
||||
[expirationReminder]
|
||||
other = "本文最后更新于 {{ .Date }},文中内容可能已过时。"
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "本文已加密,因此其原始内容不可见!"
|
||||
|
||||
[encryptedMessage]
|
||||
other = "请输入密码"
|
||||
|
||||
[password]
|
||||
other = "密码"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "重新加密"
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -189,6 +189,18 @@ other = "閱讀全文"
|
||||
|
||||
[expirationReminder]
|
||||
other = "本文最後更新於 {{ .Date }},文中內容可能已過時。"
|
||||
|
||||
[encryptedAbstract]
|
||||
other = "本文已加密,囙此其原始內容不可見!"
|
||||
|
||||
[encryptedMessage]
|
||||
other = "請輸入密碼"
|
||||
|
||||
[password]
|
||||
other = "密碼"
|
||||
|
||||
[encryptyAgain]
|
||||
other = "重新加密"
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
|
||||
@@ -12,8 +12,28 @@
|
||||
</div>
|
||||
|
||||
{{- /* Content */ -}}
|
||||
<div class="content" id="content">
|
||||
{{- dict "Content" .Content "Ruby" $params.ruby "Fraction" $params.fraction "Fontawesome" $params.fontawesome | partial "function/content.html" | safeHTML -}}
|
||||
{{- $content := dict "Content" .Content "Ruby" $params.ruby "Fraction" $params.fraction "Fontawesome" $params.fontawesome | partial "function/content.html" | safeHTML -}}
|
||||
{{- if $params.password -}}
|
||||
{{- $saltLen := strings.RuneCount (trim $params.password "") -}}
|
||||
{{- $saltLen = cond (eq (mod $saltLen 2) 0) (add $saltLen 1) $saltLen -}}
|
||||
{{- $base64EncodeContent := $content | base64Encode -}}
|
||||
{{- $content = printf "%v%v%v"
|
||||
(substr $base64EncodeContent 0 $saltLen)
|
||||
(substr (sha256 $params.password) $saltLen)
|
||||
(substr $base64EncodeContent $saltLen)
|
||||
-}}
|
||||
{{- end -}}
|
||||
<div
|
||||
class="content"
|
||||
id="content"
|
||||
{{ with $params.password }}data-password="{{ md5 $params.password }}"{{ end }}
|
||||
{{ with $params.password }}data-content="{{ $content }}"{{ end }}
|
||||
>
|
||||
{{- if not $params.password -}}
|
||||
{{- $content -}}
|
||||
{{- else -}}
|
||||
{{- partial "single/fixit-decryptor.html" . -}}
|
||||
{{- end -}}
|
||||
</div>
|
||||
|
||||
{{- /* Comment */ -}}
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
# {{ .Title }}
|
||||
|
||||
{{ .RawContent }}
|
||||
{{ if $params.password -}}
|
||||
***{{ T "encryptedAbstract" }}***
|
||||
{{- else -}}
|
||||
{{ .RawContent }}
|
||||
{{- end }}
|
||||
|
||||
---
|
||||
|
||||
> {{ T "author"}}: {{ .Site.Author.name }}
|
||||
> {{ .Permalink }}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{{- if .Site.Params.search -}}
|
||||
{{- $index := slice -}}
|
||||
{{- $pages := .Site.RegularPages -}}
|
||||
{{- $pages := where .Site.RegularPages "Params.password" "eq" nil -}}
|
||||
{{- if .Site.Params.page.hiddenFromSearch -}}
|
||||
{{- $pages = where $pages "Params.hiddenfromsearch" false -}}
|
||||
{{- else -}}
|
||||
|
||||
@@ -184,6 +184,19 @@
|
||||
{{- $config = dict "watermark" .Site.Params.watermark | merge $config -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Content Decryption */ -}}
|
||||
{{- if $params.password -}}
|
||||
{{- $cryptoCoreJS := $cdn.cryptoCoreJS | default "lib/crypto-js/core.js" -}}
|
||||
{{- $cryptoEncBase64JS := $cdn.cryptoEncBase64JS | default "lib/crypto-js/enc-base64.js" -}}
|
||||
{{- $cryptoMd5JS := $cdn.cryptoCoreJS | default "lib/crypto-js/md5.js" -}}
|
||||
{{- $cryptoSha256JS := $cdn.cryptoCoreJS | default "lib/crypto-js/sha256.js" -}}
|
||||
{{- dict "Source" $cryptoCoreJS "Minify" true "Fingerprint" $fingerprint "Defer" true | dict "Scratch" .Scratch "Data" | partial "scratch/script.html" -}}
|
||||
{{- dict "Source" $cryptoEncBase64JS "Minify" true "Fingerprint" $fingerprint "Defer" true | dict "Scratch" .Scratch "Data" | partial "scratch/script.html" -}}
|
||||
{{- dict "Source" $cryptoMd5JS "Minify" true "Fingerprint" $fingerprint "Defer" true | dict "Scratch" .Scratch "Data" | partial "scratch/script.html" -}}
|
||||
{{- dict "Source" $cryptoSha256JS "Minify" true "Fingerprint" $fingerprint "Defer" true | dict "Scratch" .Scratch "Data" | partial "scratch/script.html" -}}
|
||||
{{- dict "Source" "js/fixit-decryptor.js" "Minify" hugo.IsProduction "Fingerprint" $fingerprint "Defer" true | dict "Scratch" .Scratch "Data" | partial "scratch/script.html" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- /* 不蒜子 */ -}}
|
||||
{{- if eq .Site.Params.ibruce.enable true -}}
|
||||
{{- $source := "//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" -}}
|
||||
@@ -224,7 +237,7 @@
|
||||
|
||||
{{- /* Custom script */ -}}
|
||||
{{- if eq .Site.Params.customJS.enable true -}}
|
||||
{{- $source = "js/_custom.js" -}}
|
||||
{{- $source := "js/_custom.js" -}}
|
||||
{{- dict "Source" $source "Minify" true "Fingerprint" $fingerprint "Defer" true | dict "Scratch" .Scratch "Data" | partial "scratch/script.html" -}}
|
||||
{{- end -}}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
|
||||
<div class="fixit-decryptor-container">
|
||||
{{- $msg := $params.message | default (T "encryptedMessage") -}}
|
||||
<label for="fixit-decryptor-input" title='{{ T "password" }}'>
|
||||
<input type="password" id="fixit-decryptor-input" class="d-none" placeholder="🔑 {{ $msg }}" />
|
||||
</label>
|
||||
<button class="fixit-encryptor-btn d-none">{{ T "encryptyAgain" }}</button>
|
||||
</div>
|
||||
@@ -17,7 +17,7 @@
|
||||
{{- end -}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="post-info-license">
|
||||
<div class="post-info-license {{ with $params.password }} d-none{{ end }}">
|
||||
{{- with $params.license | string -}}
|
||||
<span>
|
||||
{{- . | safeHTML -}}
|
||||
@@ -25,7 +25,7 @@
|
||||
{{- end -}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="post-info-line">
|
||||
<div class="post-info-line{{ with $params.password }} d-none{{ end }}">
|
||||
<div class="post-info-md">
|
||||
{{- if $params.linktomarkdown -}}
|
||||
{{- with .OutputFormats.Get "markdown" -}}
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
{{- /* Auto TOC */ -}}
|
||||
{{- $tocEmpty := eq .TableOfContents `<nav id="TableOfContents"></nav>` -}}
|
||||
{{- if (ne $toc.enable false) | and (ne $tocEmpty true) -}}
|
||||
<h2 class="toc-title">{{ T "contents" }} <i class="toc-icon fa-solid fa-angle-down fa-fw"></i></h2>
|
||||
<div class="toc-content{{ if eq $toc.auto false }} always-active{{ end }}" id="toc-content-auto"></div>
|
||||
<h2 class="toc-title{{ with $params.password }} d-none{{ end }}">{{ T "contents" }} <i class="toc-icon fa-solid fa-angle-down fa-fw"></i></h2>
|
||||
<div class="toc-content{{ if eq $toc.auto false }} always-active{{ end }}{{ with $params.password }} d-none{{ end }}" id="toc-content-auto"></div>
|
||||
{{- end -}}
|
||||
</aside>
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
|
||||
{{- /* Static TOC */ -}}
|
||||
{{- if (ne $toc.enable false) | and (ne $tocEmpty true) -}}
|
||||
<div class="details toc" id="toc-static" kept="{{ if $toc.keepStatic }}true{{ else }}false{{ end }}">
|
||||
<div class="details toc{{ with $params.password }} d-none{{ end }}" id="toc-static" kept="{{ if $toc.keepStatic }}true{{ else }}false{{ end }}">
|
||||
<div class="details-summary toc-title">
|
||||
<span>{{ T "contents" }}</span>
|
||||
<span><i class="details-icon fa-solid fa-angle-right"></i></span>
|
||||
@@ -129,10 +129,30 @@
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Content */ -}}
|
||||
<div class="content" id="content">
|
||||
{{- /* Expiration Reminder */ -}}
|
||||
{{- partial "single/expiration-reminder.html" . -}}
|
||||
{{- dict "Content" .Content "Ruby" $params.ruby "Fraction" $params.fraction "Fontawesome" $params.fontawesome | partial "function/content.html" | safeHTML -}}
|
||||
{{- $content := dict "Content" .Content "Ruby" $params.ruby "Fraction" $params.fraction "Fontawesome" $params.fontawesome | partial "function/content.html" | safeHTML -}}
|
||||
{{- if $params.password -}}
|
||||
{{- $saltLen := strings.RuneCount (trim $params.password "") -}}
|
||||
{{- $saltLen = cond (eq (mod $saltLen 2) 0) (add $saltLen 1) $saltLen -}}
|
||||
{{- $base64EncodeContent := $content | base64Encode -}}
|
||||
{{- $content = printf "%v%v%v"
|
||||
(substr $base64EncodeContent 0 $saltLen)
|
||||
(substr (sha256 $params.password) $saltLen)
|
||||
(substr $base64EncodeContent $saltLen)
|
||||
-}}
|
||||
{{- end -}}
|
||||
<div
|
||||
class="content"
|
||||
id="content"
|
||||
{{ with $params.password }}data-password="{{ md5 $params.password }}"{{ end }}
|
||||
{{ with $params.password }}data-content="{{ $content }}"{{ end }}
|
||||
>
|
||||
{{- if not $params.password -}}
|
||||
{{- /* Expiration Reminder */ -}}
|
||||
{{- partial "single/expiration-reminder.html" . -}}
|
||||
{{- $content -}}
|
||||
{{- else -}}
|
||||
{{- partial "single/fixit-decryptor.html" . -}}
|
||||
{{- end -}}
|
||||
</div>
|
||||
|
||||
{{- /* Footer */ -}}
|
||||
|
||||
+81
-37
@@ -46,7 +46,9 @@ class Util {
|
||||
}
|
||||
}
|
||||
|
||||
class Theme {
|
||||
class FixIt {
|
||||
#encrypted = typeof FixItDecryptor !== 'undefined';
|
||||
|
||||
constructor() {
|
||||
this.config = window.config;
|
||||
this.data = this.config.data;
|
||||
@@ -497,10 +499,8 @@ class Theme {
|
||||
}
|
||||
/**
|
||||
* init table of contents
|
||||
* @param {Boolean} [onInit=false]
|
||||
* @returns
|
||||
*/
|
||||
initToc(onInit = false) {
|
||||
initToc() {
|
||||
const $tocCore = document.getElementById('TableOfContents');
|
||||
if ($tocCore === null) {
|
||||
return;
|
||||
@@ -560,18 +560,22 @@ class Theme {
|
||||
});
|
||||
this._tocOnScroll();
|
||||
this.scrollEventSet.add(this._tocOnScroll);
|
||||
// only addEventListener once
|
||||
onInit && document.querySelector('#toc-auto>.toc-title').addEventListener('click', () => {
|
||||
const animation = ['animate__faster']
|
||||
const tocHidden = $toc.classList.contains('toc-hidden');
|
||||
animation.push(tocHidden ? 'animate__fadeIn' : 'animate__fadeOut');
|
||||
$tocContentAuto.classList.remove(tocHidden ? 'animate__fadeOut' : 'animate__fadeIn');
|
||||
this.util.animateCSS($tocContentAuto, animation, true);
|
||||
$toc.classList.toggle('toc-hidden');
|
||||
}, false)
|
||||
}
|
||||
}
|
||||
|
||||
initTocListener() {
|
||||
const $toc = document.getElementById('toc-auto');
|
||||
const $tocContentAuto = document.getElementById('toc-content-auto');
|
||||
document.querySelector('#toc-auto>.toc-title')?.addEventListener('click', () => {
|
||||
const animation = ['animate__faster']
|
||||
const tocHidden = $toc.classList.contains('toc-hidden');
|
||||
animation.push(tocHidden ? 'animate__fadeIn' : 'animate__fadeOut');
|
||||
$tocContentAuto.classList.remove(tocHidden ? 'animate__fadeOut' : 'animate__fadeIn');
|
||||
this.util.animateCSS($tocContentAuto, animation, true);
|
||||
$toc.classList.toggle('toc-hidden');
|
||||
}, false)
|
||||
}
|
||||
|
||||
initMath() {
|
||||
if (this.config.math) {
|
||||
renderMathInElement(document.body, this.config.math);
|
||||
@@ -891,9 +895,41 @@ class Theme {
|
||||
}
|
||||
|
||||
initPangu() {
|
||||
// TODO 待优化:只渲染
|
||||
this.config.enablePangu && pangu.autoSpacingPage();
|
||||
}
|
||||
|
||||
initFixItDecryptor() {
|
||||
const $tocNodes = document.querySelectorAll('#toc-auto>.d-none, #toc-static.d-none');
|
||||
this.decryptor = new FixItDecryptor({
|
||||
decrypted: () => {
|
||||
this.initTwemoji();
|
||||
this.initDetails();
|
||||
this.initLightGallery();
|
||||
this.initHighlight();
|
||||
this.initTable();
|
||||
this.initHeaderLink();
|
||||
this.initMath();
|
||||
this.initMermaid();
|
||||
this.initEcharts();
|
||||
this.initTypeit();
|
||||
this.initMapbox();
|
||||
this.util.forEach($tocNodes, ($element) => {
|
||||
$element.classList.remove('d-none');
|
||||
});
|
||||
this.initToc();
|
||||
this.initTocListener();
|
||||
this.initPangu();
|
||||
},
|
||||
reset: () => {
|
||||
this.util.forEach($tocNodes, ($element) => {
|
||||
$element.classList.add('d-none');
|
||||
});
|
||||
}
|
||||
});
|
||||
this.decryptor.init();
|
||||
}
|
||||
|
||||
onScroll() {
|
||||
const $headers = [];
|
||||
if (document.body.getAttribute('header-desktop') === 'auto') $headers.push(document.getElementById('header-desktop'));
|
||||
@@ -952,7 +988,9 @@ class Theme {
|
||||
if (!this._resizeTimeout) {
|
||||
this._resizeTimeout = window.setTimeout(() => {
|
||||
this._resizeTimeout = null;
|
||||
for (let event of this.resizeEventSet) event();
|
||||
for (let event of this.resizeEventSet) {
|
||||
event();
|
||||
}
|
||||
this.initToc();
|
||||
this.initMermaid();
|
||||
this.initSearch();
|
||||
@@ -971,44 +1009,50 @@ class Theme {
|
||||
|
||||
init() {
|
||||
try {
|
||||
if (this.#encrypted) {
|
||||
this.initFixItDecryptor();
|
||||
} else {
|
||||
this.initTwemoji();
|
||||
this.initDetails();
|
||||
this.initLightGallery();
|
||||
this.initHighlight();
|
||||
this.initTable();
|
||||
this.initHeaderLink();
|
||||
this.initMath();
|
||||
this.initMermaid();
|
||||
this.initEcharts();
|
||||
this.initTypeit();
|
||||
this.initMapbox();
|
||||
this.initPangu();
|
||||
}
|
||||
this.initSVGIcon();
|
||||
this.initTwemoji();
|
||||
this.initMenu();
|
||||
this.initSwitchTheme();
|
||||
this.initSearch();
|
||||
this.initDetails();
|
||||
this.initLightGallery();
|
||||
this.initHighlight();
|
||||
this.initTable();
|
||||
this.initHeaderLink();
|
||||
this.initMath();
|
||||
this.initMermaid();
|
||||
this.initEcharts();
|
||||
this.initTypeit();
|
||||
this.initMapbox();
|
||||
this.initCookieconsent();
|
||||
this.initSiteTime();
|
||||
this.initServiceWorker();
|
||||
this.initWatermark();
|
||||
this.initPangu();
|
||||
|
||||
window.setTimeout(() => {
|
||||
this.initComment();
|
||||
if (!this.#encrypted) {
|
||||
this.initToc();
|
||||
this.initTocListener();
|
||||
}
|
||||
this.onScroll();
|
||||
this.onResize();
|
||||
this.onClickMask();
|
||||
}, 100);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
window.setTimeout(() => {
|
||||
this.initComment();
|
||||
this.initToc(true);
|
||||
|
||||
this.onScroll();
|
||||
this.onResize();
|
||||
this.onClickMask();
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
const themeInit = () => {
|
||||
const theme = new Theme();
|
||||
theme.init();
|
||||
window.fixit = new FixIt();
|
||||
window.fixit.init();
|
||||
};
|
||||
|
||||
if (document.readyState !== 'loading') {
|
||||
|
||||
Reference in New Issue
Block a user