spaCy/website/assets/js/models.vue.js

147 lines
6.7 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Initialise model overviews
* @param {string} repo - Repository to load from, in the format user/repo.
*/
export default function(repo) {
const LICENSES = {
'CC BY 4.0': 'https://creativecommons.org/licenses/by/4.0/',
'CC BY-SA': 'https://creativecommons.org/licenses/by-sa/3.0/',
'CC BY-SA 3.0': 'https://creativecommons.org/licenses/by-sa/3.0/',
'CC BY-SA 4.0': 'https://creativecommons.org/licenses/by-sa/4.0/',
'CC BY-NC': 'https://creativecommons.org/licenses/by-nc/3.0/',
'CC BY-NC 3.0': 'https://creativecommons.org/licenses/by-nc/3.0/',
'CC-BY-NC-SA 3.0': 'https://creativecommons.org/licenses/by-nc-sa/3.0/',
'GPL': 'https://www.gnu.org/licenses/gpl.html',
'LGPL': 'https://www.gnu.org/licenses/lgpl.html',
'MIT': 'https://opensource.org/licenses/MIT'
};
const URL = `https://raw.githubusercontent.com/${repo}/master`;
const models = [...document.querySelectorAll('[data-vue]')]
.map(el => el.getAttribute('data-vue'));
document.addEventListener('DOMContentLoaded', ev => {
fetch(`${URL}/compatibility.json`)
.then(res => res.json())
.then(json => models.forEach(modelId => new Vue({
el: `[data-vue="${modelId}"]`,
data: {
repo: `https://github.com/${repo}`,
compat: json.spacy,
loading: false,
error: false,
id: modelId,
version: 'n/a',
notes: null,
sizeFull: null,
pipeline: null,
releaseUrl: null,
description: null,
license: null,
author: null,
url: null,
vectors: null,
sources: null,
uas: null,
las: null,
tags_acc: null,
ents_f: null,
ents_p: null,
ents_r: null,
modelLicenses: LICENSES,
spacyVersion: Object.keys(json.spacy)[0]
},
computed: {
compatVersion() {
const res = this.compat[this.spacyVersion][this.id];
return res ? `${this.id}-${res[0]}` : false;
},
orderedCompat() {
return Object.keys(this.compat)
.filter(v => this.$_isStableVersion(v));
},
hasAccuracy() {
return this.uas || this.las || this.tags_acc || this.ents_f || this.ents_p || this.ents_r;
}
},
beforeMount() {
const version = this.$_getLatestVersion(this.id);
if (version) {
this.loading = true;
fetch(`${URL}/meta/${this.id}-${version}.json`)
.then(res => res.json())
.then(json => this.$_updateData(json))
.catch(err => { this.error = true });
}
},
updated() {
window.dispatchEvent(new Event('resize')); // scroll position for progress
},
methods: {
$_updateData(data) {
const fullName = `${data.lang}_${data.name}-${data.version}`;
this.version = data.version;
this.releaseUrl = `${this.repo}/releases/tag/${fullName}`;
this.sizeFull = data.size;
this.pipeline = data.pipeline;
this.notes = data.notes;
this.description = data.description;
this.vectors = this.$_formatVectors(data.vectors);
this.sources = data.sources;
this.author = data.author;
this.url = data.url;
this.license = data.license;
const accuracy = data.accuracy || {};
for (let key of Object.keys(accuracy)) {
this[key] = accuracy[key].toFixed(2);
}
this.loading = false;
},
$_getLatestVersion(modelId) {
for (let [version, models] of Object.entries(this.compat)) {
if (this.$_isStableVersion(version) && models[modelId]) {
return models[modelId][0];
}
}
},
$_formatVectors(data) {
if (!data) {
return 'n/a';
}
if (Object.values(data).every(n => n == 0)) {
return 'context vectors only';
}
const { keys, vectors, width } = data;
const nKeys = this.$_abbrNum(keys);
const nVectors = this.$_abbrNum(vectors);
return `${nKeys} keys, ${nVectors} unique vectors (${width} dimensions)`;
},
/**
* Hacky check if a version number is stable and not alpha,
* dev or a release candidate
*/
$_isStableVersion(v) {
return !v.includes('a') && !v.includes('b') && !v.includes('dev') && !v.includes('rc');
},
/**
* Abbreviate a number, e.g. 14249930 --> 14.25m.
* @param {number|string} num - The number to convert.
* @param {number} fixed - Number of decimals.
*/
$_abbrNum: function(num = 0, fixed = 1) {
const suffixes = ['', 'k', 'm', 'b', 't'];
if (num === null || num === 0) return 0;
const b = num.toPrecision(2).split('e');
const k = (b.length === 1) ? 0 : Math.floor(Math.min(b[1].slice(1), 14) / 3);
const n = (k < 1) ? num : num / Math.pow(10, k * 3);
const c = (k >= 1 && n >= 100 ) ? Math.round(n) : n.toFixed(fixed);
return (c < 0 ? c : Math.abs(c)) + suffixes[k];
}
}
})))
});
}