This commit is contained in:
Michael Murtaugh
2019-05-27 16:05:50 +02:00
commit b027ca341a
29 changed files with 17864 additions and 0 deletions

8
Makefile Normal file
View File

@@ -0,0 +1,8 @@
dist/wikimap.js: src/*.js
# node_modules/.bin/rollup src/index.js --file dist/index.js --format iife
node_modules/.bin/rollup -c
dist/%.js: src/%.js src/*.js
# node_modules/.bin/rollup src/index.js --file dist/index.js --format iife
node_modules/.bin/rollup -c

257
cats.json Normal file
View File

@@ -0,0 +1,257 @@
[
{
"title": "Actualit\u00e9s",
"depth": 0,
"name": "Cat\u00e9gorie:Actualit\u00e9s"
},
{
"title": "Actualit\u00e9s (2013)",
"depth": 1,
"parent": "Actualit\u00e9s",
"name": "Cat\u00e9gorie:Actualit\u00e9s (2013)"
},
{
"title": "Actualit\u00e9s (2014)",
"depth": 1,
"parent": "Actualit\u00e9s",
"name": "Cat\u00e9gorie:Actualit\u00e9s (2014)"
},
{
"title": "Actualit\u00e9s (2015)",
"depth": 1,
"parent": "Actualit\u00e9s",
"name": "Cat\u00e9gorie:Actualit\u00e9s (2015)"
},
{
"title": "Actualit\u00e9s (2016)",
"depth": 1,
"parent": "Actualit\u00e9s",
"name": "Cat\u00e9gorie:Actualit\u00e9s (2016)"
},
{
"title": "Actualit\u00e9s (2017)",
"depth": 1,
"parent": "Actualit\u00e9s",
"name": "Cat\u00e9gorie:Actualit\u00e9s (2017)"
},
{
"title": "Actualit\u00e9s (2018)",
"depth": 1,
"parent": "Actualit\u00e9s",
"name": "Cat\u00e9gorie:Actualit\u00e9s (2018)"
},
{
"title": "Actualit\u00e9s (2019)",
"depth": 1,
"parent": "Actualit\u00e9s",
"name": "Cat\u00e9gorie:Actualit\u00e9s (2019)"
},
{
"title": "Ateliers pluridisciplinaires",
"depth": 0,
"name": "Cat\u00e9gorie:Ateliers pluridisciplinaires"
},
{
"title": "Ateliers pluridisciplinaires (BA)",
"depth": 0,
"name": "Cat\u00e9gorie:Ateliers pluridisciplinaires (BA)"
},
{
"title": "Ateliers pluridisciplinaires (MA)",
"depth": 0,
"name": "Cat\u00e9gorie:Ateliers pluridisciplinaires (MA)"
},
{
"title": "B1",
"depth": 0,
"name": "Cat\u00e9gorie:B1"
},
{
"title": "B2",
"depth": 0,
"name": "Cat\u00e9gorie:B2"
},
{
"title": "B3",
"depth": 0,
"name": "Cat\u00e9gorie:B3"
},
{
"title": "Bachelors",
"depth": 0,
"name": "Cat\u00e9gorie:Bachelors"
},
{
"title": "Cours de soutien sp\u00e9cifique",
"depth": 0,
"name": "Cat\u00e9gorie:Cours de soutien sp\u00e9cifique"
},
{
"title": "Cours techniques",
"depth": 0,
"name": "Cat\u00e9gorie:Cours techniques"
},
{
"title": "Cours th\u00e9oriques",
"depth": 0,
"name": "Cat\u00e9gorie:Cours th\u00e9oriques"
},
{
"title": "Critique du f\u00e9minisme",
"depth": 0,
"name": "Cat\u00e9gorie:Critique du f\u00e9minisme"
},
{
"title": "English",
"depth": 0,
"name": "Cat\u00e9gorie:English"
},
{
"title": "\u00c9quipes",
"depth": 0,
"name": "Cat\u00e9gorie:\u00c9quipes"
},
{
"title": "Conseil de gestion p\u00e9dagogique",
"depth": 1,
"parent": "\u00c9quipes",
"name": "Cat\u00e9gorie:Conseil de gestion p\u00e9dagogique"
},
{
"title": "Conseil \u00e9tudiant",
"depth": 1,
"parent": "\u00c9quipes",
"name": "Cat\u00e9gorie:Conseil \u00e9tudiant"
},
{
"title": "Enseignants",
"depth": 1,
"parent": "\u00c9quipes",
"name": "Cat\u00e9gorie:Enseignants"
},
{
"title": "\u00c9quipe administrative",
"depth": 1,
"parent": "\u00c9quipes",
"name": "Cat\u00e9gorie:\u00c9quipe administrative"
},
{
"title": "Essai paru en 1984",
"depth": 0,
"name": "Cat\u00e9gorie:Essai paru en 1984"
},
{
"title": "\u00c9tudes de genre",
"depth": 0,
"name": "Cat\u00e9gorie:\u00c9tudes de genre"
},
{
"title": "Index",
"depth": 0,
"name": "Cat\u00e9gorie:Index"
},
{
"title": "International",
"depth": 0,
"name": "Cat\u00e9gorie:International"
},
{
"title": "Les lieux de production et d'exp\u00e9rimentation",
"depth": 0,
"name": "Cat\u00e9gorie:Les lieux de production et d'exp\u00e9rimentation"
},
{
"title": "Livre sur le f\u00e9minisme",
"depth": 0,
"name": "Cat\u00e9gorie:Livre sur le f\u00e9minisme"
},
{
"title": "Masters",
"depth": 0,
"name": "Cat\u00e9gorie:Masters"
},
{
"title": "Cours de soutien \u00e0 l'orientation",
"depth": 1,
"parent": "Masters",
"name": "Cat\u00e9gorie:Cours de soutien \u00e0 l'orientation"
},
{
"title": "M1",
"depth": 1,
"parent": "Masters",
"name": "Cat\u00e9gorie:M1"
},
{
"title": "M2",
"depth": 1,
"parent": "Masters",
"name": "Cat\u00e9gorie:M2"
},
{
"title": "Masters sp\u00e9cialis\u00e9s",
"depth": 0,
"name": "Cat\u00e9gorie:Masters sp\u00e9cialis\u00e9s"
},
{
"title": "Orientations",
"depth": 0,
"name": "Cat\u00e9gorie:Orientations"
},
{
"title": "Outils collectifs",
"depth": 0,
"name": "Cat\u00e9gorie:Outils collectifs"
},
{
"title": "Pages avec des erreurs de coloration syntaxique",
"depth": 0,
"name": "Cat\u00e9gorie:Pages avec des erreurs de coloration syntaxique"
},
{
"title": "Pages avec des liens de fichiers bris\u00e9s",
"depth": 0,
"name": "Cat\u00e9gorie:Pages avec des liens de fichiers bris\u00e9s"
},
{
"title": "Page web",
"depth": 1,
"parent": "Pages avec des liens de fichiers bris\u00e9s",
"name": "Cat\u00e9gorie:Page web"
},
{
"title": "Pages d\u00e9passant la profondeur d'expansion maximale",
"depth": 0,
"name": "Cat\u00e9gorie:Pages d\u00e9passant la profondeur d'expansion maximale"
},
{
"title": "Provenance web",
"depth": 0,
"name": "Cat\u00e9gorie:Provenance web"
},
{
"title": "Selection",
"depth": 0,
"name": "Cat\u00e9gorie:Selection"
},
{
"title": "Sites satellites",
"depth": 0,
"name": "Cat\u00e9gorie:Sites satellites"
},
{
"title": "Sites sattelites",
"depth": 0,
"name": "Cat\u00e9gorie:Sites sattelites"
},
{
"title": "Stages",
"depth": 0,
"name": "Cat\u00e9gorie:Stages"
},
{
"title": "Wiki only",
"depth": 0,
"name": "Cat\u00e9gorie:Wiki only"
}
]

788
dist/index.js vendored Normal file
View File

@@ -0,0 +1,788 @@
var index = (function (exports) {
'use strict';
if (typeof document !== "undefined") {
var element = document.documentElement;
}
function tree_add(d) {
var x = +this._x.call(null, d),
y = +this._y.call(null, d);
return add(this.cover(x, y), x, y, d);
}
function add(tree, x, y, d) {
if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points
var parent,
node = tree._root,
leaf = {data: d},
x0 = tree._x0,
y0 = tree._y0,
x1 = tree._x1,
y1 = tree._y1,
xm,
ym,
xp,
yp,
right,
bottom,
i,
j;
// If the tree is empty, initialize the root as a leaf.
if (!node) return tree._root = leaf, tree;
// Find the existing leaf for the new point, or add it.
while (node.length) {
if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
}
// Is the new point is exactly coincident with the existing point?
xp = +tree._x.call(null, node.data);
yp = +tree._y.call(null, node.data);
if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
// Otherwise, split the leaf node until the old and new point are separated.
do {
parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
} while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));
return parent[j] = node, parent[i] = leaf, tree;
}
function addAll(data) {
var d, i, n = data.length,
x,
y,
xz = new Array(n),
yz = new Array(n),
x0 = Infinity,
y0 = Infinity,
x1 = -Infinity,
y1 = -Infinity;
// Compute the points and their extent.
for (i = 0; i < n; ++i) {
if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;
xz[i] = x;
yz[i] = y;
if (x < x0) x0 = x;
if (x > x1) x1 = x;
if (y < y0) y0 = y;
if (y > y1) y1 = y;
}
// If there were no (valid) points, abort.
if (x0 > x1 || y0 > y1) return this;
// Expand the tree to cover the new points.
this.cover(x0, y0).cover(x1, y1);
// Add the new points.
for (i = 0; i < n; ++i) {
add(this, xz[i], yz[i], data[i]);
}
return this;
}
function tree_cover(x, y) {
if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points
var x0 = this._x0,
y0 = this._y0,
x1 = this._x1,
y1 = this._y1;
// If the quadtree has no extent, initialize them.
// Integer extent are necessary so that if we later double the extent,
// the existing quadrant boundaries dont change due to floating point error!
if (isNaN(x0)) {
x1 = (x0 = Math.floor(x)) + 1;
y1 = (y0 = Math.floor(y)) + 1;
}
// Otherwise, double repeatedly to cover.
else {
var z = x1 - x0,
node = this._root,
parent,
i;
while (x0 > x || x >= x1 || y0 > y || y >= y1) {
i = (y < y0) << 1 | (x < x0);
parent = new Array(4), parent[i] = node, node = parent, z *= 2;
switch (i) {
case 0: x1 = x0 + z, y1 = y0 + z; break;
case 1: x0 = x1 - z, y1 = y0 + z; break;
case 2: x1 = x0 + z, y0 = y1 - z; break;
case 3: x0 = x1 - z, y0 = y1 - z; break;
}
}
if (this._root && this._root.length) this._root = node;
}
this._x0 = x0;
this._y0 = y0;
this._x1 = x1;
this._y1 = y1;
return this;
}
function tree_data() {
var data = [];
this.visit(function(node) {
if (!node.length) do data.push(node.data); while (node = node.next)
});
return data;
}
function tree_extent(_) {
return arguments.length
? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
: isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];
}
function Quad(node, x0, y0, x1, y1) {
this.node = node;
this.x0 = x0;
this.y0 = y0;
this.x1 = x1;
this.y1 = y1;
}
function tree_find(x, y, radius) {
var data,
x0 = this._x0,
y0 = this._y0,
x1,
y1,
x2,
y2,
x3 = this._x1,
y3 = this._y1,
quads = [],
node = this._root,
q,
i;
if (node) quads.push(new Quad(node, x0, y0, x3, y3));
if (radius == null) radius = Infinity;
else {
x0 = x - radius, y0 = y - radius;
x3 = x + radius, y3 = y + radius;
radius *= radius;
}
while (q = quads.pop()) {
// Stop searching if this quadrant cant contain a closer node.
if (!(node = q.node)
|| (x1 = q.x0) > x3
|| (y1 = q.y0) > y3
|| (x2 = q.x1) < x0
|| (y2 = q.y1) < y0) continue;
// Bisect the current quadrant.
if (node.length) {
var xm = (x1 + x2) / 2,
ym = (y1 + y2) / 2;
quads.push(
new Quad(node[3], xm, ym, x2, y2),
new Quad(node[2], x1, ym, xm, y2),
new Quad(node[1], xm, y1, x2, ym),
new Quad(node[0], x1, y1, xm, ym)
);
// Visit the closest quadrant first.
if (i = (y >= ym) << 1 | (x >= xm)) {
q = quads[quads.length - 1];
quads[quads.length - 1] = quads[quads.length - 1 - i];
quads[quads.length - 1 - i] = q;
}
}
// Visit this point. (Visiting coincident points isnt necessary!)
else {
var dx = x - +this._x.call(null, node.data),
dy = y - +this._y.call(null, node.data),
d2 = dx * dx + dy * dy;
if (d2 < radius) {
var d = Math.sqrt(radius = d2);
x0 = x - d, y0 = y - d;
x3 = x + d, y3 = y + d;
data = node.data;
}
}
}
return data;
}
function tree_remove(d) {
if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
var parent,
node = this._root,
retainer,
previous,
next,
x0 = this._x0,
y0 = this._y0,
x1 = this._x1,
y1 = this._y1,
x,
y,
xm,
ym,
right,
bottom,
i,
j;
// If the tree is empty, initialize the root as a leaf.
if (!node) return this;
// Find the leaf node for the point.
// While descending, also retain the deepest parent with a non-removed sibling.
if (node.length) while (true) {
if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
if (!node.length) break;
if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
}
// Find the point to remove.
while (node.data !== d) if (!(previous = node, node = node.next)) return this;
if (next = node.next) delete node.next;
// If there are multiple coincident points, remove just the point.
if (previous) return (next ? previous.next = next : delete previous.next), this;
// If this is the root point, remove it.
if (!parent) return this._root = next, this;
// Remove this leaf.
next ? parent[i] = next : delete parent[i];
// If the parent now contains exactly one leaf, collapse superfluous parents.
if ((node = parent[0] || parent[1] || parent[2] || parent[3])
&& node === (parent[3] || parent[2] || parent[1] || parent[0])
&& !node.length) {
if (retainer) retainer[j] = node;
else this._root = node;
}
return this;
}
function removeAll(data) {
for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
return this;
}
function tree_root() {
return this._root;
}
function tree_size() {
var size = 0;
this.visit(function(node) {
if (!node.length) do ++size; while (node = node.next)
});
return size;
}
function tree_visit(callback) {
var quads = [], q, node = this._root, child, x0, y0, x1, y1;
if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));
while (q = quads.pop()) {
if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
}
}
return this;
}
function tree_visitAfter(callback) {
var quads = [], next = [], q;
if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));
while (q = quads.pop()) {
var node = q.node;
if (node.length) {
var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
}
next.push(q);
}
while (q = next.pop()) {
callback(q.node, q.x0, q.y0, q.x1, q.y1);
}
return this;
}
function defaultX(d) {
return d[0];
}
function tree_x(_) {
return arguments.length ? (this._x = _, this) : this._x;
}
function defaultY(d) {
return d[1];
}
function tree_y(_) {
return arguments.length ? (this._y = _, this) : this._y;
}
function quadtree(nodes, x, y) {
var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);
return nodes == null ? tree : tree.addAll(nodes);
}
function Quadtree(x, y, x0, y0, x1, y1) {
this._x = x;
this._y = y;
this._x0 = x0;
this._y0 = y0;
this._x1 = x1;
this._y1 = y1;
this._root = undefined;
}
function leaf_copy(leaf) {
var copy = {data: leaf.data}, next = copy;
while (leaf = leaf.next) next = next.next = {data: leaf.data};
return copy;
}
var treeProto = quadtree.prototype = Quadtree.prototype;
treeProto.copy = function() {
var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),
node = this._root,
nodes,
child;
if (!node) return copy;
if (!node.length) return copy._root = leaf_copy(node), copy;
nodes = [{source: node, target: copy._root = new Array(4)}];
while (node = nodes.pop()) {
for (var i = 0; i < 4; ++i) {
if (child = node.source[i]) {
if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});
else node.target[i] = leaf_copy(child);
}
}
}
return copy;
};
treeProto.add = tree_add;
treeProto.addAll = addAll;
treeProto.cover = tree_cover;
treeProto.data = tree_data;
treeProto.extent = tree_extent;
treeProto.find = tree_find;
treeProto.remove = tree_remove;
treeProto.removeAll = removeAll;
treeProto.root = tree_root;
treeProto.size = tree_size;
treeProto.visit = tree_visit;
treeProto.visitAfter = tree_visitAfter;
treeProto.x = tree_x;
treeProto.y = tree_y;
var noop = {value: function() {}};
function dispatch() {
for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t);
_[t] = [];
}
return new Dispatch(_);
}
function Dispatch(_) {
this._ = _;
}
function parseTypenames(typenames, types) {
return typenames.trim().split(/^|\s+/).map(function(t) {
var name = "", i = t.indexOf(".");
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
return {type: t, name: name};
});
}
Dispatch.prototype = dispatch.prototype = {
constructor: Dispatch,
on: function(typename, callback) {
var _ = this._,
T = parseTypenames(typename + "", _),
t,
i = -1,
n = T.length;
// If no callback was specified, return the callback of the given type and name.
if (arguments.length < 2) {
while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
return;
}
// If a type was specified, set the callback for the given type and name.
// Otherwise, if a null callback was specified, remove callbacks of the given name.
if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
while (++i < n) {
if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
}
return this;
},
copy: function() {
var copy = {}, _ = this._;
for (var t in _) copy[t] = _[t].slice();
return new Dispatch(copy);
},
call: function(type, that) {
if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
},
apply: function(type, that, args) {
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
}
};
function get(type, name) {
for (var i = 0, n = type.length, c; i < n; ++i) {
if ((c = type[i]).name === name) {
return c.value;
}
}
}
function set(type, name, callback) {
for (var i = 0, n = type.length; i < n; ++i) {
if (type[i].name === name) {
type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
break;
}
}
if (callback != null) type.push({name: name, value: callback});
return type;
}
var frame = 0, // is an animation frame pending?
timeout = 0, // is a timeout pending?
interval = 0, // are any timers active?
pokeDelay = 1000, // how frequently we check for clock skew
taskHead,
taskTail,
clockLast = 0,
clockNow = 0,
clockSkew = 0,
clock = typeof performance === "object" && performance.now ? performance : Date,
setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };
function now() {
return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
}
function clearNow() {
clockNow = 0;
}
function Timer() {
this._call =
this._time =
this._next = null;
}
Timer.prototype = timer.prototype = {
constructor: Timer,
restart: function(callback, delay, time) {
if (typeof callback !== "function") throw new TypeError("callback is not a function");
time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
if (!this._next && taskTail !== this) {
if (taskTail) taskTail._next = this;
else taskHead = this;
taskTail = this;
}
this._call = callback;
this._time = time;
sleep();
},
stop: function() {
if (this._call) {
this._call = null;
this._time = Infinity;
sleep();
}
}
};
function timer(callback, delay, time) {
var t = new Timer;
t.restart(callback, delay, time);
return t;
}
function timerFlush() {
now(); // Get the current time, if not already set.
++frame; // Pretend weve set an alarm, if we havent already.
var t = taskHead, e;
while (t) {
if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
t = t._next;
}
--frame;
}
function wake() {
clockNow = (clockLast = clock.now()) + clockSkew;
frame = timeout = 0;
try {
timerFlush();
} finally {
frame = 0;
nap();
clockNow = 0;
}
}
function poke() {
var now = clock.now(), delay = now - clockLast;
if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
}
function nap() {
var t0, t1 = taskHead, t2, time = Infinity;
while (t1) {
if (t1._call) {
if (time > t1._time) time = t1._time;
t0 = t1, t1 = t1._next;
} else {
t2 = t1._next, t1._next = null;
t1 = t0 ? t0._next = t2 : taskHead = t2;
}
}
taskTail = t0;
sleep(time);
}
function sleep(time) {
if (frame) return; // Soonest alarm already set, or will be.
if (timeout) timeout = clearTimeout(timeout);
var delay = time - clockNow; // Strictly less than if we recomputed clockNow.
if (delay > 24) {
if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);
if (interval) interval = clearInterval(interval);
} else {
if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
frame = 1, setFrame(wake);
}
}
var initialRadius = 10,
initialAngle = Math.PI * (3 - Math.sqrt(5));
function forceSimulation(nodes) {
var simulation,
alpha = 1,
alphaMin = 0.001,
alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),
alphaTarget = 0,
velocityDecay = 0.6,
forces = new Map(),
stepper = timer(step),
event = dispatch("tick", "end");
if (nodes == null) nodes = [];
function step() {
tick();
event.call("tick", simulation);
if (alpha < alphaMin) {
stepper.stop();
event.call("end", simulation);
}
}
function tick(iterations) {
var i, n = nodes.length, node;
if (iterations === undefined) iterations = 1;
for (var k = 0; k < iterations; ++k) {
alpha += (alphaTarget - alpha) * alphaDecay;
forces.forEach(function(force) {
force(alpha);
});
for (i = 0; i < n; ++i) {
node = nodes[i];
if (node.fx == null) node.x += node.vx *= velocityDecay;
else node.x = node.fx, node.vx = 0;
if (node.fy == null) node.y += node.vy *= velocityDecay;
else node.y = node.fy, node.vy = 0;
}
}
return simulation;
}
function initializeNodes() {
for (var i = 0, n = nodes.length, node; i < n; ++i) {
node = nodes[i], node.index = i;
if (node.fx != null) node.x = node.fx;
if (node.fy != null) node.y = node.fy;
if (isNaN(node.x) || isNaN(node.y)) {
var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;
node.x = radius * Math.cos(angle);
node.y = radius * Math.sin(angle);
}
if (isNaN(node.vx) || isNaN(node.vy)) {
node.vx = node.vy = 0;
}
}
}
function initializeForce(force) {
if (force.initialize) force.initialize(nodes);
return force;
}
initializeNodes();
return simulation = {
tick: tick,
restart: function() {
return stepper.restart(step), simulation;
},
stop: function() {
return stepper.stop(), simulation;
},
nodes: function(_) {
return arguments.length ? (nodes = _, initializeNodes(), forces.forEach(initializeForce), simulation) : nodes;
},
alpha: function(_) {
return arguments.length ? (alpha = +_, simulation) : alpha;
},
alphaMin: function(_) {
return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
},
alphaDecay: function(_) {
return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
},
alphaTarget: function(_) {
return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
},
velocityDecay: function(_) {
return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
},
force: function(name, _) {
return arguments.length > 1 ? ((_ == null ? forces.delete(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name);
},
find: function(x, y, radius) {
var i = 0,
n = nodes.length,
dx,
dy,
d2,
node,
closest;
if (radius == null) radius = Infinity;
else radius *= radius;
for (i = 0; i < n; ++i) {
node = nodes[i];
dx = x - node.x;
dy = y - node.y;
d2 = dx * dx + dy * dy;
if (d2 < radius) closest = node, radius = d2;
}
return closest;
},
on: function(name, _) {
return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
}
};
}
// import { test } from './test.js';
// console.log("in index.js", test);
// test();
console.log("in index.js");
// import * as fetchJsonp from 'fetch-jsonp';
// import { jsonp } from 'jsonp';
var jsonp = require("jsonp");
console.log("force", forceSimulation);
console.log("fetchJsonp", fetchJsonp);
class Map$1 {
constructor (apiurl) {
this.apiurl = apiurl;
}
load (pagetitle) {
console.log("Map.load", pagetitle, this.apiurl);
jsonpP (this.apiurl).then(data => {
console.log("got data", data);
}).catch(err => {
console.log("ERROR", err);
});
}
}
// http://erg.activearchives.org/mw/api.php?action=query&prop=links&titles=Bienvenue_%C3%A0_l%E2%80%99erg
// http://erg.activearchives.org/w/api.php?action=query&prop=info&titles=Main%20Page
// Bienvenue_à_lerg
// http://erg.activearchives.org/mw/index.php/Bienvenue_%C3%A0_l%E2%80%99erg
exports.Map = Map$1;
return exports;
}({}));

3108
dist/wikimap.js vendored Normal file

File diff suppressed because it is too large Load Diff

5550
dist/wikimaptotal.js vendored Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

BIN
img/Cours_techniques.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

BIN
img/Cours_theoriques.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

BIN
img/Enseignants.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

BIN
img/Main.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

BIN
img/Orientations.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

84
index.html Normal file
View File

@@ -0,0 +1,84 @@
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="controls">
<a href="http://localhost/mw/api.php" id="mediawikiapi"></a><input id="startpage" value="Bienvenue à lerg" autofocus /><button id="button">ok</button>
</div>
<div id="content">
<svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"></svg>
</div>
<div id="wiki">
<iframe src="http://localhost/mw/"></iframe>
</div>
</body>
<script type="text/javascript" src="dist/wikimap.js"></script>
<script>
var mediawikiapi = document.querySelector("#mediawikiapi").href,
startpage = document.querySelector("#startpage"),
button = document.querySelector("#button"),
svg = document.querySelector("#svg"),
iframe = document.querySelector("iframe");
window.addEventListener("resize", resize);
function resize() {
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight|| e.clientHeight|| g.clientHeight;
svg.setAttribute("width", x);
svg.setAttribute("height", y);
console.log("resize", x, y);
}
resize();
// console.log("mediawikiapi", mediawikiapi);
var map = new wikimap.Map(mediawikiapi);
map.init_svg("#svg");
map.on("page", function (title) {
console.log("map.page", title);
var url = wiki_title_to_url(title);
iframe.src = url;
})
async function doload() {
map.set_active_node(startpage.value);
}
var URLPAT = new RegExp("http://localhost/mw/index.php/(.+)");
function strip_fragment (href) {
var spos = href.indexOf("#");
if (spos >= 0) {
return href.substr(0, href.indexOf("#"))
}
return href;
}
function url_to_wiki_title (href) {
href = strip_fragment(href);
var m = URLPAT.exec(href);
if (m !== null) {
return decodeURI(m[1]).replace(/_/g, " ");
}
console.log("m", m);
}
function wiki_title_to_url (title) {
return "http://localhost/mw/index.php/"+encodeURI(title.replace(/ /g, "_"));
}
// window.addEventListener("DOMContentLoaded", doload);
button.addEventListener("click", doload);
iframe.addEventListener("load", function () {
var href = strip_fragment(iframe.contentWindow.location.href);
console.log("iframe loaded", href);
var title = url_to_wiki_title(href);
console.log("title", title);
if (title) {
map.set_active_title(title);
}
// attempt to map url to wiki page title and update the map if it is one
})
</script>
</html>

153
map.html Normal file
View File

@@ -0,0 +1,153 @@
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<style>
#wiki {
left: 80%;
}
</style>
</head>
<body>
<div id="controls">
<a href="http://localhost/mw/api.php" id="mediawikiapi"></a><input id="startpage" value="Bienvenue à lerg" autofocus /><button id="button">ok</button>
</div>
<div id="content">
<svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"></svg>
</div>
<div id="wiki">
<iframe src="http://localhost/mw/"></iframe>
</div>
<div id="cats" class="expanded">
<div class="ocontents">
<div class="contents">
<div class="head">Liste des catégories</div>
<div class="body"></div>
<div class="foot"><input id="allcats" type="checkbox"><label for="allcats">Afficher tous</label></div>
<hr>
<div class="history"><input id="history" type="checkbox"><label for="history">Histoire</div>
</div>
</div>
<div class="botright"><div class="thumb"></div></div>
</div>
</body>
<script type="text/javascript" src="dist/wikimaptotal.js"></script>
<script>
var mediawikiapi = document.querySelector("#mediawikiapi").href,
startpage = document.querySelector("#startpage"),
button = document.querySelector("#button"),
svg = document.querySelector("#svg"),
iframe = document.querySelector("iframe"),
cats = document.querySelector("#cats"),
cats_contents = document.querySelector("#cats .body"),
cats_thumb = document.querySelector("#cats .thumb"),
allcatscb = document.querySelector("input#allcats"),
historycb = document.querySelector("input#history"),
current_title = null,
loaded = false;
window.addEventListener("resize", resize);
function resize() {
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight|| e.clientHeight|| g.clientHeight;
svg.setAttribute("width", x);
svg.setAttribute("height", y);
console.log("resize", x, y);
}
resize();
// console.log("mediawikiapi", mediawikiapi);
var symbols = {
"Orientations": "symbols.svg#Orientations",
"Ateliers pluridisciplinaires": "symbols.svg#Ateliers_pluridisciplinaires",
"Cours de soutien à l'orientation": "symbols.svg#Cours_de_soutien_a_l'orientation",
"Cours de soutien spécifique": "symbols.svg#Cours_de_soutien_specifique",
"Cours techniques": "symbols.svg#Cours_techniques",
"Cours théoriques": "symbols.svg#Cours_theoriques",
"Enseignants": "symbols.svg#Enseignants",
"default": "symbols.svg#Main"
};
var map = new wikimap.SimpleMap(symbols);
map.init_svg("#svg");
async function doload () {
console.log("loading map");
await map.load_json("sitemap.json");
console.log("loading categories");
await map.load_cats("cats.json", cats_contents);
console.log("LOADED!");
loaded = true;
if (current_title) {
map.set_active_title(current_title);
}
}
map.on("page", function (title) {
console.log("map.page", title);
var url = wiki_title_to_url(title);
iframe.src = url;
})
// async function doload() {
// map.set_active_node(startpage.value);
// }
var URLPAT = new RegExp("http://localhost/mw/index.php/(.+)");
function strip_fragment (href) {
var spos = href.indexOf("#");
if (spos >= 0) {
return href.substr(0, href.indexOf("#"))
}
return href;
}
function url_to_wiki_title (href) {
href = strip_fragment(href);
var m = URLPAT.exec(href);
if (m !== null) {
return decodeURI(m[1]).replace(/_/g, " ");
}
console.log("m", m);
}
function wiki_title_to_url (title) {
return "http://localhost/mw/index.php/"+encodeURI(title.replace(/ /g, "_"));
}
window.addEventListener("DOMContentLoaded", doload);
iframe.addEventListener("load", function () {
var href = strip_fragment(iframe.contentWindow.location.href);
console.log("iframe loaded", href);
var title = url_to_wiki_title(href);
console.log("title", title);
if (title) {
current_title = title;
if (loaded) {
map.set_active_title(title);
}
}
// attempt to map url to wiki page title and update the map if it is one
});
cats_thumb.addEventListener("click", function () {
cats.classList.toggle("expanded");
});
// allcats checkbox
// match current state & respond to change events
// console.log("setting checked to", cats.classList.contains("showall"))
allcatscb.checked = cats.classList.contains("showall");
allcatscb.addEventListener("change", function () {
// console.log("allcats", allcatscb);
if (allcatscb.checked) {
cats.classList.add("showall")
} else {
cats.classList.remove("showall")
}
})
historycb.addEventListener("change", function () {
// console.log("history", historycb.checked);
map.set_show_history(historycb.checked);
})
</script>
</html>

29
rollup.config.js Normal file
View File

@@ -0,0 +1,29 @@
// rollup.config.js
// https://github.com/rollup/rollup-plugin-commonjs
import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
export default [{
input: 'src/wikimap.js',
output: {
file: 'dist/wikimap.js',
format: 'iife',
name: 'wikimap'
},
plugins: [
resolve(),
commonjs()
]
},{
input: 'src/wikimaptotal.js',
output: {
file: 'dist/wikimaptotal.js',
format: 'iife',
name: 'wikimap'
},
plugins: [
resolve(),
commonjs()
]
}
];

View File

@@ -0,0 +1,33 @@
#!/usr/bin/env python3
from __future__ import print_function
import argparse, sys, json, time, os
from jinja2 import Template, DictLoader, Environment, FileSystemLoader
ap = argparse.ArgumentParser("template + svg = interface")
ap.add_argument("template")
ap.add_argument("svg")
ap.add_argument("--output", type=argparse.FileType('w'), default=sys.stdout)
args = ap.parse_args()
tpath, tname = os.path.split(args.template)
env = Environment(loader=FileSystemLoader(tpath))
import jinjafilters
for name, fn in jinjafilters.all.items():
env.filters[name] = fn
from xml.etree import ElementTree as ET
ET.register_namespace("","http://www.w3.org/2000/svg")
ET.register_namespace("xlink","http://www.w3.org/1999/xlink")
with open(args.svg) as f:
svgt = ET.parse(f)
# print ("svgt", svgt)
svg_root = svgt.getroot()
svg_root.attrib['xmlns:xlink'] = 'http://www.w3.org/1999/xlink'
del svg_root.attrib['viewBox']
svg = ET.tostring(svgt.getroot(), method="xml")
tvars = {'svg': svg}
template = env.get_template(tname)
print (template.render(**tvars).encode("utf-8"), file=args.output)

105
scripts/buildsitemap.py Normal file
View File

@@ -0,0 +1,105 @@
from mwclient import Site, APIError
from mwclient.page import Page
import argparse, json, sys
ap = argparse.ArgumentParser("")
ap.add_argument("--wikiprotocol", default="http")
ap.add_argument("--wikihost", default="localhost")
ap.add_argument("--wikipath", default="/mw/")
ap.add_argument("--limit", default=None)
ap.add_argument("--output", default=sys.stdout, type=argparse.FileType('w'))
# ap.add_argument("--user", default=None)
# ap.add_argument("--password", default=None)
args = ap.parse_args()
site = Site((args.wikiprotocol, args.wikihost), path=args.wikipath)
def category_subcats (site, cattitle, objects=True):
cmcontinue = None
ret = []
while True:
if cmcontinue == None:
resp = site.api("query", list="categorymembers", cmtitle=cattitle, cmtype="subcat", cmlimit=50)
else:
resp = site.api("query", list="categorymembers", cmtitle=cattitle, cmtype="subcat", cmlimit=50, cmcontinue=cmcontinue)
ret.extend([x['title'] for x in resp['query']['categorymembers']])
if 'continue' in resp:
cmcontinue = resp['continue']['cmcontinue']
else:
break
if objects:
# print "converting to page objects ({0})".format(len(ret))
ret = [site.pages[x] for x in ret]
return ret
"""
>>> c.page_title
'Équipes'
>>> c.name
'Catégorie:Équipes'
"""
"""
graph = {
nodes: [
{name: "Bienvenue"}
]
links: [
{source: "name", target: "name2"}
]
}
"""
redirects = {}
pages = []
count = 0
all_links = set()
page_exists = {}
def resolve (x):
while x in redirects:
x = redirects[x]
return x
print ("Pass 1")
for p in site.allpages():
r = p.redirects_to()
if (r):
redirects[p.name] = r.name
else:
page_exists[p.name] = True
print ("Pass 2")
# pages_by_title = {}
for p in site.allpages():
if (p.name in redirects):
continue
pd = {}
pd['title'] = p.page_title
pd['ns'] = 0
print ("Page {0}".format(p.name), file=sys.stderr)
# categories
cats = [c.page_title for c in p.categories()]
pd['cats'] = cats
# links
links = [x for x in p.links() if x.namespace == 0]
links = [resolve(x.name) for x in links]
links = [x for x in links if x in page_exists]
for l in links:
if p.name < l:
link = (p.name, l)
else:
link = (l, p.name)
all_links.add(link)
pages.append(pd)
count += 1
if args.limit and count >= args.limit:
break
graph = {}
graph['nodes'] = pages
graph['links'] = [{'source': a, 'target': b} for a, b in all_links]
graph['redirects'] = redirects
print (json.dumps(graph, indent=2), file=args.output)

91
scripts/categories.py Normal file
View File

@@ -0,0 +1,91 @@
from mwclient import Site, APIError
from mwclient.page import Page
import argparse, json, sys
import unidecode
# unaccented_string = unidecode.unidecode(accented_string)
ap = argparse.ArgumentParser("")
ap.add_argument("--wikiprotocol", default="http")
ap.add_argument("--wikihost", default="localhost")
ap.add_argument("--wikipath", default="/mw/")
ap.add_argument("--limit", default=None)
ap.add_argument("--output", default=sys.stdout, type=argparse.FileType('w'))
# ap.add_argument("--user", default=None)
# ap.add_argument("--password", default=None)
args = ap.parse_args()
site = Site((args.wikiprotocol, args.wikihost), path=args.wikipath)
def category_subcats (site, cattitle, objects=True):
cmcontinue = None
ret = []
while True:
if cmcontinue == None:
resp = site.api("query", list="categorymembers", cmtitle=cattitle, cmtype="subcat", cmlimit=50)
else:
resp = site.api("query", list="categorymembers", cmtitle=cattitle, cmtype="subcat", cmlimit=50, cmcontinue=cmcontinue)
ret.extend([x['title'] for x in resp['query']['categorymembers']])
if 'continue' in resp:
cmcontinue = resp['continue']['cmcontinue']
else:
break
if objects:
# print "converting to page objects ({0})".format(len(ret))
ret = [site.pages[x] for x in ret]
return ret
def strip_namespace (x):
if ":" in x:
return x.split(":", 1)[1]
return x
cats = list(site.allcategories())
cats.sort(key=lambda x: unidecode.unidecode(x.name))
# cats_by_name = {}
cats = [{ 'title': cat.page_title, 'name': cat.name } for cat in cats]
index = {}
for c in cats:
index[c['title']] = c
for c in cats:
sc = category_subcats(site, c['name'], objects=False)
sc = [strip_namespace(x) for x in sc]
if sc:
for subcat in sc:
subcat = index[subcat]
if 'parent' not in subcat:
subcat['parent'] = c
def make_hierarchy (items):
root = {'children': []}
for item in items:
if 'parent' in item:
if 'children' not in item['parent']:
item['parent']['children'] = []
item['parent']['children'].append(item)
item['parent'] = item['parent']['title']
# del item['parent']
else:
root['children'].append(item)
return root
def flatten (root, depth=0):
for x in root['children']:
r = {'title': x['title'], 'name': x['name'], 'depth': depth}
if 'parent' in x:
r['parent'] = x['parent']
yield(r)
if 'children' in x:
for item in flatten(x, depth+1):
yield item
import json
root = make_hierarchy(cats)
#print (json.dumps(root, indent=2), file=args.output)
flat = list(flatten(root))
print (json.dumps(flat, indent=2), file=args.output)

6116
sitemap.json Normal file

File diff suppressed because it is too large Load Diff

221
src/forcenet.js Normal file
View File

@@ -0,0 +1,221 @@
import { event, select, selectAll} from 'd3-selection';
import { values, set, map } from 'd3-collection';
import { drag } from 'd3-drag';
import { zoom } from 'd3-zoom';
import { forceSimulation, forceLink, forceManyBody, forceCenter, forceX, forceY, forceRadial } from 'd3-force';
// import { Wiki, Page } from './wiki.js';
import EventEmitter from 'eventemitter3';
// import { json } from 'd3-fetch';
export class ForceNet {
constructor (symbols) {
var width = 600,
height = 600;
this.symbols = symbols || {};
this.events = new EventEmitter();
this.active_page = null;
// this.nodes = {};
this.simulation = forceSimulation()
.velocityDecay(0.1)
.force("link", forceLink().id(d => d.title))
.force("charge", forceManyBody())
.force("radial", forceRadial(180, width/2, height/2));
// .force("center", forceCenter(width / 2, height / 2));
this.svg = null;
// this.historylinks = {};
}
on (message, callback, context) {
this.events.on(message, callback, context);
}
init_svg (svg) {
this.svg = select(svg || "svg");
this.zoom = zoom()
.scaleExtent([1 / 16, 4])
.on("zoom", () => {
this.content.attr("transform", event.transform);
// console.log("transform", event.transform, this.content.attr("transform"));
});
this.rect = this.svg.append("rect")
.attr("width", 1000)
.attr("height", 1000)
.style("fill", "none")
.style("pointer-events", "all")
.call(this.zoom);
this.content = this.svg.append("g")
.attr("id", "content"),
this.linksg = this.content.append("g")
.attr("class", "links");
this.nodesg = this.content.append("g")
.attr("class", "nodes");
}
dragstarted (d) {
if (!event.active) this.simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
dragged (d) {
d.fx = event.x;
d.fy = event.y;
}
dragended(d) {
if (!event.active) this.simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
link_key (a, b) {
return (a < b) ? ("link_"+a+"_"+b) : ("link_"+b+"_"+a);
}
get_symbol (d, def) {
for (var i=0, l=d.cats.length; i<l; i++) {
if (this.symbols[d.cats[i]]) {
return this.symbols[d.cats[i]];
}
}
return this.symbols.default || def;
}
update_graph (graph) {
console.log("UPDATE GRAPH", graph.nodes.length, graph.links.length);
var link = this.linksg.selectAll("line")
.data(graph.links, d => { return this.link_key(d.source.title, d.target.title) });
var link_enter = link.enter()
.append("line");
link.exit().each(d => {
d.source.linked = false;
d.target.linked = false;
}).remove();
link_enter.merge(link).each(d => {
d.source.linked = true;
d.target.linked = true;
});
var node = this.nodesg
.selectAll("g.page")
.data(graph.nodes, function (d) { return d.title });
var that = this;
var node_enter = node.enter().append("g")
.attr("class", "page")
// .attr("class", d=>"page "+this.wiki.get_ns_classname(d.ns))
.on("click", function(d) {
that.events.emit("nodeclick", d, this);
// this.set_active_node(d.title);
})
.on("mouseover", function (d) {
// console.log("mouseover", this);
select(this).classed("mouse", true);
})
.on("mouseout", function (d) {
// console.log("mouseout", this);
select(this).classed("mouse", false);
})
.call(drag()
.on("start", this.dragstarted.bind(this))
.on("drag", this.dragged.bind(this))
.on("end", this.dragended.bind(this)));
node_enter.append("use")
.attr("xlink:href", d => this.get_symbol(d, "default"))
.attr("class", "testcolor");
// {
// for (var i=0, l=d.cats.length; i<l; i++) {
// if (this.symbols[d.cats[i]]) {
// return this.symbols[d.cats[i]];
// }
// }
// return this.symbols.default || "default";
// });
// node_enter.append("circle")
// .attr("r", 6);
node_enter.append("text")
.text(d => d.title)
.attr("x", 10);
//node_enter.append("title")
// .text(function(d) { return d.title; });
node = node_enter.merge(node);
link = link_enter.merge(link);
node.classed("active", d=>d.active);
this.simulation
.nodes(graph.nodes)
.on("tick", ticked);
this.simulation.force("link")
.links(graph.links);
this.simulation.force("radial").radius(d => d.linked ? null : 200);
function ticked() {
link
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
// node
// .attr("cx", function(d) { return d.x; })
// .attr("cy", function(d) { return d.y; });
node
.attr("transform", d => `translate(${d.x},${d.y})`);
}
this.update_nodes();
this.update_forces();
// this.simulation.alphaTarget(0.3).restart();
}
update_nodes () {
var nodes = this.nodesg.selectAll("g.page");
console.log("update_nodes", nodes.size());
nodes.classed("active", d=>d.active);
nodes.classed("active2", d=>d.active2);
nodes.classed("highlight", d=>d.highlight);
nodes.sort((a, b) => {
// console.log("sort", a, b);
var x = a.active ? 10 : (a.active2 ? 5 : 0),
y = b.active ? 10 : (b.active2 ? 5 : 0);
return x - y;
});
var links = this.linksg.selectAll("line");
links.classed("active2", d=>d.active2);
links.classed("history", d=>d.type == "history");
links.sort((a, b) => {
// console.log("sort", a, b);
var x = a.active2 ? 10 : (a.history ? 5 : 0),
y = b.active2 ? 10 : (b.history ? 5 : 0);
return x - y;
});
}
update_forces () {
var force = this.simulation.force("link");
console.log("update_forces:force", force);
this.simulation.force("link").strength(d => {
if (d.source.active || d.target.active) {
return 1;
} else {
// same as d3.force's defaultStrength
return 0.5 * (1 / Math.min(d.source.count, d.target.count));
}
});
this.simulation.alphaTarget(0.3).restart();
}
}

3
src/test.js Normal file
View File

@@ -0,0 +1,3 @@
export function test () {
alert("testing import");
}

154
src/wiki.js Normal file
View File

@@ -0,0 +1,154 @@
import fetchJsonp from 'fetch-jsonp';
import { map } from 'd3-collection';
var NS = {
main: 0,
discussion: 1,
template: 10,
category: 14,
news: 3106,
web: 3116
}
export class Wiki {
constructor (apiurl) {
this.apiurl = apiurl;
this.pages_by_title = {};
this.ns_names = {};
for (var key in NS) {
var nsid = NS[key];
this.ns_names[nsid] = key;
}
}
get_page_by_title (title) {
var p = this.pages_by_title[title];
if (p) {
return p;
} else {
p = new Page(this, {title: title, ns: 0});
this.pages_by_title[title] = p;
return p;
}
}
page_for_object (n, merge_data) {
if (merge_data === undefined) { merge_data = true; }
var title = n.title,
p = this.pages_by_title[title];
if (p) {
if (merge_data) { p.merge_data(n); }
return p;
} else {
p = new Page(this, n);
this.pages_by_title[title] = p;
return p;
}
}
get_ns_classname (nsid) {
// console.log("get_ns_classname", nsid, this.ns_names[nsid]);
var ret = this.ns_names[nsid];
console.log("classname", ret);
if (ret === undefined) { console.log("warning classname undefined for ns", nsid); }
return ret;
}
union (p1, p2) {
var union = map(p1, d=>d.title);
for (var i=0, l=p2.length; i<l; i++) {
var x = p2[i];
union.set(x.title, x);
}
return union.values();
}
}
export class Page {
constructor (wiki, node) {
this.wiki = wiki;
this.merge_data(node);
}
url () {
// return this.wiki.apiurl.replace("api.php", "index.php")+"/"+encodeURIComponent(this.title);
return this.wiki.apiurl.replace("api.php", "index.php")+"/"+encodeURIComponent(this.title);
}
merge_data (node) {
for (var key in node) {
if (node.hasOwnProperty(key)) {
this[key] = node[key];
}
}
}
// api.php?action=query&prop=categories&titles=Albert%20Einstein
async get_prop (pname, prefix) {
var ret = [];
var url = this.wiki.apiurl+"?action=query&format=json&formatversion=2&prop="+pname+"&titles="+encodeURIComponent(this.title);
while (true) {
var data = await fetchJsonp(url);
var json = await data.json();
// console.log("BACKLINKS.RAW", json);
// filter REDIRECTS + Discussion pages (ns==1)
if (json.query.pages[0]) {
var p = json.query.pages[0];
// extract any missing page info
if (p.ns && !this.ns) { this.ns = p.ns; }
if (p.pageid && !this.pageid) { this.pageid = p.pageid; }
}
if (json.query.pages[0][pname]) {
ret.push.apply(ret, json.query.pages[0][pname]);
}
if (!json.continue) { break; }
url = this.wiki.apiurl+"?action=query&format=json&formatversion=2&prop="+pname+"&"+prefix+"continue="+json.continue[prefix+"continue"]+"&titles="+encodeURIComponent(this.title);
}
ret = ret.map(x => this.wiki.page_for_object(x));
// console.log("get_backlinks", ret);
console.log("get_prop", pname, prefix, ret);
return ret;
}
async get_links () {
return await this.get_prop("links", "pl");
// // http://localhost/mw/api.php?action=query&prop=links&titles=Bienvenue_%C3%A0_l%E2%80%99erg
// var ret = [];
// var url = this.wiki.apiurl+"?action=query&format=json&formatversion=2&prop=links&titles="+encodeURIComponent(this.title);
// while (true) {
// var data = await fetchJsonp(url);
// var json = await data.json();
// // console.log("JSON", json);
// if (json.query.pages[0]) {
// var p = json.query.pages[0];
// // extract any missing page info
// if (p.ns && !this.ns) { this.ns = p.ns; }
// if (p.pageid && !this.pageid) { this.pageid = p.pageid; }
// }
// if (json.query.pages[0].links) {
// ret.push.apply(ret, json.query.pages[0].links);
// }
// if (!json.continue) { break; }
// url = this.wiki.apiurl+"?action=query&format=json&formatversion=2&prop=links&plcontinue="+json.continue.plcontinue+"&titles="+encodeURIComponent(this.title);
// }
// ret = ret.map(x => this.wiki.page_for_object(x));
// // map these to page objects
// return ret;
}
async get_linkshere () {
return await this.get_prop("linkshere", "lh");
}
async get_list () {
// http://localhost/mw/api.php?action=query&prop=links&titles=Bienvenue_%C3%A0_l%E2%80%99erg
var ret = [];
var url = this.wiki.apiurl+"?action=query&format=json&formatversion=2&list=backlinks&bltitle="+encodeURIComponent(this.title);
while (true) {
var data = await fetchJsonp(url);
var json = await data.json();
// console.log("BACKLINKS.RAW", json);
// filter REDIRECTS + Discussion pages (ns==1)
var backlinks = json.query.backlinks;
// backlink = backlinks.filter(x => (!x.redirect && x.ns != 1);
ret.push.apply(ret, backlinks);
if (!json.continue) { break; }
url = this.wiki.apiurl+"?action=query&format=json&formatversion=2&list=backlinks&blcontinue="+json.continue.blcontinue+"&bltitle="+encodeURIComponent(this.title);
}
ret = ret.map(x => this.wiki.page_for_object(x));
// console.log("get_backlinks", ret);
return ret;
}
}

210
src/wikimap.js Normal file
View File

@@ -0,0 +1,210 @@
import { event, select, selectAll} from 'd3-selection';
import { values, set, map } from 'd3-collection';
import { drag } from 'd3-drag';
import { forceSimulation, forceLink, forceManyBody, forceCenter, forceX, forceY, forceRadial } from 'd3-force';
import { Wiki, Page } from './wiki.js';
import EventEmitter from 'eventemitter3';
export class Map {
constructor (apiurl) {
var width = 600,
height = 600;
this.wiki = new Wiki(apiurl);
this.events = new EventEmitter();
this.active_page = null;
// this.nodes = {};
this.simulation = forceSimulation()
.velocityDecay(0.1)
.force("link", forceLink().id(d => d.title))
.force("charge", forceManyBody())
.force("radial", forceRadial(180, width/2, height/2));
// .force("center", forceCenter(width / 2, height / 2));
this.svg = null;
this.historylinks = {};
}
on (message, callback, context) {
this.events.on(message, callback, context);
}
init_svg (svg) {
this.svg = select(svg || "svg");
this.linksg = this.svg.append("g")
.attr("class", "links");
this.nodesg = this.svg.append("g")
.attr("class", "nodes");
}
dragstarted (d) {
if (!event.active) this.simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
dragged (d) {
d.fx = event.x;
d.fy = event.y;
}
dragended(d) {
if (!event.active) this.simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
update_graph (graph) {
// console.log("UPDATE GRAPH", graph.nodes.length, graph.links.length);
var that = this,
link = this.linksg.selectAll("line")
.data(graph.links, function (d) { return that.link_key(d.source.title, d.target.title) });
var link_enter = link.enter()
.append("line");
link.exit().each(d => {
d.source.linked = false;
d.target.linked = false;
}).remove();
link_enter.merge(link).each(d => {
d.source.linked = true;
d.target.linked = true;
});
var node = this.nodesg
.selectAll("g.page")
.data(graph.nodes, function (d) { return d.title });
var node_enter = node.enter().append("g")
.attr("class", d=>"page "+this.wiki.get_ns_classname(d.ns))
.on("click", d => {
this.set_active_node(d.title);
})
.on("mouseover", function (d) {
// console.log("mouseover", this);
select(this).classed("mouse", true);
})
.on("mouseout", function (d) {
// console.log("mouseout", this);
select(this).classed("mouse", false);
})
.call(drag()
.on("start", this.dragstarted.bind(this))
.on("drag", this.dragged.bind(this))
.on("end", this.dragended.bind(this)));
node_enter.append("circle")
.attr("r", 6);
node_enter.append("text")
.text(d => d.title)
.attr("x", 10);
//node_enter.append("title")
// .text(function(d) { return d.title; });
node = node_enter.merge(node);
link = link_enter.merge(link);
node.classed("active", d=>d.active);
this.simulation
.nodes(graph.nodes)
.on("tick", ticked);
this.simulation.force("link")
.links(graph.links);
this.simulation.force("radial").radius(d => d.linked ? null : 200);
function ticked() {
link
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
// node
// .attr("cx", function(d) { return d.x; })
// .attr("cy", function(d) { return d.y; });
node
.attr("transform", d => `translate(${d.x},${d.y})`);
}
this.simulation.alphaTarget(0.3).restart();
}
link_key (a, b) {
return (a < b) ? ("link_"+a+"_"+b) : ("link_"+b+"_"+a);
}
walk (node, links) {
var links_seen = {};
// var node = this.ensure_node(nodename);
node.all_links.forEach(x => {
var link_key = this.link_key(node.title, x.title);
if (!links_seen[link_key]) {
links.push({source: node, target: x});
links_seen[link_key] = true;
}
})
return;
}
set_active_title (title) {
this.set_active_node(title);
}
async set_active_node (page) {
if (typeof(page) === "string") {
page = this.wiki.get_page_by_title(page)
}
if (page === this.active_page) {
// console.log("page is already the active page", page, this.active_page);
return;
}
if (this.active_page) {
this.active_page.active = false;
var lkey = this.link_key(this.active_page.title, page.title),
source = (this.active_page.title < page.title) ? this.active_page : page,
target = (this.active_page.title < page.title) ? page : this.active_page;
this.historylinks[lkey] = {source: source, target: target};
}
// n = this.ensure_node(pagetitle);
this.active_page = page;
this.active_page.active = true;
this.load(this.active_page);
this.events.emit("page", this.active_page.title);
}
async load (page) {
console.log("loading", page.title);
var links = await page.get_links(),
backlinks = await page.get_linkshere(),
alllinks = this.wiki.union(links, backlinks);
page.all_links = alllinks;
// console.log("alllinks", alllinks);
var graph = {};
graph.nodes = values(this.wiki.pages_by_title);
graph.links = [];
this.walk(page, graph.links);
// activate historylinks
values(this.historylinks).forEach(x => {
graph.links.push(x);
})
// graph.links = titles.map(t => ({source: pagetitle, target: t}));
this.update_graph(graph);
// console.log("GOT DATA", titles);
// return titles;
}
}
// http://erg.activearchives.org/mw/api.php?action=query&prop=links&titles=Bienvenue_%C3%A0_l%E2%80%99erg
// http://erg.activearchives.org/w/api.php?action=query&prop=info&titles=Main%20Page
// Bienvenue_à_lerg
// http://erg.activearchives.org/mw/index.php/Bienvenue_%C3%A0_l%E2%80%99erg

285
src/wikimapsimple.js Normal file
View File

@@ -0,0 +1,285 @@
import { event, select, selectAll} from 'd3-selection';
import { values, set, map } from 'd3-collection';
import { drag } from 'd3-drag';
import { zoom } from 'd3-zoom';
import { forceSimulation, forceLink, forceManyBody, forceCenter, forceX, forceY, forceRadial } from 'd3-force';
import { Wiki, Page } from './wiki.js';
import EventEmitter from 'eventemitter3';
import { json } from 'd3-fetch';
import { ForceNet } from './forcenet.js';
export class SimpleMap {
constructor (symbols) {
var width = 600,
height = 600;
this.events = new EventEmitter();
this.active_page = null;
// this.nodes = {};
this.symbols = symbols;
this.net = new ForceNet(symbols);
this.net.on("nodeclick", this.nodeclick.bind(this));
// this.simulation = forceSimulation()
// .velocityDecay(0.1)
// .force("link", forceLink().id(d => d.title))
// .force("charge", forceManyBody())
// .force("radial", forceRadial(180, width/2, height/2));
// // .force("center", forceCenter(width / 2, height / 2));
this.svg = null;
this.historylinks = {};
this.links = null;
this.highlight_category = null;
this.show_history = false;
}
nodeclick (d, elt) {
console.log("nodeclick", d, elt, this);
this.set_active_node(d, elt);
}
init_svg (svg) {
this.net.init_svg(svg);
}
async load_json (source) {
var data = await json(source);
// index the nodes by title, init link-arity count
var index = {};
this.nodes_by_title = index;
for (let i=0, l=data.nodes.length; i<l; i++) {
let node = data.nodes[i];
node.count = 0;
index[node.title] = node;
}
this.nodes = data.nodes;
var use_links = [];
data.links = data.links.forEach(x => {
var source = index[x.source],
target = index[x.target];
if (source === undefined) {
console.log("bad source", x.source);
return;
}
if (target === undefined) {
console.log("bad target", x.target);
return;
}
source.count += 1;
target.count += 1;
use_links.push({ source: source, target: target });
});
data.links = use_links;
this.links = data.links;
// console.log("data", data);
// calculate the node sizes (link arity)
this.net.update_graph(data);
}
get_symbol_image_path (cname) {
var symbol = this.symbols[cname];
if (symbol) {
let hpos = symbol.indexOf("#"),
rest = symbol.substr(hpos+1);
rest = rest.replace(/'/g, '');
return "img/"+rest+".png";
}
}
async load_cats (src, elt) {
var data = await json(src);
console.log("indexing categories by title");
var cats_by_title = {};
for (let i=0, l=data.length; i<l; i++) {
let cat = data[i];
cats_by_title[cat.title] = cat;
cat.pages = [];
cat.tcount = 0;
}
// index categories
console.log("indexing categories");
for (let key in this.nodes_by_title) {
let node = this.nodes_by_title[key];
// console.log("key", key, node.cats);
for (let j=0, jl=node.cats.length; j<jl; j++) {
let cname = node.cats[j],
cat = cats_by_title[cname];
if (cat) {
// increment the category + parents
cat.pages.push(node);
cat.tcount += 1
while (cat.parent) {
cat = cats_by_title[cat.parent];
cat.tcount += 1;
}
} else {
console.log("Warning, unknown category", cname);
}
}
}
console.log("pre filter", data.length);
data = data.filter(d => d.tcount > 0)
console.log("post filter", data.length);
console.log("load_cats.data", data, elt);
var cat = select(elt)
.selectAll("div.cat")
.data(data)
.enter()
.append("div")
.attr("class", "cat");
cat.classed("icon", d => this.get_symbol_image_path(d.title));
cat.append("span").attr("class", "icon").filter(d=> this.get_symbol_image_path(d.title)).style("background-image", d => "url("+this.get_symbol_image_path(d.title)+")");
cat.append("span").attr("class", "spacing").html(d => {
var d = d.depth,
ret = "";
while(d) {
ret += "&nbsp;&nbsp;&nbsp;&nbsp;";
d-=1;
}
return ret;
});
cat.append("a").attr("class", "label").html(d => d.title).attr("href", "#").on("click", d => {
event.preventDefault();
this.category_click(d);
})
cat.append("span").attr("class", "count").html(d => d.tcount)
}
category_click (d) {
console.log("category click", d);
if (this.highlight_category) {
// cleanup old pages
this.highlight_category.pages.forEach(d => d.highlight = false);
}
this.highlight_category = d;
this.highlight_category.pages.forEach(d => d.highlight = true);
this.net.update_nodes();
// set highlight category...
// all nodes with this category get .highlight = true
// make a category index ?!
}
on (message, callback, context) {
this.events.on(message, callback, context);
}
/* OLD STYLE with node.all_links
walk (node, links) {
var links_seen = {};
// var node = this.ensure_node(nodename);
node.all_links.forEach(x => {
var link_key = this.link_key(node.title, x.title);
if (!links_seen[link_key]) {
links.push({source: node, target: x});
links_seen[link_key] = true;
}
})
return;
}
*/
set_active_title (title) {
this.set_active_node(title);
}
activate_linked_nodes (page, active) {
// deactivate linked links/nodes
for (let i=0, l=this.links.length; i<l; i++) {
let link = this.links[i];
if (link.source == page || link.target == page) {
link.active2 = active;
link.source.active2 = active;
link.target.active2 = active;
}
}
}
async set_active_node (page) {
if (typeof(page) === "string") {
let pagename = page;
page = this.nodes_by_title[page];
if (!page) {
console.log("wikimap.set_active_node: page not found", pagename);
}
}
if (page === this.active_page) {
// console.log("page is already the active page", page, this.active_page);
return;
}
if (this.active_page) {
this.active_page.active = false;
// deactivate linked links/nodes
this.activate_linked_nodes(this.active_page, false);
// ENSURE HISTORY LINK TO PREVIOUS NODE AND CURRENT
var lkey = this.net.link_key(this.active_page.title, page.title),
source = (this.active_page.title < page.title) ? this.active_page : page,
target = (this.active_page.title < page.title) ? page : this.active_page;
this.historylinks[lkey] = {source: source, target: target, type:"history"};
}
this.active_page = page;
this.active_page.active = true;
this.activate_linked_nodes(this.active_page, true);
this.events.emit("page", this.active_page.title);
this.net.update_nodes();
this.net.update_forces();
}
set_show_history (value) {
console.log("wikimapsimple.show_history", value);
if (this.show_history !== value) {
this.show_history = value;
if (this.show_history) {
let graph = {};
graph.nodes = this.nodes;
graph.links = this.links.slice();
for (var key in this.historylinks) {
graph.links.push(this.historylinks[key])
}
this.net.update_graph(graph);
} else {
let graph = {};
graph.nodes = this.nodes;
graph.links = this.links;
this.net.update_graph(graph);
}
}
}
/*
async load (page) {
console.log("loading", page.title);
var links = await page.get_links(),
backlinks = await page.get_linkshere(),
alllinks = this.wiki.union(links, backlinks);
page.all_links = alllinks;
// console.log("alllinks", alllinks);
var graph = {};
graph.nodes = values(this.wiki.pages_by_title);
graph.links = [];
this.walk(page, graph.links);
// activate historylinks
values(this.historylinks).forEach(x => {
graph.links.push(x);
})
// graph.links = titles.map(t => ({source: pagetitle, target: t}));
this.update_graph(graph);
// console.log("GOT DATA", titles);
// return titles;
}
*/
}
// http://erg.activearchives.org/mw/api.php?action=query&prop=links&titles=Bienvenue_%C3%A0_l%E2%80%99erg
// http://erg.activearchives.org/w/api.php?action=query&prop=info&titles=Main%20Page
// Bienvenue_à_lerg
// http://erg.activearchives.org/mw/index.php/Bienvenue_%C3%A0_l%E2%80%99erg

6
src/wikimaptotal.js Normal file
View File

@@ -0,0 +1,6 @@
import { SimpleMap } from './wikimapsimple.js';
// gather ALL nodes + links from the wiki via the API
export { SimpleMap };

183
style.css Normal file
View File

@@ -0,0 +1,183 @@
#content {
position: absolute;
left: 0; top: 0; right: 0; bottom: 0;
background: #EEE;
}
#wiki {
position: absolute;
left: 50%;
right: 0;
top: 0;
bottom: 0;
}
#wiki iframe {
width: 100%;
height: 100%;
border: none;
}
body {
margin: 0;
overflow: hidden;
}
#controls {
position: absolute;
z-index:10;
bottom: 0;
display: none;
}
.links line {
/*stroke: #aaa;*/
stroke: none;
}
.links line.active2 {
stroke: red;
}
.links line.history {
stroke: purple;
}
.active {
stroke: red;
}
.category circle {
fill: yellow;
}
.web circle {
fill: purple;
}
.news circle {
fill: lightgray;
}
.template circle {
fill: lightgreen;
}
.discussion circle {
fill: aqua;
}
svg {
font: 10px sans-serif;
}
svg g.page {
cursor: pointer;
}
svg g.page text {
visibility: hidden;
fill: #222;
font: 10px sans-serif;
}
svg g.active text {
visibility: visible;
}
svg g.mouse text {
visibility: visible;
}
#cats {
position: absolute;
left: 0;
bottom: 0;
}
#cats .ocontents {
background: #FFFFFFDD;
display: none;
/*padding: 5px;*/
/*box-sizing: border-box;*/
}
#cats.expanded .ocontents {
display: block;
}
/* showall class */
#cats div.cat {
display: none;
}
#cats div.cat span.spacing {
display: none;
}
#cats div.cat.icon {
display: block;
}
#cats.showall div.cat {
display: block;
}
#cats.showall div.cat span.spacing {
display: inline;
}
#cats .contents {
overflow: auto;
height: 50vh;
min-width: 300px;
}
#cats .contents .scroll {
}
#cats .botright {
position: absolute;
right: 0;
bottom: 0;
}
#cats .botright .thumb {
position: absolute;
left: 0;
bottom: 0;
width: 32px;
height: 32px;
background: #FFFFFFDD;
}
#cats div.cat span.icon {
position: relative;
top: 4px;
display: inline-block;
width: 18px;
height: 18px;
background-repeat: no-repeat;
margin-right: 4px;
}
#cats div.cat span.count {
padding: 0px 3px;
background: #DDD;
color: #444;
font-size: 10px;
margin-left: 4px;
}
#cats div.cat a {
color: black;
text-decoration: none;
}
use {
fill: #EEE;
stroke: black;
}
.active use {
fill: #FFF;
stroke: red;
}
.active text {
stroke: black;
}
.active2 use {
fill: #FFF;
stroke: red;
}
.highlight use {
fill: #FFF;
stroke: orange;
}

241
symbols.00.svg Normal file
View File

@@ -0,0 +1,241 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32.387501mm"
height="32.356251mm"
viewBox="0 0 32.3875 32.356251"
version="1.1"
id="svg5507"
inkscape:version="0.92.1 r15371"
sodipodi:docname="symbols.svg"
enable-background="new">
<defs
id="defs5501" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6"
inkscape:cx="-9.2789814"
inkscape:cy="99.623528"
inkscape:document-units="mm"
inkscape:current-layer="layer8"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1366"
inkscape:window-height="704"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<metadata
id="metadata5504">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Main"
style="display:none">
<circle
r="5.0396824"
cy="1.4819558"
cx="0.43864226"
style="fill:#ffffff;fill-opacity:1;stroke:#020202;stroke-width:2.01587296;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:none"
id="Main"
inkscape:label="#path8162" />
</g>
<g
inkscape:label="Orientations"
inkscape:groupmode="layer"
id="layer1"
style="display:none">
<g
id="Orientations"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-opacity:0.99615389"
transform="matrix(0.404233,0,0,0.404233,36.032029,1.0220986)">
<path
id="Orientations-0"
d="m -87.8577,-14.01912 c -8.05454,0 -14.59375,6.50796 -14.59375,14.5625 0,8.05454 6.53921,14.59375 14.59375,14.59375 8.05454,0 14.59375,-6.53921 14.59375,-14.59375 0,-8.05454 -6.53921,-14.5625 -14.59375,-14.5625 z"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.19999981;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
<path
id="path6386"
d="m -87.7327,-7.603495 c -1.108176,0 -2.164768,0.243856 -3.125,0.65 -0.960232,0.406144 -1.823784,0.998784 -2.55,1.725 -0.726216,0.726216 -1.318856,1.589768 -1.725,2.55 -0.406144,0.960232 -0.625,2.016824 -0.625,3.125 0,1.108176 0.218856,2.139768 0.625,3.1 0.406144,0.960232 0.998784,1.848784 1.725,2.575 0.726216,0.726216 1.589768,1.293856 2.55,1.7 0.960232,0.406144 2.016824,0.65 3.125,0.65 1.108176,0 2.164768,-0.243856 3.125,-0.65 0.960232,-0.406144 1.823784,-0.973784 2.55,-1.7 0.726216,-0.726216 1.318856,-1.614768 1.725,-2.575 0.406144,-0.960232 0.625,-1.991824 0.625,-3.1 0,-1.108176 -0.218856,-2.164768 -0.625,-3.125 -0.406144,-0.960232 -0.998784,-1.823784 -1.725,-2.55 -0.726216,-0.726216 -1.589768,-1.318856 -2.55,-1.725 -0.960232,-0.406144 -2.016824,-0.65 -3.125,-0.65 z"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.55999994;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="Ateliers_pluridisciplinaires"
style="display:none;">
<g
transform="matrix(0.71815477,0,0,0.71815477,65.187921,-29.508788)"
id="Ateliers_pluridisciplinaires">
<circle
r="19.208878"
cy="40.264759"
cx="116.73087"
transform="matrix(0.36441483,0,0,0.36441483,-132.69908,28.796006)"
id="path6780"
style="fill:#ffffff;fill-opacity:1;stroke:#010001;stroke-width:16.4647522;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:none" />
<g
id="g8172"
transform="matrix(2.1333332,0,0,-2.1333332,13.499857,367.42774)"
style="fill:#020002;fill-opacity:0.99615389;stroke:#030003;stroke-opacity:0.98846154">
<circle
r="19.208878"
cy="40.264759"
cx="116.73087"
transform="matrix(0.05856667,0,0,-0.05856667,-55.427399,154.21379)"
id="path8174"
style="fill:#020002;fill-opacity:0.99615389;stroke:#030003;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98846154;marker-start:none" />
</g>
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer4"
inkscape:label="Cours_de_soutien_a_l'orientation"
style="display:none">
<g
id="Cours_de_soutien_a_l'orientation"
style="stroke:#000000;stroke-opacity:0.99615389"
transform="matrix(0.37928334,0,0,0.37928334,34.100402,17.553674)">
<path
transform="translate(-446.2952,-500.01912)"
id="path8166"
d="m 357.75,444.40625 c -7.15954,0 -12.96875,5.77796 -12.96875,12.9375 0,7.15954 5.80921,12.96875 12.96875,12.96875 7.15954,0 12.9375,-5.80921 12.9375,-12.96875 0,-7.15954 -5.77796,-12.9375 -12.9375,-12.9375 z"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.48174286;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
<path
transform="translate(-446.2952,-500.01912)"
id="path6363"
d="m 357.75,454.125 c 0.44747,0 0.86227,0.086 1.25,0.25 0.38773,0.164 0.73801,0.39426 1.03125,0.6875 0.29324,0.29324 0.5235,0.64352 0.6875,1.03125 0.164,0.38773 0.25,0.80253 0.25,1.25 0,0.44747 -0.086,0.89352 -0.25,1.28125 -0.164,0.38773 -0.39426,0.73801 -0.6875,1.03125 -0.29324,0.29324 -0.64352,0.5235 -1.03125,0.6875 -0.38773,0.164 -0.80253,0.25 -1.25,0.25 -0.44747,0 -0.89352,-0.086 -1.28125,-0.25 -0.38773,-0.164 -0.73801,-0.39426 -1.03125,-0.6875 -0.29324,-0.29324 -0.5235,-0.64352 -0.6875,-1.03125 -0.164,-0.38773 -0.25,-0.83378 -0.25,-1.28125 0,-0.44747 0.086,-0.86227 0.25,-1.25 0.164,-0.38773 0.39426,-0.73801 0.6875,-1.03125 0.29324,-0.29324 0.64352,-0.5235 1.03125,-0.6875 0.38773,-0.164 0.83378,-0.25 1.28125,-0.25 z"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:6.48174286;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer5"
inkscape:label="Cours_de_soutien_specifique"
style="display:none">
<g
id="Cours_de_soutien_specifique"
style="fill:#ffffff;fill-opacity:0.99615389;stroke:#020002;stroke-opacity:0.99615389"
transform="matrix(0.41178012,0,0,0.41178012,37.56977,36.122666)">
<path
transform="translate(-446.2952,-500.01912)"
id="path6358"
d="m 356.1875,401.09375 c -8.05454,0 -14.59375,6.53921 -14.59375,14.59375 0,8.05454 6.53921,14.5625 14.59375,14.5625 8.05454,0 14.5625,-6.50796 14.5625,-14.5625 0,-8.05454 -6.50796,-14.59375 -14.5625,-14.59375 z"
style="fill:#ffffff;fill-opacity:0.99615389;stroke:#020002;stroke-width:3.19999981;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
<path
transform="translate(-446.2952,-500.01912)"
id="path6329"
d="m 356.3125,413.9375 c -0.44744,0 -0.86303,0.17553 -1.15625,0.46875 -0.29322,0.29322 -0.46875,0.70881 -0.46875,1.15625 0,0.44744 0.17553,0.83178 0.46875,1.125 0.29322,0.29322 0.70881,0.46875 1.15625,0.46875 0.44744,0 0.83178,-0.17553 1.125,-0.46875 0.29322,-0.29322 0.46875,-0.67756 0.46875,-1.125 0,-0.44744 -0.17553,-0.86303 -0.46875,-1.15625 -0.29322,-0.29322 -0.67756,-0.46875 -1.125,-0.46875 z"
style="fill:#ffffff;fill-opacity:0.99615389;stroke:#020002;stroke-width:3.19999981;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
<path
transform="translate(-446.2952,-500.01912)"
id="path6327"
d="m 356.3125,413.9375 c 0.44744,0 0.83178,0.17553 1.125,0.46875 0.29322,0.29322 0.46875,0.70881 0.46875,1.15625 0,0.44744 -0.17553,0.83178 -0.46875,1.125 -0.29322,0.29322 -0.67756,0.46875 -1.125,0.46875 -0.44744,0 -0.86303,-0.17553 -1.15625,-0.46875 -0.29322,-0.29322 -0.46875,-0.67756 -0.46875,-1.125 0,-0.44744 0.17553,-0.86303 0.46875,-1.15625 0.29322,-0.29322 0.70881,-0.46875 1.15625,-0.46875 z"
style="fill:#ffffff;fill-opacity:0.99615389;stroke:#020002;stroke-width:3.19999981;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
<path
transform="translate(-446.2952,-500.01912)"
id="path6324"
d="m 356.3125,413.9375 c -0.44744,0 -0.86303,0.17553 -1.15625,0.46875 -0.29322,0.29322 -0.46875,0.70881 -0.46875,1.15625 0,0.44744 0.17553,0.83178 0.46875,1.125 0.29322,0.29322 0.70881,0.46875 1.15625,0.46875 0.44744,0 0.83178,-0.17553 1.125,-0.46875 0.29322,-0.29322 0.46875,-0.67756 0.46875,-1.125 0,-0.44744 -0.17553,-0.86303 -0.46875,-1.15625 -0.29322,-0.29322 -0.67756,-0.46875 -1.125,-0.46875 z"
style="fill:#ffffff;fill-opacity:0.99615389;stroke:#020002;stroke-width:3.19999981;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer6"
inkscape:label="Cours_techniques"
style="display:none">
<g
id="Cours_techniques"
transform="matrix(0.42076685,0,0,-0.42076685,-14.006109,85.183824)"
inkscape:label="#g3142"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-opacity:1">
<title
id="title3278">template</title>
<path
inkscape:connector-curvature="0"
id="path87"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.12598443;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:2.23606801;stroke-dasharray:none;stroke-opacity:1"
d="m 49.067296,199.32385 c 0,-8.21904 -6.662847,-14.88189 -14.881888,-14.88189 -8.219041,0 -14.881889,6.66285 -14.881889,14.88189 0,8.21904 6.662848,14.88189 14.881889,14.88189 8.219041,0 14.881888,-6.66285 14.881888,-14.88189 z" />
<g
id="g3119"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-opacity:1">
<path
d="m 44.815326,199.32385 c 0,-5.87075 -4.759174,-10.62992 -10.629918,-10.62992 -5.870744,0 -10.629921,4.75917 -10.629921,10.62992 0,5.87074 4.759177,10.62992 10.629921,10.62992 5.870744,0 10.629918,-4.75918 10.629918,-10.62992 z"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.12598443;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:2.23606801;stroke-dasharray:none;stroke-opacity:1"
id="path85"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer7"
inkscape:label="Cours_theoriques">
<path
d="m 6.7797495,1.3385787 c 0,3.5225563 -2.8555966,6.378149 -6.37815062,6.378149 -3.52255578,0 -6.37814838,-2.8555927 -6.37814838,-6.378149 0,-3.5225563 2.8555926,-6.3781491 6.37814838,-6.3781491 3.52255402,0 6.37815062,2.8555928 6.37815062,6.3781491 z"
style="fill:#ffffff;fill-opacity:1;stroke:#010001;stroke-width:0.80359638;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:2.23606801;stroke-dasharray:2.41078917, 2.41078917;stroke-dashoffset:0;stroke-opacity:1;marker-start:none;marker-mid:none;marker-end:none"
id="Cours_theoriques"
inkscape:connector-curvature="0"
inkscape:label="#path87-1"
mask="none" />
</g>
<g
inkscape:groupmode="layer"
id="layer8"
inkscape:label="Enseignants"
style="display:none">
<path
sodipodi:type="star"
style="fill:#ffffff;fill-opacity:1;stroke:#020202;stroke-width:0.97391373;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="Enseignants"
sodipodi:sides="3"
sodipodi:cx="0.36393768"
sodipodi:cy="2.2478313"
sodipodi:r1="6.7946506"
sodipodi:r2="3.397325"
sodipodi:arg1="0.52606642"
sodipodi:arg2="1.573264"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="M 6.2398764,5.6596667 -5.5287678,5.6306258 0.38070444,-4.5467985 Z"
inkscape:transform-center-x="0.013378058"
inkscape:transform-center-y="2.6969222"
inkscape:label="#path3225-6-7-7" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

239
symbols.svg Normal file
View File

@@ -0,0 +1,239 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32.387501mm"
height="32.356251mm"
viewBox="0 0 32.3875 32.356251"
version="1.1"
id="svg5507"
inkscape:version="0.92.1 r15371"
sodipodi:docname="symbols.svg"
enable-background="new">
<defs
id="defs5501" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6"
inkscape:cx="-9.2789814"
inkscape:cy="99.623528"
inkscape:document-units="mm"
inkscape:current-layer="layer8"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1366"
inkscape:window-height="704"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<metadata
id="metadata5504">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Main"
style="display:none">
<circle
r="5.0396824"
cy="1.4819558"
cx="0.43864226"
style="fill-opacity:1;stroke-width:2.01587296;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:none"
id="Main"
inkscape:label="#path8162" />
</g>
<g
inkscape:label="Orientations"
inkscape:groupmode="layer"
id="layer1"
style="display:none">
<g
id="Orientations"
style="fill-opacity:1;stroke-opacity:0.99615389"
transform="matrix(0.404233,0,0,0.404233,36.032029,1.0220986)">
<path
id="Orientations-0"
d="m -87.8577,-14.01912 c -8.05454,0 -14.59375,6.50796 -14.59375,14.5625 0,8.05454 6.53921,14.59375 14.59375,14.59375 8.05454,0 14.59375,-6.53921 14.59375,-14.59375 0,-8.05454 -6.53921,-14.5625 -14.59375,-14.5625 z"
style="fill-opacity:1;stroke-width:3.19999981;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
<path
id="path6386"
d="m -87.7327,-7.603495 c -1.108176,0 -2.164768,0.243856 -3.125,0.65 -0.960232,0.406144 -1.823784,0.998784 -2.55,1.725 -0.726216,0.726216 -1.318856,1.589768 -1.725,2.55 -0.406144,0.960232 -0.625,2.016824 -0.625,3.125 0,1.108176 0.218856,2.139768 0.625,3.1 0.406144,0.960232 0.998784,1.848784 1.725,2.575 0.726216,0.726216 1.589768,1.293856 2.55,1.7 0.960232,0.406144 2.016824,0.65 3.125,0.65 1.108176,0 2.164768,-0.243856 3.125,-0.65 0.960232,-0.406144 1.823784,-0.973784 2.55,-1.7 0.726216,-0.726216 1.318856,-1.614768 1.725,-2.575 0.406144,-0.960232 0.625,-1.991824 0.625,-3.1 0,-1.108176 -0.218856,-2.164768 -0.625,-3.125 -0.406144,-0.960232 -0.998784,-1.823784 -1.725,-2.55 -0.726216,-0.726216 -1.589768,-1.318856 -2.55,-1.725 -0.960232,-0.406144 -2.016824,-0.65 -3.125,-0.65 z"
style="fill-opacity:1;stroke-width:2.55999994;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="Ateliers_pluridisciplinaires"
style="display:none;">
<g
transform="matrix(0.71815477,0,0,0.71815477,65.187921,-29.508788)"
id="Ateliers_pluridisciplinaires">
<circle
r="19.208878"
cy="40.264759"
cx="116.73087"
transform="matrix(0.36441483,0,0,0.36441483,-132.69908,28.796006)"
id="path6780"
style="fill-opacity:1;stroke-width:16.4647522;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:none" />
<g
id="g8172"
transform="matrix(2.1333332,0,0,-2.1333332,13.499857,367.42774)"
style="fill-opacity:0.99615389;stroke-opacity:0.98846154">
<path
transform="matrix(0.05856667,0,0,-0.05856667,-55.427399,154.21379)"
style="fill-opacity:0.99615389;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98846154;marker-start:none"
d="M 135.93975,40.264759 A 19.208878,19.208878 0 0 1 116.73087,59.473637 19.208878,19.208878 0 0 1 97.521996,40.264759 19.208878,19.208878 0 0 1 116.73087,21.055882 19.208878,19.208878 0 0 1 135.93975,40.264759 Z"
id="path8174" />
</g>
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer4"
inkscape:label="Cours_de_soutien_a_l'orientation"
style="display:none">
<g
id="Cours_de_soutien_a_l'orientation"
style="stroke-opacity:0.99615389"
transform="matrix(0.37928334,0,0,0.37928334,34.100402,17.553674)">
<path
transform="translate(-446.2952,-500.01912)"
id="path8166"
d="m 357.75,444.40625 c -7.15954,0 -12.96875,5.77796 -12.96875,12.9375 0,7.15954 5.80921,12.96875 12.96875,12.96875 7.15954,0 12.9375,-5.80921 12.9375,-12.96875 0,-7.15954 -5.77796,-12.9375 -12.9375,-12.9375 z"
style="fill-opacity:1;stroke-width:6.48174286;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
<path
transform="translate(-446.2952,-500.01912)"
id="path6363"
d="m 357.75,454.125 c 0.44747,0 0.86227,0.086 1.25,0.25 0.38773,0.164 0.73801,0.39426 1.03125,0.6875 0.29324,0.29324 0.5235,0.64352 0.6875,1.03125 0.164,0.38773 0.25,0.80253 0.25,1.25 0,0.44747 -0.086,0.89352 -0.25,1.28125 -0.164,0.38773 -0.39426,0.73801 -0.6875,1.03125 -0.29324,0.29324 -0.64352,0.5235 -1.03125,0.6875 -0.38773,0.164 -0.80253,0.25 -1.25,0.25 -0.44747,0 -0.89352,-0.086 -1.28125,-0.25 -0.38773,-0.164 -0.73801,-0.39426 -1.03125,-0.6875 -0.29324,-0.29324 -0.5235,-0.64352 -0.6875,-1.03125 -0.164,-0.38773 -0.25,-0.83378 -0.25,-1.28125 0,-0.44747 0.086,-0.86227 0.25,-1.25 0.164,-0.38773 0.39426,-0.73801 0.6875,-1.03125 0.29324,-0.29324 0.64352,-0.5235 1.03125,-0.6875 0.38773,-0.164 0.83378,-0.25 1.28125,-0.25 z"
style="fill-opacity:1;stroke-width:6.48174286;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer5"
inkscape:label="Cours_de_soutien_specifique"
style="display:none">
<g
id="Cours_de_soutien_specifique"
style="fill-opacity:0.99615389;stroke-opacity:0.99615389"
transform="matrix(0.41178012,0,0,0.41178012,37.56977,36.122666)">
<path
transform="translate(-446.2952,-500.01912)"
id="path6358"
d="m 356.1875,401.09375 c -8.05454,0 -14.59375,6.53921 -14.59375,14.59375 0,8.05454 6.53921,14.5625 14.59375,14.5625 8.05454,0 14.5625,-6.50796 14.5625,-14.5625 0,-8.05454 -6.50796,-14.59375 -14.5625,-14.59375 z"
style="fill-opacity:0.99615389;stroke-width:3.19999981;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
<path
transform="translate(-446.2952,-500.01912)"
id="path6329"
d="m 356.3125,413.9375 c -0.44744,0 -0.86303,0.17553 -1.15625,0.46875 -0.29322,0.29322 -0.46875,0.70881 -0.46875,1.15625 0,0.44744 0.17553,0.83178 0.46875,1.125 0.29322,0.29322 0.70881,0.46875 1.15625,0.46875 0.44744,0 0.83178,-0.17553 1.125,-0.46875 0.29322,-0.29322 0.46875,-0.67756 0.46875,-1.125 0,-0.44744 -0.17553,-0.86303 -0.46875,-1.15625 -0.29322,-0.29322 -0.67756,-0.46875 -1.125,-0.46875 z"
style="fill-opacity:0.99615389;stroke-width:3.19999981;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
<path
transform="translate(-446.2952,-500.01912)"
id="path6327"
d="m 356.3125,413.9375 c 0.44744,0 0.83178,0.17553 1.125,0.46875 0.29322,0.29322 0.46875,0.70881 0.46875,1.15625 0,0.44744 -0.17553,0.83178 -0.46875,1.125 -0.29322,0.29322 -0.67756,0.46875 -1.125,0.46875 -0.44744,0 -0.86303,-0.17553 -1.15625,-0.46875 -0.29322,-0.29322 -0.46875,-0.67756 -0.46875,-1.125 0,-0.44744 0.17553,-0.86303 0.46875,-1.15625 0.29322,-0.29322 0.70881,-0.46875 1.15625,-0.46875 z"
style="fill-opacity:0.99615389;stroke-width:3.19999981;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
<path
transform="translate(-446.2952,-500.01912)"
id="path6324"
d="m 356.3125,413.9375 c -0.44744,0 -0.86303,0.17553 -1.15625,0.46875 -0.29322,0.29322 -0.46875,0.70881 -0.46875,1.15625 0,0.44744 0.17553,0.83178 0.46875,1.125 0.29322,0.29322 0.70881,0.46875 1.15625,0.46875 0.44744,0 0.83178,-0.17553 1.125,-0.46875 0.29322,-0.29322 0.46875,-0.67756 0.46875,-1.125 0,-0.44744 -0.17553,-0.86303 -0.46875,-1.15625 -0.29322,-0.29322 -0.67756,-0.46875 -1.125,-0.46875 z"
style="fill-opacity:0.99615389;stroke-width:3.19999981;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99615389;marker-start:none"
inkscape:connector-curvature="0" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer6"
inkscape:label="Cours_techniques"
style="display:none">
<g
id="Cours_techniques"
transform="matrix(0.42076685,0,0,-0.42076685,-14.006109,85.183824)"
inkscape:label="#g3142"
style="fill-opacity:1;stroke-opacity:1">
<title
id="title3278">template</title>
<path
inkscape:connector-curvature="0"
id="path87"
style="fill-opacity:1;stroke-width:2.12598443;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:2.23606801;stroke-dasharray:none;stroke-opacity:1"
d="m 49.067296,199.32385 c 0,-8.21904 -6.662847,-14.88189 -14.881888,-14.88189 -8.219041,0 -14.881889,6.66285 -14.881889,14.88189 0,8.21904 6.662848,14.88189 14.881889,14.88189 8.219041,0 14.881888,-6.66285 14.881888,-14.88189 z" />
<g
id="g3119"
style="fill-opacity:1;stroke-opacity:1">
<path
d="m 44.815326,199.32385 c 0,-5.87075 -4.759174,-10.62992 -10.629918,-10.62992 -5.870744,0 -10.629921,4.75917 -10.629921,10.62992 0,5.87074 4.759177,10.62992 10.629921,10.62992 5.870744,0 10.629918,-4.75918 10.629918,-10.62992 z"
style="fill-opacity:1;stroke-width:2.12598443;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:2.23606801;stroke-dasharray:none;stroke-opacity:1"
id="path85"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer7"
inkscape:label="Cours_theoriques">
<path
d="m 6.7797495,1.3385787 c 0,3.5225563 -2.8555966,6.378149 -6.37815062,6.378149 -3.52255578,0 -6.37814838,-2.8555927 -6.37814838,-6.378149 0,-3.5225563 2.8555926,-6.3781491 6.37814838,-6.3781491 3.52255402,0 6.37815062,2.8555928 6.37815062,6.3781491 z"
style="fill-opacity:1;stroke-width:0.80359638;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:2.23606801;stroke-dasharray:2.41078917, 2.41078917;stroke-dashoffset:0;stroke-opacity:1;marker-start:none;marker-mid:none;marker-end:none"
id="Cours_theoriques"
inkscape:connector-curvature="0"
inkscape:label="#path87-1"
mask="none" />
</g>
<g
inkscape:groupmode="layer"
id="layer8"
inkscape:label="Enseignants"
style="display:none">
<path
sodipodi:type="star"
style="fill-opacity:1;stroke-width:0.97391373;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="Enseignants"
sodipodi:sides="3"
sodipodi:cx="0.36393768"
sodipodi:cy="2.2478313"
sodipodi:r1="6.7946506"
sodipodi:r2="3.397325"
sodipodi:arg1="0.52606642"
sodipodi:arg2="1.573264"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="M 6.2398764,5.6596667 -5.5287678,5.6306258 0.38070444,-4.5467985 Z"
inkscape:transform-center-x="0.013378058"
inkscape:transform-center-y="2.6969222"
inkscape:label="#path3225-6-7-7" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB