初始化
|
|
@ -0,0 +1,5 @@
|
|||
.idea/
|
||||
/.idea/
|
||||
/.env
|
||||
.database/
|
||||
/storage/logs/
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<head><title>404 Not Found</title></head>
|
||||
<body>
|
||||
<center><h1>404 Not Found</h1></center>
|
||||
<hr><center>nginx</center>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
芸众商城使用请看以下链接
|
||||
|
||||
https://bbs.cloudeapi.com/forum.php?mod=viewthread&tid=24201
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
$env=@file_get_contents('.env');
|
||||
|
||||
if (empty($env)) {
|
||||
$env=@file_get_contents('../../.env');
|
||||
}
|
||||
|
||||
$is_yunshop=strpos($env,"APP_Framework");
|
||||
|
||||
$extend = '';
|
||||
$boot_file = __DIR__ . '/../../framework/bootstrap.inc.php';
|
||||
|
||||
if (!$is_yunshop) {
|
||||
include_once $boot_file;
|
||||
} else {
|
||||
$extend = '/../..';
|
||||
}
|
||||
|
||||
include_once __DIR__ . $extend . '/app/laravel.php';
|
||||
|
||||
include_once __DIR__ . $extend . '/app/yunshop.php';
|
||||
|
|
@ -0,0 +1 @@
|
|||
(function(){var b={};var a={};a.PADCHAR="=";a.ALPHA="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";a.makeDOMException=function(){var f,d;try{return new DOMException(DOMException.INVALID_CHARACTER_ERR)}catch(d){var c=new Error("DOM Exception 5");c.code=c.number=5;c.name=c.description="INVALID_CHARACTER_ERR";c.toString=function(){return"Error: "+c.name+": "+c.message};return c}};a.getbyte64=function(e,d){var c=a.ALPHA.indexOf(e.charAt(d));if(c===-1){throw a.makeDOMException()}return c};a.decode=function(f){f=""+f;var j=a.getbyte64;var h,e,g;var d=f.length;if(d===0){return f}if(d%4!==0){throw a.makeDOMException()}h=0;if(f.charAt(d-1)===a.PADCHAR){h=1;if(f.charAt(d-2)===a.PADCHAR){h=2}d-=4}var c=[];for(e=0;e<d;e+=4){g=(j(f,e)<<18)|(j(f,e+1)<<12)|(j(f,e+2)<<6)|j(f,e+3);c.push(String.fromCharCode(g>>16,(g>>8)&255,g&255))}switch(h){case 1:g=(j(f,e)<<18)|(j(f,e+1)<<12)|(j(f,e+2)<<6);c.push(String.fromCharCode(g>>16,(g>>8)&255));break;case 2:g=(j(f,e)<<18)|(j(f,e+1)<<12);c.push(String.fromCharCode(g>>16));break}return c.join("")};a.getbyte=function(e,d){var c=e.charCodeAt(d);if(c>255){throw a.makeDOMException()}return c};a.encode=function(f){if(arguments.length!==1){throw new SyntaxError("Not enough arguments")}var g=a.PADCHAR;var h=a.ALPHA;var k=a.getbyte;var e,j;var c=[];f=""+f;var d=f.length-f.length%3;if(f.length===0){return f}for(e=0;e<d;e+=3){j=(k(f,e)<<16)|(k(f,e+1)<<8)|k(f,e+2);c.push(h.charAt(j>>18));c.push(h.charAt((j>>12)&63));c.push(h.charAt((j>>6)&63));c.push(h.charAt(j&63))}switch(f.length-d){case 1:j=k(f,e)<<16;c.push(h.charAt(j>>18)+h.charAt((j>>12)&63)+g+g);break;case 2:j=(k(f,e)<<16)|(k(f,e+1)<<8);c.push(h.charAt(j>>18)+h.charAt((j>>12)&63)+h.charAt((j>>6)&63)+g);break}return c.join("")};b.pay=function(d){var c=encodeURIComponent(a.encode(d));location.href="./../sgmobile/sz_yi/template/mobile/default/order/pay.htm?goto="+c};b.decode=function(c){return a.decode(decodeURIComponent(c))};window._AP=b})();
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
var YDB = new YDBOBJ();
|
||||
var YDB_isWXApp = true;
|
||||
var YDB_GPSla = 0;
|
||||
var YDB_GPSlo = 0;
|
||||
if (isApp()) {
|
||||
YDB.isWXAppInstalled("installstate");
|
||||
}
|
||||
|
||||
//回调是否安装微信
|
||||
function installstate(state){
|
||||
if(state == 0){
|
||||
YDB_isWXApp = false;
|
||||
}
|
||||
}
|
||||
//云打包APP获取地理位置
|
||||
function DoWithYDBGPS (la,lo){
|
||||
YDB_GPSla = la;
|
||||
YDB_GPSlo = lo;
|
||||
}
|
||||
|
||||
//分享回调
|
||||
function Sharesback(state) {
|
||||
YDB.GoBack();
|
||||
}
|
||||
|
||||
//是否为app打开
|
||||
function isApp(){
|
||||
var ua = window.navigator.userAgent.toLowerCase();
|
||||
if (ua.indexOf('yunzshop') > -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 聚合CPS的登录跳转
|
||||
function callAndroid() {
|
||||
// 由于对象映射,所以调用cps对象等于调用Android映射的对象
|
||||
cps.toLogin();
|
||||
}
|
||||
function callIOS(data) {
|
||||
window.webkit.messageHandlers.toLogin.postMessage(data);
|
||||
}
|
||||
|
||||
// 聚合CPS的退出跳转
|
||||
function toQuitAndroid() {
|
||||
cps.toQuitAndroid();
|
||||
}
|
||||
function toQuitIOS(data) {
|
||||
window.webkit.messageHandlers.toQuitIOS.postMessage(data);
|
||||
}
|
||||
|
||||
// 聚合CPS的分享方法
|
||||
function shareByH5Android(json) {
|
||||
// 由于对象映射,所以调用cps对象等于调用Android映射的对象
|
||||
cps.shareByH5Android(json);
|
||||
}
|
||||
function shareByH5IOS(data) {
|
||||
window.webkit.messageHandlers.shareByH5IOS.postMessage(data);
|
||||
}
|
||||
|
||||
// 聚合CPS的返回上一页的方法
|
||||
function routeBackUrlAndroid() {
|
||||
cps.routeBackUrlAndroid();
|
||||
}
|
||||
function routeBackUrlIOS(data) {
|
||||
window.webkit.messageHandlers.routeBackUrlIOS.postMessage(data);
|
||||
}
|
||||
|
||||
// 聚合CPS调起小程序的方法
|
||||
function miniWXAndroid(json) {
|
||||
cps.miniWXAndroid(json);
|
||||
}
|
||||
function miniWXIOS(data) {
|
||||
window.webkit.messageHandlers.miniWXIOS.postMessage(data);
|
||||
}
|
||||
|
||||
// 聚合CPS原生微信支付
|
||||
function wxPayAndroid(json) {
|
||||
cps.wxPayAndroid(json);
|
||||
}
|
||||
function wxPayIOS(data) {
|
||||
window.webkit.messageHandlers.wxPayIOS.postMessage(data);
|
||||
}
|
||||
|
||||
// 聚合APP 任务中心跳转
|
||||
function toUrlAndroid(json) {
|
||||
cps.toUrlAndroid(json);
|
||||
}
|
||||
function toUrlIOS(data) {
|
||||
window.webkit.messageHandlers.toUrlIOS.postMessage(data);
|
||||
}
|
||||
|
||||
// 聚合APP 原生页面跳转
|
||||
function toAPPUrlAndroid(json) {
|
||||
cps.toAPPUrlAndroid(json);
|
||||
}
|
||||
function toAPPUrlIOS(data) {
|
||||
window.webkit.messageHandlers.toAPPUrlIOS.postMessage(data);
|
||||
}
|
||||
|
||||
// 获取聚合APP的公众号i和域名
|
||||
function getKeyIAndroid() {
|
||||
if(cps.getKeyIAndroid()) {
|
||||
return JSON.parse(cps.getKeyIAndroid()) || {};
|
||||
}else {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
function toGetKeyIIOS(data) {
|
||||
window.webkit.messageHandlers.toGetKeyIIOS.postMessage(data);
|
||||
}
|
||||
|
||||
function getKeyIIOS(data) {
|
||||
var obj = {};
|
||||
// if(data){
|
||||
// obj = JSON.parse(data)
|
||||
// }
|
||||
// console.log(obj['token'],obj.i,obj.domain,"obj")
|
||||
// window.localStorage.setItem('getKeyIIOS',JSON.stringify(obj));
|
||||
var regex = /\{(.+?)\}/g;
|
||||
if(window.navigator.userAgent.match(regex)) {
|
||||
obj = JSON.parse(window.navigator.userAgent.match(regex)[0]);
|
||||
}
|
||||
// console.log(obj,"obj")
|
||||
return obj;
|
||||
}
|
||||
|
||||
// 跳转详情通知APP
|
||||
function toGoodDetailIOS(data) {
|
||||
if(window.webkit && window.webkit.messageHandlers) {
|
||||
window.webkit.messageHandlers.toGoodDetailIOS.postMessage(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 详情返回列表通知APP
|
||||
function toGoodListIOS(data) {
|
||||
var u = window.navigator.userAgent;
|
||||
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); // ios终端
|
||||
var ua = window.navigator.userAgent.toLowerCase();
|
||||
if (ua.indexOf("yz_cps") > -1) {
|
||||
// 是否为cps环境
|
||||
if (isiOS) {
|
||||
if(window.webkit && window.webkit.messageHandlers) {
|
||||
window.webkit.messageHandlers.toGoodListIOS.postMessage(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 商品购买成功通知APP
|
||||
function toGoodBuyIOS(data) {
|
||||
if(window.webkit && window.webkit.messageHandlers) {
|
||||
window.webkit.messageHandlers.toGoodBuyIOS.postMessage(data);
|
||||
}
|
||||
}
|
||||
|
||||
// 商品购买成功通知APP
|
||||
function sharePoster(data) {
|
||||
if(window.webkit && window.webkit.messageHandlers) {
|
||||
window.webkit.messageHandlers.sharePoster.postMessage(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
(function () {
|
||||
// Shortcuts
|
||||
var C = CryptoJS;
|
||||
var C_lib = C.lib;
|
||||
var BlockCipher = C_lib.BlockCipher;
|
||||
var C_algo = C.algo;
|
||||
|
||||
// Lookup tables
|
||||
var SBOX = [];
|
||||
var INV_SBOX = [];
|
||||
var SUB_MIX_0 = [];
|
||||
var SUB_MIX_1 = [];
|
||||
var SUB_MIX_2 = [];
|
||||
var SUB_MIX_3 = [];
|
||||
var INV_SUB_MIX_0 = [];
|
||||
var INV_SUB_MIX_1 = [];
|
||||
var INV_SUB_MIX_2 = [];
|
||||
var INV_SUB_MIX_3 = [];
|
||||
|
||||
// Compute lookup tables
|
||||
(function () {
|
||||
// Compute double table
|
||||
var d = [];
|
||||
for (var i = 0; i < 256; i++) {
|
||||
if (i < 128) {
|
||||
d[i] = i << 1;
|
||||
} else {
|
||||
d[i] = (i << 1) ^ 0x11b;
|
||||
}
|
||||
}
|
||||
|
||||
// Walk GF(2^8)
|
||||
var x = 0;
|
||||
var xi = 0;
|
||||
for (var i = 0; i < 256; i++) {
|
||||
// Compute sbox
|
||||
var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
|
||||
sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
|
||||
SBOX[x] = sx;
|
||||
INV_SBOX[sx] = x;
|
||||
|
||||
// Compute multiplication
|
||||
var x2 = d[x];
|
||||
var x4 = d[x2];
|
||||
var x8 = d[x4];
|
||||
|
||||
// Compute sub bytes, mix columns tables
|
||||
var t = (d[sx] * 0x101) ^ (sx * 0x1010100);
|
||||
SUB_MIX_0[x] = (t << 24) | (t >>> 8);
|
||||
SUB_MIX_1[x] = (t << 16) | (t >>> 16);
|
||||
SUB_MIX_2[x] = (t << 8) | (t >>> 24);
|
||||
SUB_MIX_3[x] = t;
|
||||
|
||||
// Compute inv sub bytes, inv mix columns tables
|
||||
var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
|
||||
INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8);
|
||||
INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16);
|
||||
INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24);
|
||||
INV_SUB_MIX_3[sx] = t;
|
||||
|
||||
// Compute next counter
|
||||
if (!x) {
|
||||
x = xi = 1;
|
||||
} else {
|
||||
x = x2 ^ d[d[d[x8 ^ x2]]];
|
||||
xi ^= d[d[xi]];
|
||||
}
|
||||
}
|
||||
}());
|
||||
|
||||
// Precomputed Rcon lookup
|
||||
var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
|
||||
|
||||
/**
|
||||
* AES block cipher algorithm.
|
||||
*/
|
||||
var AES = C_algo.AES = BlockCipher.extend({
|
||||
_doReset: function () {
|
||||
var t;
|
||||
|
||||
// Skip reset of nRounds has been set before and key did not change
|
||||
if (this._nRounds && this._keyPriorReset === this._key) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Shortcuts
|
||||
var key = this._keyPriorReset = this._key;
|
||||
var keyWords = key.words;
|
||||
var keySize = key.sigBytes / 4;
|
||||
|
||||
// Compute number of rounds
|
||||
var nRounds = this._nRounds = keySize + 6;
|
||||
|
||||
// Compute number of key schedule rows
|
||||
var ksRows = (nRounds + 1) * 4;
|
||||
|
||||
// Compute key schedule
|
||||
var keySchedule = this._keySchedule = [];
|
||||
for (var ksRow = 0; ksRow < ksRows; ksRow++) {
|
||||
if (ksRow < keySize) {
|
||||
keySchedule[ksRow] = keyWords[ksRow];
|
||||
} else {
|
||||
t = keySchedule[ksRow - 1];
|
||||
|
||||
if (!(ksRow % keySize)) {
|
||||
// Rot word
|
||||
t = (t << 8) | (t >>> 24);
|
||||
|
||||
// Sub word
|
||||
t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
|
||||
|
||||
// Mix Rcon
|
||||
t ^= RCON[(ksRow / keySize) | 0] << 24;
|
||||
} else if (keySize > 6 && ksRow % keySize == 4) {
|
||||
// Sub word
|
||||
t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
|
||||
}
|
||||
|
||||
keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute inv key schedule
|
||||
var invKeySchedule = this._invKeySchedule = [];
|
||||
for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) {
|
||||
var ksRow = ksRows - invKsRow;
|
||||
|
||||
if (invKsRow % 4) {
|
||||
var t = keySchedule[ksRow];
|
||||
} else {
|
||||
var t = keySchedule[ksRow - 4];
|
||||
}
|
||||
|
||||
if (invKsRow < 4 || ksRow <= 4) {
|
||||
invKeySchedule[invKsRow] = t;
|
||||
} else {
|
||||
invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^
|
||||
INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
encryptBlock: function (M, offset) {
|
||||
this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);
|
||||
},
|
||||
|
||||
decryptBlock: function (M, offset) {
|
||||
// Swap 2nd and 4th rows
|
||||
var t = M[offset + 1];
|
||||
M[offset + 1] = M[offset + 3];
|
||||
M[offset + 3] = t;
|
||||
|
||||
this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);
|
||||
|
||||
// Inv swap 2nd and 4th rows
|
||||
var t = M[offset + 1];
|
||||
M[offset + 1] = M[offset + 3];
|
||||
M[offset + 3] = t;
|
||||
},
|
||||
|
||||
_doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {
|
||||
// Shortcut
|
||||
var nRounds = this._nRounds;
|
||||
|
||||
// Get input, add round key
|
||||
var s0 = M[offset] ^ keySchedule[0];
|
||||
var s1 = M[offset + 1] ^ keySchedule[1];
|
||||
var s2 = M[offset + 2] ^ keySchedule[2];
|
||||
var s3 = M[offset + 3] ^ keySchedule[3];
|
||||
|
||||
// Key schedule row counter
|
||||
var ksRow = 4;
|
||||
|
||||
// Rounds
|
||||
for (var round = 1; round < nRounds; round++) {
|
||||
// Shift rows, sub bytes, mix columns, add round key
|
||||
var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++];
|
||||
var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++];
|
||||
var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++];
|
||||
var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++];
|
||||
|
||||
// Update state
|
||||
s0 = t0;
|
||||
s1 = t1;
|
||||
s2 = t2;
|
||||
s3 = t3;
|
||||
}
|
||||
|
||||
// Shift rows, sub bytes, add round key
|
||||
var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];
|
||||
var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];
|
||||
var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];
|
||||
var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];
|
||||
|
||||
// Set output
|
||||
M[offset] = t0;
|
||||
M[offset + 1] = t1;
|
||||
M[offset + 2] = t2;
|
||||
M[offset + 3] = t3;
|
||||
},
|
||||
|
||||
keySize: 256/32
|
||||
});
|
||||
|
||||
/**
|
||||
* Shortcut functions to the cipher's object interface.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);
|
||||
* var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg);
|
||||
*/
|
||||
C.AES = BlockCipher._createHelper(AES);
|
||||
}());
|
||||
|
|
@ -0,0 +1,872 @@
|
|||
/**
|
||||
* Cipher core components.
|
||||
*/
|
||||
CryptoJS.lib.Cipher || (function (undefined) {
|
||||
// Shortcuts
|
||||
var C = CryptoJS;
|
||||
var C_lib = C.lib;
|
||||
var Base = C_lib.Base;
|
||||
var WordArray = C_lib.WordArray;
|
||||
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;
|
||||
var C_enc = C.enc;
|
||||
var Utf8 = C_enc.Utf8;
|
||||
var Base64 = C_enc.Base64;
|
||||
var C_algo = C.algo;
|
||||
var EvpKDF = C_algo.EvpKDF;
|
||||
|
||||
/**
|
||||
* Abstract base cipher template.
|
||||
*
|
||||
* @property {number} keySize This cipher's key size. Default: 4 (128 bits)
|
||||
* @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)
|
||||
* @property {number} _ENC_XFORM_MODE A constant representing encryption mode.
|
||||
* @property {number} _DEC_XFORM_MODE A constant representing decryption mode.
|
||||
*/
|
||||
var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({
|
||||
/**
|
||||
* Configuration options.
|
||||
*
|
||||
* @property {WordArray} iv The IV to use for this operation.
|
||||
*/
|
||||
cfg: Base.extend(),
|
||||
|
||||
/**
|
||||
* Creates this cipher in encryption mode.
|
||||
*
|
||||
* @param {WordArray} key The key.
|
||||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||||
*
|
||||
* @return {Cipher} A cipher instance.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });
|
||||
*/
|
||||
createEncryptor: function (key, cfg) {
|
||||
return this.create(this._ENC_XFORM_MODE, key, cfg);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates this cipher in decryption mode.
|
||||
*
|
||||
* @param {WordArray} key The key.
|
||||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||||
*
|
||||
* @return {Cipher} A cipher instance.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });
|
||||
*/
|
||||
createDecryptor: function (key, cfg) {
|
||||
return this.create(this._DEC_XFORM_MODE, key, cfg);
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes a newly created cipher.
|
||||
*
|
||||
* @param {number} xformMode Either the encryption or decryption transormation mode constant.
|
||||
* @param {WordArray} key The key.
|
||||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });
|
||||
*/
|
||||
init: function (xformMode, key, cfg) {
|
||||
// Apply config defaults
|
||||
this.cfg = this.cfg.extend(cfg);
|
||||
|
||||
// Store transform mode and key
|
||||
this._xformMode = xformMode;
|
||||
this._key = key;
|
||||
|
||||
// Set initial values
|
||||
this.reset();
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets this cipher to its initial state.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* cipher.reset();
|
||||
*/
|
||||
reset: function () {
|
||||
// Reset data buffer
|
||||
BufferedBlockAlgorithm.reset.call(this);
|
||||
|
||||
// Perform concrete-cipher logic
|
||||
this._doReset();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds data to be encrypted or decrypted.
|
||||
*
|
||||
* @param {WordArray|string} dataUpdate The data to encrypt or decrypt.
|
||||
*
|
||||
* @return {WordArray} The data after processing.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var encrypted = cipher.process('data');
|
||||
* var encrypted = cipher.process(wordArray);
|
||||
*/
|
||||
process: function (dataUpdate) {
|
||||
// Append
|
||||
this._append(dataUpdate);
|
||||
|
||||
// Process available blocks
|
||||
return this._process();
|
||||
},
|
||||
|
||||
/**
|
||||
* Finalizes the encryption or decryption process.
|
||||
* Note that the finalize operation is effectively a destructive, read-once operation.
|
||||
*
|
||||
* @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.
|
||||
*
|
||||
* @return {WordArray} The data after final processing.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var encrypted = cipher.finalize();
|
||||
* var encrypted = cipher.finalize('data');
|
||||
* var encrypted = cipher.finalize(wordArray);
|
||||
*/
|
||||
finalize: function (dataUpdate) {
|
||||
// Final data update
|
||||
if (dataUpdate) {
|
||||
this._append(dataUpdate);
|
||||
}
|
||||
|
||||
// Perform concrete-cipher logic
|
||||
var finalProcessedData = this._doFinalize();
|
||||
|
||||
return finalProcessedData;
|
||||
},
|
||||
|
||||
keySize: 128/32,
|
||||
|
||||
ivSize: 128/32,
|
||||
|
||||
_ENC_XFORM_MODE: 1,
|
||||
|
||||
_DEC_XFORM_MODE: 2,
|
||||
|
||||
/**
|
||||
* Creates shortcut functions to a cipher's object interface.
|
||||
*
|
||||
* @param {Cipher} cipher The cipher to create a helper for.
|
||||
*
|
||||
* @return {Object} An object with encrypt and decrypt shortcut functions.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);
|
||||
*/
|
||||
_createHelper: (function () {
|
||||
function selectCipherStrategy(key) {
|
||||
if (typeof key == 'string') {
|
||||
return PasswordBasedCipher;
|
||||
} else {
|
||||
return SerializableCipher;
|
||||
}
|
||||
}
|
||||
|
||||
return function (cipher) {
|
||||
return {
|
||||
encrypt: function (message, key, cfg) {
|
||||
return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);
|
||||
},
|
||||
|
||||
decrypt: function (ciphertext, key, cfg) {
|
||||
return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);
|
||||
}
|
||||
};
|
||||
};
|
||||
}())
|
||||
});
|
||||
|
||||
/**
|
||||
* Abstract base stream cipher template.
|
||||
*
|
||||
* @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)
|
||||
*/
|
||||
var StreamCipher = C_lib.StreamCipher = Cipher.extend({
|
||||
_doFinalize: function () {
|
||||
// Process partial blocks
|
||||
var finalProcessedBlocks = this._process(!!'flush');
|
||||
|
||||
return finalProcessedBlocks;
|
||||
},
|
||||
|
||||
blockSize: 1
|
||||
});
|
||||
|
||||
/**
|
||||
* Mode namespace.
|
||||
*/
|
||||
var C_mode = C.mode = {};
|
||||
|
||||
/**
|
||||
* Abstract base block cipher mode template.
|
||||
*/
|
||||
var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({
|
||||
/**
|
||||
* Creates this mode for encryption.
|
||||
*
|
||||
* @param {Cipher} cipher A block cipher instance.
|
||||
* @param {Array} iv The IV words.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);
|
||||
*/
|
||||
createEncryptor: function (cipher, iv) {
|
||||
return this.Encryptor.create(cipher, iv);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates this mode for decryption.
|
||||
*
|
||||
* @param {Cipher} cipher A block cipher instance.
|
||||
* @param {Array} iv The IV words.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);
|
||||
*/
|
||||
createDecryptor: function (cipher, iv) {
|
||||
return this.Decryptor.create(cipher, iv);
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes a newly created mode.
|
||||
*
|
||||
* @param {Cipher} cipher A block cipher instance.
|
||||
* @param {Array} iv The IV words.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);
|
||||
*/
|
||||
init: function (cipher, iv) {
|
||||
this._cipher = cipher;
|
||||
this._iv = iv;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Cipher Block Chaining mode.
|
||||
*/
|
||||
var CBC = C_mode.CBC = (function () {
|
||||
/**
|
||||
* Abstract base CBC mode.
|
||||
*/
|
||||
var CBC = BlockCipherMode.extend();
|
||||
|
||||
/**
|
||||
* CBC encryptor.
|
||||
*/
|
||||
CBC.Encryptor = CBC.extend({
|
||||
/**
|
||||
* Processes the data block at offset.
|
||||
*
|
||||
* @param {Array} words The data words to operate on.
|
||||
* @param {number} offset The offset where the block starts.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* mode.processBlock(data.words, offset);
|
||||
*/
|
||||
processBlock: function (words, offset) {
|
||||
// Shortcuts
|
||||
var cipher = this._cipher;
|
||||
var blockSize = cipher.blockSize;
|
||||
|
||||
// XOR and encrypt
|
||||
xorBlock.call(this, words, offset, blockSize);
|
||||
cipher.encryptBlock(words, offset);
|
||||
|
||||
// Remember this block to use with next block
|
||||
this._prevBlock = words.slice(offset, offset + blockSize);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* CBC decryptor.
|
||||
*/
|
||||
CBC.Decryptor = CBC.extend({
|
||||
/**
|
||||
* Processes the data block at offset.
|
||||
*
|
||||
* @param {Array} words The data words to operate on.
|
||||
* @param {number} offset The offset where the block starts.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* mode.processBlock(data.words, offset);
|
||||
*/
|
||||
processBlock: function (words, offset) {
|
||||
// Shortcuts
|
||||
var cipher = this._cipher;
|
||||
var blockSize = cipher.blockSize;
|
||||
|
||||
// Remember this block to use with next block
|
||||
var thisBlock = words.slice(offset, offset + blockSize);
|
||||
|
||||
// Decrypt and XOR
|
||||
cipher.decryptBlock(words, offset);
|
||||
xorBlock.call(this, words, offset, blockSize);
|
||||
|
||||
// This block becomes the previous block
|
||||
this._prevBlock = thisBlock;
|
||||
}
|
||||
});
|
||||
|
||||
function xorBlock(words, offset, blockSize) {
|
||||
var block;
|
||||
|
||||
// Shortcut
|
||||
var iv = this._iv;
|
||||
|
||||
// Choose mixing block
|
||||
if (iv) {
|
||||
block = iv;
|
||||
|
||||
// Remove IV for subsequent blocks
|
||||
this._iv = undefined;
|
||||
} else {
|
||||
block = this._prevBlock;
|
||||
}
|
||||
|
||||
// XOR blocks
|
||||
for (var i = 0; i < blockSize; i++) {
|
||||
words[offset + i] ^= block[i];
|
||||
}
|
||||
}
|
||||
|
||||
return CBC;
|
||||
}());
|
||||
|
||||
/**
|
||||
* Padding namespace.
|
||||
*/
|
||||
var C_pad = C.pad = {};
|
||||
|
||||
/**
|
||||
* PKCS #5/7 padding strategy.
|
||||
*/
|
||||
var Pkcs7 = C_pad.Pkcs7 = {
|
||||
/**
|
||||
* Pads data using the algorithm defined in PKCS #5/7.
|
||||
*
|
||||
* @param {WordArray} data The data to pad.
|
||||
* @param {number} blockSize The multiple that the data should be padded to.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* CryptoJS.pad.Pkcs7.pad(wordArray, 4);
|
||||
*/
|
||||
pad: function (data, blockSize) {
|
||||
// Shortcut
|
||||
var blockSizeBytes = blockSize * 4;
|
||||
|
||||
// Count padding bytes
|
||||
var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
|
||||
|
||||
// Create padding word
|
||||
var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;
|
||||
|
||||
// Create padding
|
||||
var paddingWords = [];
|
||||
for (var i = 0; i < nPaddingBytes; i += 4) {
|
||||
paddingWords.push(paddingWord);
|
||||
}
|
||||
var padding = WordArray.create(paddingWords, nPaddingBytes);
|
||||
|
||||
// Add padding
|
||||
data.concat(padding);
|
||||
},
|
||||
|
||||
/**
|
||||
* Unpads data that had been padded using the algorithm defined in PKCS #5/7.
|
||||
*
|
||||
* @param {WordArray} data The data to unpad.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* CryptoJS.pad.Pkcs7.unpad(wordArray);
|
||||
*/
|
||||
unpad: function (data) {
|
||||
// Get number of padding bytes from last byte
|
||||
var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
|
||||
|
||||
// Remove padding
|
||||
data.sigBytes -= nPaddingBytes;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract base block cipher template.
|
||||
*
|
||||
* @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)
|
||||
*/
|
||||
var BlockCipher = C_lib.BlockCipher = Cipher.extend({
|
||||
/**
|
||||
* Configuration options.
|
||||
*
|
||||
* @property {Mode} mode The block mode to use. Default: CBC
|
||||
* @property {Padding} padding The padding strategy to use. Default: Pkcs7
|
||||
*/
|
||||
cfg: Cipher.cfg.extend({
|
||||
mode: CBC,
|
||||
padding: Pkcs7
|
||||
}),
|
||||
|
||||
reset: function () {
|
||||
var modeCreator;
|
||||
|
||||
// Reset cipher
|
||||
Cipher.reset.call(this);
|
||||
|
||||
// Shortcuts
|
||||
var cfg = this.cfg;
|
||||
var iv = cfg.iv;
|
||||
var mode = cfg.mode;
|
||||
|
||||
// Reset block mode
|
||||
if (this._xformMode == this._ENC_XFORM_MODE) {
|
||||
modeCreator = mode.createEncryptor;
|
||||
} else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
|
||||
modeCreator = mode.createDecryptor;
|
||||
// Keep at least one block in the buffer for unpadding
|
||||
this._minBufferSize = 1;
|
||||
}
|
||||
|
||||
if (this._mode && this._mode.__creator == modeCreator) {
|
||||
this._mode.init(this, iv && iv.words);
|
||||
} else {
|
||||
this._mode = modeCreator.call(mode, this, iv && iv.words);
|
||||
this._mode.__creator = modeCreator;
|
||||
}
|
||||
},
|
||||
|
||||
_doProcessBlock: function (words, offset) {
|
||||
this._mode.processBlock(words, offset);
|
||||
},
|
||||
|
||||
_doFinalize: function () {
|
||||
var finalProcessedBlocks;
|
||||
|
||||
// Shortcut
|
||||
var padding = this.cfg.padding;
|
||||
|
||||
// Finalize
|
||||
if (this._xformMode == this._ENC_XFORM_MODE) {
|
||||
// Pad data
|
||||
padding.pad(this._data, this.blockSize);
|
||||
|
||||
// Process final blocks
|
||||
finalProcessedBlocks = this._process(!!'flush');
|
||||
} else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
|
||||
// Process final blocks
|
||||
finalProcessedBlocks = this._process(!!'flush');
|
||||
|
||||
// Unpad data
|
||||
padding.unpad(finalProcessedBlocks);
|
||||
}
|
||||
|
||||
return finalProcessedBlocks;
|
||||
},
|
||||
|
||||
blockSize: 128/32
|
||||
});
|
||||
|
||||
/**
|
||||
* A collection of cipher parameters.
|
||||
*
|
||||
* @property {WordArray} ciphertext The raw ciphertext.
|
||||
* @property {WordArray} key The key to this ciphertext.
|
||||
* @property {WordArray} iv The IV used in the ciphering operation.
|
||||
* @property {WordArray} salt The salt used with a key derivation function.
|
||||
* @property {Cipher} algorithm The cipher algorithm.
|
||||
* @property {Mode} mode The block mode used in the ciphering operation.
|
||||
* @property {Padding} padding The padding scheme used in the ciphering operation.
|
||||
* @property {number} blockSize The block size of the cipher.
|
||||
* @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.
|
||||
*/
|
||||
var CipherParams = C_lib.CipherParams = Base.extend({
|
||||
/**
|
||||
* Initializes a newly created cipher params object.
|
||||
*
|
||||
* @param {Object} cipherParams An object with any of the possible cipher parameters.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var cipherParams = CryptoJS.lib.CipherParams.create({
|
||||
* ciphertext: ciphertextWordArray,
|
||||
* key: keyWordArray,
|
||||
* iv: ivWordArray,
|
||||
* salt: saltWordArray,
|
||||
* algorithm: CryptoJS.algo.AES,
|
||||
* mode: CryptoJS.mode.CBC,
|
||||
* padding: CryptoJS.pad.PKCS7,
|
||||
* blockSize: 4,
|
||||
* formatter: CryptoJS.format.OpenSSL
|
||||
* });
|
||||
*/
|
||||
init: function (cipherParams) {
|
||||
this.mixIn(cipherParams);
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts this cipher params object to a string.
|
||||
*
|
||||
* @param {Format} formatter (Optional) The formatting strategy to use.
|
||||
*
|
||||
* @return {string} The stringified cipher params.
|
||||
*
|
||||
* @throws Error If neither the formatter nor the default formatter is set.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var string = cipherParams + '';
|
||||
* var string = cipherParams.toString();
|
||||
* var string = cipherParams.toString(CryptoJS.format.OpenSSL);
|
||||
*/
|
||||
toString: function (formatter) {
|
||||
return (formatter || this.formatter).stringify(this);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Format namespace.
|
||||
*/
|
||||
var C_format = C.format = {};
|
||||
|
||||
/**
|
||||
* OpenSSL formatting strategy.
|
||||
*/
|
||||
var OpenSSLFormatter = C_format.OpenSSL = {
|
||||
/**
|
||||
* Converts a cipher params object to an OpenSSL-compatible string.
|
||||
*
|
||||
* @param {CipherParams} cipherParams The cipher params object.
|
||||
*
|
||||
* @return {string} The OpenSSL-compatible string.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);
|
||||
*/
|
||||
stringify: function (cipherParams) {
|
||||
var wordArray;
|
||||
|
||||
// Shortcuts
|
||||
var ciphertext = cipherParams.ciphertext;
|
||||
var salt = cipherParams.salt;
|
||||
|
||||
// Format
|
||||
if (salt) {
|
||||
wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
|
||||
} else {
|
||||
wordArray = ciphertext;
|
||||
}
|
||||
|
||||
return wordArray.toString(Base64);
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts an OpenSSL-compatible string to a cipher params object.
|
||||
*
|
||||
* @param {string} openSSLStr The OpenSSL-compatible string.
|
||||
*
|
||||
* @return {CipherParams} The cipher params object.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);
|
||||
*/
|
||||
parse: function (openSSLStr) {
|
||||
var salt;
|
||||
|
||||
// Parse base64
|
||||
var ciphertext = Base64.parse(openSSLStr);
|
||||
|
||||
// Shortcut
|
||||
var ciphertextWords = ciphertext.words;
|
||||
|
||||
// Test for salt
|
||||
if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {
|
||||
// Extract salt
|
||||
salt = WordArray.create(ciphertextWords.slice(2, 4));
|
||||
|
||||
// Remove salt from ciphertext
|
||||
ciphertextWords.splice(0, 4);
|
||||
ciphertext.sigBytes -= 16;
|
||||
}
|
||||
|
||||
return CipherParams.create({ ciphertext: ciphertext, salt: salt });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A cipher wrapper that returns ciphertext as a serializable cipher params object.
|
||||
*/
|
||||
var SerializableCipher = C_lib.SerializableCipher = Base.extend({
|
||||
/**
|
||||
* Configuration options.
|
||||
*
|
||||
* @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL
|
||||
*/
|
||||
cfg: Base.extend({
|
||||
format: OpenSSLFormatter
|
||||
}),
|
||||
|
||||
/**
|
||||
* Encrypts a message.
|
||||
*
|
||||
* @param {Cipher} cipher The cipher algorithm to use.
|
||||
* @param {WordArray|string} message The message to encrypt.
|
||||
* @param {WordArray} key The key.
|
||||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||||
*
|
||||
* @return {CipherParams} A cipher params object.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);
|
||||
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });
|
||||
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });
|
||||
*/
|
||||
encrypt: function (cipher, message, key, cfg) {
|
||||
// Apply config defaults
|
||||
cfg = this.cfg.extend(cfg);
|
||||
|
||||
// Encrypt
|
||||
var encryptor = cipher.createEncryptor(key, cfg);
|
||||
var ciphertext = encryptor.finalize(message);
|
||||
|
||||
// Shortcut
|
||||
var cipherCfg = encryptor.cfg;
|
||||
|
||||
// Create and return serializable cipher params
|
||||
return CipherParams.create({
|
||||
ciphertext: ciphertext,
|
||||
key: key,
|
||||
iv: cipherCfg.iv,
|
||||
algorithm: cipher,
|
||||
mode: cipherCfg.mode,
|
||||
padding: cipherCfg.padding,
|
||||
blockSize: cipher.blockSize,
|
||||
formatter: cfg.format
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Decrypts serialized ciphertext.
|
||||
*
|
||||
* @param {Cipher} cipher The cipher algorithm to use.
|
||||
* @param {CipherParams|string} ciphertext The ciphertext to decrypt.
|
||||
* @param {WordArray} key The key.
|
||||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||||
*
|
||||
* @return {WordArray} The plaintext.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });
|
||||
* var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });
|
||||
*/
|
||||
decrypt: function (cipher, ciphertext, key, cfg) {
|
||||
// Apply config defaults
|
||||
cfg = this.cfg.extend(cfg);
|
||||
|
||||
// Convert string to CipherParams
|
||||
ciphertext = this._parse(ciphertext, cfg.format);
|
||||
|
||||
// Decrypt
|
||||
var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);
|
||||
|
||||
return plaintext;
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts serialized ciphertext to CipherParams,
|
||||
* else assumed CipherParams already and returns ciphertext unchanged.
|
||||
*
|
||||
* @param {CipherParams|string} ciphertext The ciphertext.
|
||||
* @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.
|
||||
*
|
||||
* @return {CipherParams} The unserialized ciphertext.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);
|
||||
*/
|
||||
_parse: function (ciphertext, format) {
|
||||
if (typeof ciphertext == 'string') {
|
||||
return format.parse(ciphertext, this);
|
||||
} else {
|
||||
return ciphertext;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Key derivation function namespace.
|
||||
*/
|
||||
var C_kdf = C.kdf = {};
|
||||
|
||||
/**
|
||||
* OpenSSL key derivation function.
|
||||
*/
|
||||
var OpenSSLKdf = C_kdf.OpenSSL = {
|
||||
/**
|
||||
* Derives a key and IV from a password.
|
||||
*
|
||||
* @param {string} password The password to derive from.
|
||||
* @param {number} keySize The size in words of the key to generate.
|
||||
* @param {number} ivSize The size in words of the IV to generate.
|
||||
* @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.
|
||||
*
|
||||
* @return {CipherParams} A cipher params object with the key, IV, and salt.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);
|
||||
* var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');
|
||||
*/
|
||||
execute: function (password, keySize, ivSize, salt) {
|
||||
// Generate random salt
|
||||
if (!salt) {
|
||||
salt = WordArray.random(64/8);
|
||||
}
|
||||
|
||||
// Derive key and IV
|
||||
var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
|
||||
|
||||
// Separate key and IV
|
||||
var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);
|
||||
key.sigBytes = keySize * 4;
|
||||
|
||||
// Return params
|
||||
return CipherParams.create({ key: key, iv: iv, salt: salt });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A serializable cipher wrapper that derives the key from a password,
|
||||
* and returns ciphertext as a serializable cipher params object.
|
||||
*/
|
||||
var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({
|
||||
/**
|
||||
* Configuration options.
|
||||
*
|
||||
* @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL
|
||||
*/
|
||||
cfg: SerializableCipher.cfg.extend({
|
||||
kdf: OpenSSLKdf
|
||||
}),
|
||||
|
||||
/**
|
||||
* Encrypts a message using a password.
|
||||
*
|
||||
* @param {Cipher} cipher The cipher algorithm to use.
|
||||
* @param {WordArray|string} message The message to encrypt.
|
||||
* @param {string} password The password.
|
||||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||||
*
|
||||
* @return {CipherParams} A cipher params object.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');
|
||||
* var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });
|
||||
*/
|
||||
encrypt: function (cipher, message, password, cfg) {
|
||||
// Apply config defaults
|
||||
cfg = this.cfg.extend(cfg);
|
||||
|
||||
// Derive key and other params
|
||||
var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);
|
||||
|
||||
// Add IV to config
|
||||
cfg.iv = derivedParams.iv;
|
||||
|
||||
// Encrypt
|
||||
var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);
|
||||
|
||||
// Mix in derived params
|
||||
ciphertext.mixIn(derivedParams);
|
||||
|
||||
return ciphertext;
|
||||
},
|
||||
|
||||
/**
|
||||
* Decrypts serialized ciphertext using a password.
|
||||
*
|
||||
* @param {Cipher} cipher The cipher algorithm to use.
|
||||
* @param {CipherParams|string} ciphertext The ciphertext to decrypt.
|
||||
* @param {string} password The password.
|
||||
* @param {Object} cfg (Optional) The configuration options to use for this operation.
|
||||
*
|
||||
* @return {WordArray} The plaintext.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });
|
||||
* var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });
|
||||
*/
|
||||
decrypt: function (cipher, ciphertext, password, cfg) {
|
||||
// Apply config defaults
|
||||
cfg = this.cfg.extend(cfg);
|
||||
|
||||
// Convert string to CipherParams
|
||||
ciphertext = this._parse(ciphertext, cfg.format);
|
||||
|
||||
// Derive key and other params
|
||||
var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);
|
||||
|
||||
// Add IV to config
|
||||
cfg.iv = derivedParams.iv;
|
||||
|
||||
// Decrypt
|
||||
var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
});
|
||||
}());
|
||||
|
|
@ -0,0 +1,777 @@
|
|||
/*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 (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 i = 0; i < thatSigBytes; i += 4) {
|
||||
thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 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));
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
(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);
|
||||
}
|
||||
}());
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const DEFAULT_LANG = 'zh'
|
||||
const LOCALE_KEY = 'localeLanguage'
|
||||
|
||||
const locales = {
|
||||
zh: require('./zh.json'),
|
||||
en: require('./en.json'),
|
||||
}
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: DEFAULT_LANG,
|
||||
messages: locales,
|
||||
})
|
||||
|
||||
|
||||
export const setup = lang => {
|
||||
if (lang === undefined) {
|
||||
lang = window.localStorage.getItem(LOCALE_KEY)
|
||||
if (locales[lang] === undefined) {
|
||||
lang = DEFAULT_LANG
|
||||
}
|
||||
}
|
||||
window.localStorage.setItem(LOCALE_KEY, lang)
|
||||
|
||||
Object.keys(locales).forEach(lang => {
|
||||
document.body.classList.remove(`lang-${lang}`)
|
||||
})
|
||||
document.body.classList.add(`lang-${lang}`)
|
||||
document.body.setAttribute('lang', lang)
|
||||
|
||||
Vue.config.lang = lang
|
||||
i18n.locale = lang
|
||||
}
|
||||
|
||||
setup("en")
|
||||
window.$i18n = i18n;
|
||||
export default i18n
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
{
|
||||
"en":{
|
||||
"home": {
|
||||
"输入关键词搜索": "输入关键词搜索",
|
||||
"品牌优选": "品牌优选",
|
||||
"限时优惠": "限时优惠",
|
||||
"用最低价格买好物": "用最低价格买好物",
|
||||
"限时价": "限时价",
|
||||
"人气推荐": "人气推荐",
|
||||
"精选最适合您的商品": "精选最适合您的商品",
|
||||
"推荐商品": "推荐商品",
|
||||
"选择区域": "选择区域",
|
||||
"当前区域": "当前区域",
|
||||
"已开放城市": "已开放城市",
|
||||
"选择城市": "选择城市"
|
||||
},
|
||||
"category": {
|
||||
"搜索商品": "搜索商品",
|
||||
"未检测到子分类数据": "未检测到子分类数据",
|
||||
"选择分类": "选择分类",
|
||||
"三级分类": "三级分类",
|
||||
"暂无其他分类": "暂无其他分类",
|
||||
"已售": "已售",
|
||||
"选规格": "选规格",
|
||||
"去租赁": "去租赁",
|
||||
"推荐品牌": "推荐品牌",
|
||||
"推荐分类": "推荐分类",
|
||||
"加入购物车": "加入购物车"
|
||||
},
|
||||
"extension": {
|
||||
"会员": "会员",
|
||||
"分享": "分享",
|
||||
"累计": "累计",
|
||||
"可": "可",
|
||||
"去": "去",
|
||||
"日自动": "日自动",
|
||||
"领取收益": "领取收益",
|
||||
"明细": "明细",
|
||||
"营业额": "营业额",
|
||||
"权限": "权限",
|
||||
"更多权限": "更多权限"
|
||||
},
|
||||
"cart": {
|
||||
"购物车": "购物车",
|
||||
"编辑": "编辑",
|
||||
"完成": "完成",
|
||||
"租赁": "租赁",
|
||||
"购买": "购买",
|
||||
"吊牌价": "吊牌价",
|
||||
"近期热租": "近期热租",
|
||||
"看看其他宝宝都再想什么": "看看其他宝宝都再想什么",
|
||||
"不含运费": "不含运费",
|
||||
"天起": "天起",
|
||||
"合计": "合计",
|
||||
"结算": "结算",
|
||||
"删除": "删除",
|
||||
"购物车快饿瘪了": "购物车快饿瘪了",
|
||||
"主人快去给我找点东西吧": "主人快去给我找点东西吧",
|
||||
"个人中心": "个人中心",
|
||||
"去逛逛": "去逛逛"
|
||||
},
|
||||
"member": {
|
||||
"退出登录": "退出登录",
|
||||
"邀请码": "邀请码",
|
||||
"复制": "复制",
|
||||
"订单": "订单",
|
||||
"我的订单": "我的订单",
|
||||
"待付款": "待付款",
|
||||
"待发货": "待发货",
|
||||
"待收货": "待收货",
|
||||
"售后列表": "售后列表",
|
||||
"待确认": "待确认",
|
||||
"待入住": "待入住",
|
||||
"待退房": "待退房",
|
||||
"拼团订单": "拼团订单",
|
||||
"网约车订单": "网约车订单",
|
||||
"待审核": "待审核",
|
||||
"待贷款": "待贷款",
|
||||
"待提车": "待提车",
|
||||
"租赁订单": "租赁订单",
|
||||
"待支付": "待支付",
|
||||
"待归还": "待归还",
|
||||
"实用工具": "实用工具",
|
||||
"收藏": "收藏",
|
||||
"足迹": "足迹",
|
||||
"地址管理": "地址管理",
|
||||
"设置": "设置",
|
||||
"消息通知": "消息通知",
|
||||
"商家管理": "商家管理",
|
||||
"营销互动": "营销互动",
|
||||
"二维码": "二维码",
|
||||
"评论": "评论",
|
||||
"客户": "客户",
|
||||
"优惠券": "优惠券",
|
||||
"资产权益": "资产权益",
|
||||
"聚合cps": "聚合cps",
|
||||
"二维码生成中": "二维码生成中 请稍候查看"
|
||||
},
|
||||
"我的推广": "我的推广",
|
||||
"预估收益": "预估收益",
|
||||
"天": "天",
|
||||
"搜索": "搜索",
|
||||
"加载更多": "加载更多",
|
||||
"没有更多了": "没有更多了",
|
||||
"money": "¥",
|
||||
"元": "元",
|
||||
"全选": "全选",
|
||||
"下架": "下架",
|
||||
"售罄": "售罄",
|
||||
"已下架": "已下架",
|
||||
"不存在": "不存在",
|
||||
"失效": "失效"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
{
|
||||
"home": {
|
||||
"输入关键词搜索": "输入关键词搜索",
|
||||
"品牌优选": "品牌优选",
|
||||
"限时优惠": "限时优惠",
|
||||
"用最低价格买好物": "用最低价格买好物",
|
||||
"限时价": "限时价",
|
||||
"人气推荐": "人气推荐",
|
||||
"精选最适合您的商品": "精选最适合您的商品",
|
||||
"推荐商品": "推荐商品",
|
||||
"选择区域": "选择区域",
|
||||
"当前区域": "当前区域",
|
||||
"已开放城市": "已开放城市",
|
||||
"选择城市": "选择城市"
|
||||
},
|
||||
"category": {
|
||||
"搜索商品": "搜索商品",
|
||||
"未检测到子分类数据": "未检测到子分类数据",
|
||||
"选择分类": "选择分类",
|
||||
"三级分类": "三级分类",
|
||||
"暂无其他分类": "暂无其他分类",
|
||||
"已售": "已售",
|
||||
"选规格": "选规格",
|
||||
"去租赁": "去租赁",
|
||||
"推荐品牌": "推荐品牌",
|
||||
"推荐分类": "推荐分类",
|
||||
"加入购物车": "加入购物车"
|
||||
},
|
||||
"extension": {
|
||||
"会员": "会员",
|
||||
"分享": "分享",
|
||||
"累计": "累计",
|
||||
"可": "可",
|
||||
"去": "去",
|
||||
"日自动": "日自动",
|
||||
"领取收益": "领取收益",
|
||||
"明细": "明细",
|
||||
"营业额": "营业额",
|
||||
"权限": "权限",
|
||||
"更多权限": "更多权限"
|
||||
},
|
||||
"cart": {
|
||||
"购物车": "购物车",
|
||||
"编辑": "编辑",
|
||||
"完成": "完成",
|
||||
"租赁": "租赁",
|
||||
"购买": "购买",
|
||||
"吊牌价": "吊牌价",
|
||||
"近期热租": "近期热租",
|
||||
"看看其他宝宝都再想什么": "看看其他宝宝都再想什么",
|
||||
"不含运费": "不含运费",
|
||||
"天起": "天起",
|
||||
"合计": "合计",
|
||||
"结算": "结算",
|
||||
"删除": "删除",
|
||||
"购物车快饿瘪了": "购物车快饿瘪了",
|
||||
"主人快去给我找点东西吧": "主人快去给我找点东西吧",
|
||||
"个人中心": "个人中心",
|
||||
"去逛逛": "去逛逛"
|
||||
},
|
||||
"member": {
|
||||
"退出登录": "退出登录",
|
||||
"邀请码": "邀请码",
|
||||
"复制": "复制",
|
||||
"订单": "订单",
|
||||
"我的订单": "我的订单",
|
||||
"待付款": "待付款",
|
||||
"待发货": "待发货",
|
||||
"待收货": "待收货",
|
||||
"售后列表": "售后列表",
|
||||
"待确认": "待确认",
|
||||
"待入住": "待入住",
|
||||
"待退房": "待退房",
|
||||
"拼团订单": "拼团订单",
|
||||
"网约车订单": "网约车订单",
|
||||
"待审核": "待审核",
|
||||
"待贷款": "待贷款",
|
||||
"待提车": "待提车",
|
||||
"租赁订单": "租赁订单",
|
||||
"待支付": "待支付",
|
||||
"待归还": "待归还",
|
||||
"实用工具": "实用工具",
|
||||
"收藏": "收藏",
|
||||
"足迹": "足迹",
|
||||
"地址管理": "地址管理",
|
||||
"设置": "设置",
|
||||
"消息通知": "消息通知",
|
||||
"商家管理": "商家管理",
|
||||
"营销互动": "营销互动",
|
||||
"二维码": "二维码",
|
||||
"评论": "评论",
|
||||
"客户": "客户",
|
||||
"优惠券": "优惠券",
|
||||
"资产权益": "资产权益",
|
||||
"聚合cps": "聚合cps",
|
||||
"二维码生成中": "二维码生成中 请稍候查看"
|
||||
},
|
||||
"我的推广": "我的推广",
|
||||
"预估收益": "预估收益",
|
||||
"天": "天",
|
||||
"搜索": "搜索",
|
||||
"加载更多": "加载更多",
|
||||
"没有更多了": "没有更多了",
|
||||
"money": "{{$i18n.t('money')}}",
|
||||
"元": "元",
|
||||
"全选": "全选",
|
||||
"天起": "天起"
|
||||
}
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
(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));
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
(function(){var each=function(ary,cb){var key=0;if(ary&&ary.length){while(ary[key]){if(false===cb.call(ary[key],ary[key],key)){return;}
|
||||
key+=1;}}},gW=function(a){var b='width',c,d,e;if(document.defaultView&&document.defaultView.getComputedStyle){b=b.replace(/([A-Z]|^ms)/g,"-$1").toLowerCase();if((d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))){c=e.getPropertyValue(b)}
|
||||
return c}else if(document.documentElement.currentStyle){d=a.currentStyle&&a.currentStyle[b];e=a.style;if(d===null&&e&&(c=e[b])){d=c}
|
||||
return d}};setTimeout(function(){each(document.getElementsByTagName('iframe'),function(ifm){var ifmSrc=(ifm.src||'').toLowerCase();if(ifmSrc.indexOf('play.video.qcloud.com')<0&&ifmSrc.indexOf('playvideo.qcloud.com')<0){return;}
|
||||
var search=ifm.src,map={};each((search.split('?')[1]||'').split('&'),function(str){var sp=str.split('=');map[sp[0]]=sp[1];});if(!!map['$fileid']){var tw=(gW(ifm)+'').toLowerCase().replace('px','')-0;if(tw>1){if(tw>map['$sw']){tw=map['$sw']-0;}
|
||||
var pureGH=tw*(map['$sh']/map['$sw']);ifm.height=pureGH>190?(pureGH|0):190;}}});},300);})();/* |xGv00|a0b12c29b3a13431306c9a14bac6af98 */
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/**
|
||||
* @ProjectName flutter-hearts-zmt
|
||||
* @Version 0.0.0
|
||||
* @Author Jiangshilong(https://github.com/JSL8023)
|
||||
* @Update 2018-03-22 17:24 pm
|
||||
*/
|
||||
! function(t, e) {
|
||||
"object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : t.BubbleHearts = e()
|
||||
}(this, function() {
|
||||
"use strict";
|
||||
|
||||
function t(t, n, r) {
|
||||
var i = e.uniformDiscrete(89, 91) / 100,
|
||||
o = 1 - i,
|
||||
u = (e.uniformDiscrete(45, 60) + e.uniformDiscrete(45, 60)) / 100,
|
||||
a = function(t) {
|
||||
return t > i ? Math.max(((1 - t) / o).toFixed(2), .1) * u : u
|
||||
},
|
||||
c = e.uniformDiscrete(-30, 30),
|
||||
f = function(t) {
|
||||
return c
|
||||
},
|
||||
h = 10,
|
||||
s = n.width / 2 + e.uniformDiscrete(-h, h),
|
||||
d = (n.width - Math.sqrt(Math.pow(t.width, 2) + Math.pow(t.height, 2))) / 2 - h,
|
||||
l = e.uniformDiscrete(.8 * d, d) * (e.uniformDiscrete(0, 1) ? 1 : -1),
|
||||
m = e.uniformDiscrete(250, 400),
|
||||
w = function(t) {
|
||||
return t > i ? s : s + l * Math.sin(m * (i - t) * Math.PI / 180)
|
||||
},
|
||||
v = function(e) {
|
||||
return t.height / 2 + (n.height - t.height / 2) * e
|
||||
},
|
||||
p = e.uniformDiscrete(14, 18) / 100,
|
||||
g = function(t) {
|
||||
return t > p ? 1 : 1 - ((p - t) / p).toFixed(2)
|
||||
};
|
||||
return function(e) {
|
||||
if(!(e >= 0)) return !0;
|
||||
r.save();
|
||||
var n = a(e),
|
||||
i = f(e),
|
||||
o = w(e),
|
||||
u = v(e);
|
||||
r.translate(o, u), r.scale(n, n), r.rotate(i * Math.PI / 180), r.globalAlpha = g(e), r.drawImage(t, -t.width / 2, -t.height / 2, 30, 30), r.restore()
|
||||
}
|
||||
}
|
||||
var e = function(t) {
|
||||
var e = t,
|
||||
n = Math.floor,
|
||||
r = Math.random;
|
||||
return t.uniform = function(t, e) {
|
||||
return t + (e - t) * r()
|
||||
}, t.uniformDiscrete = function(t, r) {
|
||||
return t + n((r - t + 1) * e.uniform(0, 1))
|
||||
}, t
|
||||
}({}),
|
||||
n = function(t, e) {
|
||||
if(!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
|
||||
},
|
||||
r = function() {
|
||||
function t(t, e) {
|
||||
for(var n = 0; n < e.length; n++) {
|
||||
var r = e[n];
|
||||
r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(t, r.key, r)
|
||||
}
|
||||
}
|
||||
return function(e, n, r) {
|
||||
return n && t(e.prototype, n), r && t(e, r), e
|
||||
}
|
||||
}(),
|
||||
i = window.requestAnimationFrame || window.webkitRequestAnimationFrame || function(t) {
|
||||
return setTimeout(t, 16)
|
||||
},
|
||||
o = function() {
|
||||
function o() {
|
||||
n(this, o);
|
||||
var t = this.canvas = document.getElementById('likeId'),
|
||||
e = this.context = t.getContext("2d"),
|
||||
r = this._children = [],
|
||||
u = function n() {
|
||||
i(n), e.clearRect(0, 0, t.width, t.height);
|
||||
for(var o = 0, u = r.length; o < u;) {
|
||||
var a = r[o];
|
||||
a.render.call(null, (a.timestamp + a.duration - new Date) / a.duration) ? (r.splice(o, 1), u--) : o++
|
||||
}
|
||||
};
|
||||
i(u)
|
||||
}
|
||||
return r(o, [{
|
||||
key: "bubble",
|
||||
value: function(n) {
|
||||
var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : e.uniformDiscrete(2400, 3600),
|
||||
i = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : t(n, this.canvas, this.context);
|
||||
return this._children.push({
|
||||
render: i,
|
||||
duration: r,
|
||||
timestamp: +new Date
|
||||
}), this
|
||||
}
|
||||
}]), o
|
||||
}();
|
||||
return o
|
||||
});
|
||||
// 图片地址在此处更换 可换成你的图片
|
||||
var bg = document.getElementById('canvasImg');
|
||||
console.log("sssssssssssssssssssss",bg)
|
||||
var assets = [
|
||||
bg.src
|
||||
];
|
||||
assets.forEach(function(src, index) {
|
||||
assets[index] = new Promise(function(resolve) {
|
||||
var img = new Image();
|
||||
img.onload = resolve.bind(null, img);
|
||||
img.src = src;
|
||||
});
|
||||
});
|
||||
|
||||
Promise.all(assets).then(function(images) {
|
||||
var random = {
|
||||
uniform: function(min, max) {
|
||||
return min + (max - min) * Math.random();
|
||||
},
|
||||
uniformDiscrete: function(i, j) {
|
||||
return i + Math.floor((j - i + 1) * random.uniform(0, 1));
|
||||
},
|
||||
};
|
||||
var stage = new BubbleHearts();
|
||||
var canvas = stage.canvas;
|
||||
// canvas.width = 170;
|
||||
// canvas.height = 300;
|
||||
// canvas.style['width'] = '170px';
|
||||
// canvas.style['height'] = '300px';
|
||||
// document.body.appendChild(canvas);
|
||||
//journal-reward 为触发的按钮
|
||||
document.getElementsByClassName('journal-reward')[0].addEventListener('click', function() {
|
||||
//随机飘动
|
||||
stage.bubble(images[random.uniformDiscrete(0, images.length - 1)]);
|
||||
|
||||
//垂直向上飘动效果
|
||||
// let image = images[random.uniformDiscrete(0, images.length - 1)];
|
||||
// stage.bubble(image, 3000, function(lifespan) {
|
||||
// if(lifespan >= 0) {
|
||||
// stage.context.drawImage(
|
||||
// image,
|
||||
// (canvas.width - image.width) / 2,
|
||||
// (canvas.height - image.height) * lifespan,
|
||||
// image.width,
|
||||
// image.height
|
||||
// );
|
||||
// } else {
|
||||
// return true;
|
||||
// }
|
||||
// });
|
||||
}, false);
|
||||
|
||||
}).catch((error) => {
|
||||
console.log('失败 了 ')
|
||||
});
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 271 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
|
@ -0,0 +1,146 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>
|
||||
Created by FontForge 20120731 at Tue Sep 6 12:16:07 2016
|
||||
By admin
|
||||
</metadata>
|
||||
<defs>
|
||||
<font id="el-icon" horiz-adv-x="1024" >
|
||||
<font-face
|
||||
font-family="el-icon"
|
||||
font-weight="500"
|
||||
font-stretch="normal"
|
||||
units-per-em="1024"
|
||||
panose-1="2 0 6 3 0 0 0 0 0 0"
|
||||
ascent="896"
|
||||
descent="-128"
|
||||
x-height="792"
|
||||
bbox="-0.0862045 -128.321 1326 896.053"
|
||||
underline-thickness="50"
|
||||
underline-position="-100"
|
||||
unicode-range="U+0078-E627"
|
||||
/>
|
||||
<missing-glyph horiz-adv-x="374"
|
||||
d="M34 0v682h272v-682h-272zM68 34h204v614h-204v-614z" />
|
||||
<glyph glyph-name=".notdef" horiz-adv-x="374"
|
||||
d="M34 0v682h272v-682h-272zM68 34h204v614h-204v-614z" />
|
||||
<glyph glyph-name=".null" horiz-adv-x="0"
|
||||
/>
|
||||
<glyph glyph-name="nonmarkingreturn" horiz-adv-x="341"
|
||||
/>
|
||||
<glyph glyph-name="x" unicode="x" horiz-adv-x="1001"
|
||||
d="M281 543q-27 -1 -53 -1h-83q-18 0 -36.5 -6t-32.5 -18.5t-23 -32t-9 -45.5v-76h912v41q0 16 -0.5 30t-0.5 18q0 13 -5 29t-17 29.5t-31.5 22.5t-49.5 9h-133v-97h-438v97zM955 310v-52q0 -23 0.5 -52t0.5 -58t-10.5 -47.5t-26 -30t-33 -16t-31.5 -4.5q-14 -1 -29.5 -0.5
|
||||
t-29.5 0.5h-32l-45 128h-439l-44 -128h-29h-34q-20 0 -45 1q-25 0 -41 9.5t-25.5 23t-13.5 29.5t-4 30v167h911zM163 247q-12 0 -21 -8.5t-9 -21.5t9 -21.5t21 -8.5q13 0 22 8.5t9 21.5t-9 21.5t-22 8.5zM316 123q-8 -26 -14 -48q-5 -19 -10.5 -37t-7.5 -25t-3 -15t1 -14.5
|
||||
t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-5 19 -11 39h-368zM336 498v228q0 11 2.5 23t10 21.5t20.5 15.5t34 6h188q31 0 51.5 -14.5t20.5 -52.5v-227h-327z" />
|
||||
<glyph glyph-name="uniE600" unicode=""
|
||||
d="M488 134q18 -8 39 -5t35 16l445 403q18 16 17 38.5t-20 38.5t-45.5 15t-44.5 -17l-399 -362l-405 360q-19 17 -45 17.5t-45 -15.5q-20 -16 -20 -40q0 -22 18 -38l449 -399h1l2 -2t2 -1q2 -2 12 -7l2 -2h2z" />
|
||||
<glyph glyph-name="uniE601" unicode=""
|
||||
d="M262 360q-8 18 -5 39t16 35l403 445q16 18 38.5 17t38.5 -20t15 -45.5t-17 -44.5l-362 -399l360 -405q17 -19 17.5 -45t-15.5 -45q-16 -20 -40 -20q-22 0 -38 18l-399 449v1l-2 2t-1 2q-2 2 -7 12l-2 2v2z" />
|
||||
<glyph glyph-name="uniE602" unicode=""
|
||||
d="M762 360q8 18 5 39t-16 35l-403 445q-16 18 -38.5 17t-38.5 -20t-15 -45.5t17 -44.5l362 -399l-360 -405q-17 -19 -17.5 -45t15.5 -45q16 -20 40 -20q22 0 38 18l399 449v1l2 2t1 2q2 2 7 12l2 2v2z" />
|
||||
<glyph glyph-name="uniE603" unicode=""
|
||||
d="M536 634q-18 8 -39 5t-35 -16l-445 -403q-18 -16 -17 -38.5t20 -38.5t45.5 -15t44.5 17l399 362l405 -360q19 -17 45 -17.5t45 15.5q20 16 20 40q0 22 -18 38l-449 399h-1l-2 2t-2 1q-2 2 -12 7l-2 2h-2z" />
|
||||
<glyph glyph-name="uniE604" unicode="" horiz-adv-x="1025"
|
||||
d="M410 177q28 -28 67.5 -27.5t67.5 27.5l367 357q55 53 39.5 91t-92.5 38h-763q-77 0 -92.5 -38t39.5 -91z" />
|
||||
<glyph glyph-name="uniE605" unicode=""
|
||||
d="M294 293q-27 27 -27 67t27 67l357 367q54 55 92 39.5t38 -92.5v-763q0 -77 -38 -92.5t-92 39.5l-357 367v1z" />
|
||||
<glyph glyph-name="uniE606" unicode=""
|
||||
d="M754 293q27 27 27 67t-27 67l-358 367q-53 55 -91 39.5t-38 -92.5v-763q0 -77 38 -92.5t91 39.5l358 367v1z" />
|
||||
<glyph glyph-name="uniE607" unicode="" horiz-adv-x="1025"
|
||||
d="M410 636q28 27 67.5 27t67.5 -27l367 -357q55 -54 39.5 -91.5t-92.5 -37.5h-763q-77 0 -92.5 37.5t39.5 91.5z" />
|
||||
<glyph glyph-name="uniE608" unicode="" horiz-adv-x="1376"
|
||||
d="M548 -17q-40 0 -68 28l-389 389q-29 29 -29 69t28.5 68.5t69 28.5t68.5 -28l320 -320l612 612q29 28 69 28t68.5 -28.5t28.5 -68.5t-28 -69l-681 -681q-28 -28 -69 -28v0z" />
|
||||
<glyph glyph-name="uniE609" unicode=""
|
||||
d="M512 896q-106 0 -199.5 -40t-163 -109.5t-109.5 -163t-40 -199.5t40 -199.5t109.5 -163t163 -109.5t199.5 -40t199.5 40t163 109.5t109.5 163t40 199.5t-40 199.5t-109.5 163t-163 109.5t-199.5 40zM798 497l-373 -373q-8 -7 -17.5 -7t-17.5 7l-7 8l-206 206q-7 8 -7 18
|
||||
t7 17l51 50q7 8 17 8t17 -8l145 -146l306 305q7 8 17 8t17 -8l50 -50q8 -8 8 -17.5t-8 -17.5h1z" />
|
||||
<glyph glyph-name="uniE60A" unicode=""
|
||||
d="M522 429l202 202q11 11 26 11t26 -11q11 -10 11 -25.5t-11 -26.5l-202 -202l202 -202q11 -11 10.5 -26t-10.5 -26q-11 -10 -26 -10t-26 10l-202 203l-202 -203q-11 -10 -26.5 -10t-25.5 10q-11 11 -11 26t11 26l202 202l-202 202q-11 11 -10.5 26.5t10.5 25.5
|
||||
q11 11 26 11t26 -11zM512 -128q139 0 257 68.5t186.5 186.5t68.5 257t-68.5 257t-186.5 186.5t-257 68.5t-257 -68.5t-186.5 -186.5t-68.5 -257t68.5 -257t186.5 -186.5t257 -68.5z" />
|
||||
<glyph glyph-name="uniE60B" unicode=""
|
||||
d="M512 -128q-106 0 -199.5 40t-163 109.5t-109.5 163t-40 199.5t40 199.5t109.5 163t163 109.5t199.5 40t199.5 -40t163 -109.5t109.5 -163t40 -199.5t-40 -199.5t-109.5 -163t-163 -109.5t-199.5 -40zM747 533q7 7 7 17.5t-7 18.5l-53 51q-7 8 -17 8t-17 -8l-148 -147
|
||||
l-149 147q-7 8 -17 8t-17 -8l-53 -51q-6 -8 -6 -18.5t6 -17.5l149 -148l-149 -147q-6 -8 -6 -18.5t6 -17.5l53 -52q7 -7 17 -7t17 7l149 148l148 -148q7 -7 17 -7t17 7l53 52q7 7 7 17.5t-7 18.5l-149 147z" />
|
||||
<glyph glyph-name="uniE60C" unicode=""
|
||||
d="M512 484l-391 391q-21 21 -50.5 21t-49.5 -21q-20 -20 -20.5 -49.5t20.5 -50.5l391 -391l-391 -391q-21 -21 -21 -50.5t21 -49.5q20 -21 49.5 -21t50.5 21l391 391l391 -391q21 -21 50.5 -21t49.5 21q21 20 21 49.5t-21 50.5l-391 391l391 391q21 21 21 50.5t-21 49.5
|
||||
q-20 20 -49.5 20.5t-50.5 -20.5z" />
|
||||
<glyph glyph-name="uniE60D" unicode=""
|
||||
d="M566 0h213q102 3 173.5 77t71.5 176q0 105 -74 179.5t-178 74.5h-8v8q0 105 -73.5 179t-178 74t-178.5 -74t-74 -179v-8h-8q-104 0 -178 -74.5t-74 -179.5q0 -102 71.5 -176t173.5 -77h229v172h-90q-20 0 -26 11t5 27l140 214q7 10 16.5 10t16.5 -10l141 -214
|
||||
q10 -16 4 -27t-25 -11h-90v-172z" />
|
||||
<glyph glyph-name="uniE60E" unicode="" horiz-adv-x="1025"
|
||||
d="M6 360q-8 18 -5 39t16 35l403 445q16 18 38.5 17t38.5 -20t15 -45.5t-17 -44.5l-362 -399l360 -405q17 -19 17.5 -45t-15.5 -45q-16 -20 -40 -20q-22 0 -38 18l-399 449v1l-2 2t-1 2q-2 2 -7 12l-2 2v2zM518 360q-8 18 -5 39t16 35l403 445q16 18 38.5 17t38.5 -20
|
||||
t15 -45.5t-17 -44.5l-362 -399l360 -405q17 -19 17.5 -45t-15.5 -45q-16 -20 -40 -20q-22 0 -38 18l-399 449v1l-2 2t-1 2q-2 2 -7 12l-2 2v2z" />
|
||||
<glyph glyph-name="uniE60F" unicode="" horiz-adv-x="1025"
|
||||
d="M1018 360q8 18 5.5 39t-16.5 35l-403 445q-16 18 -38.5 17t-38.5 -20t-15 -45.5t17 -44.5l362 -399l-360 -405q-17 -19 -17.5 -45t15.5 -45q16 -20 40 -20q22 0 38 18l399 449v1l2 2l2 2l6 12l2 2v2zM506 360q8 18 5.5 39t-16.5 35l-403 445q-16 18 -38.5 17t-38.5 -20
|
||||
t-15 -45.5t17 -44.5l362 -399l-360 -405q-17 -19 -17.5 -45t15.5 -45q16 -20 40 -20q22 0 38 18l399 449v1l2 2t1 2q2 2 7 12l2 2v2z" />
|
||||
<glyph glyph-name="uniE610" unicode=""
|
||||
d="M440 -99q26 -24 62 -24t62 24l300 284q52 48 38.5 82t-83.5 34h-634q-70 0 -83.5 -34t37.5 -82zM440 872q26 24 62 24t62 -24l300 -283q52 -49 38.5 -83t-83.5 -34h-634q-70 0 -83.5 34t37.5 83z" />
|
||||
<glyph glyph-name="uniE611" unicode=""
|
||||
d="M713 782h-402v114h-151v-114h-50q-28 0 -47.5 -19.5t-19.5 -47.5v-776q0 -28 19 -47.5t47 -19.5h806q28 0 47 19.5t19 47.5v776q0 28 -19.5 47.5t-46.5 19.5h-51v114h-151v-114zM160 -18v573h704v-573h-704zM555 299v-256h256v256h-256z" />
|
||||
<glyph glyph-name="uniE612" unicode=""
|
||||
d="M642 706v126q0 27 -16.5 45.5t-40.5 18.5h-136q-25 0 -45.5 -19t-20.5 -45v-126h-204q0 -1 -2 -2q-49 -22 -49 -64q0 -26 17.5 -45t41.5 -19h650q24 0 41.5 19t17.5 45q0 24 -15 40.5t-29 21.5l-15 4h-195zM448 704v64q0 32 18 48t46 16q29 0 46.5 -16t17.5 -48v-64h-128
|
||||
zM320 -128h384q53 0 90.5 37.5t37.5 90.5v512h-640v-512q0 -53 37.5 -90.5t90.5 -37.5zM644 356q0 11 7.5 19.5t18.5 8.5t19 -8.5t8 -19.5v-342q0 -12 -8 -20t-19 -8t-18.5 8t-7.5 20v342zM486 356q0 11 7.5 19.5t18.5 8.5t18.5 -8.5t7.5 -19.5v-342q0 -12 -7.5 -20
|
||||
t-18.5 -8t-18.5 8t-7.5 20v342zM328 356q0 11 7.5 19.5t18.5 8.5t18.5 -8.5t7.5 -19.5v-342q0 -12 -7.5 -20t-18.5 -8t-18.5 8t-7.5 20v342z" />
|
||||
<glyph glyph-name="uniE613" unicode=""
|
||||
d="M441 896l-356 -366v-519q0 -57 41 -98t99 -41h574q58 0 99 41t41 98v746q0 57 -41 98t-99 41h-358zM832 53q0 -29 -21 -50t-50 -21h-498q-30 0 -50.5 20.5t-20.5 50.5v404h249q29 0 50 21t21 51v257h249q29 0 50 -21t21 -50v-662z" />
|
||||
<glyph glyph-name="uniE614" unicode=""
|
||||
d="M84 180l-84 -308l307 85l485 485l-226 219zM755 850l-121 -121l227 -219l117 117q46 46 46 111.5t-46 111.5t-111.5 46t-111.5 -46z" />
|
||||
<glyph glyph-name="uniE615" unicode=""
|
||||
d="M512 -128q-106 0 -199.5 40t-163 109.5t-109.5 163t-40 199.5t40 199.5t109.5 163t163 109.5t199.5 40t199.5 -40t163 -109.5t109.5 -163t40 -199.5t-40 -199.5t-109.5 -163t-163 -109.5t-199.5 -40zM512 677q-31 0 -52 -21.5t-21 -52t21.5 -52t52 -21.5t51.5 21.5t21 52
|
||||
t-21.5 52t-51.5 21.5zM571 401q0 23 -17 39.5t-42 16.5t-42 -16.5t-17 -39.5v-261q0 -24 17 -40t42 -16t42 16t17 40v261z" />
|
||||
<glyph glyph-name="uniE616" unicode=""
|
||||
d="M0 384q0 -139 68.5 -257t186.5 -186.5t257 -68.5t257 68.5t186.5 186.5t68.5 257t-68.5 257t-186.5 186.5t-257 68.5q-16 0 -27.5 -11.5t-11.5 -28t11.5 -28t27.5 -11.5q118 0 217.5 -58t157.5 -157.5t58 -217.5t-58 -217.5t-157.5 -157.5t-217.5 -58t-217.5 58
|
||||
t-157.5 157.5t-58 217.5q0 16 -11.5 27.5t-28 11.5t-28 -11.5t-11.5 -27.5z" />
|
||||
<glyph glyph-name="uniE617" unicode=""
|
||||
d="M358 347h-244q-47 0 -80.5 -33.5t-33.5 -80.5v-245q0 -48 33.5 -82t80.5 -34h244q48 0 81 33.5t33 80.5v244q2 49 -31.5 83t-82.5 34zM358 896h-244q-47 0 -80.5 -33.5t-33.5 -80.5v-244q0 -48 33.5 -81t80.5 -33h244q48 0 81 33t33 81v244q2 47 -31.5 80.5t-82.5 33.5z
|
||||
M910 347h-244q-48 0 -81 -33.5t-33 -80.5v-245q0 -47 33 -80.5t81 -33.5h244q47 0 80.5 33.5t33.5 80.5v242q0 49 -33.5 83t-80.5 34zM910 896h-244q-48 0 -81 -33.5t-33 -80.5v-244q0 -48 33 -81t81 -33h244q47 0 80.5 33t33.5 81v244q0 47 -33.5 80.5t-80.5 33.5z" />
|
||||
<glyph glyph-name="uniE618" unicode=""
|
||||
d="M896 811h-768q-41 0 -84.5 -29t-43.5 -65v-18q18 -15 47.5 -40t108.5 -89t143.5 -113t127.5 -89t85 -40t85 39.5t127.5 88.5t143.5 112.5t108.5 89t47.5 40.5v19q0 36 -43.5 65t-84.5 29v0zM0 549v-526q2 -3 5.5 -7.5t16 -15.5t26.5 -20t35.5 -16t44.5 -7h768
|
||||
q21 0 42.5 7t36 16.5t26 19t17.5 16.5l6 7v528q-15 -14 -40.5 -36.5t-96 -80t-132.5 -101.5t-132 -80t-111 -36t-109 34.5t-135.5 83t-129 97.5t-100.5 83l-38 34v0z" />
|
||||
<glyph glyph-name="uniE619" unicode=""
|
||||
d="M79 463h866q33 0 56 -23t23 -56t-23 -56t-56 -23h-866q-33 0 -56 23t-23 56t23 56t56 23z" />
|
||||
<glyph glyph-name="uniE61A" unicode=""
|
||||
d="M118 266q49 0 83.5 34.5t34.5 83.5t-34.5 83.5t-83.5 34.5t-83.5 -34.5t-34.5 -83.5t34.5 -83.5t83.5 -34.5zM512 266q49 0 83.5 34.5t34.5 83.5t-34.5 83.5t-83.5 34.5t-83.5 -34.5t-34.5 -83.5t34.5 -83.5t83.5 -34.5zM906 266q49 0 83.5 34.5t34.5 83.5t-34.5 83.5
|
||||
t-83.5 34.5t-83.5 -34.5t-34.5 -83.5t34.5 -83.5t83.5 -34.5z" />
|
||||
<glyph glyph-name="uniE61B" unicode=""
|
||||
d="M147 811q-61 0 -104 -43t-43 -104v-560q0 -61 43 -104t104 -43h730q61 0 104 43t43 104v560q0 61 -43 104t-104 43h-730zM743 431q-1 2 -4 6t-16.5 10t-32.5 6q-20 0 -35 -5.5t-20 -10.5l-5 -5l-176 -279q-10 -19 -33 -19q-11 0 -20 5t-13 9l-3 5l-93 109q-2 3 -7 8.5
|
||||
t-19.5 14.5t-28 9t-27.5 -9t-21 -18l-7 -9l-72 -87v460q0 30 21 51.5t52 21.5h659q30 0 51 -21.5t21 -51.5v-425zM475 491q0 -45 -32 -76t-77.5 -31t-77.5 31.5t-32 75.5t32 75t77.5 31t77.5 -31t32 -75v0z" />
|
||||
<glyph glyph-name="uniE61C" unicode=""
|
||||
d="M439 457h-365q-31 0 -52.5 -21.5t-21.5 -51.5t21.5 -51.5t52.5 -21.5h365v-365q0 -31 21.5 -52.5t51.5 -21.5t51.5 21.5t21.5 52.5v365h365q31 0 52.5 21.5t21.5 51.5t-21.5 51.5t-52.5 21.5h-365v365q0 31 -21.5 52.5t-51.5 21.5t-51.5 -21.5t-21.5 -52.5v-365z" />
|
||||
<glyph glyph-name="uniE61D" unicode=""
|
||||
d="M591 274q75 75 75 181t-75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75zM650 155q-75 -60 -167.5 -78t-184 9.5t-159.5 96.5q-74 74 -100 173t0 197.5t99.5 172.5t172.5 100t198 0t173 -100q96 -96 110 -230.5t-57 -245.5l203 -202q19 -19 19 -45.5t-19 -45.5
|
||||
q-18 -19 -44.5 -19t-46.5 19z" />
|
||||
<glyph glyph-name="uniE61E" unicode="" horiz-adv-x="1025"
|
||||
d="M1020 454q-3 16 -17 30.5t-31 18.5l-16 3q-63 19 -96 75t-18 119l5 15q5 16 -0.5 35.5t-18.5 30.5q-16 13 -60 38q-19 11 -35 18.5t-22 10.5l-6 2q-16 6 -35.5 1.5t-31.5 -17.5l-12 -12q-47 -44 -113.5 -44t-114.5 44l-11 12q-12 13 -31.5 17.5t-35.5 -1.5
|
||||
q-20 -7 -64 -31q-19 -12 -34 -21.5t-20 -13.5l-5 -4q-13 -10 -19 -29t-1 -36l5 -15q15 -63 -18 -119q-33 -57 -96 -75l-16 -3q-17 -4 -31 -18.5t-17 -30.5q-4 -20 -4 -70q0 -22 1 -39.5t2 -23.5l1 -7q3 -16 17 -30.5t31 -18.5l15 -3q64 -19 97 -75t18 -119l-5 -15
|
||||
q-5 -16 1 -35.5t19 -30.5q15 -13 59 -38q20 -11 36 -18.5t22 -10.5l6 -2q16 -6 35.5 -1.5t31.5 17.5l11 11q48 45 114 45q67 0 115 -45l11 -11q11 -13 31 -17.5t36 1.5q19 7 63 31q20 11 35 21t20 14l5 3q13 11 18.5 30t0.5 35l-4 16q-16 63 17 119t97 75l16 3q16 4 30 18.5
|
||||
t18 30.5q3 20 3 70q0 22 -1 39.5t-2 23.5l-1 7v0v0zM512 184q-84 0 -144 58.5t-60 141.5t60 141.5t144.5 58.5t144 -58.5t59.5 -141.5t-59.5 -141.5t-144.5 -58.5v0z" />
|
||||
<glyph glyph-name="uniE61F" unicode=""
|
||||
d="M877 159q27 -11 47.5 -31.5t32 -47.5t11.5 -58.5t-11.5 -58.5t-32 -47.5t-47.5 -32t-58 -11.5t-58 11.5t-47.5 32t-32 47.5t-11.5 58v9q0 5 2 8v9q1 5 2 8l-365 213q-11 -9 -22 -17t-25 -13q-13 -6 -27 -8q-14 -3 -30 -3q-31 0 -59.5 12.5t-48.5 32.5q-22 22 -34 49.5
|
||||
t-12 60.5q0 31 12 59.5t34 48.5q20 22 48.5 34t59.5 12q15 0 30 -3q14 -3 27 -9q14 -5 25 -13t22 -17l361 212q-1 3 -1 8q-1 5 -2 9q0 5 -0.5 9.5t-0.5 9.5q0 31 12 59.5t33 48.5q21 21 49 33.5t59 12.5t59.5 -12.5t48.5 -33.5q22 -20 34 -48.5t12 -59.5q0 -33 -12 -61
|
||||
t-34 -49q-20 -20 -48.5 -32t-59.5 -12q-15 0 -29.5 2t-27.5 9q-14 4 -25 12t-22 18l-361 -211q1 -5 1.5 -9.5t1.5 -8.5q0 -5 0.5 -9t0.5 -9t-0.5 -10t-0.5 -10q-1 -3 -2 -8q0 -4 -1 -8l364 -214q10 9 22 16t24 13q13 5 27 7q14 3 28 3q31 0 58 -12z" />
|
||||
<glyph glyph-name="uniE620" unicode="" horiz-adv-x="1086"
|
||||
d="M825 -58q15 -9 25 -10q-3 0 -8.5 -4t-6.5 -7q2 9 -2 27l-52 226q-9 40 5 82.5t45 68.5l176 154q14 12 18 20q-1 -3 1 -10t5 -8q-8 4 -27 6l-235 22q-40 3 -76 29.5t-52 62.5l-93 213q-7 17 -14 24q2 -2 9 -2t8 2q-7 -7 -14 -24l-93 -213q-16 -36 -52 -62.5t-76 -29.5
|
||||
l-235 -22q-19 -2 -27 -6q3 1 5 8.5t1 9.5q4 -8 18 -20l177 -154q30 -26 44 -68.5t5 -82.5l-51 -226q-4 -18 -3 -27q0 3 -6 7t-8 4q9 1 25 10l202 119q35 21 80 21t79 -21zM493 10l-202 -119q-54 -32 -82.5 -11t-14.5 82l52 226q5 23 -4 50t-27 42l-177 154q-47 41 -36 74
|
||||
t73 39l236 21q23 2 46 19t32 38l93 213q25 58 60.5 58t60.5 -58l93 -213q9 -21 32 -38t46 -19l236 -21q62 -6 73 -39t-36 -74l-177 -154q-18 -15 -27 -42t-4 -50l52 -226q14 -61 -14.5 -82t-82.5 11l-202 119q-21 12 -49.5 12t-49.5 -12z" />
|
||||
<glyph glyph-name="uniE621" unicode="" horiz-adv-x="1086"
|
||||
d="M592 10q-21 12 -49.5 12t-49.5 -12l-202 -119q-54 -32 -82.5 -11t-14.5 82l52 226q5 23 -4 50t-27 42l-177 154q-47 41 -36 74t73 39l236 21q23 2 46 19t32 38l93 213q25 58 60.5 58t60.5 -58l93 -213q9 -21 32 -38t46 -19l236 -21q62 -6 73 -39t-36 -74l-177 -154
|
||||
q-18 -15 -27 -42t-4 -50l52 -226q14 -61 -14.5 -82t-82.5 11z" />
|
||||
<glyph glyph-name="uniE622" unicode=""
|
||||
d="M512 -128q-139 0 -257 68.5t-186.5 186.5t-68.5 257q0 104 40.5 199t109 163.5t163.5 109t199 40.5t199 -40.5t163.5 -109t109 -163.5t40.5 -199t-40.5 -199t-109 -163.5t-163.5 -109t-199 -40.5zM512 786q-109 0 -202 -53.5t-146.5 -146.5t-53.5 -202t53.5 -202
|
||||
t146.5 -146.5t202 -53.5t202 53.5t146.5 146.5t53.5 202t-53.5 202t-146.5 146.5t-202 53.5zM513 316q-20 0 -34 14.5t-14 33.5v229q0 19 14 33.5t34 14.5t34 -14.5t14 -33.5v-181h160q20 0 34 -14t14 -33.5t-14 -34t-34 -14.5h-208z" />
|
||||
<glyph glyph-name="uniE623" unicode=""
|
||||
d="M512 896q-106 0 -199.5 -40t-163 -109.5t-109.5 -163t-40 -199.5t40 -199.5t109.5 -163t163 -109.5t199.5 -40t199.5 40t163 109.5t109.5 163t40 199.5t-40 199.5t-109.5 163t-163 109.5t-199.5 40zM512 94q-25 0 -42 17t-17 41.5t17 42t42 17.5t42 -17.5t17 -42
|
||||
t-17 -41.5t-42 -17zM571 350q0 -25 -17 -42.5t-42 -17.5t-42 17.5t-17 42.5v275q0 25 17 42t42 17t42 -17t17 -42v-275z" />
|
||||
<glyph glyph-name="uniE624" unicode=""
|
||||
d="M382 491v-384q0 -10 -6 -16t-15 -6h-43q-10 0 -16 6t-6 16v384q0 9 6 15t16 6h43q9 0 15 -6t6 -15zM555 491v-384q0 -10 -6 -16t-15 -6h-44q-9 0 -15 6t-6 16v384q0 9 6 15t15 6h44q9 0 15 -6t6 -15zM728 491v-384q0 -10 -6 -16t-16 -6h-43q-9 0 -15 6t-6 16v384
|
||||
q0 9 6 15t15 6h43q10 0 16 -6t6 -15zM815 8v632h-606v-632q0 -15 5 -27t10 -18t7 -6h562q2 0 7 6t10 18t5 27zM361 725h302l-32 78q-5 6 -12 8h-214q-6 -2 -11 -8zM987 704v-43q0 -9 -6 -15t-15 -6h-65v-632q0 -55 -31.5 -95.5t-76.5 -40.5h-562q-45 0 -76.5 39t-31.5 94
|
||||
v635h-65q-9 0 -15 6t-6 15v43q0 9 6 15t15 6h209l47 112q10 24 36.5 41.5t53.5 17.5h216q27 0 53.5 -17.5t36.5 -41.5l47 -112h209q9 0 15 -6t6 -15z" />
|
||||
<glyph glyph-name="uniE626" unicode=""
|
||||
d="M634 506h-146v147q0 20 -14.5 34t-34.5 14t-34.5 -14t-14.5 -34v-147h-146q-20 0 -34 -14t-14 -34.5t14 -34.5t34 -14h146v-147q0 -20 14.5 -34t34.5 -14t34.5 14t14.5 34v147h146q20 0 34.5 14t14.5 34.5t-14.5 34.5t-34.5 14zM1009 -41l-226 227q67 85 86.5 190.5
|
||||
t-12 209t-109.5 181.5q-63 64 -145 96.5t-165 32.5t-165 -32.5t-145 -96t-95.5 -145.5t-32.5 -165t32.5 -165t95.5 -145q79 -78 182.5 -109.5t209.5 -11.5t191 87l226 -226q15 -15 36 -15t36 15t15 36t-15 36zM679 217q-65 -66 -153 -89t-176 0t-153.5 89t-88.5 153.5
|
||||
t0 175.5t88.5 153.5t153.5 89t176 0t153.5 -89t88.5 -153.5t0 -175.5t-89 -153.5z" />
|
||||
<glyph glyph-name="uniE627" unicode="" horiz-adv-x="1103"
|
||||
d="M1039 -128h-975q-27 0 -45.5 19t-18.5 45v320q0 27 18.5 45.5t45 18.5t45 -18.5t18.5 -45.5v-256h849v256q0 27 18.5 45.5t44.5 18.5t45 -18.5t19 -45.5v-320q0 -26 -18.5 -45t-45.5 -19zM742 555q-28 0 -47 21l-80 89v-388q0 -26 -18.5 -45t-45 -19t-45 19t-18.5 45v388
|
||||
l-80 -89q-19 -21 -47 -21q-27 0 -45.5 18.5t-18.5 45.5q0 24 16 42l191 214q19 21 47.5 21t47.5 -21l191 -214q16 -18 16 -42q0 -27 -18.5 -45.5t-45.5 -18.5z" />
|
||||
</font>
|
||||
</defs></svg>
|
||||
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 434 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 620 B |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 313 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 16 KiB |