mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Current file header is : /*! showdown v 2.0.0-alpha1 - 25-09-2018 */ Official 2.0.0-alpha doesn't match neither on content nor date :( Considering date we would be at 1.8.7, but it is also quite different (and has vulnerabilities) In consequence switching to 2.0.0.
98 lines
2.2 KiB
JavaScript
98 lines
2.2 KiB
JavaScript
const conversions = require('./conversions');
|
|
|
|
/*
|
|
This function routes a model to all other models.
|
|
|
|
all functions that are routed have a property `.conversion` attached
|
|
to the returned synthetic function. This property is an array
|
|
of strings, each with the steps in between the 'from' and 'to'
|
|
color models (inclusive).
|
|
|
|
conversions that are not possible simply are not included.
|
|
*/
|
|
|
|
function buildGraph() {
|
|
const graph = {};
|
|
// https://jsperf.com/object-keys-vs-for-in-with-closure/3
|
|
const models = Object.keys(conversions);
|
|
|
|
for (let len = models.length, i = 0; i < len; i++) {
|
|
graph[models[i]] = {
|
|
// http://jsperf.com/1-vs-infinity
|
|
// micro-opt, but this is simple.
|
|
distance: -1,
|
|
parent: null
|
|
};
|
|
}
|
|
|
|
return graph;
|
|
}
|
|
|
|
// https://en.wikipedia.org/wiki/Breadth-first_search
|
|
function deriveBFS(fromModel) {
|
|
const graph = buildGraph();
|
|
const queue = [fromModel]; // Unshift -> queue -> pop
|
|
|
|
graph[fromModel].distance = 0;
|
|
|
|
while (queue.length) {
|
|
const current = queue.pop();
|
|
const adjacents = Object.keys(conversions[current]);
|
|
|
|
for (let len = adjacents.length, i = 0; i < len; i++) {
|
|
const adjacent = adjacents[i];
|
|
const node = graph[adjacent];
|
|
|
|
if (node.distance === -1) {
|
|
node.distance = graph[current].distance + 1;
|
|
node.parent = current;
|
|
queue.unshift(adjacent);
|
|
}
|
|
}
|
|
}
|
|
|
|
return graph;
|
|
}
|
|
|
|
function link(from, to) {
|
|
return function (args) {
|
|
return to(from(args));
|
|
};
|
|
}
|
|
|
|
function wrapConversion(toModel, graph) {
|
|
const path = [graph[toModel].parent, toModel];
|
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
|
|
let cur = graph[toModel].parent;
|
|
while (graph[cur].parent) {
|
|
path.unshift(graph[cur].parent);
|
|
fn = link(conversions[graph[cur].parent][cur], fn);
|
|
cur = graph[cur].parent;
|
|
}
|
|
|
|
fn.conversion = path;
|
|
return fn;
|
|
}
|
|
|
|
module.exports = function (fromModel) {
|
|
const graph = deriveBFS(fromModel);
|
|
const conversion = {};
|
|
|
|
const models = Object.keys(graph);
|
|
for (let len = models.length, i = 0; i < len; i++) {
|
|
const toModel = models[i];
|
|
const node = graph[toModel];
|
|
|
|
if (node.parent === null) {
|
|
// No possible conversion, or this node is the source model.
|
|
continue;
|
|
}
|
|
|
|
conversion[toModel] = wrapConversion(toModel, graph);
|
|
}
|
|
|
|
return conversion;
|
|
};
|
|
|