docsify
Version:
A magical documentation generator.
1,908 lines (1,600 loc) • 330 kB
JavaScript
(function () {
/**
* Create a cached version of a pure function.
* @param {*} fn The function call to be cached
* @void
*/
function cached(fn) {
var cache = Object.create(null);
return function (str) {
var key = isPrimitive(str) ? str : JSON.stringify(str);
var hit = cache[key];
return hit || (cache[key] = fn(str));
};
}
/**
* Hyphenate a camelCase string.
*/
var hyphenate = cached(function (str) {
return str.replace(/([A-Z])/g, function (m) { return '-' + m.toLowerCase(); });
});
var hasOwn = Object.prototype.hasOwnProperty;
/**
* Simple Object.assign polyfill
* @param {Object} to The object to be merged with
* @returns {Object} The merged object
*/
var merge =
Object.assign ||
function (to) {
var arguments$1 = arguments;
for (var i = 1; i < arguments.length; i++) {
var from = Object(arguments$1[i]);
for (var key in from) {
if (hasOwn.call(from, key)) {
to[key] = from[key];
}
}
}
return to;
};
/**
* Check if value is primitive
* @param {*} value Checks if a value is primitive
* @returns {Boolean} Result of the check
*/
function isPrimitive(value) {
return typeof value === 'string' || typeof value === 'number';
}
/**
* Performs no operation.
* @void
*/
function noop() {}
/**
* Check if value is function
* @param {*} obj Any javascript object
* @returns {Boolean} True if the passed-in value is a function
*/
function isFn(obj) {
return typeof obj === 'function';
}
/**
* Check if url is external
* @param {String} string url
* @returns {Boolean} True if the passed-in url is external
*/
function isExternal(url) {
var match = url.match(
/^([^:/?#]+:)?(?:\/{2,}([^/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/
);
if (
typeof match[1] === 'string' &&
match[1].length > 0 &&
match[1].toLowerCase() !== location.protocol
) {
return true;
}
if (
typeof match[2] === 'string' &&
match[2].length > 0 &&
match[2].replace(
new RegExp(
':(' + { 'http:': 80, 'https:': 443 }[location.protocol] + ')?$'
),
''
) !== location.host
) {
return true;
}
if (/^\/\\/.test(url)) {
return true;
}
return false;
}
var inBrowser = !false;
var isMobile = document.body.clientWidth <= 600;
/**
* @see https://github.com/MoOx/pjax/blob/master/lib/is-supported.js
*/
var supportsPushState =
(function () {
// Borrowed wholesale from https://github.com/defunkt/jquery-pjax
return (
window.history &&
window.history.pushState &&
window.history.replaceState &&
// PushState isn’t reliable on iOS until 5.
!navigator.userAgent.match(
/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/
)
);
})();
var cacheNode = {};
/**
* Get Node
* @param {String|Element} el A DOM element
* @param {Boolean} noCache Flag to use or not use the cache
* @return {Element} The found node element
*/
function getNode(el, noCache) {
if ( noCache === void 0 ) noCache = false;
if (typeof el === 'string') {
if (typeof window.Vue !== 'undefined') {
return find(el);
}
el = noCache ? find(el) : cacheNode[el] || (cacheNode[el] = find(el));
}
return el;
}
var $ = document;
var body = $.body;
var head = $.head;
/**
* Find elements
* @param {String|Element} el The root element where to perform the search from
* @param {Element} node The query
* @returns {Element} The found DOM element
* @example
* find('nav') => document.querySelector('nav')
* find(nav, 'a') => nav.querySelector('a')
*/
function find(el, node) {
return node ? el.querySelector(node) : $.querySelector(el);
}
/**
* Find all elements
* @param {String|Element} el The root element where to perform the search from
* @param {Element} node The query
* @returns {Array<Element>} An array of DOM elements
* @example
* findAll('a') => [].slice.call(document.querySelectorAll('a'))
* findAll(nav, 'a') => [].slice.call(nav.querySelectorAll('a'))
*/
function findAll(el, node) {
return [].slice.call(
node ? el.querySelectorAll(node) : $.querySelectorAll(el)
);
}
function create(node, tpl) {
node = $.createElement(node);
if (tpl) {
node.innerHTML = tpl;
}
return node;
}
function appendTo(target, el) {
return target.appendChild(el);
}
function before(target, el) {
return target.insertBefore(el, target.children[0]);
}
function on(el, type, handler) {
isFn(type)
? window.addEventListener(el, type)
: el.addEventListener(type, handler);
}
function off(el, type, handler) {
isFn(type)
? window.removeEventListener(el, type)
: el.removeEventListener(type, handler);
}
/**
* Toggle class
* @param {String|Element} el The element that needs the class to be toggled
* @param {Element} type The type of action to be performed on the classList (toggle by default)
* @param {String} val Name of the class to be toggled
* @void
* @example
* toggleClass(el, 'active') => el.classList.toggle('active')
* toggleClass(el, 'add', 'active') => el.classList.add('active')
*/
function toggleClass(el, type, val) {
el && el.classList[val ? type : 'toggle'](val || type);
}
function style(content) {
appendTo(head, create('style', content));
}
/**
* Fork https://github.com/bendrucker/document-ready/blob/master/index.js
* @param {Function} callback The callbacack to be called when the page is loaded
* @returns {Number|void} If the page is already laoded returns the result of the setTimeout callback,
* otherwise it only attaches the callback to the DOMContentLoaded event
*/
function documentReady(callback, doc) {
if ( doc === void 0 ) doc = document;
var state = doc.readyState;
if (state === 'complete' || state === 'interactive') {
return setTimeout(callback, 0);
}
doc.addEventListener('DOMContentLoaded', callback);
}
var dom = /*#__PURE__*/Object.freeze({
__proto__: null,
getNode: getNode,
$: $,
body: body,
head: head,
find: find,
findAll: findAll,
create: create,
appendTo: appendTo,
before: before,
on: on,
off: off,
toggleClass: toggleClass,
style: style,
documentReady: documentReady
});
function startsWith(str, prefix) {
return str.indexOf(prefix) === 0;
}
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
var decode = decodeURIComponent;
var encode = encodeURIComponent;
function parseQuery(query) {
var res = {};
query = query.trim().replace(/^(\?|#|&)/, '');
if (!query) {
return res;
}
// Simple parse
query.split('&').forEach(function (param) {
var parts = param.replace(/\+/g, ' ').split('=');
res[parts[0]] = parts[1] && decode(parts[1]);
});
return res;
}
function stringifyQuery(obj, ignores) {
if ( ignores === void 0 ) ignores = [];
var qs = [];
for (var key in obj) {
if (ignores.indexOf(key) > -1) {
continue;
}
qs.push(
obj[key]
? ((encode(key)) + "=" + (encode(obj[key]))).toLowerCase()
: encode(key)
);
}
return qs.length ? ("?" + (qs.join('&'))) : '';
}
var isAbsolutePath = cached(function (path) {
return /(:|(\/{2}))/g.test(path);
});
var removeParams = cached(function (path) {
return path.split(/[?#]/)[0];
});
var getParentPath = cached(function (path) {
if (/\/$/g.test(path)) {
return path;
}
var matchingParts = path.match(/(\S*\/)[^/]+$/);
return matchingParts ? matchingParts[1] : '';
});
var cleanPath = cached(function (path) {
return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/');
});
var resolvePath = cached(function (path) {
var segments = path.replace(/^\//, '').split('/');
var resolved = [];
for (var i = 0, len = segments.length; i < len; i++) {
var segment = segments[i];
if (segment === '..') {
resolved.pop();
} else if (segment !== '.') {
resolved.push(segment);
}
}
return '/' + resolved.join('/');
});
/**
* Normalises the URI path to handle the case where Docsify is
* hosted off explicit files, i.e. /index.html. This function
* eliminates any path segments that contain `#` fragments.
*
* This is used to map browser URIs to markdown file sources.
*
* For example:
*
* http://example.org/base/index.html#/blah
*
* would be mapped to:
*
* http://example.org/base/blah.md.
*
* See here for more information:
*
* https://github.com/docsifyjs/docsify/pull/1372
*
* @param {string} path The URI path to normalise
* @return {string} { path, query }
*/
function normaliseFragment(path) {
return path
.split('/')
.filter(function (p) { return p.indexOf('#') === -1; })
.join('/');
}
function getPath() {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
return cleanPath(args.map(normaliseFragment).join('/'));
}
var replaceSlug = cached(function (path) {
return path.replace('#', '?id=');
});
var cached$1 = {};
function getAlias(path, alias, last) {
var match = Object.keys(alias).filter(function (key) {
var re = cached$1[key] || (cached$1[key] = new RegExp(("^" + key + "$")));
return re.test(path) && path !== last;
})[0];
return match
? getAlias(path.replace(cached$1[match], alias[match]), alias, path)
: path;
}
function getFileName(path, ext) {
return new RegExp(("\\.(" + (ext.replace(/^\./, '')) + "|html)$"), 'g').test(path)
? path
: /\/$/g.test(path)
? (path + "README" + ext)
: ("" + path + ext);
}
var History = function History(config) {
this.config = config;
};
History.prototype.getBasePath = function getBasePath () {
return this.config.basePath;
};
History.prototype.getFile = function getFile (path, isRelative) {
if ( path === void 0 ) path = this.getCurrentPath();
var ref = this;
var config = ref.config;
var base = this.getBasePath();
var ext = typeof config.ext === 'string' ? config.ext : '.md';
path = config.alias ? getAlias(path, config.alias) : path;
path = getFileName(path, ext);
path = path === ("/README" + ext) ? config.homepage || path : path;
path = isAbsolutePath(path) ? path : getPath(base, path);
if (isRelative) {
path = path.replace(new RegExp(("^" + base)), '');
}
return path;
};
History.prototype.onchange = function onchange (cb) {
if ( cb === void 0 ) cb = noop;
cb();
};
History.prototype.getCurrentPath = function getCurrentPath () {};
History.prototype.normalize = function normalize () {};
History.prototype.parse = function parse () {};
History.prototype.toURL = function toURL (path, params, currentRoute) {
var local = currentRoute && path[0] === '#';
var route = this.parse(replaceSlug(path));
route.query = merge({}, route.query, params);
path = route.path + stringifyQuery(route.query);
path = path.replace(/\.md(\?)|\.md$/, '$1');
if (local) {
var idIndex = currentRoute.indexOf('?');
path =
(idIndex > 0 ? currentRoute.substring(0, idIndex) : currentRoute) +
path;
}
if (this.config.relativePath && path.indexOf('/') !== 0) {
var currentDir = currentRoute.substring(
0,
currentRoute.lastIndexOf('/') + 1
);
return cleanPath(resolvePath(currentDir + path));
}
return cleanPath('/' + path);
};
function replaceHash(path) {
var i = location.href.indexOf('#');
location.replace(location.href.slice(0, i >= 0 ? i : 0) + '#' + path);
}
var HashHistory = /*@__PURE__*/(function (History) {
function HashHistory(config) {
History.call(this, config);
this.mode = 'hash';
}
if ( History ) HashHistory.__proto__ = History;
HashHistory.prototype = Object.create( History && History.prototype );
HashHistory.prototype.constructor = HashHistory;
HashHistory.prototype.getBasePath = function getBasePath () {
var path = window.location.pathname || '';
var base = this.config.basePath;
// This handles the case where Docsify is served off an
// explicit file path, i.e.`/base/index.html#/blah`. This
// prevents the `/index.html` part of the URI from being
// remove during routing.
// See here: https://github.com/docsifyjs/docsify/pull/1372
var basePath = endsWith(path, '.html')
? path + '#/' + base
: path + '/' + base;
return /^(\/|https?:)/g.test(base) ? base : cleanPath(basePath);
};
HashHistory.prototype.getCurrentPath = function getCurrentPath () {
// We can't use location.hash here because it's not
// consistent across browsers - Firefox will pre-decode it!
var href = location.href;
var index = href.indexOf('#');
return index === -1 ? '' : href.slice(index + 1);
};
/** @param {((params: {source: TODO}) => void)} [cb] */
HashHistory.prototype.onchange = function onchange (cb) {
if ( cb === void 0 ) cb = noop;
// The hashchange event does not tell us if it originated from
// a clicked link or by moving back/forward in the history;
// therefore we set a `navigating` flag when a link is clicked
// to be able to tell these two scenarios apart
var navigating = false;
on('click', function (e) {
var el = e.target.tagName === 'A' ? e.target : e.target.parentNode;
if (el && el.tagName === 'A' && !isExternal(el.href)) {
navigating = true;
}
});
on('hashchange', function (e) {
var source = navigating ? 'navigate' : 'history';
navigating = false;
cb({ event: e, source: source });
});
};
HashHistory.prototype.normalize = function normalize () {
var path = this.getCurrentPath();
path = replaceSlug(path);
if (path.charAt(0) === '/') {
return replaceHash(path);
}
replaceHash('/' + path);
};
/**
* Parse the url
* @param {string} [path=location.herf] URL to be parsed
* @return {object} { path, query }
*/
HashHistory.prototype.parse = function parse (path) {
if ( path === void 0 ) path = location.href;
var query = '';
var hashIndex = path.indexOf('#');
if (hashIndex >= 0) {
path = path.slice(hashIndex + 1);
}
var queryIndex = path.indexOf('?');
if (queryIndex >= 0) {
query = path.slice(queryIndex + 1);
path = path.slice(0, queryIndex);
}
return {
path: path,
file: this.getFile(path, true),
query: parseQuery(query),
};
};
HashHistory.prototype.toURL = function toURL (path, params, currentRoute) {
return '#' + History.prototype.toURL.call(this, path, params, currentRoute);
};
return HashHistory;
}(History));
/** @typedef {any} TODO */
var HTML5History = /*@__PURE__*/(function (History) {
function HTML5History(config) {
History.call(this, config);
this.mode = 'history';
}
if ( History ) HTML5History.__proto__ = History;
HTML5History.prototype = Object.create( History && History.prototype );
HTML5History.prototype.constructor = HTML5History;
HTML5History.prototype.getCurrentPath = function getCurrentPath () {
var base = this.getBasePath();
var path = window.location.pathname;
if (base && path.indexOf(base) === 0) {
path = path.slice(base.length);
}
return (path || '/') + window.location.search + window.location.hash;
};
HTML5History.prototype.onchange = function onchange (cb) {
if ( cb === void 0 ) cb = noop;
on('click', function (e) {
var el = e.target.tagName === 'A' ? e.target : e.target.parentNode;
if (el && el.tagName === 'A' && !isExternal(el.href)) {
e.preventDefault();
var url = el.href;
window.history.pushState({ key: url }, '', url);
cb({ event: e, source: 'navigate' });
}
});
on('popstate', function (e) {
cb({ event: e, source: 'history' });
});
};
/**
* Parse the url
* @param {string} [path=location.href] URL to be parsed
* @return {object} { path, query }
*/
HTML5History.prototype.parse = function parse (path) {
if ( path === void 0 ) path = location.href;
var query = '';
var queryIndex = path.indexOf('?');
if (queryIndex >= 0) {
query = path.slice(queryIndex + 1);
path = path.slice(0, queryIndex);
}
var base = getPath(location.origin);
var baseIndex = path.indexOf(base);
if (baseIndex > -1) {
path = path.slice(baseIndex + base.length);
}
return {
path: path,
file: this.getFile(path),
query: parseQuery(query),
};
};
return HTML5History;
}(History));
/**
* @typedef {{
* path?: string
* }} Route
*/
/** @type {Route} */
var lastRoute = {};
/** @typedef {import('../Docsify').Constructor} Constructor */
/**
* @template {!Constructor} T
* @param {T} Base - The class to extend
*/
function Router(Base) {
return /*@__PURE__*/(function (Base) {
function Router() {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
Base.apply(this, args);
this.route = {};
}
if ( Base ) Router.__proto__ = Base;
Router.prototype = Object.create( Base && Base.prototype );
Router.prototype.constructor = Router;
Router.prototype.updateRender = function updateRender () {
this.router.normalize();
this.route = this.router.parse();
body.setAttribute('data-page', this.route.file);
};
Router.prototype.initRouter = function initRouter () {
var this$1 = this;
var config = this.config;
var mode = config.routerMode || 'hash';
var router;
if (mode === 'history' && supportsPushState) {
router = new HTML5History(config);
} else {
router = new HashHistory(config);
}
this.router = router;
this.updateRender();
lastRoute = this.route;
// eslint-disable-next-line no-unused-vars
router.onchange(function (params) {
this$1.updateRender();
this$1._updateRender();
if (lastRoute.path === this$1.route.path) {
this$1.$resetEvents(params.source);
return;
}
this$1.$fetch(noop, this$1.$resetEvents.bind(this$1, params.source));
lastRoute = this$1.route;
});
};
return Router;
}(Base));
}
var RGX = /([^{]*?)\w(?=\})/g;
var MAP = {
YYYY: 'getFullYear',
YY: 'getYear',
MM: function (d) {
return d.getMonth() + 1;
},
DD: 'getDate',
HH: 'getHours',
mm: 'getMinutes',
ss: 'getSeconds',
fff: 'getMilliseconds'
};
function tinydate (str, custom) {
var parts=[], offset=0;
str.replace(RGX, function (key, _, idx) {
// save preceding string
parts.push(str.substring(offset, idx - 1));
offset = idx += key.length + 1;
// save function
parts.push(custom && custom[key] || function (d) {
return ('00' + (typeof MAP[key] === 'string' ? d[MAP[key]]() : MAP[key](d))).slice(-key.length);
});
});
if (offset !== str.length) {
parts.push(str.substring(offset));
}
return function (arg) {
var out='', i=0, d=arg||new Date();
for (; i<parts.length; i++) {
out += (typeof parts[i]==='string') ? parts[i] : parts[i](d);
}
return out;
};
}
var barEl;
var timeId;
/**
* Init progress component
*/
function init() {
var div = create('div');
div.classList.add('progress');
appendTo(body, div);
barEl = div;
}
/**
* Render progress bar
*/
function progressbar (ref) {
var loaded = ref.loaded;
var total = ref.total;
var step = ref.step;
var num;
!barEl && init();
if (step) {
num = parseInt(barEl.style.width || 0, 10) + step;
num = num > 80 ? 80 : num;
} else {
num = Math.floor((loaded / total) * 100);
}
barEl.style.opacity = 1;
barEl.style.width = num >= 95 ? '100%' : num + '%';
if (num >= 95) {
clearTimeout(timeId);
// eslint-disable-next-line no-unused-vars
timeId = setTimeout(function (_) {
barEl.style.opacity = 0;
barEl.style.width = '0%';
}, 200);
}
}
/* eslint-disable no-unused-vars */
var cache = {};
/**
* Ajax GET implmentation
* @param {string} url Resource URL
* @param {boolean} [hasBar=false] Has progress bar
* @param {String[]} headers Array of headers
* @return {Promise} Promise response
*/
function get(url, hasBar, headers) {
if ( hasBar === void 0 ) hasBar = false;
if ( headers === void 0 ) headers = {};
var xhr = new XMLHttpRequest();
var on = function () {
xhr.addEventListener.apply(xhr, arguments);
};
var cached = cache[url];
if (cached) {
return { then: function (cb) { return cb(cached.content, cached.opt); }, abort: noop };
}
xhr.open('GET', url);
for (var i in headers) {
if (hasOwn.call(headers, i)) {
xhr.setRequestHeader(i, headers[i]);
}
}
xhr.send();
return {
then: function (success, error) {
if ( error === void 0 ) error = noop;
if (hasBar) {
var id = setInterval(
function (_) { return progressbar({
step: Math.floor(Math.random() * 5 + 1),
}); },
500
);
on('progress', progressbar);
on('loadend', function (evt) {
progressbar(evt);
clearInterval(id);
});
}
on('error', error);
on('load', function (ref) {
var target = ref.target;
if (target.status >= 400) {
error(target);
} else {
var result = (cache[url] = {
content: target.response,
opt: {
updatedAt: xhr.getResponseHeader('last-modified'),
},
});
success(result.content, result.opt);
}
});
},
abort: function (_) { return xhr.readyState !== 4 && xhr.abort(); },
};
}
function replaceVar(block, color) {
block.innerHTML = block.innerHTML.replace(
/var\(\s*--theme-color.*?\)/g,
color
);
}
function cssVars (color) {
// Variable support
if (window.CSS && window.CSS.supports && window.CSS.supports('(--v:red)')) {
return;
}
var styleBlocks = findAll('style:not(.inserted),link');
[].forEach.call(styleBlocks, function (block) {
if (block.nodeName === 'STYLE') {
replaceVar(block, color);
} else if (block.nodeName === 'LINK') {
var href = block.getAttribute('href');
if (!/\.css$/.test(href)) {
return;
}
get(href).then(function (res) {
var style = create('style', res);
head.appendChild(style);
replaceVar(style, color);
});
}
});
}
/* eslint-disable no-unused-vars */
var title = $.title;
/**
* Toggle button
* @param {Element} el Button to be toggled
* @void
*/
function btn(el) {
var toggle = function (_) { return body.classList.toggle('close'); };
el = getNode(el);
if (el === null || el === undefined) {
return;
}
on(el, 'click', function (e) {
e.stopPropagation();
toggle();
});
isMobile &&
on(
body,
'click',
function (_) { return body.classList.contains('close') && toggle(); }
);
}
function collapse(el) {
el = getNode(el);
if (el === null || el === undefined) {
return;
}
on(el, 'click', function (ref) {
var target = ref.target;
if (
target.nodeName === 'A' &&
target.nextSibling &&
target.nextSibling.classList &&
target.nextSibling.classList.contains('app-sub-sidebar')
) {
toggleClass(target.parentNode, 'collapse');
}
});
}
function sticky() {
var cover = getNode('section.cover');
if (!cover) {
return;
}
var coverHeight = cover.getBoundingClientRect().height;
if (window.pageYOffset >= coverHeight || cover.classList.contains('hidden')) {
toggleClass(body, 'add', 'sticky');
} else {
toggleClass(body, 'remove', 'sticky');
}
}
/**
* Get and active link
* @param {Object} router Router
* @param {String|Element} el Target element
* @param {Boolean} isParent Active parent
* @param {Boolean} autoTitle Automatically set title
* @return {Element} Active element
*/
function getAndActive(router, el, isParent, autoTitle) {
el = getNode(el);
var links = [];
if (el !== null && el !== undefined) {
links = findAll(el, 'a');
}
var hash = decodeURI(router.toURL(router.getCurrentPath()));
var target;
links
.sort(function (a, b) { return b.href.length - a.href.length; })
.forEach(function (a) {
var href = decodeURI(a.getAttribute('href'));
var node = isParent ? a.parentNode : a;
a.title = a.title || a.innerText;
if (hash.indexOf(href) === 0 && !target) {
target = a;
toggleClass(node, 'add', 'active');
} else {
toggleClass(node, 'remove', 'active');
}
});
if (autoTitle) {
$.title = target
? target.title || ((target.innerText) + " - " + title)
: title;
}
return target;
}
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) { descriptor.writable = true; } Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) { defineProperties(Constructor.prototype, protoProps); } if (staticProps) { defineProperties(Constructor, staticProps); } return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var SingleTweener = function () {
function SingleTweener() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, SingleTweener);
this.start = opts.start;
this.end = opts.end;
this.decimal = opts.decimal;
}
_createClass(SingleTweener, [{
key: "getIntermediateValue",
value: function getIntermediateValue(tick) {
if (this.decimal) {
return tick;
} else {
return Math.round(tick);
}
}
}, {
key: "getFinalValue",
value: function getFinalValue() {
return this.end;
}
}]);
return SingleTweener;
}();
var _createClass$1 = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) { descriptor.writable = true; } Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) { defineProperties(Constructor.prototype, protoProps); } if (staticProps) { defineProperties(Constructor, staticProps); } return Constructor; }; }();
function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Tweezer = function () {
function Tweezer() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck$1(this, Tweezer);
this.duration = opts.duration || 1000;
this.ease = opts.easing || this._defaultEase;
this.tweener = opts.tweener || new SingleTweener(opts);
this.start = this.tweener.start;
this.end = this.tweener.end;
this.frame = null;
this.next = null;
this.isRunning = false;
this.events = {};
this.direction = this.start < this.end ? 'up' : 'down';
}
_createClass$1(Tweezer, [{
key: 'begin',
value: function begin() {
if (!this.isRunning && this.next !== this.end) {
this.frame = window.requestAnimationFrame(this._tick.bind(this));
}
return this;
}
}, {
key: 'stop',
value: function stop() {
window.cancelAnimationFrame(this.frame);
this.isRunning = false;
this.frame = null;
this.timeStart = null;
this.next = null;
return this;
}
}, {
key: 'on',
value: function on(name, handler) {
this.events[name] = this.events[name] || [];
this.events[name].push(handler);
return this;
}
}, {
key: '_emit',
value: function _emit(name, val) {
var _this = this;
var e = this.events[name];
e && e.forEach(function (handler) {
return handler.call(_this, val);
});
}
}, {
key: '_tick',
value: function _tick(currentTime) {
this.isRunning = true;
var lastTick = this.next || this.start;
if (!this.timeStart) { this.timeStart = currentTime; }
this.timeElapsed = currentTime - this.timeStart;
this.next = this.ease(this.timeElapsed, this.start, this.end - this.start, this.duration);
if (this._shouldTick(lastTick)) {
this._emit('tick', this.tweener.getIntermediateValue(this.next));
this.frame = window.requestAnimationFrame(this._tick.bind(this));
} else {
this._emit('tick', this.tweener.getFinalValue());
this._emit('done', null);
}
}
}, {
key: '_shouldTick',
value: function _shouldTick(lastTick) {
return {
up: this.next < this.end && lastTick <= this.next,
down: this.next > this.end && lastTick >= this.next
}[this.direction];
}
}, {
key: '_defaultEase',
value: function _defaultEase(t, b, c, d) {
if ((t /= d / 2) < 1) { return c / 2 * t * t + b; }
return -c / 2 * (--t * (t - 2) - 1) + b;
}
}]);
return Tweezer;
}();
var currentScript = document.currentScript;
/** @param {import('./Docsify').Docsify} vm */
function config (vm) {
var config = merge(
{
auto2top: false,
autoHeader: false,
basePath: '',
catchPluginErrors: true,
cornerExternalLinkTarget: '_blank',
coverpage: '',
el: '#app',
executeScript: null,
ext: '.md',
externalLinkRel: 'noopener',
externalLinkTarget: '_blank',
formatUpdated: '',
ga: '',
homepage: 'README.md',
loadNavbar: null,
loadSidebar: null,
maxLevel: 6,
mergeNavbar: false,
name: '',
nameLink: window.location.pathname,
nativeEmoji: false,
noCompileLinks: [],
noEmoji: false,
notFoundPage: true,
relativePath: false,
repo: '',
routes: {},
routerMode: 'hash',
subMaxLevel: 0,
themeColor: '',
topMargin: 0,
},
typeof window.$docsify === 'function'
? window.$docsify(vm)
: window.$docsify
);
var script =
currentScript ||
[].slice
.call(document.getElementsByTagName('script'))
.filter(function (n) { return /docsify\./.test(n.src); })[0];
if (script) {
for (var prop in config) {
if (hasOwn.call(config, prop)) {
var val = script.getAttribute('data-' + hyphenate(prop));
if (isPrimitive(val)) {
config[prop] = val === '' ? true : val;
}
}
}
}
if (config.loadSidebar === true) {
config.loadSidebar = '_sidebar' + config.ext;
}
if (config.loadNavbar === true) {
config.loadNavbar = '_navbar' + config.ext;
}
if (config.coverpage === true) {
config.coverpage = '_coverpage' + config.ext;
}
if (config.repo === true) {
config.repo = '';
}
if (config.name === true) {
config.name = '';
}
window.$docsify = config;
return config;
}
var nav = {};
var hoverOver = false;
var scroller = null;
var enableScrollEvent = true;
var coverHeight = 0;
function scrollTo(el, offset) {
if ( offset === void 0 ) offset = 0;
if (scroller) {
scroller.stop();
}
enableScrollEvent = false;
scroller = new Tweezer({
start: window.pageYOffset,
end:
Math.round(el.getBoundingClientRect().top) + window.pageYOffset - offset,
duration: 500,
})
.on('tick', function (v) { return window.scrollTo(0, v); })
.on('done', function () {
enableScrollEvent = true;
scroller = null;
})
.begin();
}
function highlight(path) {
if (!enableScrollEvent) {
return;
}
var sidebar = getNode('.sidebar');
var anchors = findAll('.anchor');
var wrap = find(sidebar, '.sidebar-nav');
var active = find(sidebar, 'li.active');
var doc = document.documentElement;
var top = ((doc && doc.scrollTop) || document.body.scrollTop) - coverHeight;
var last;
for (var i = 0, len = anchors.length; i < len; i += 1) {
var node = anchors[i];
if (node.offsetTop > top) {
if (!last) {
last = node;
}
break;
} else {
last = node;
}
}
if (!last) {
return;
}
var li = nav[getNavKey(path, last.getAttribute('data-id'))];
if (!li || li === active) {
return;
}
active && active.classList.remove('active');
li.classList.add('active');
active = li;
// Scroll into view
// https://github.com/vuejs/vuejs.org/blob/master/themes/vue/source/js/common.js#L282-L297
if (!hoverOver && body.classList.contains('sticky')) {
var height = sidebar.clientHeight;
var curOffset = 0;
var cur = active.offsetTop + active.clientHeight + 40;
var isInView =
active.offsetTop >= wrap.scrollTop && cur <= wrap.scrollTop + height;
var notThan = cur - curOffset < height;
sidebar.scrollTop = isInView
? wrap.scrollTop
: notThan
? curOffset
: cur - height;
}
}
function getNavKey(path, id) {
return ((decodeURIComponent(path)) + "?id=" + (decodeURIComponent(id)));
}
function scrollActiveSidebar(router) {
var cover = find('.cover.show');
coverHeight = cover ? cover.offsetHeight : 0;
var sidebar = getNode('.sidebar');
var lis = [];
if (sidebar !== null && sidebar !== undefined) {
lis = findAll(sidebar, 'li');
}
for (var i = 0, len = lis.length; i < len; i += 1) {
var li = lis[i];
var a = li.querySelector('a');
if (!a) {
continue;
}
var href = a.getAttribute('href');
if (href !== '/') {
var ref = router.parse(href);
var id = ref.query.id;
var path$1 = ref.path;
if (id) {
href = getNavKey(path$1, id);
}
}
if (href) {
nav[decodeURIComponent(href)] = li;
}
}
if (isMobile) {
return;
}
var path = removeParams(router.getCurrentPath());
off('scroll', function () { return highlight(path); });
on('scroll', function () { return highlight(path); });
on(sidebar, 'mouseover', function () {
hoverOver = true;
});
on(sidebar, 'mouseleave', function () {
hoverOver = false;
});
}
function scrollIntoView(path, id) {
if (!id) {
return;
}
var topMargin = config().topMargin;
var section = find('#' + id);
section && scrollTo(section, topMargin);
var li = nav[getNavKey(path, id)];
var sidebar = getNode('.sidebar');
var active = find(sidebar, 'li.active');
active && active.classList.remove('active');
li && li.classList.add('active');
}
var scrollEl = $.scrollingElement || $.documentElement;
function scroll2Top(offset) {
if ( offset === void 0 ) offset = 0;
scrollEl.scrollTop = offset === true ? 0 : Number(offset);
}
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var defaults = createCommonjsModule(function (module) {
function getDefaults() {
return {
baseUrl: null,
breaks: false,
gfm: true,
headerIds: true,
headerPrefix: '',
highlight: null,
langPrefix: 'language-',
mangle: true,
pedantic: false,
renderer: null,
sanitize: false,
sanitizer: null,
silent: false,
smartLists: false,
smartypants: false,
tokenizer: null,
walkTokens: null,
xhtml: false
};
}
function changeDefaults(newDefaults) {
module.exports.defaults = newDefaults;
}
module.exports = {
defaults: getDefaults(),
getDefaults: getDefaults,
changeDefaults: changeDefaults
};
});
var defaults_1 = defaults.defaults;
var defaults_2 = defaults.getDefaults;
var defaults_3 = defaults.changeDefaults;
/**
* Helpers
*/
var escapeTest = /[&<>"']/;
var escapeReplace = /[&<>"']/g;
var escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/;
var escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g;
var escapeReplacements = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
var getEscapeReplacement = function (ch) { return escapeReplacements[ch]; };
function escape(html, encode) {
if (encode) {
if (escapeTest.test(html)) {
return html.replace(escapeReplace, getEscapeReplacement);
}
} else {
if (escapeTestNoEncode.test(html)) {
return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
}
}
return html;
}
var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
function unescape(html) {
// explicitly match decimal, hex, and named HTML entities
return html.replace(unescapeTest, function (_, n) {
n = n.toLowerCase();
if (n === 'colon') { return ':'; }
if (n.charAt(0) === '#') {
return n.charAt(1) === 'x'
? String.fromCharCode(parseInt(n.substring(2), 16))
: String.fromCharCode(+n.substring(1));
}
return '';
});
}
var caret = /(^|[^\[])\^/g;
function edit(regex, opt) {
regex = regex.source || regex;
opt = opt || '';
var obj = {
replace: function (name, val) {
val = val.source || val;
val = val.replace(caret, '$1');
regex = regex.replace(name, val);
return obj;
},
getRegex: function () {
return new RegExp(regex, opt);
}
};
return obj;
}
var nonWordAndColonTest = /[^\w:]/g;
var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
function cleanUrl(sanitize, base, href) {
if (sanitize) {
var prot;
try {
prot = decodeURIComponent(unescape(href))
.replace(nonWordAndColonTest, '')
.toLowerCase();
} catch (e) {
return null;
}
if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
return null;
}
}
if (base && !originIndependentUrl.test(href)) {
href = resolveUrl(base, href);
}
try {
href = encodeURI(href).replace(/%25/g, '%');
} catch (e) {
return null;
}
return href;
}
var baseUrls = {};
var justDomain = /^[^:]+:\/*[^/]*$/;
var protocol = /^([^:]+:)[\s\S]*$/;
var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
function resolveUrl(base, href) {
if (!baseUrls[' ' + base]) {
// we can ignore everything in base after the last slash of its path component,
// but we might need to add _that_
// https://tools.ietf.org/html/rfc3986#section-3
if (justDomain.test(base)) {
baseUrls[' ' + base] = base + '/';
} else {
baseUrls[' ' + base] = rtrim(base, '/', true);
}
}
base = baseUrls[' ' + base];
var relativeBase = base.indexOf(':') === -1;
if (href.substring(0, 2) === '//') {
if (relativeBase) {
return href;
}
return base.replace(protocol, '$1') + href;
} else if (href.charAt(0) === '/') {
if (relativeBase) {
return href;
}
return base.replace(domain, '$1') + href;
} else {
return base + href;
}
}
var noopTest = { exec: function noopTest() {} };
function merge$1(obj) {
var arguments$1 = arguments;
var i = 1,
target,
key;
for (; i < arguments.length; i++) {
target = arguments$1[i];
for (key in target) {
if (Object.prototype.hasOwnProperty.call(target, key)) {
obj[key] = target[key];
}
}
}
return obj;
}
function splitCells(tableRow, count) {
// ensure that every cell-delimiting pipe has a space
// before it to distinguish it from an escaped pipe
var row = tableRow.replace(/\|/g, function (match, offset, str) {
var escaped = false,
curr = offset;
while (--curr >= 0 && str[curr] === '\\') { escaped = !escaped; }
if (escaped) {
// odd number of slashes means | is escaped
// so we leave it alone
return '|';
} else {
// add space before unescaped |
return ' |';
}
}),
cells = row.split(/ \|/);
var i = 0;
if (cells.length > count) {
cells.splice(count);
} else {
while (cells.length < count) { cells.push(''); }
}
for (; i < cells.length; i++) {
// leading or trailing whitespace is ignored per the gfm spec
cells[i] = cells[i].trim().replace(/\\\|/g, '|');
}
return cells;
}
// Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
// /c*$/ is vulnerable to REDOS.
// invert: Remove suffix of non-c chars instead. Default falsey.
function rtrim(str, c, invert) {
var l = str.length;
if (l === 0) {
return '';
}
// Length of suffix matching the invert condition.
var suffLen = 0;
// Step left until we fail to match the invert condition.
while (suffLen < l) {
var currChar = str.charAt(l - suffLen - 1);
if (currChar === c && !invert) {
suffLen++;
} else if (currChar !== c && invert) {
suffLen++;
} else {
break;
}
}
return str.substr(0, l - suffLen);
}
function findClosingBracket(str, b) {
if (str.indexOf(b[1]) === -1) {
return -1;
}
var l = str.length;
var level = 0,
i = 0;
for (; i < l; i++) {
if (str[i] === '\\') {
i++;
} else if (str[i] === b[0]) {
level++;
} else if (str[i] === b[1]) {
level--;
if (level < 0) {
return i;
}
}
}
return -1;
}
function checkSanitizeDeprecation(opt) {
if (opt && opt.sanitize && !opt.silent) {
console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');
}
}
// copied from https://stackoverflow.com/a/5450113/806777
function repeatString(pattern, count) {
if (count < 1) {
return '';
}
var result = '';
while (count > 1) {
if (count & 1) {
result += pattern;
}
count >>= 1;
pattern += pattern;
}
return result + pattern;
}
var helpers = {
escape: escape,
unescape: unescape,
edit: edit,
cleanUrl: cleanUrl,
resolveUrl: resolveUrl,
noopTest: noopTest,
merge: merge$1,
splitCells: splitCells,
rtrim: rtrim,
findClosingBracket: findClosingBracket,
checkSanitizeDeprecation: checkSanitizeDeprecation,
repeatString: repeatString
};
var defaults$1 = defaults.defaults;
var rtrim$1 = helpers.rtrim;
var splitCells$1 = helpers.splitCells;
var escape$1 = helpers.escape;
var findClosingBracket$1 = helpers.findClosingBracket;
function outputLink(cap, link, raw) {
var href = link.href;
var title = link.title ? escape$1(link.title) : null;
var text = cap[1].replace(/\\([\[\]])/g, '$1');
if (cap[0].charAt(0) !== '!') {
return {
type: 'link',
raw: raw,
href: href,
title: title,
text: text
};
} else {
return {
type: 'image',
raw: raw,
href: href,
title: title,
text: escape$1(text)
};
}
}
function indentCodeCompensation(raw, text) {
var matchIndentToCode = raw.match(/^(\s+)(?:```)/);
if (matchIndentToCode === null) {
return text;
}
var indentToCode = matchIndentToCode[1];
return text
.split('\n')
.map(function (node) {
var matchIndentInNode = node.match(/^\s+/);
if (matchIndentInNode === null) {
return node;
}
var indentInNode = matchIndentInNode[0];
if (indentInNode.length >= indentToCode.length) {
return node.slice(indentToCode.length);
}
return node;
})
.join('\n');
}
/**
* Tokenizer
*/
var Tokenizer = /*@__PURE__*/(function () {
function Tokenizer(options) {
this.options = options || defaults$1;
}
Tokenizer.prototype.space = function space (src) {
var cap = this.rules.block.newline.exec(src);
if (cap) {
if (cap[0].length > 1) {
return {
type: 'space',
raw: cap[0]
};
}
return { raw: '\n' };
}
};
Tokenizer.prototype.code = function code (src, tokens) {
var cap = this.rules.block.code.exec(src);
if (cap) {
var lastToken = tokens[tokens.length - 1];
// An indented code block cannot interrupt a paragraph.
if (lastToken && lastToken.type === 'paragraph') {
return {
raw: cap[0],
text: cap[0].trimRight()
};
}
var text = cap[0].replace(/^ {1,4}/gm, '');
return {
type: 'code',
raw: cap[0],
codeBlockStyle: 'indented',
text: !this.options.pedantic
? rtrim$1(text, '\n')
: text
};
}
};
Tokenizer.prototype.fences = function fences (src) {
var cap = this.rules.block.fences.exec(src);
if (cap) {
var raw = cap[0];
var text = indentCodeCompensation(raw, cap[3] || '');
return {
type: 'code',
raw: raw,
lang: cap[2] ? cap[2].trim() : cap[2],
text: text
};
}
};
Tokenizer.prototype.heading = function heading (src) {
var cap = this.rules.block.heading.exec(src);
if (cap) {
var text = cap[2].trim();
// remove trailing #s
if (/#$/.test(text)) {
var trimmed = rtrim$1(text, '#');
if (this.options.pedantic) {
text = trimmed.trim();
} else if (!trimmed || / $/.test(trimmed)) {
// CommonMark requires space before trailing #s
text = trimmed.trim();
}
}
return {
type: 'heading',
raw: cap[0],
depth: cap[1].length,
text: text
};
}
};
Tokenizer.prototype.nptable = function nptable (src) {
var cap = this.rules.block.nptable.exec(src);
if (cap) {
var item = {
type: 'table',
header: splitCells$1(cap[1].replace(/^ *| *\| *$/g, '')),
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : [],
raw: cap[0]
};
if (item.header.length === item.align.length) {
var l = item.align.length;
var i;
for (i = 0; i < l; i++) {
if (/^ *-+: *$/.test(item.align[i])) {
item.align[i] = 'right';
} else if (/^ *:-+: *$/.test(item.align[i])) {
item.align[i] = 'center';
} else if (/^ *:-+ *$/.test(item.align[i])) {
item.align[i] = 'left';
} else {
item.align[i] = null;
}
}
l = item.cells.length;
for (i = 0; i < l; i++) {
item.cells[i] = splitCells$1(item.cells[i], item.header.length);
}
return item;
}
}
};
T