stuff
This commit is contained in:
parent
bc92231240
commit
b8225c639e
11904 changed files with 1472749 additions and 133 deletions
141
node_modules/mathjax-full/ts/components/global.ts
generated
vendored
Normal file
141
node_modules/mathjax-full/ts/components/global.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Handles using MathJax global as config object, and to hold
|
||||
* methods and data to be available to the page author
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide Cervone)
|
||||
*/
|
||||
|
||||
import {VERSION} from './version.js';
|
||||
|
||||
/**
|
||||
* The MathJax variable as a configuration object
|
||||
*/
|
||||
export interface MathJaxConfig {
|
||||
[name: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* The object used to store class and other definitions
|
||||
* from the various MathJax modules so that they can be shared
|
||||
* among the various component webpack files
|
||||
*/
|
||||
export interface MathJaxLibrary {
|
||||
[name: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* The MathJax global object structure
|
||||
*/
|
||||
export interface MathJaxObject {
|
||||
version: string;
|
||||
_: MathJaxLibrary;
|
||||
config: MathJaxConfig;
|
||||
}
|
||||
|
||||
declare const global: {MathJax: MathJaxObject | MathJaxConfig};
|
||||
|
||||
/**
|
||||
* @param {any} x An item to test if it is an object
|
||||
* @return {boolean} True if the item is a non-null object
|
||||
*/
|
||||
export function isObject(x: any): boolean {
|
||||
return typeof x === 'object' && x !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine user-produced configuration with existing defaults. Values
|
||||
* from src will replace those in dst.
|
||||
*
|
||||
* @param {any} dst The destination config object (to be merged into)
|
||||
* @param {any} src The source configuration object (to replace defaul values in dst}
|
||||
* @return {any} The resulting (modified) config object
|
||||
*/
|
||||
export function combineConfig(dst: any, src: any): any {
|
||||
for (const id of Object.keys(src)) {
|
||||
if (id === '__esModule') continue;
|
||||
if (isObject(dst[id]) && isObject(src[id]) &&
|
||||
!(src[id] instanceof Promise) /* needed for IE polyfill */) {
|
||||
combineConfig(dst[id], src[id]);
|
||||
} else if (src[id] !== null && src[id] !== undefined) {
|
||||
dst[id] = src[id];
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine defaults into a configuration that may already have
|
||||
* user-provided values. Values in src only go into dst if
|
||||
* there is not already a value for that key.
|
||||
*
|
||||
* @param {any} dst The destination config object (to be merged into)
|
||||
* @param {string} name The id of the configuration block to modify (created if doesn't exist)
|
||||
* @param {any} src The source configuration object (to replace defaul values in dst}
|
||||
* @return {any} The resulting (modified) config object
|
||||
*/
|
||||
export function combineDefaults(dst: any, name: string, src: any): any {
|
||||
if (!dst[name]) {
|
||||
dst[name] = {};
|
||||
}
|
||||
dst = dst[name];
|
||||
for (const id of Object.keys(src)) {
|
||||
if (isObject(dst[id]) && isObject(src[id])) {
|
||||
combineDefaults(dst, id, src[id]);
|
||||
} else if (dst[id] == null && src[id] != null) {
|
||||
dst[id] = src[id];
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine configuration or data with the existing MathJax object
|
||||
*
|
||||
* @param {any} config The data to be merged into the MathJax object
|
||||
*/
|
||||
export function combineWithMathJax(config: any): MathJaxObject {
|
||||
return combineConfig(MathJax, config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the MathJax global, if it doesn't exist
|
||||
*/
|
||||
if (typeof global.MathJax === 'undefined') {
|
||||
global.MathJax = {} as MathJaxConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the global is currently a config object, convert it to the
|
||||
* MathJaxObject containing the version, class library, and user
|
||||
* configuration.
|
||||
*/
|
||||
if (!(global.MathJax as MathJaxObject).version) {
|
||||
global.MathJax = {
|
||||
version: VERSION,
|
||||
_: {},
|
||||
config: global.MathJax
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the global MathJax object for convenience
|
||||
*/
|
||||
export const MathJax = global.MathJax as MathJaxObject;
|
||||
407
node_modules/mathjax-full/ts/components/latest.ts
generated
vendored
Normal file
407
node_modules/mathjax-full/ts/components/latest.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,407 @@
|
|||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The data for a CDN
|
||||
*/
|
||||
type CdnData = {
|
||||
api: string, // URL for JSON containing version number
|
||||
key: string, // key for versionb string in JSON data
|
||||
base?: string // base URL for MathJax on the CDN (version is appended to get actual URL)
|
||||
};
|
||||
|
||||
/**
|
||||
* A map of server names to CDN data
|
||||
*/
|
||||
type CdnList = Map<string, CdnData>;
|
||||
|
||||
/**
|
||||
* The data from a script tag for latest.js
|
||||
*/
|
||||
type ScriptData = {
|
||||
tag: HTMLScriptElement, // the script DOM element
|
||||
src: string, // the script's (possibly modified) source attribute
|
||||
id: string, // the script's (possibly empty) id string
|
||||
version: string, // the MathJax version where latest.js was loaded
|
||||
dir: string, // the subdirectory where latest.js was loaded from (e.g., /es5)
|
||||
file: string, // the file to be loaded by latest.js
|
||||
cdn: CdnData // the CDN where latest.js was loaded
|
||||
} | null;
|
||||
|
||||
/**
|
||||
* Add XMLHttpRequest and ActiveXObject (for IE)
|
||||
*/
|
||||
declare const window: {
|
||||
XMLHttpRequest: XMLHttpRequest;
|
||||
ActiveXObject: any;
|
||||
};
|
||||
|
||||
/*=====================================================================*/
|
||||
|
||||
|
||||
/**
|
||||
* The various CDNs and their data for how to obtain versions
|
||||
*/
|
||||
const CDN: CdnList = new Map([
|
||||
['cdnjs.cloudflare.com', {
|
||||
api: 'https://api.cdnjs.com/libraries/mathjax?fields=version',
|
||||
key: 'version',
|
||||
base: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/'
|
||||
}],
|
||||
|
||||
['rawcdn.githack.com', {
|
||||
api: 'https://api.github.com/repos/mathjax/mathjax/releases/latest',
|
||||
key: 'tag_name',
|
||||
base: 'https://rawcdn.githack.com/mathjax/MathJax/'
|
||||
}],
|
||||
|
||||
['gitcdn.xyz', {
|
||||
api: 'https://api.github.com/repos/mathjax/mathjax/releases/latest',
|
||||
key: 'tag_name',
|
||||
base: 'https://gitcdn.xyz/mathjax/MathJax/'
|
||||
}],
|
||||
|
||||
['cdn.statically.io', {
|
||||
api: 'https://api.github.com/repos/mathjax/mathjax/releases/latest',
|
||||
key: 'tag_name',
|
||||
base: 'https://cdn.statically.io/gh/mathjax/MathJax/'
|
||||
}],
|
||||
|
||||
['unpkg.com', {
|
||||
api: 'https://api.github.com/repos/mathjax/mathjax/releases/latest',
|
||||
key: 'tag_name',
|
||||
base: 'https://unpkg.com/mathjax@'
|
||||
}],
|
||||
|
||||
['cdn.jsdelivr.net', {
|
||||
api: 'https://api.github.com/repos/mathjax/mathjax/releases/latest',
|
||||
key: 'tag_name',
|
||||
base: 'https://cdn.jsdelivr.net/npm/mathjax@'
|
||||
}]
|
||||
]);
|
||||
|
||||
/**
|
||||
* The data for getting release versions from GitHub
|
||||
*/
|
||||
const GITHUB: CdnData = {
|
||||
api: 'https://api.github.com/repos/mathjax/mathjax/releases',
|
||||
key: 'tag_name'
|
||||
};
|
||||
|
||||
/**
|
||||
* The major version number for MathJax (we will load the highest version with this initial number)
|
||||
*/
|
||||
const MJX_VERSION = 3;
|
||||
|
||||
/**
|
||||
* The name to use for the version in localStorage
|
||||
*/
|
||||
const MJX_LATEST = 'mjx-latest-version';
|
||||
|
||||
/**
|
||||
* The amount of time a cached version number is valid
|
||||
*/
|
||||
const SAVE_TIME = 1000 * 60 * 60 * 24 * 7; // one week
|
||||
|
||||
/**
|
||||
* Data for the script that loaded latest.js
|
||||
*/
|
||||
let script: ScriptData = null;
|
||||
|
||||
/*=====================================================================*/
|
||||
|
||||
/**
|
||||
* Produce an error message on the console
|
||||
*
|
||||
* @param {string} message The error message to display
|
||||
*/
|
||||
function Error(message: string) {
|
||||
if (console && console.error) {
|
||||
console.error('MathJax(latest.js): ' + message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ScriptData object from the given script tag and CDN
|
||||
*
|
||||
* @param {HTMLScriptElement} script The script tag whose data is desired
|
||||
* @param {CdnData} cdn The CDN data already obtained for the script (or null)
|
||||
* @return {ScriptData} The data for the given script
|
||||
*/
|
||||
function scriptData(script: HTMLScriptElement, cdn: CdnData = null): ScriptData {
|
||||
script.parentNode.removeChild(script);
|
||||
let src = script.src;
|
||||
let file = src.replace(/.*?\/latest\.js(\?|$)/, '');
|
||||
if (file === '') {
|
||||
file = 'startup.js';
|
||||
src = src.replace(/\?$/, '') + '?' + file;
|
||||
}
|
||||
const version = (src.match(/(\d+\.\d+\.\d+)(\/es\d+)?\/latest.js\?/) || ['', ''])[1];
|
||||
const dir = (src.match(/(\/es\d+)\/latest.js\?/) || ['', ''])[1] || '';
|
||||
return {
|
||||
tag: script,
|
||||
src: src,
|
||||
id: script.id,
|
||||
version: version,
|
||||
dir: dir,
|
||||
file: file,
|
||||
cdn: cdn
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a script refers to MathJax on one of the CDNs
|
||||
*
|
||||
* @param {HTMLScriptElement} script The script tag to check
|
||||
* @return {ScriptData | null} Non-null if the script is from a MathJax CDN
|
||||
*/
|
||||
function checkScript(script: HTMLScriptElement): ScriptData | null {
|
||||
for (const server of CDN.keys()) {
|
||||
const cdn = CDN.get(server);
|
||||
const url = cdn.base;
|
||||
const src = script.src;
|
||||
if (src && src.substr(0, url.length) === url && src.match(/\/latest\.js(\?|$)/)) {
|
||||
return scriptData(script, cdn);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {ScriptData} The data for the script tag that loaded latest.js
|
||||
*/
|
||||
function getScript(): ScriptData {
|
||||
if (document.currentScript) {
|
||||
return scriptData(document.currentScript as HTMLScriptElement);
|
||||
}
|
||||
const script = document.getElementById('MathJax-script') as HTMLScriptElement;
|
||||
if (script && script.nodeName.toLowerCase() === 'script') {
|
||||
return checkScript(script);
|
||||
}
|
||||
const scripts = document.getElementsByTagName('script');
|
||||
for (const script of Array.from(scripts)) {
|
||||
const data = checkScript(script);
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*=====================================================================*/
|
||||
|
||||
/**
|
||||
* Save the version and date information in localStorage so we don't
|
||||
* have to contact the CDN for every page that uses MathJax.
|
||||
*
|
||||
* @param {string} version The version to save
|
||||
*/
|
||||
function saveVersion(version: string) {
|
||||
try {
|
||||
const data = version + ' ' + Date.now();
|
||||
localStorage.setItem(MJX_LATEST, data);
|
||||
} catch (err) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version from localStorage, and make sure it is fresh enough to use
|
||||
*
|
||||
* @return {string|null} The version string (if one has been saved) or null (if not)
|
||||
*/
|
||||
function getSavedVersion(): string | null {
|
||||
try {
|
||||
const [version, date] = localStorage.getItem(MJX_LATEST).split(/ /);
|
||||
if (date && Date.now() - parseInt(date) < SAVE_TIME) {
|
||||
return version;
|
||||
}
|
||||
} catch (err) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*=====================================================================*/
|
||||
|
||||
/**
|
||||
* Create a script tag that loads the given URL
|
||||
*
|
||||
* @param {string} url The URL of the javascript file to be loaded
|
||||
* @param {string} id The id to use for the script tag
|
||||
*/
|
||||
function loadMathJax(url: string, id: string) {
|
||||
const script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.async = true;
|
||||
script.src = url;
|
||||
if (id) {
|
||||
script.id = id;
|
||||
}
|
||||
const head = document.head || document.getElementsByTagName('head')[0] || document.body;
|
||||
if (head) {
|
||||
head.appendChild(script);
|
||||
} else {
|
||||
Error('Can\'t find the document <head> element');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When we can't find the current version, use the original URL but remove the "latest.js"
|
||||
*/
|
||||
function loadDefaultMathJax() {
|
||||
if (script) {
|
||||
loadMathJax(script.src.replace(/\/latest\.js\?/, '/'), script.id);
|
||||
} else {
|
||||
Error('Can\'t determine the URL for loading MathJax');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the given version using the base URL and file to load
|
||||
* (if the versions differ, run latest.js from the new version
|
||||
* in case there are important changes there)
|
||||
*
|
||||
* @param {string} version The version of MathJax to load from
|
||||
*/
|
||||
function loadVersion(version: string) {
|
||||
if (script.version && script.version !== version) {
|
||||
script.file = 'latest.js?' + script.file;
|
||||
}
|
||||
loadMathJax(script.cdn.base + version + script.dir + '/' + script.file, script.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given version is acceptable and load it if it is.
|
||||
*
|
||||
* @param {string} version The version to check if it is the latest (valid) one
|
||||
* @return {boolean} True if it is the latest version, false if not
|
||||
*/
|
||||
function checkVersion(version: string): boolean {
|
||||
const major = parseInt(version.split(/\./)[0]);
|
||||
if (major === MJX_VERSION && !version.match(/-(beta|rc)/)) {
|
||||
saveVersion(version);
|
||||
loadVersion(version);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*=====================================================================*/
|
||||
|
||||
/**
|
||||
* Create an XMLHttpRequest object, if possible
|
||||
*
|
||||
* @return {XMLHttpRequest} The XMLHttpRequest instance
|
||||
*/
|
||||
function getXMLHttpRequest(): XMLHttpRequest {
|
||||
if (window.XMLHttpRequest) {
|
||||
return new XMLHttpRequest();
|
||||
}
|
||||
if (window.ActiveXObject) {
|
||||
try { return new window.ActiveXObject('Msxml2.XMLHTTP'); } catch (err) {}
|
||||
try { return new window.ActiveXObject('Microsoft.XMLHTTP'); } catch (err) {}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request JSON data from a CDN. If it loads OK, call the action() function
|
||||
* on the data. If not, or if the action returns false, run the failure() function.
|
||||
*
|
||||
* @param {CdnData} cdn The CDN whose API will be used
|
||||
* @param {Function} action The function to perform when the data are received
|
||||
* @param {Function} failure The function to perform if data can't be obtained,
|
||||
* or if action() returns false
|
||||
*/
|
||||
function requestXML(cdn: CdnData, action: (json: JSON | JSON[]) => boolean, failure: () => void) {
|
||||
const request = getXMLHttpRequest();
|
||||
if (request) {
|
||||
// tslint:disable-next-line:jsdoc-require
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === 4) {
|
||||
if (request.status === 200) {
|
||||
!action(JSON.parse(request.responseText)) && failure();
|
||||
} else {
|
||||
Error('Problem acquiring MathJax version: status = ' + request.status);
|
||||
failure();
|
||||
}
|
||||
}
|
||||
};
|
||||
request.open('GET', cdn.api, true);
|
||||
request.send(null);
|
||||
} else {
|
||||
Error('Can\'t create XMLHttpRequest object');
|
||||
failure();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Look through the list of versions on GitHub and find the first one that
|
||||
* has the MJX_VERSION as its major version number, and load that. If none
|
||||
* is found, run the version from which latest.js was loaded.
|
||||
*/
|
||||
function loadLatestGitVersion() {
|
||||
requestXML(GITHUB, (json: JSON[]) => {
|
||||
if (!(json instanceof Array)) return false;
|
||||
for (const data of json) {
|
||||
if (checkVersion((data as any)[GITHUB.key])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}, loadDefaultMathJax);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the CDN for its latest version, and load that, if it is an
|
||||
* acceptable version, otherwise, (e.g., the current version has a
|
||||
* higher major version that MJX_VERSION), find the highest version on
|
||||
* GitHub with the given major version and use that. If one can't be
|
||||
* found, use the version where latest.js was loaded.
|
||||
*/
|
||||
function loadLatestCdnVersion() {
|
||||
requestXML(script.cdn, function (json) {
|
||||
if (json instanceof Array) {
|
||||
json = json[0];
|
||||
}
|
||||
if (!checkVersion((json as any)[script.cdn.key])) {
|
||||
loadLatestGitVersion();
|
||||
}
|
||||
return true;
|
||||
}, loadDefaultMathJax);
|
||||
}
|
||||
|
||||
/*=====================================================================*/
|
||||
|
||||
|
||||
/**
|
||||
* Find the script that loaded latest.js
|
||||
* If the script is from a known CDN:
|
||||
* Retrieve the cached version (if any)
|
||||
* Load the given version of the file, if the version is cached,
|
||||
* Otherwise find the latest version and load that.
|
||||
* Otherwise,
|
||||
* Load using the version where latest.js was loaded.
|
||||
*/
|
||||
export function loadLatest() {
|
||||
script = getScript();
|
||||
if (script && script.cdn) {
|
||||
const version = getSavedVersion();
|
||||
version ?
|
||||
loadVersion(version) :
|
||||
loadLatestCdnVersion();
|
||||
} else {
|
||||
loadDefaultMathJax();
|
||||
}
|
||||
}
|
||||
305
node_modules/mathjax-full/ts/components/loader.ts
generated
vendored
Normal file
305
node_modules/mathjax-full/ts/components/loader.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview A dynamic loader for loading MathJax components based
|
||||
* on a user configuration, while handling timing of
|
||||
* dependencies properly
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide Cervone)
|
||||
*/
|
||||
|
||||
import {MathJax as MJGlobal, MathJaxObject as MJObject, MathJaxLibrary,
|
||||
MathJaxConfig as MJConfig, combineWithMathJax, combineDefaults} from './global.js';
|
||||
|
||||
import {Package, PackageError, PackageReady, PackageFailed} from './package.js';
|
||||
export {Package, PackageError, PackageReady, PackageFailed} from './package.js';
|
||||
export {MathJaxLibrary} from './global.js';
|
||||
|
||||
import {FunctionList} from '../util/FunctionList.js';
|
||||
|
||||
/*
|
||||
* The current directory (for webpack), and the browser document (if any)
|
||||
*/
|
||||
declare var __dirname: string;
|
||||
declare var document: Document;
|
||||
|
||||
/**
|
||||
* Function used to determine path to a given package.
|
||||
*/
|
||||
export type PathFilterFunction = (data: {name: string, original: string, addExtension: boolean}) => boolean;
|
||||
export type PathFilterList = (PathFilterFunction | [PathFilterFunction, number])[];
|
||||
|
||||
/**
|
||||
* Update the configuration structure to include the loader configuration
|
||||
*/
|
||||
export interface MathJaxConfig extends MJConfig {
|
||||
loader?: {
|
||||
paths?: {[name: string]: string}; // The path prefixes for use in locations
|
||||
source?: {[name: string]: string}; // The URLs for the extensions, e.g., tex: [mathjax]/input/tex.js
|
||||
dependencies?: {[name: string]: string[]}; // The dependencies for each package
|
||||
provides?: {[name: string]: string[]}; // The sub-packages provided by each package
|
||||
load?: string[]; // The packages to load (found in locations or [mathjax]/name])
|
||||
ready?: PackageReady; // A function to call when MathJax is ready
|
||||
failed?: PackageFailed; // A function to call when MathJax fails to load
|
||||
require?: (url: string) => any; // A function for loading URLs
|
||||
pathFilters?: PathFilterList; // List of path filters (and optional priorities) to add
|
||||
versionWarnings?: boolean; // True means warn when extension version doesn't match MJ version
|
||||
[name: string]: any; // Other configuration blocks
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the MathJax object to inclide the loader information
|
||||
*/
|
||||
export interface MathJaxObject extends MJObject {
|
||||
_: MathJaxLibrary;
|
||||
config: MathJaxConfig;
|
||||
loader: {
|
||||
ready: (...names: string[]) => Promise<string[]>; // Get a promise for when all the named packages are loaded
|
||||
load: (...names: string[]) => Promise<string>; // Load the packages and return a promise for when ready
|
||||
preLoad: (...names: string[]) => void; // Indicate that packages are already loaded by hand
|
||||
defaultReady: () => void; // The function performed when all packages are loaded
|
||||
getRoot: () => string; // Find the root URL for the MathJax files
|
||||
checkVersion: (name: string, version: string) => boolean; // Check the version of an extension
|
||||
pathFilters: FunctionList; // the filters to use for looking for package paths
|
||||
};
|
||||
startup?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions used to filter the path to a package
|
||||
*/
|
||||
export const PathFilters: {[name: string]: PathFilterFunction} = {
|
||||
/**
|
||||
* Look up the path in the configuration's source list
|
||||
*/
|
||||
source: (data) => {
|
||||
if (CONFIG.source.hasOwnProperty(data.name)) {
|
||||
data.name = CONFIG.source[data.name];
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add [mathjax] before any relative path, and add .js if needed
|
||||
*/
|
||||
normalize: (data) => {
|
||||
const name = data.name;
|
||||
if (!name.match(/^(?:[a-z]+:\/)?\/|[a-z]:\\|\[/i)) {
|
||||
data.name = '[mathjax]/' + name.replace(/^\.\//, '');
|
||||
}
|
||||
if (data.addExtension && !name.match(/\.[^\/]+$/)) {
|
||||
data.name += '.js';
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Recursively replace path prefixes (e.g., [mathjax], [tex], etc.)
|
||||
*/
|
||||
prefix: (data) => {
|
||||
let match;
|
||||
while ((match = data.name.match(/^\[([^\]]*)\]/))) {
|
||||
if (!CONFIG.paths.hasOwnProperty(match[1])) break;
|
||||
data.name = CONFIG.paths[match[1]] + data.name.substr(match[0].length);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The implementation of the dynamic loader
|
||||
*/
|
||||
export namespace Loader {
|
||||
|
||||
/**
|
||||
* The version of MathJax that is running.
|
||||
*/
|
||||
const VERSION = MJGlobal.version;
|
||||
|
||||
/**
|
||||
* The versions of all the loaded extensions.
|
||||
*/
|
||||
export const versions: Map<string, string> = new Map();
|
||||
|
||||
/**
|
||||
* Get a promise that is resolved when all the named packages have been loaded.
|
||||
*
|
||||
* @param {string[]} names The packages to wait for
|
||||
* @returns {Promise} A promise that resolves when all the named packages are ready
|
||||
*/
|
||||
export function ready(...names: string[]): Promise<string[]> {
|
||||
if (names.length === 0) {
|
||||
names = Array.from(Package.packages.keys());
|
||||
}
|
||||
const promises = [];
|
||||
for (const name of names) {
|
||||
const extension = Package.packages.get(name) || new Package(name, true);
|
||||
promises.push(extension.promise);
|
||||
}
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the named packages and return a promise that is resolved when they are all loaded
|
||||
*
|
||||
* @param {string[]} names The packages to load
|
||||
* @returns {Promise} A promise that resolves when all the named packages are ready
|
||||
*/
|
||||
export function load(...names: string[]): Promise<void | string[]> {
|
||||
if (names.length === 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const promises = [];
|
||||
for (const name of names) {
|
||||
let extension = Package.packages.get(name);
|
||||
if (!extension) {
|
||||
extension = new Package(name);
|
||||
extension.provides(CONFIG.provides[name]);
|
||||
}
|
||||
extension.checkNoLoad();
|
||||
promises.push(extension.promise.then(() => {
|
||||
if (!CONFIG.versionWarnings) return;
|
||||
if (extension.isLoaded && !versions.has(Package.resolvePath(name))) {
|
||||
console.warn(`No version information available for component ${name}`);
|
||||
}
|
||||
}) as Promise<null>);
|
||||
}
|
||||
Package.loadAll();
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the named packages are being loaded by hand (e.g., as part of a larger package).
|
||||
*
|
||||
* @param {string[]} names The packages to load
|
||||
*/
|
||||
export function preLoad(...names: string[]) {
|
||||
for (const name of names) {
|
||||
let extension = Package.packages.get(name);
|
||||
if (!extension) {
|
||||
extension = new Package(name, true);
|
||||
extension.provides(CONFIG.provides[name]);
|
||||
}
|
||||
extension.loaded();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default function to perform when all the packages are loaded
|
||||
*/
|
||||
export function defaultReady() {
|
||||
if (typeof MathJax.startup !== 'undefined') {
|
||||
MathJax.config.startup.ready();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root location for where the MathJax package files are found
|
||||
*
|
||||
* @returns {string} The root location (directory for node.js, URL for browser)
|
||||
*/
|
||||
export function getRoot(): string {
|
||||
let root = __dirname + '/../../es5';
|
||||
if (typeof document !== 'undefined') {
|
||||
const script = document.currentScript || document.getElementById('MathJax-script');
|
||||
if (script) {
|
||||
root = (script as HTMLScriptElement).src.replace(/\/[^\/]*$/, '');
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the version of an extension and report an error if not correct
|
||||
*
|
||||
* @param {string} name The name of the extension being checked
|
||||
* @param {string} version The version of the extension to check
|
||||
* @param {string} type The type of extension (future code may use this to check ranges of versions)
|
||||
* @return {boolean} True if there was a mismatch, false otherwise
|
||||
*/
|
||||
export function checkVersion(name: string, version: string, _type?: string): boolean {
|
||||
versions.set(Package.resolvePath(name), VERSION);
|
||||
if (CONFIG.versionWarnings && version !== VERSION) {
|
||||
console.warn(`Component ${name} uses ${version} of MathJax; version in use is ${VERSION}`);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The filters to use to modify the paths used to obtain the packages
|
||||
*/
|
||||
export const pathFilters = new FunctionList();
|
||||
|
||||
/**
|
||||
* The default filters to use.
|
||||
*/
|
||||
pathFilters.add(PathFilters.source, 0);
|
||||
pathFilters.add(PathFilters.normalize, 10);
|
||||
pathFilters.add(PathFilters.prefix, 20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the global MathJax object for convenience
|
||||
*/
|
||||
export const MathJax = MJGlobal as MathJaxObject;
|
||||
|
||||
/*
|
||||
* If the loader hasn't been added to the MathJax variable,
|
||||
* Add the loader configuration, library, and data objects.
|
||||
* Add any path filters from the configuration.
|
||||
*/
|
||||
if (typeof MathJax.loader === 'undefined') {
|
||||
|
||||
combineDefaults(MathJax.config, 'loader', {
|
||||
paths: {
|
||||
mathjax: Loader.getRoot()
|
||||
},
|
||||
source: {},
|
||||
dependencies: {},
|
||||
provides: {},
|
||||
load: [],
|
||||
ready: Loader.defaultReady.bind(Loader),
|
||||
failed: (error: PackageError) => console.log(`MathJax(${error.package || '?'}): ${error.message}`),
|
||||
require: null,
|
||||
pathFilters: [],
|
||||
versionWarnings: true
|
||||
});
|
||||
combineWithMathJax({
|
||||
loader: Loader
|
||||
});
|
||||
|
||||
//
|
||||
// Add any path filters from the configuration
|
||||
//
|
||||
for (const filter of MathJax.config.loader.pathFilters) {
|
||||
if (Array.isArray(filter)) {
|
||||
Loader.pathFilters.add(filter[0], filter[1]);
|
||||
} else {
|
||||
Loader.pathFilters.add(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the loader configuration for convenience
|
||||
*/
|
||||
export const CONFIG = MathJax.config.loader;
|
||||
426
node_modules/mathjax-full/ts/components/package.ts
generated
vendored
Normal file
426
node_modules/mathjax-full/ts/components/package.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Implements component Package object for handling
|
||||
* dynamic loading of components.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide Cervone)
|
||||
*/
|
||||
|
||||
import {CONFIG, Loader} from './loader.js';
|
||||
|
||||
/*
|
||||
* The browser document (for creating scripts to load components)
|
||||
*/
|
||||
declare var document: Document;
|
||||
|
||||
/**
|
||||
* A map of package names to Package instances
|
||||
*/
|
||||
export type PackageMap = Map<string, Package>;
|
||||
|
||||
/**
|
||||
* An error class that includes the package name
|
||||
*/
|
||||
export class PackageError extends Error {
|
||||
/* tslint:disable:jsdoc-require */
|
||||
public package: string;
|
||||
constructor(message: string, name: string) {
|
||||
super(message);
|
||||
this.package = name;
|
||||
}
|
||||
/* tslint:enable */
|
||||
}
|
||||
|
||||
/**
|
||||
* Types for ready() and failed() functions and for promises
|
||||
*/
|
||||
export type PackageReady = (name: string) => string | void;
|
||||
export type PackageFailed = (message: PackageError) => void;
|
||||
export type PackagePromise = (resolve: PackageReady, reject: PackageFailed) => void;
|
||||
|
||||
/**
|
||||
* The configuration data for a package
|
||||
*/
|
||||
export interface PackageConfig {
|
||||
ready?: PackageReady; // Function to call when package is loaded successfully
|
||||
failed?: PackageFailed; // Function to call when package fails to load
|
||||
checkReady?: () => Promise<void>; // Function called to see if package is fully loaded
|
||||
// (may cause additional packages to load, for example)
|
||||
}
|
||||
|
||||
/**
|
||||
* The Package class for handling individual components
|
||||
*/
|
||||
export class Package {
|
||||
/**
|
||||
* The set of packages being used
|
||||
*/
|
||||
public static packages: PackageMap = new Map();
|
||||
|
||||
/**
|
||||
* The package name
|
||||
*/
|
||||
public name: string;
|
||||
|
||||
/**
|
||||
* True when the package has been loaded successfully
|
||||
*/
|
||||
public isLoaded: boolean = false;
|
||||
|
||||
/**
|
||||
* A promise that resolves when the package is loaded successfully and rejects when it fails to load
|
||||
*/
|
||||
public promise: Promise<string>;
|
||||
|
||||
/**
|
||||
* True when the package is being loaded but hasn't yet finished loading
|
||||
*/
|
||||
protected isLoading: boolean = false;
|
||||
|
||||
/**
|
||||
* True if the package has failed to load
|
||||
*/
|
||||
protected hasFailed: boolean = false;
|
||||
|
||||
/**
|
||||
* True if this package should be loaded automatically (e.g., it was created in reference
|
||||
* to a MathJax.loader.ready() call when the package hasn't been requested to load)
|
||||
*/
|
||||
protected noLoad: boolean;
|
||||
|
||||
/**
|
||||
* The function that resolves the package's promise
|
||||
*/
|
||||
protected resolve: PackageReady;
|
||||
|
||||
/**
|
||||
* The function that rejects the package's promise
|
||||
*/
|
||||
protected reject: PackageFailed;
|
||||
|
||||
/**
|
||||
* The packages that require this one
|
||||
*/
|
||||
protected dependents: Package[] = [];
|
||||
|
||||
/**
|
||||
* The packages that this one depends on
|
||||
*/
|
||||
protected dependencies: Package[] = [];
|
||||
|
||||
/**
|
||||
* The number of dependencies that haven't yet been loaded
|
||||
*/
|
||||
protected dependencyCount: number = 0;
|
||||
|
||||
/**
|
||||
* The sub-packages that this one provides
|
||||
*/
|
||||
protected provided: Package[] = [];
|
||||
|
||||
/**
|
||||
* @return {boolean} True when the package can be loaded (i.e., its dependencies are all loaded,
|
||||
* it is allowed to be loaded, isn't already loading, and hasn't failed to load
|
||||
* in the past)
|
||||
*/
|
||||
get canLoad(): boolean {
|
||||
return this.dependencyCount === 0 && !this.noLoad && !this.isLoading && !this.hasFailed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the path for a package using the loader's path filters
|
||||
*
|
||||
* @param {string} name The name of the package to resolve
|
||||
* @param {boolean} addExtension True if .js should be added automatically
|
||||
* @return {string} The path (file or URL) for this package
|
||||
*/
|
||||
public static resolvePath(name: string, addExtension: boolean = true): string {
|
||||
const data = {name, original: name, addExtension};
|
||||
Loader.pathFilters.execute(data);
|
||||
return data.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to load all packages that are ready to be loaded
|
||||
* (i.e., that have no unloaded dependencies, and that haven't
|
||||
* already been loaded, and that aren't in process of being
|
||||
* loaded, and that aren't marked as noLoad).
|
||||
*/
|
||||
public static loadAll() {
|
||||
for (const extension of this.packages.values()) {
|
||||
if (extension.canLoad) {
|
||||
extension.load();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name The name of the package
|
||||
* @param {boolean} noLoad True when the package is just for reference, not loading
|
||||
*/
|
||||
constructor(name: string, noLoad: boolean = false) {
|
||||
this.name = name;
|
||||
this.noLoad = noLoad;
|
||||
Package.packages.set(name, this);
|
||||
this.promise = this.makePromise(this.makeDependencies());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Promise<string>[]} The array of promises that must be resolved before this package
|
||||
* can be loaded
|
||||
*/
|
||||
protected makeDependencies(): Promise<string>[] {
|
||||
const promises = [] as Promise<string>[];
|
||||
const map = Package.packages;
|
||||
const noLoad = this.noLoad;
|
||||
const name = this.name;
|
||||
//
|
||||
// Get the dependencies for this package
|
||||
//
|
||||
const dependencies = [] as string[];
|
||||
if (CONFIG.dependencies.hasOwnProperty(name)) {
|
||||
dependencies.push(...CONFIG.dependencies[name]);
|
||||
} else if (name !== 'core') {
|
||||
dependencies.push('core'); // Add 'core' dependency by default
|
||||
}
|
||||
//
|
||||
// Add all the dependencies (creating them, if needed)
|
||||
// and record the promises of unloaded ones
|
||||
//
|
||||
for (const dependent of dependencies) {
|
||||
const extension = map.get(dependent) || new Package(dependent, noLoad);
|
||||
if (this.dependencies.indexOf(extension) < 0) {
|
||||
extension.addDependent(this, noLoad);
|
||||
this.dependencies.push(extension);
|
||||
if (!extension.isLoaded) {
|
||||
this.dependencyCount++;
|
||||
promises.push(extension.promise);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Return the collected promises
|
||||
//
|
||||
return promises;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Promise<string>[]} promises The array or promises that must be resolved before
|
||||
* this package can load
|
||||
*/
|
||||
protected makePromise(promises: Promise<string>[]) {
|
||||
//
|
||||
// Make a promise and save its resolve/reject functions
|
||||
//
|
||||
let promise = new Promise<string>(((resolve, reject) => {
|
||||
this.resolve = resolve;
|
||||
this.reject = reject;
|
||||
}) as PackagePromise);
|
||||
//
|
||||
// If there is a ready() function in the configuration for this package,
|
||||
// Add running that to the promise
|
||||
//
|
||||
const config = (CONFIG[this.name] || {}) as PackageConfig;
|
||||
if (config.ready) {
|
||||
promise = promise.then((_name: string) => config.ready(this.name)) as Promise<string>;
|
||||
}
|
||||
//
|
||||
// If there are promises for dependencies,
|
||||
// Add the one for loading this package and create a promise for all of them
|
||||
// (That way, if any of them fail to load, our promise will reject automatically)
|
||||
//
|
||||
if (promises.length) {
|
||||
promises.push(promise);
|
||||
promise = Promise.all(promises).then((names: string[]) => names.join(', '));
|
||||
}
|
||||
//
|
||||
// If there is a failed() function in the configuration for this package,
|
||||
// Add a catch to handle the error
|
||||
//
|
||||
if (config.failed) {
|
||||
promise.catch((message: string) => config.failed(new PackageError(message, this.name)));
|
||||
}
|
||||
//
|
||||
// Return the promise that represents when this file is loaded
|
||||
//
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to load this package
|
||||
*/
|
||||
public load() {
|
||||
if (!this.isLoaded && !this.isLoading && !this.noLoad) {
|
||||
this.isLoading = true;
|
||||
const url = Package.resolvePath(this.name);
|
||||
if (CONFIG.require) {
|
||||
this.loadCustom(url);
|
||||
} else {
|
||||
this.loadScript(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load using a custom require method (usually the one from node.js)
|
||||
*/
|
||||
protected loadCustom(url: string) {
|
||||
try {
|
||||
const result = CONFIG.require(url);
|
||||
if (result instanceof Promise) {
|
||||
result.then(() => this.checkLoad())
|
||||
.catch((err) => this.failed('Can\'t load "' + url + '"\n' + err.message.trim()));
|
||||
} else {
|
||||
this.checkLoad();
|
||||
}
|
||||
} catch (err) {
|
||||
this.failed(err.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load in a browser by inserting a script to load the proper URL
|
||||
*/
|
||||
protected loadScript(url: string) {
|
||||
const script = document.createElement('script');
|
||||
script.src = url;
|
||||
script.charset = 'UTF-8';
|
||||
script.onload = (_event) => this.checkLoad();
|
||||
script.onerror = (_event) => this.failed('Can\'t load "' + url + '"');
|
||||
// FIXME: Should there be a timeout failure as well?
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the package is loaded.
|
||||
*
|
||||
* Mark it as loaded, and tell its dependents that this package
|
||||
* has been loaded (may cause dependents to load themselves).
|
||||
* Mark any provided packages as loaded.
|
||||
* Resolve the promise that says this package is loaded.
|
||||
*/
|
||||
public loaded() {
|
||||
this.isLoaded = true;
|
||||
this.isLoading = false;
|
||||
for (const dependent of this.dependents) {
|
||||
dependent.requirementSatisfied();
|
||||
}
|
||||
for (const provided of this.provided) {
|
||||
provided.loaded();
|
||||
}
|
||||
this.resolve(this.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the package fails to load for some reason
|
||||
*
|
||||
* Mark it as failed to load
|
||||
* Reject the promise for this package with an error
|
||||
*
|
||||
* @param {string} message The error message for a load failure
|
||||
*/
|
||||
protected failed(message: string) {
|
||||
this.hasFailed = true;
|
||||
this.isLoading = false;
|
||||
this.reject(new PackageError(message, this.name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a package is really ready to be marked as loaded
|
||||
* (When it is loaded, it may set its own checkReady() function
|
||||
* as a means of loading additional packages. E.g., an output
|
||||
* jax may load a font package, dependent on its configuration.)
|
||||
*
|
||||
* The configuration's checkReady() function returns a promise
|
||||
* that allows the loader to wait for addition actions to finish
|
||||
* before marking the file as loaded (or failing to load).
|
||||
*/
|
||||
protected checkLoad() {
|
||||
const config = (CONFIG[this.name] || {}) as PackageConfig;
|
||||
const checkReady = config.checkReady || (() => Promise.resolve());
|
||||
checkReady().then(() => this.loaded())
|
||||
.catch((message) => this.failed(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when a dependency loads.
|
||||
*
|
||||
* Decrease the dependency count, and try to load this package
|
||||
* when the dependencies are all loaded.
|
||||
*/
|
||||
public requirementSatisfied() {
|
||||
if (this.dependencyCount) {
|
||||
this.dependencyCount--;
|
||||
if (this.canLoad) {
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} names The names of the packages that this package provides
|
||||
*/
|
||||
public provides(names: string[] = []) {
|
||||
for (const name of names) {
|
||||
let provided = Package.packages.get(name);
|
||||
if (!provided) {
|
||||
if (!CONFIG.dependencies[name]) {
|
||||
CONFIG.dependencies[name] = [];
|
||||
}
|
||||
CONFIG.dependencies[name].push(name);
|
||||
provided = new Package(name, true);
|
||||
provided.isLoading = true;
|
||||
}
|
||||
this.provided.push(provided);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a package as a dependent, and if it is not just for reference,
|
||||
* check if we need to change our noLoad status.
|
||||
*
|
||||
* @param {Package} extension The package to add as a dependent
|
||||
* @param {boolean} noLoad The noLoad status of the dependent
|
||||
*/
|
||||
public addDependent(extension: Package, noLoad: boolean) {
|
||||
this.dependents.push(extension);
|
||||
if (!noLoad) {
|
||||
this.checkNoLoad();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If this package is marked as noLoad, change that and check all
|
||||
* our dependencies to see if they need to change their noLoad
|
||||
* status as well.
|
||||
*
|
||||
* I.e., if there are dependencies that were set up for reference
|
||||
* and a leaf node needs to be loaded, make sure all parent nodes
|
||||
* are marked as needing to be loaded as well.
|
||||
*/
|
||||
public checkNoLoad() {
|
||||
if (this.noLoad) {
|
||||
this.noLoad = false;
|
||||
for (const dependency of this.dependencies) {
|
||||
dependency.checkNoLoad();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
579
node_modules/mathjax-full/ts/components/startup.ts
generated
vendored
Normal file
579
node_modules/mathjax-full/ts/components/startup.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,579 @@
|
|||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Implements a startup module that allows dynamically
|
||||
* loaded components to register themselves, and then
|
||||
* creates MathJax methods for typesetting and converting
|
||||
* math based on the registered components.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide Cervone)
|
||||
*/
|
||||
|
||||
import {MathJax as MJGlobal, MathJaxObject as MJObject,
|
||||
MathJaxConfig as MJConfig, combineWithMathJax, combineDefaults} from './global.js';
|
||||
|
||||
import {MathDocument} from '../core/MathDocument.js';
|
||||
import {MmlNode} from '../core/MmlTree/MmlNode.js';
|
||||
import {Handler} from '../core/Handler.js';
|
||||
import {InputJax} from '../core/InputJax.js';
|
||||
import {OutputJax} from '../core/OutputJax.js';
|
||||
import {CommonOutputJax} from '../output/common/OutputJax.js';
|
||||
import {DOMAdaptor} from '../core/DOMAdaptor.js';
|
||||
import {PrioritizedList} from '../util/PrioritizedList.js';
|
||||
import {OptionList, OPTIONS} from '../util/Options.js';
|
||||
|
||||
import {TeX} from '../input/tex.js';
|
||||
|
||||
|
||||
/**
|
||||
* Update the configuration structure to include the startup configuration
|
||||
*/
|
||||
export interface MathJaxConfig extends MJConfig {
|
||||
startup?: {
|
||||
input?: string[]; // The names of the input jax to use
|
||||
output?: string; // The name for the output jax to use
|
||||
handler?: string; // The handler to register
|
||||
adaptor?: string; // The name for the DOM adaptor to use
|
||||
document?: any; // The document (or fragment or string) to work in
|
||||
elements?: any[]; // The elements to typeset (default is document body)
|
||||
typeset?: boolean; // Perform initial typeset?
|
||||
ready?: () => void; // Function to perform when components are ready
|
||||
pageReady?: () => void; // Function to perform when page is ready
|
||||
invalidOption?: 'fatal' | 'warn'; // Do invalid options produce a warning, or throw an error?
|
||||
optionError?: (message: string, key: string) => void, // Function to report invalid options
|
||||
[name: string]: any; // Other configuration blocks
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic types for the standard MathJax objects
|
||||
*/
|
||||
export type MATHDOCUMENT = MathDocument<any, any, any>;
|
||||
export type HANDLER = Handler<any, any, any>;
|
||||
export type DOMADAPTOR = DOMAdaptor<any, any, any>;
|
||||
export type INPUTJAX = InputJax<any, any, any>;
|
||||
export type OUTPUTJAX = OutputJax<any, any, any>;
|
||||
export type COMMONJAX = CommonOutputJax<any, any, any, any, any, any, any>;
|
||||
export type TEX = TeX<any, any, any>;
|
||||
|
||||
/**
|
||||
* A function to extend a handler class
|
||||
*/
|
||||
export type HandlerExtension = (handler: HANDLER) => HANDLER;
|
||||
|
||||
/**
|
||||
* Update the MathJax object to inclide the startup information
|
||||
*/
|
||||
export interface MathJaxObject extends MJObject {
|
||||
config: MathJaxConfig;
|
||||
startup: {
|
||||
constructors: {[name: string]: any};
|
||||
input: INPUTJAX[];
|
||||
output: OUTPUTJAX;
|
||||
handler: HANDLER;
|
||||
adaptor: DOMADAPTOR;
|
||||
elements: any[];
|
||||
document: MATHDOCUMENT;
|
||||
promise: Promise<void>;
|
||||
/* tslint:disable:jsdoc-require */
|
||||
registerConstructor(name: string, constructor: any): void;
|
||||
useHandler(name: string, force?: boolean): void;
|
||||
useAdaptor(name: string, force?: boolean): void;
|
||||
useOutput(name: string, force?: boolean): void;
|
||||
useInput(name: string, force?: boolean): void;
|
||||
extendHandler(extend: HandlerExtension): void;
|
||||
toMML(node: MmlNode): string;
|
||||
defaultReady(): void;
|
||||
defaultPageReady(): Promise<void>;
|
||||
getComponents(): void;
|
||||
makeMethods(): void;
|
||||
makeTypesetMethods(): void;
|
||||
makeOutputMethods(iname: string, oname: string, input: INPUTJAX): void;
|
||||
makeMmlMethods(name: string, input: INPUTJAX): void;
|
||||
makeResetMethod(name: string, input: INPUTJAX): void;
|
||||
getInputJax(): INPUTJAX[];
|
||||
getOutputJax(): OUTPUTJAX;
|
||||
getAdaptor(): DOMADAPTOR;
|
||||
getHandler(): HANDLER;
|
||||
/* tslint:enable */
|
||||
};
|
||||
[name: string]: any; // Needed for the methods created by the startup module
|
||||
}
|
||||
|
||||
/*
|
||||
* Access to the browser document
|
||||
*/
|
||||
declare var global: {document: Document};
|
||||
|
||||
/**
|
||||
* The implementation of the startup module
|
||||
*/
|
||||
export namespace Startup {
|
||||
|
||||
/**
|
||||
* The array of handler extensions
|
||||
*/
|
||||
const extensions = new PrioritizedList<HandlerExtension>();
|
||||
|
||||
let visitor: any; // the visitor for toMML();
|
||||
let mathjax: any; // the mathjax variable from mathjax.js
|
||||
|
||||
/**
|
||||
* The constructors (or other data) registered by the loaded packages
|
||||
*/
|
||||
export const constructors: {[name: string]: any} = {};
|
||||
|
||||
/**
|
||||
* The array of InputJax instances (created after everything is loaded)
|
||||
*/
|
||||
export let input: INPUTJAX[] = [];
|
||||
|
||||
/**
|
||||
* The OutputJax instance (created after everything is loaded)
|
||||
*/
|
||||
export let output: OUTPUTJAX = null;
|
||||
|
||||
/**
|
||||
* The Handler instance (created after everything is loaded)
|
||||
*/
|
||||
export let handler: HANDLER = null;
|
||||
|
||||
/**
|
||||
* The DOMAdaptor instance (created after everything is loaded)
|
||||
*/
|
||||
export let adaptor: DOMADAPTOR = null;
|
||||
|
||||
/**
|
||||
* The elements to process (set when typeset or conversion method is called)
|
||||
*/
|
||||
export let elements: any[] = null;
|
||||
|
||||
/**
|
||||
* The MathDocument instance being used (based on the browser DOM or configuration value)
|
||||
*/
|
||||
export let document: MATHDOCUMENT = null;
|
||||
|
||||
/**
|
||||
* The function that resolves the first promise defined below
|
||||
* (called in the defaultReady() function when MathJax is finished with
|
||||
* its initial typesetting)
|
||||
*/
|
||||
export let promiseResolve: () => void;
|
||||
/**
|
||||
* The function that rejects the first promise defined below
|
||||
* (called in the defaultReady() function when MathJax's initial
|
||||
* typesetting fails)
|
||||
*/
|
||||
export let promiseReject: (reason: any) => void;
|
||||
|
||||
/**
|
||||
* The promise for the startup process (the initial typesetting).
|
||||
* It is resolves or rejected in the ready() function.
|
||||
*/
|
||||
export let promise = new Promise<void>((resolve, reject) => {
|
||||
promiseResolve = resolve;
|
||||
promiseReject = reject;
|
||||
});
|
||||
|
||||
/**
|
||||
* A promise that is resolved when the page contents are available
|
||||
* for processing.
|
||||
*/
|
||||
export let pagePromise = new Promise<void>((resolve, _reject) => {
|
||||
const doc = global.document;
|
||||
if (!doc || !doc.readyState || doc.readyState === 'complete' || doc.readyState === 'interactive') {
|
||||
resolve();
|
||||
} else {
|
||||
const listener = () => resolve();
|
||||
doc.defaultView.addEventListener('load', listener, true);
|
||||
doc.defaultView.addEventListener('DOMContentLoaded', listener, true);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {MmlNode} node The root of the tree to convert to serialized MathML
|
||||
* @return {string} The serialized MathML from the tree
|
||||
*/
|
||||
export function toMML(node: MmlNode): string {
|
||||
return visitor.visitTree(node, document);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name The identifier for the constructor
|
||||
* @param {any} constructor The constructor function for the named object
|
||||
*/
|
||||
export function registerConstructor(name: string, constructor: any) {
|
||||
constructors[name] = constructor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name The identifier for the Handler to use
|
||||
* @param {boolean} force True to force the Handler to be used even if one is already registered
|
||||
*/
|
||||
export function useHandler(name: string, force: boolean = false) {
|
||||
if (!CONFIG.handler || force) {
|
||||
CONFIG.handler = name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name The identifier for the DOMAdaptor to use
|
||||
* @param {boolean} force True to force the DOMAdaptor to be used even if one is already registered
|
||||
*/
|
||||
export function useAdaptor(name: string, force: boolean = false) {
|
||||
if (!CONFIG.adaptor || force) {
|
||||
CONFIG.adaptor = name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name The identifier for the InputJax to use
|
||||
* @param {boolean} force True to force the InputJax to be used even if the configuration already
|
||||
* included an array of input jax
|
||||
*/
|
||||
export function useInput(name: string, force: boolean = false) {
|
||||
if (!inputSpecified || force) {
|
||||
CONFIG.input.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name The identifier for the OutputJax to use
|
||||
* @param {boolean} force True to force the OutputJax to be used even if one is already registered
|
||||
*/
|
||||
export function useOutput(name: string, force: boolean = false) {
|
||||
if (!CONFIG.output || force) {
|
||||
CONFIG.output = name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HandlerExtension} extend A function to extend the handler class
|
||||
* @param {number} priority The priority of the extension
|
||||
*/
|
||||
export function extendHandler(extend: HandlerExtension, priority: number = 10) {
|
||||
extensions.add(extend, priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* The default ready() function called when all the packages have been loaded,
|
||||
* which creates the various objects needed by MathJax, creates the methods
|
||||
* based on the loaded components, and does the initial typesetting.
|
||||
*
|
||||
* Setting MathJax.startup.ready in the configuration will
|
||||
* override this, but you can call MathJax.startup.defaultReady()
|
||||
* within your own ready function if needed, or can use the
|
||||
* individual methods below to perform portions of the default
|
||||
* startup actions.
|
||||
*/
|
||||
export function defaultReady() {
|
||||
getComponents();
|
||||
makeMethods();
|
||||
pagePromise
|
||||
.then(() => CONFIG.pageReady()) // usually the initial typesetting call
|
||||
.then(() => promiseResolve())
|
||||
.catch((err) => promiseReject(err));
|
||||
}
|
||||
|
||||
/**
|
||||
* The default pageReady() function called when the page is ready to be processed,
|
||||
* which returns the function that performs the initial typesetting, if needed.
|
||||
*
|
||||
* Setting Mathjax.startup.pageReady in the configuration will override this.
|
||||
*/
|
||||
export function defaultPageReady() {
|
||||
return (CONFIG.typeset && MathJax.typesetPromise ?
|
||||
MathJax.typesetPromise(CONFIG.elements) as Promise<void> :
|
||||
Promise.resolve());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the instances of the registered components
|
||||
*/
|
||||
export function getComponents() {
|
||||
visitor = new MathJax._.core.MmlTree.SerializedMmlVisitor.SerializedMmlVisitor();
|
||||
mathjax = MathJax._.mathjax.mathjax;
|
||||
input = getInputJax();
|
||||
output = getOutputJax();
|
||||
adaptor = getAdaptor();
|
||||
if (handler) {
|
||||
mathjax.handlers.unregister(handler);
|
||||
}
|
||||
handler = getHandler();
|
||||
if (handler) {
|
||||
mathjax.handlers.register(handler);
|
||||
document = getDocument();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the typeset and conversion methods based on the registered components
|
||||
*
|
||||
* If there are both input and output jax,
|
||||
* Make Typeset() and TypesetPromise() methods using the given jax,
|
||||
* and TypesetClear() to clear the existing math items
|
||||
* For each input jax
|
||||
* Make input2mml() and input2mmlPromise() conversion methods and inputReset() method
|
||||
* If there is a registered output jax
|
||||
* Make input2output() and input2outputPromise conversion methods and outputStylesheet() method
|
||||
*/
|
||||
export function makeMethods() {
|
||||
if (input && output) {
|
||||
makeTypesetMethods();
|
||||
}
|
||||
const oname = (output ? output.name.toLowerCase() : '');
|
||||
for (const jax of input) {
|
||||
const iname = jax.name.toLowerCase();
|
||||
makeMmlMethods(iname, jax);
|
||||
makeResetMethod(iname, jax);
|
||||
if (output) {
|
||||
makeOutputMethods(iname, oname, jax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Typeset(elements?), TypesetPromise(elements?), and TypesetClear() methods.
|
||||
*
|
||||
* The first two call the document's render() function, the latter
|
||||
* wrapped in handleRetriesFor() and returning the resulting promise.
|
||||
*
|
||||
* TypeseClear() clears all the MathItems from the document.
|
||||
*/
|
||||
export function makeTypesetMethods() {
|
||||
MathJax.typeset = (elements: any[] = null) => {
|
||||
document.options.elements = elements;
|
||||
document.reset();
|
||||
document.render();
|
||||
};
|
||||
MathJax.typesetPromise = (elements: any[] = null) => {
|
||||
document.options.elements = elements;
|
||||
document.reset();
|
||||
return mathjax.handleRetriesFor(() => {
|
||||
document.render();
|
||||
});
|
||||
};
|
||||
MathJax.typesetClear = (elements: any[] = null) => {
|
||||
if (elements) {
|
||||
document.clearMathItemsWithin(elements);
|
||||
} else {
|
||||
document.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the input2output(math, options?) and input2outputPromise(math, options?) methods,
|
||||
* and outputStylesheet() method, where "input" and "output" are replaced by the
|
||||
* jax names (e.g., tex2chtml() and chtmlStyleSheet()).
|
||||
*
|
||||
* The first two perform the document's convert() call, with the Promise version wrapped in
|
||||
* handlerRetriesFor() and returning the resulting promise. The return value is the
|
||||
* DOM object for the converted math. Use MathJax.startup.adaptor.outerHTML(result)
|
||||
* to get the serialized string version of the output.
|
||||
*
|
||||
* The outputStylesheet() method returns the styleSheet object for the output.
|
||||
* Use MathJax.startup.adaptor.innerHTML(MathJax.outputStylesheet()) to get the serialized
|
||||
* version of the stylesheet.
|
||||
* The getMetricsFor(node, display) method returns the metric data for the given node
|
||||
*
|
||||
* @param {string} iname The name of the input jax
|
||||
* @param {string} oname The name of the output jax
|
||||
* @param {INPUTJAX} input The input jax instance
|
||||
*/
|
||||
export function makeOutputMethods(iname: string, oname: string, input: INPUTJAX) {
|
||||
const name = iname + '2' + oname;
|
||||
MathJax[name] =
|
||||
(math: string, options: OptionList = {}) => {
|
||||
options.format = input.name;
|
||||
return document.convert(math, options);
|
||||
};
|
||||
MathJax[name + 'Promise'] =
|
||||
(math: string, options: OptionList = {}) => {
|
||||
options.format = input.name;
|
||||
return mathjax.handleRetriesFor(() => document.convert(math, options));
|
||||
};
|
||||
MathJax[oname + 'Stylesheet'] = () => output.styleSheet(document);
|
||||
if ('getMetricsFor' in output) {
|
||||
MathJax.getMetricsFor = (node: any, display: boolean) => {
|
||||
return (output as COMMONJAX).getMetricsFor(node, display);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the input2mml(math, options?) and input2mmlPromise(math, options?) methods,
|
||||
* where "input" is replaced by the name of the input jax (e.g., "tex2mml").
|
||||
*
|
||||
* These convert the math to its serialized MathML representation.
|
||||
* The second wraps the conversion in handleRetriesFor() and
|
||||
* returns the resulting promise.
|
||||
*
|
||||
* @param {string} name The name of the input jax
|
||||
* @param {INPUTJAX} input The input jax itself
|
||||
*/
|
||||
export function makeMmlMethods(name: string, input: INPUTJAX) {
|
||||
const STATE = MathJax._.core.MathItem.STATE;
|
||||
MathJax[name + '2mml'] =
|
||||
(math: string, options: OptionList = {}) => {
|
||||
options.end = STATE.CONVERT;
|
||||
options.format = input.name;
|
||||
return toMML(document.convert(math, options));
|
||||
};
|
||||
MathJax[name + '2mmlPromise'] =
|
||||
(math: string, options: OptionList = {}) => {
|
||||
options.end = STATE.CONVERT;
|
||||
options.format = input.name;
|
||||
return mathjax.handleRetriesFor(() => toMML(document.convert(math, options)));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the inputReset() method, where "input" is replaced by the input jax name (e.g., "texReset()).
|
||||
*
|
||||
* The texReset() method clears the equation numbers and labels
|
||||
*
|
||||
* @param {string} name The name of the input jax
|
||||
* @param {INPUTJAX} input The input jax itself
|
||||
*/
|
||||
export function makeResetMethod(name: string, input: INPUTJAX) {
|
||||
MathJax[name + 'Reset'] = (...args: any[]) => input.reset(...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {INPUTJAX[]} The array of instances of the registered input jax
|
||||
*/
|
||||
export function getInputJax(): INPUTJAX[] {
|
||||
const jax = [] as INPUTJAX[];
|
||||
for (const name of CONFIG.input) {
|
||||
const inputClass = constructors[name];
|
||||
if (inputClass) {
|
||||
jax.push(new inputClass(MathJax.config[name]));
|
||||
} else {
|
||||
throw Error('Input Jax "' + name + '" is not defined (has it been loaded?)');
|
||||
}
|
||||
}
|
||||
return jax;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {OUTPUTJAX} The instance of the registered output jax
|
||||
*/
|
||||
export function getOutputJax(): OUTPUTJAX {
|
||||
const name = CONFIG.output;
|
||||
if (!name) return null;
|
||||
const outputClass = constructors[name];
|
||||
if (!outputClass) {
|
||||
throw Error('Output Jax "' + name + '" is not defined (has it been loaded?)');
|
||||
}
|
||||
return new outputClass(MathJax.config[name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {DOMADAPTOR} The instance of the registered DOMAdator (the registered constructor
|
||||
* in this case is a function that creates the adaptor, not a class)
|
||||
*/
|
||||
export function getAdaptor(): DOMADAPTOR {
|
||||
const name = CONFIG.adaptor;
|
||||
if (!name || name === 'none') return null;
|
||||
const adaptor = constructors[name];
|
||||
if (!adaptor) {
|
||||
throw Error('DOMAdaptor "' + name + '" is not defined (has it been loaded?)');
|
||||
}
|
||||
return adaptor(MathJax.config[name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {HANDLER} The instance of the registered Handler, extended by the registered extensions
|
||||
*/
|
||||
export function getHandler(): HANDLER {
|
||||
const name = CONFIG.handler;
|
||||
if (!name || name === 'none' || !adaptor) return null;
|
||||
const handlerClass = constructors[name];
|
||||
if (!handlerClass) {
|
||||
throw Error('Handler "' + name + '" is not defined (has it been loaded?)');
|
||||
}
|
||||
let handler = new handlerClass(adaptor, 5);
|
||||
for (const extend of extensions) {
|
||||
handler = extend.item(handler);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the document with the given input and output jax
|
||||
*
|
||||
* @param {any=} root The Document to use as the root document (or null to use the configured document)
|
||||
* @returns {MathDocument} The MathDocument with the configured input and output jax
|
||||
*/
|
||||
export function getDocument(root: any = null): MathDocument<any, any, any> {
|
||||
return mathjax.document(root || CONFIG.document, {
|
||||
...MathJax.config.options,
|
||||
InputJax: input,
|
||||
OutputJax: output
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the global MathJax object for convenience
|
||||
*/
|
||||
export const MathJax = MJGlobal as MathJaxObject;
|
||||
|
||||
/*
|
||||
* If the startup module hasn't been added to the MathJax variable,
|
||||
* Add the startup configuration and data objects, and
|
||||
* set the method for handling invalid options, if provided.
|
||||
*/
|
||||
if (typeof MathJax._.startup === 'undefined') {
|
||||
|
||||
combineDefaults(MathJax.config, 'startup', {
|
||||
input: [],
|
||||
output: '',
|
||||
handler: null,
|
||||
adaptor: null,
|
||||
document: (typeof document === 'undefined' ? '' : document),
|
||||
elements: null,
|
||||
typeset: true,
|
||||
ready: Startup.defaultReady.bind(Startup),
|
||||
pageReady: Startup.defaultPageReady.bind(Startup)
|
||||
});
|
||||
combineWithMathJax({
|
||||
startup: Startup,
|
||||
options: {}
|
||||
});
|
||||
|
||||
if (MathJax.config.startup.invalidOption) {
|
||||
OPTIONS.invalidOption = MathJax.config.startup.invalidOption;
|
||||
}
|
||||
if (MathJax.config.startup.optionError) {
|
||||
OPTIONS.optionError = MathJax.config.startup.optionError;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the startup configuration for convenience
|
||||
*/
|
||||
export const CONFIG = MathJax.config.startup;
|
||||
|
||||
|
||||
/*
|
||||
* Tells if the user configuration included input jax or not
|
||||
*/
|
||||
const inputSpecified = CONFIG.input.length !== 0;
|
||||
25
node_modules/mathjax-full/ts/components/version.ts
generated
vendored
Normal file
25
node_modules/mathjax-full/ts/components/version.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview The version of MathJax (used to tell what version a component
|
||||
* was compiled against).
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide Cervone)
|
||||
*/
|
||||
|
||||
export const VERSION = '3.2.2';
|
||||
Loading…
Add table
Add a link
Reference in a new issue