├── CNAME
├── docs
└── CNAME
├── index.js
├── data
├── sample.csv
├── cars.csv
├── flights.csv
└── notes.csv
├── test.md
├── static
├── img
│ ├── contrast.svg
│ ├── embed.svg
│ ├── visdown.svg
│ ├── share.svg
│ ├── pencil.svg
│ ├── datasets.svg
│ ├── view.svg
│ ├── twitter.svg
│ ├── github.svg
│ └── view-blocked.svg
├── css
│ ├── visdown.css
│ ├── codemirror.css
│ └── github-markdown.css
└── lib
│ ├── markdown.min.js
│ ├── highlight.pack.js
│ ├── marked.min.js
│ ├── vega-embed.min.js
│ └── markdown.js
├── README.md
├── pages
├── annotate-layer.md
├── data-layer.md
├── interactive.md
├── intro.md
├── london.md
├── notes.md
├── start.md
├── visual-layer.md
├── composition.md
├── data.md
└── interact-layer.md
├── rollup.config.js
├── LICENSE
├── js
├── visdown-vegalite-1.js
├── visdown-marked.js
├── visdown-app.js
└── editor.js
├── package.json
├── src
└── main.js
├── cars.csv
├── experiments
├── vega-embed.js
├── visdown.1.js
└── datum.js
├── .gitignore
└── index.html
/CNAME:
--------------------------------------------------------------------------------
1 | visdown.com
--------------------------------------------------------------------------------
/docs/CNAME:
--------------------------------------------------------------------------------
1 | visdown.com
2 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | export {default as visdown} from "./src/visdown";
2 |
--------------------------------------------------------------------------------
/data/sample.csv:
--------------------------------------------------------------------------------
1 | area,sales,profit
2 | North,5,2
3 | East,25,8
4 | West,15,6
5 | South,20,5
6 | Central,10,3
7 |
--------------------------------------------------------------------------------
/test.md:
--------------------------------------------------------------------------------
1 | "scripts": {
2 | "pretest": "rm -rf build && mkdir build && rollup -f umd -n visdown -o build/visdown.js -- index.js",
3 | "prepare": "uglifyjs build/visdown.js -c -m -o build/visdown.min.js",
4 | "postpublish": "zip -j build/visdown.zip -- LICENSE README.md build/visdown.js build/visdown.min.js"
5 | },
--------------------------------------------------------------------------------
/static/img/contrast.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/static/img/embed.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
--------------------------------------------------------------------------------
/static/img/visdown.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Visdown
2 |
3 | Make visualisation using markdown
4 |
5 | Demo -> [http://visdown.com/](http://visdown.com/)
6 |
7 | Allows you to write *json specification* in simple *yaml* and uses **marked** and **vega-lite** (or vega) to convert those specific code blocks in to svg.
8 |
9 | - yaml -> json (using [yaml.js](https://github.com/jeremyfa/yaml.js))
10 | - json -> vega-lite -> svg (using [vegalite.js](https://vega.github.io/vega-lite/))
11 | - markdown -> html (using [marked.js](https://github.com/marked)
12 |
13 |
14 |
--------------------------------------------------------------------------------
/static/img/share.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/static/img/pencil.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/static/img/datasets.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/pages/annotate-layer.md:
--------------------------------------------------------------------------------
1 | # Annotate Layer
2 |
3 | - Title and Labels
4 | - Axis and Tick marks
5 | - Guides e.g. Legends
6 | - Grids and Reference marks
7 | - Text Annotation
8 | - Story Elements
9 |
10 |
11 | ```vis
12 | data:
13 | url: data/notes.csv
14 | mark: area
15 | encoding:
16 | x:
17 | field: year
18 | type: temporal
19 | axis:
20 | format: %Y
21 | labelAngle: 0
22 | title: Year
23 | titleFontSize: 12
24 | y:
25 | aggregate: sum
26 | field: money
27 | type: quantitative
28 | axis:
29 | title: Notes in Circulation (Value ₹ Billions)
30 | titleFontSize: 12
31 | color:
32 | field: denom
33 | type: nominal
34 |
35 | config:
36 | cell:
37 | width: 400
38 | height: 300
39 | ```
40 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import resolve from 'rollup-plugin-node-resolve';
2 | import pkg from './package.json';
3 |
4 | export default [
5 | // browser-friendly UMD build
6 | {
7 | input: 'src/main.js',
8 | output: {
9 | name: 'visdown',
10 | file: pkg.browser,
11 | format: 'umd'
12 | },
13 | plugins: [
14 | resolve(), // so Rollup can find `dependencies`
15 | ]
16 | },
17 |
18 | // CommonJS (for Node) and ES module (for bundlers) build.
19 | // (We could have three entries in the configuration array
20 | // instead of two, but it's quicker to generate multiple
21 | // builds from a single configuration where possible, using
22 | // an array for the `output` option, where we can specify
23 | // `file` and `format` for each target)
24 | {
25 | input: 'src/main.js',
26 | external: ['ms'],
27 | output: {
28 | file: pkg.module,
29 | format: 'es'
30 | }
31 | }
32 | ];
--------------------------------------------------------------------------------
/static/img/view.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/static/img/twitter.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Amit Kapoor
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/pages/data-layer.md:
--------------------------------------------------------------------------------
1 | # Data Layer
2 |
3 | ## Types of Variables
4 | - Categorical: Nominal, Ordinal
5 | - Continuous: Temporal, Quantitative
6 |
7 | ```vis
8 | data(data/notes.csv)
9 | line(x=year:T, y=money:Q, color=denom:N)
10 | ```
11 |
12 | ## Transforming the Data
13 | - Filter, Sort
14 | - Aggregate (e.g. min, max, sum, ...)
15 | - Bin
16 | - Derive (new variable)
17 | - Sample
18 | - Reshape (e.g. tall <-> wide)
19 |
20 |
21 | ### Filter
22 |
23 | Lets filter this data for denominations greater than INR 10.
24 |
25 | ```vis
26 | data(data/notes.csv)
27 | filter(datum.value > 10)
28 | line(x=year:T, y=money:Q, color=denom:N)
29 | ```
30 |
31 | ### Aggregate
32 |
33 | You can aggregate on a particular variable to do basic statistical operations like mean, sum, quantile etc.
34 |
35 | ```vis
36 | data(data/notes.csv)
37 | area(x=year:T, y=sum(money:Q), color=denom:N)
38 | ```
39 |
40 | ### Bins
41 |
42 | Binning is a technique for grouping quantitative, continuous data values of a particular field into smaller number of “bins”
43 |
44 | ```vis
45 | data(data/notes.csv)
46 | bar(x=bin(money:Q), y=count:Q, color=denom:N)
47 | ```
48 |
--------------------------------------------------------------------------------
/js/visdown-vegalite-1.js:
--------------------------------------------------------------------------------
1 | window.onload = function () {
2 |
3 | // Start a new marked instance and renderer
4 | var marked = window.marked;
5 | var renderer = new marked.Renderer();
6 | var counter = 0;
7 |
8 | // Render the ```vis as a vega-lite chart
9 | renderer.code = function (code, lang, escaped) {
10 | if (lang == "vis") {
11 | var jsonVis = YAML.parse(code);
12 | var embedSpec = {mode: "vega-lite", spec: jsonVis, renderer: "svg" };
13 | counter++;
14 | el = "#vis-" + counter;
15 | vg.embed(el, embedSpec, function(error, result) {});
16 | htmlChart = "
";
17 | return htmlChart;
18 | }
19 | var result = marked.Renderer.prototype.code.call(this, code, lang, escaped);
20 | return result;
21 | };
22 |
23 | // Convert from Markdown to HTML
24 | var input = document.querySelector("#visdown-input");
25 | var output = document.querySelector("#visdown-output");
26 |
27 | window.visdownVega = function () {
28 | console.log('visdownVega');
29 | var markdownText = input.value;
30 | output.innerHTML = marked(markdownText, { renderer: renderer });
31 | }
32 | visdownVega()
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/pages/interactive.md:
--------------------------------------------------------------------------------
1 |
2 | ```vis
3 | data(data/cars.csv) | point(x=kmpl:Q, y=price:Q)
4 | ```
5 |
6 | # Testing Grammar
7 |
8 |
9 | var x = 2
10 |
11 |
12 |
13 | var x = 2
14 |
15 |
16 | This is [an example] [id] reference-style link.
17 |
18 | [id]: http://example.com/ "Optional Title Here"
19 |
20 |
21 | Test 1
22 |
23 | 
24 |
25 | - One
26 | - Two
27 | - Three
28 |
29 | There is a test **bold** here
30 |
31 | ```vis
32 | data(data/cars.csv) | point(x=kmpl:Q, y=price:Q)
33 | ```
34 |
35 | This is [an example] [id] reference-style link.
36 |
37 | [id]: http://example.com/
38 |
39 | And this is another code element
40 |
41 | ```vis
42 | data(data/cars.csv) | point(x=kmpl:Q, y=price:Q, color=bhp:Q)
43 | ```
44 | hello
45 |
46 | ```vis
47 | data(data/cars.csv) | point(x=kmpl:Q, y=price:Q, color=bhp:Q)
48 | ```
49 |
50 | ```js
51 | var x = 2
52 | ```
53 |
54 | And another vis here
55 |
56 | ## Another Vis
57 |
58 | ```vis
59 | data(data/cars.csv) | point(x=kmpl:Q, y=price:Q)
60 | ```
61 |
62 | And here is more text
--------------------------------------------------------------------------------
/static/img/github.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "visdown",
3 | "version": "0.1.0",
4 | "description": "Make Visualisations using Markdown",
5 | "keywords": [
6 | "markdown",
7 | "visualisation",
8 | "interaction",
9 | "vega-lite",
10 | "analytics"
11 | ],
12 | "author": "Amit Kapoor (http://amitkaps.com)",
13 | "license": "MIT",
14 | "main": "build/visdown.js",
15 | "homepage": "https://github.com/amitkaps/visdown",
16 | "repository": {
17 | "type": "git",
18 | "url": "git+https://github.com/amitkaps/visdown.git"
19 | },
20 | "bugs": {
21 | "url": "https://github.com/amitkaps/visdown/issues"
22 | },
23 | "scripts": {
24 | "pretest": "rm -rf build && mkdir build && rollup -f umd -n visdown -o build/visdown.js -- index.js",
25 | "test": "tape 'test/**/*-test.js'",
26 | "prepublish": "npm run test && uglifyjs build/visdown.js -c -m -o build/visdown.min.js",
27 | "postpublish": "zip -j build/visdown.zip -- LICENSE README.md build/visdown.js build/visdown.min.js"
28 | },
29 | "dependencies": {
30 | "yamljs": "^0.3.0",
31 | "marked": "^2.0.3",
32 | "vega": "^5.20.2",
33 | "vega-lite": "^5.1.0",
34 | "vega-embed": "^6.17.0"
35 | },
36 | "devDependencies": {
37 | "rollup": "^2.45.2",
38 | "tape": "^5.2.2",
39 | "uglify-js": "^3.13.4"
40 | },
41 | "directories": {
42 | "doc": "docs"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/pages/intro.md:
--------------------------------------------------------------------------------
1 | # Visdown
2 |
3 | **Make visualisations using only markdown**
4 |
5 | Write visualisation using a simple declarative markup like you would write code. Just wrap it in fenced block (three backticks) and mark the language as `vis`.
6 |
7 | *Make simple static visualisations*
8 |
9 | ```vis
10 | data:
11 | url: data/cars.csv
12 | mark: point
13 | encoding:
14 | x:
15 | field: kmpl
16 | type: quantitative
17 | y:
18 | field: price
19 | type: quantitative
20 | ```
21 |
22 | Visdown is based on the grammar of interactive graphic (vega-lite) which allows you to specify the visualisation including interactions in a declarative fashion.
23 |
24 | *Make interactive visualisations*
25 |
26 | Select the circles with the mouse
27 |
28 | ```vis
29 | data:
30 | url: "data/cars.csv"
31 | mark: circle
32 | selection:
33 | brush:
34 | type: interval
35 | encoding:
36 | x:
37 | type: quantitative
38 | field: kmpl
39 | scale:
40 | domain: [12,25]
41 | y:
42 | type: quantitative
43 | field: price
44 | scale:
45 | domain: [100,900]
46 | color:
47 | condition:
48 | selection: brush
49 | field: type
50 | type: nominal
51 | value: grey
52 | size:
53 | type: quantitative
54 | field: bhp
55 | width: 450
56 | height: 300
57 | ```
58 |
59 | ---
60 | Handcrafted by [Amit Kapoor](http://amitkaps.com)
61 |
--------------------------------------------------------------------------------
/js/visdown-marked.js:
--------------------------------------------------------------------------------
1 | window.onload = function () {
2 |
3 | // Start a new marked instance and renderer
4 | var marked = window.marked;
5 | var renderer = new marked.Renderer();
6 | var counter = 0;
7 | var specs = [];
8 | var opts = {"mode": "vega-lite", "renderer": "svg" };
9 |
10 |
11 | // Render the ```vis as a div and save the json spec
12 | renderer.code = function (code, lang, escaped) {
13 | if (lang == "vis") {
14 | jsonVis = YAML.parse(code);
15 | specs.push(jsonVis);
16 | counter++;
17 | el = "#vis-" + counter;
18 | htmlChart = "";
19 | return htmlChart;
20 | }
21 | var result = marked.Renderer.prototype.code.call(this, code, lang, escaped);
22 | return result;
23 | };
24 |
25 | // Render the vega-lite chart for each json spec
26 | vegaliteRender = function (err, content) {
27 | for (var i=0; i < specs.length; i++) {
28 | j = i + 1;
29 | el = "#vis-" + j;
30 | vega.embed(el, specs[i], opts);
31 | }
32 | return content;
33 | };
34 |
35 |
36 | // Convert from Markdown to HTML
37 | var input = document.querySelector("#visdown-input");
38 | var output = document.querySelector("#visdown-output");
39 |
40 | window.visdown = function () {
41 | console.log('visdown');
42 | var markdownText = input.value;
43 | output.innerHTML = marked(markdownText, { renderer: renderer});
44 | vegaliteRender();
45 | }
46 | visdown()
47 |
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/static/img/view-blocked.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | * visdown - a parser for vega-lite vis in markdown
3 | * Copyright (c) 2016-2018, Amit Kapoor. (MIT Licensed)
4 | * https://github.com/amitkaps/visdown
5 | */
6 |
7 |
8 | // Need to have vega and vega-lite as dependencies
9 | // const vega = window.vega
10 | // const vl = window.vl
11 |
12 |
13 | // import vega from 'vega'
14 | // import vega-lite as vl from 'vega-lite'
15 | import marked from 'marked'
16 | import YAML from 'yamljs'
17 | import vegaEmbed from 'vega-embed'
18 |
19 | // Start Marked Renderer
20 | const renderer = new marked.Renderer();
21 | marked.setOptions({
22 | renderer: renderer,
23 | gfm: true,
24 | tables: true,
25 | });
26 |
27 | const opts = {
28 | "mode": "vega-lite",
29 | "renderer": "svg",
30 | "actions": {export: false, source: false, editor: false}
31 | };
32 |
33 |
34 | //Render the vega-lite chart for each json spec
35 | function _render(element) {
36 | let specs = element.getElementsByClassName('lang-vis')
37 | let num = specs.length;
38 | for (var i=0; i < num; i++) {
39 | let el = "#vis-" + i;
40 | let jsonSpec = YAML.parse(specs[i].textContent)
41 | console.log(jsonSpec)
42 | //console.log(vl.compile(jsonVis).spec == undefined)
43 | htmlString = ""
44 | specs[i].parentNode.insertAdjacentHTML('beforebegin', htmlString);
45 | specs[i].parentNode.style.display = 'none';
46 | vegaEmbed(el, jsonSpec, opts);
47 | };
48 | };
49 |
50 | function visdown(input, element) {
51 | console.log('visdown');
52 | let visdownText = input;
53 | element.innerHTML = marked(visdownText);
54 | _render(element);
55 | }
--------------------------------------------------------------------------------
/cars.csv:
--------------------------------------------------------------------------------
1 | brand,model,price,kmpl,bhp,type
2 | Chevrolet,Beat,421,18.6,79,Hatchback
3 | Chevrolet,Sail,551,18.2,82,Sedan
4 | Chevrolet,Sail Hatchback,468,18.2,82,Hatchback
5 | Chevrolet,Spark,345,16.2,62,Hatchback
6 | Fiat,Linea Classic,612,14.9,89,Sedan
7 | Fiat,Linea,700,15.7,112,Sedan
8 | Fiat,Punto Evo,499,15.8,67,Hatchback
9 | Ford,Classic,506,14.1,100,Sedan
10 | Ford,Figo,414,15.3,70,Hatchback
11 | Honda,Amaze,519,18,87,Sedan
12 | Honda,Brio,421,19.4,87,Hatchback
13 | Hyundai,EON,302,21.1,55,Hatchback
14 | Hyundai,i10,418,19.8,68,Hatchback
15 | Hyundai,i20,523,18.6,82,Hatchback
16 | Hyundai,Verna,774,17.4,106,Sedan
17 | Hyundai,Xcent,496,19.1,82,Sedan
18 | Suzuki,Alto,315,24.1,67,Hatchback
19 | Suzuki,Alto 800,248,22.7,47,Hatchback
20 | Suzuki,Celerio,392,23.1,67,Hatchback
21 | Suzuki,Ciaz,725,20.7,91,Sedan
22 | Suzuki,Estilo,338,19,67,Hatchback
23 | Suzuki,Ritz,442,18.5,86,Hatchback
24 | Suzuki,Swift,462,20.4,83,Hatchback
25 | Suzuki,Swift DZire,508,19.1,86,Sedan
26 | Suzuki,SX4,715,16.5,103,Sedan
27 | Suzuki,Wagon-R,363,20.5,67,Hatchback
28 | Nissan,Datsun GO,312,20.6,67,Hatchback
29 | Nissan,Micra,413,19.5,67,Hatchback
30 | Nissan,Sunny,699,16.9,98,Sedan
31 | Renault,Pulse,446,18,74,Hatchback
32 | Renault,Scala,724,16.9,98,Sedan
33 | San,Storm,595,16,59,Sedan
34 | Skoda,Fabia,503,16.4,75,Hatchback
35 | Skoda,Rapid,756,15,104,Sedan
36 | Tata,Indigo,499,14,65,Sedan
37 | Tata,Nano,199,23.9,38,Hatchback
38 | Tata,Zest,481,17.6,89,Sedan
39 | Toyota,Etios,603,16.8,89,Sedan
40 | Toyota,Etios Liva,500,17.7,79,Hatchback
41 | Volkswagen,Polo,535,16.5,74,Hatchback
42 | Volkswagen,Up,360,21,74,Hatchback
43 | Volkswagen,Vento,785,16.1,104,Sedan
44 |
--------------------------------------------------------------------------------
/data/cars.csv:
--------------------------------------------------------------------------------
1 | brand,model,price,kmpl,bhp,type
2 | Chevrolet,Beat,421,18.6,79,Hatchback
3 | Chevrolet,Sail,551,18.2,82,Sedan
4 | Chevrolet,Sail Hatchback,468,18.2,82,Hatchback
5 | Chevrolet,Spark,345,16.2,62,Hatchback
6 | Fiat,Linea Classic,612,14.9,89,Sedan
7 | Fiat,Linea,700,15.7,112,Sedan
8 | Fiat,Punto Evo,499,15.8,67,Hatchback
9 | Ford,Classic,506,14.1,100,Sedan
10 | Ford,Figo,414,15.3,70,Hatchback
11 | Honda,Amaze,519,18,87,Sedan
12 | Honda,Brio,421,19.4,87,Hatchback
13 | Hyundai,EON,302,21.1,55,Hatchback
14 | Hyundai,i10,418,19.8,68,Hatchback
15 | Hyundai,i20,523,18.6,82,Hatchback
16 | Hyundai,Verna,774,17.4,106,Sedan
17 | Hyundai,Xcent,496,19.1,82,Sedan
18 | Suzuki,Alto,315,24.1,67,Hatchback
19 | Suzuki,Alto 800,248,22.7,47,Hatchback
20 | Suzuki,Celerio,392,23.1,67,Hatchback
21 | Suzuki,Ciaz,725,20.7,91,Sedan
22 | Suzuki,Estilo,338,19,67,Hatchback
23 | Suzuki,Ritz,442,18.5,86,Hatchback
24 | Suzuki,Swift,462,20.4,83,Hatchback
25 | Suzuki,Swift DZire,508,19.1,86,Sedan
26 | Suzuki,SX4,715,16.5,103,Sedan
27 | Suzuki,Wagon-R,363,20.5,67,Hatchback
28 | Nissan,Datsun GO,312,20.6,67,Hatchback
29 | Nissan,Micra,413,19.5,67,Hatchback
30 | Nissan,Sunny,699,16.9,98,Sedan
31 | Renault,Pulse,446,18,74,Hatchback
32 | Renault,Scala,724,16.9,98,Sedan
33 | San,Storm,595,16,59,Sedan
34 | Skoda,Fabia,503,16.4,75,Hatchback
35 | Skoda,Rapid,756,15,104,Sedan
36 | Tata,Indigo,499,14,65,Sedan
37 | Tata,Nano,199,23.9,38,Hatchback
38 | Tata,Zest,481,17.6,89,Sedan
39 | Toyota,Etios,603,16.8,89,Sedan
40 | Toyota,Etios Liva,500,17.7,79,Hatchback
41 | Volkswagen,Polo,535,16.5,74,Hatchback
42 | Volkswagen,Up,360,21,74,Hatchback
43 | Volkswagen,Vento,785,16.1,104,Sedan
--------------------------------------------------------------------------------
/experiments/vega-embed.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | /**
4 | * Embed a Vega-lite visualization component in a web page.
5 | * This function will either throw an exception, or return a promise
6 | *
7 | * @param el DOM element in which to place component (DOM node or CSS selector)
8 | * @param spec String : A URL string from which to load the Vega specification.
9 | Object : The Vega-Lite specification as a parsed JSON object.
10 | * @param opt A JavaScript object containing options for embedding.
11 | */
12 | function embed(el, spec, opt) {
13 | opt = opt || {};
14 | var renderer = opt.renderer || 'canvas';
15 | var runtime = vl.compile(vljson).spec; // may throw an Error if parsing fails
16 | var view = new vega.View(runtime)
17 | .logLevel(vega.Warn) // set view logging level
18 | .initialize(document.querySelector(el)) // set parent DOM element
19 | .renderer(renderer) // set render type (defaults to 'canvas')
20 | .run(); // update and render the view
21 | return Promise.resolve({view: view});
22 | }
23 |
24 |
25 | /**
26 | * Embed a Vega-lite visualization component in a web page.
27 | *
28 | * @param el DOM element in which to place component (DOM node or CSS selector)
29 | * @param spec String : A URL string from which to load the Vega-lite specification.
30 | * Object : The Vega/Vega-Lite specification as a parsed JSON object.
31 | * @param opt A JavaScript object containing options for embedding.
32 | */
33 | function embedMain(el, spec, opt) {
34 | // Ensure any exceptions will be properly handled
35 | return new Promise((accept, reject) => {
36 | embed(el, spec, opt).then(accept, reject);
37 | });
38 | }
39 |
--------------------------------------------------------------------------------
/pages/london.md:
--------------------------------------------------------------------------------
1 | # London Dataset
2 |
3 | This dataset was is about flight punctuality from London Airport to 5 major US airports
4 |
5 | | source| dest | airline | flights| onTimePerf| delayAvg | year |
6 | |:------|:-----|:--------|-------:|----------:|---------:|-----:|
7 | | LHR | ORD | AA | 2490 | 63.33 | 21.11 | 2010 |
8 | | LHR | ORD | BA | 1413 | 57.36 | 23.30 | 2010 |
9 | | LHR | ORD | UA | 2105 | 73.24 | 14.57 | 2010 |
10 | | LHR | ORD | VS | 218 | 77.06 | 11.10 | 2010 |
11 | | ... | ... | ... | ... | ... | ... | ... |
12 | | LHR | IAD | US | 2134 | 82.05 | 13.24 | 2016 |
13 | | LHR | IAD | VS | 699 | 84.69 | 8.02 | 2016 |
14 | | LCY | JFK | BA | 921 | 90.01 | 5.26 | 2016 |
15 | | LTN | EWR | DJT | 333 | 87.05 | 8.44 | 2016 |
16 |
17 | Metadata
18 | - Observations `(n)` : 157
19 | - Features `(p)` : 7
20 | - `source` : The source IATA airport code
21 | - `dest` : The destination IATA airport code
22 | - `airline` : The two letter IATA code for the airline
23 | - `flights` : The number of flights in that year
24 | - `onTimePerf` : The precentage of flights on-time in that route
25 | - `delayAvg` : The average delay in minutes for that route and airline
26 | - `year`: The year of data
27 |
28 | - Source: It is adapted from flight punctuality statistics from the London Civil Aviation Authority
29 |
30 |
31 | Make simple visualisations
32 |
33 | ```vis
34 | data:
35 | url: "data/london.csv"
36 | transform:
37 | -
38 | filter: datum.year == 2016
39 | mark: rect
40 | encoding:
41 | x:
42 | type: nominal
43 | field: source
44 | y:
45 | type: nominal
46 | field: dest
47 | color:
48 | type: quantitative
49 | field: flights
50 | aggregate: sum
51 | ```
52 |
--------------------------------------------------------------------------------
/pages/notes.md:
--------------------------------------------------------------------------------
1 | # Notes Dataset
2 |
3 | This dataset was inspired by the demonetisation of INR 500 and INR 1000 notes in India conducted in 2016.
4 |
5 | | year | type | denom | value | money | number |
6 | |--------:|:-------|-------:|-------:|--------:|-------:|
7 | | 1977 | Notes | 0001 | 1 | 2.72 | 2.720 |
8 | | 1977 | Notes | 1000 | 1000 | 0.55 | 0.001 |
9 | | 1977 | Notes | 0002 | 2 | 1.48 | 0.740 |
10 | | 1977 | Notes | 0050 | 50 | 9.95 | 0.199 |
11 | | ... | ... | ... | ... | ... | ... |
12 | | 2015 | Notes | 0500 | 500 | 7853.75 | 15.708 |
13 | | 2015 | Notes | 0001 | 1 | 3.09 | 3.090 |
14 | | 2015 | Notes | 0010 | 10 | 320.15 | 32.015 |
15 | | 2015 | Notes | 1000 | 1000 | 6325.68 | 6.326 |
16 |
17 | Metadata
18 | - Observations `(n)` : 351
19 | - Features `(p)` : 6
20 | - `year` : The year of circulation
21 | - `type` : The type of currency
22 | - `denom` : The denomination of the currency
23 | - `value` : The face value of the currency
24 | - `money` : The monetary value of currency in circulation (in INR Billion)
25 | - `number`: The number of currency in circulation (in INR Billion)
26 |
27 | - Source: It is taken from Reserve Bank of India’s - Handbook of Statistics on Indian Economy 2016. Within it, Table 160 deals with [Notes and Coins in Circulation](https://www.rbi.org.in/scripts/PublicationsView.aspx?id=17293) and this dataset is only about the Notes circulation.
28 |
29 |
30 | Make simple visualisations
31 |
32 | ```vis
33 | data:
34 | url: data/notes.csv
35 | transform:
36 | -
37 | filter: datum.year == 2015
38 | mark: bar
39 | encoding:
40 | x:
41 | type: nominal
42 | field: denom
43 | y:
44 | type: quantitative
45 | field: money
46 | color:
47 | type: nominal
48 | field: denom
49 | ```
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.gitignore.io/api/node,macos,jekyll
2 |
3 | ### Jekyll ###
4 | _site/
5 | .sass-cache/
6 | .jekyll-metadata
7 |
8 | ### macOS ###
9 | *.DS_Store
10 | .AppleDouble
11 | .LSOverride
12 |
13 | # Icon must end with two \r
14 | Icon
15 |
16 | # Thumbnails
17 | ._*
18 |
19 | # Files that might appear in the root of a volume
20 | .DocumentRevisions-V100
21 | .fseventsd
22 | .Spotlight-V100
23 | .TemporaryItems
24 | .Trashes
25 | .VolumeIcon.icns
26 | .com.apple.timemachine.donotpresent
27 |
28 | # Directories potentially created on remote AFP share
29 | .AppleDB
30 | .AppleDesktop
31 | Network Trash Folder
32 | Temporary Items
33 | .apdisk
34 |
35 | ### Node ###
36 | # Logs
37 | logs
38 | *.log
39 | npm-debug.log*
40 | yarn-debug.log*
41 | yarn-error.log*
42 |
43 | # Runtime data
44 | pids
45 | *.pid
46 | *.seed
47 | *.pid.lock
48 |
49 | # Directory for instrumented libs generated by jscoverage/JSCover
50 | lib-cov
51 |
52 | # Coverage directory used by tools like istanbul
53 | coverage
54 |
55 | # nyc test coverage
56 | .nyc_output
57 |
58 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
59 | .grunt
60 |
61 | # Bower dependency directory (https://bower.io/)
62 | bower_components
63 |
64 | # node-waf configuration
65 | .lock-wscript
66 |
67 | # Compiled binary addons (http://nodejs.org/api/addons.html)
68 | build/Release
69 |
70 | # Dependency directories
71 | node_modules/
72 | jspm_packages/
73 |
74 | # Typescript v1 declaration files
75 | typings/
76 |
77 | # Optional npm cache directory
78 | .npm
79 |
80 | # Optional eslint cache
81 | .eslintcache
82 |
83 | # Optional REPL history
84 | .node_repl_history
85 |
86 | # Output of 'npm pack'
87 | *.tgz
88 |
89 | # Yarn Integrity file
90 | .yarn-integrity
91 |
92 | # dotenv environment variables file
93 | .env
94 |
95 |
96 |
97 | # End of https://www.gitignore.io/api/node,macos,jekyll
--------------------------------------------------------------------------------
/experiments/visdown.1.js:
--------------------------------------------------------------------------------
1 | /*
2 | * visdown - a parser for vega-lite vis in markdown
3 | * Copyright (c) 2016-2018, Amit Kapoor. (MIT Licensed)
4 | * https://github.com/amitkaps/visdown
5 | */
6 |
7 | ;(function() {
8 |
9 | // Need to have vega, vega-lite and marked as dependencies
10 | // const vega = window.vega
11 | // const vl = window.vl
12 | // const marked = window.marked
13 | // const YAML = window.yaml
14 |
15 |
16 | // Start Marked Renderer
17 | const renderer = new marked.Renderer();
18 | marked.setOptions({
19 | renderer: renderer,
20 | gfm: true,
21 | tables: true,
22 | });
23 |
24 |
25 | const opts = {
26 | "mode": "vega-lite",
27 | "renderer": "svg",
28 | "actions": {export: false, source: false, editor: false}
29 | };
30 |
31 |
32 | //Render the vega-lite chart for each json spec
33 | function _render(element) {
34 | let specs = element.getElementsByClassName('lang-vis')
35 | let num = specs.length;
36 | for (var i=0; i < num; i++) {
37 | let el = "#vis-" + i;
38 | let jsonSpec = YAML.parse(specs[i].textContent)
39 | console.log(jsonSpec)
40 | //console.log(vl.compile(jsonVis).spec == undefined)
41 | htmlString = ""
42 | specs[i].parentNode.insertAdjacentHTML('beforebegin', htmlString);
43 | specs[i].parentNode.style.display = 'none';
44 | vegaEmbed(el, jsonSpec, opts);
45 | };
46 | };
47 |
48 | function visdown(input, element) {
49 | console.log('visdown');
50 | let visdownText = input;
51 | element.innerHTML = marked(visdownText);
52 | _render(element);
53 | }
54 |
55 | if (typeof module !== 'undefined' && typeof exports === 'object') {
56 | module.exports = visdown;
57 | } else if (typeof define === 'function' && define.amd) {
58 | define(function() { return visdown; });
59 | } else {
60 | this.visdown = visdown;
61 | }
62 |
63 | }).call(function() {
64 | return this || (typeof window !== 'undefined' ? window : global);
65 | }());
--------------------------------------------------------------------------------
/pages/start.md:
--------------------------------------------------------------------------------
1 | # Starting with Visdown
2 |
3 | This is a simple introduction to start using Visdown.
4 |
5 | ## Basic
6 | Visdown here is a markdown application and it will render the markdown as html in the view block.
7 |
8 | **This is an introduction to Visdown**
9 |
10 | ```
11 | Hello world!
12 | ```
13 |
14 | The one and only modification to markdown is to add static and interactive visualisation to the html. This is done by creating a new visualisation in fenced block (three backticks) and marking the language as 'vis'.
15 |
16 | ```vis
17 | data(data/london.csv)
18 | filter(datum.year == 2016)
19 | rect(x=source:N, y=dest:N, color=flights:Q:sum)
20 | ```
21 |
22 | Lets build this visualisation step by step
23 |
24 | ## Data and Marks
25 |
26 | We can add the data in directly, csv or json using the `data` entry and then encode it using `mark`
27 |
28 | ```vis
29 | data(data/london.csv)
30 | rect()
31 | ```
32 |
33 | ## Encoding
34 |
35 | Right now every field is mapped to this one rectangle. We need to add the encoding channel to define which field we want to show. So lets add `x`channel to encoding.
36 |
37 | ```vis
38 | data(data/london.csv)
39 | rect(x=source:N)
40 | ```
41 |
42 | Now we can see the four rect corresponding to the 4 source destination that are there. Now if we add a 'y' channel to the mix, we will start to see the rect corresponding to the `dest` value in it.
43 |
44 | ```vis
45 | data(data/london.csv)
46 | rect(x=source:N, y=dest:N)
47 | ```
48 |
49 | We can add the `color` channel to color them by the `flights`
50 |
51 | ```vis
52 | data(data/london.csv)
53 | rect(x=source:N, y=dest:N, color=flights:Q)
54 | ```
55 |
56 | However we need to do color them by the sum of number of flights
57 |
58 | ```vis
59 | data(data/london.csv)
60 | rect(x=source:N, y=dest:N, color=flights:Q:sum)
61 | ```
62 |
63 | ## Transform
64 |
65 | We want to show this chart for one particular `year`, which is 2016. So we need to transform the data and filter it for only that year. Lets do that.
66 |
67 | ```vis
68 | data(data/london.csv)
69 | filter(datum.year == 2016)
70 | rect(x=source:N, y=dest:N, color=flights:Q:sum)
71 | ```
72 |
73 |
--------------------------------------------------------------------------------
/js/visdown-app.js:
--------------------------------------------------------------------------------
1 | window.onload = function () {
2 |
3 | var sc = document.getElementById("visdown-input");
4 | var content = sc.textContent || sc.innerText || sc.innerHTML;
5 |
6 | window.editor = CodeMirror.fromTextArea(sc, {
7 | lineNumbers: false,
8 | lineWrapping: true,
9 | mode: "markdown",
10 | value: content,
11 | });
12 |
13 | var marked = window.marked;
14 |
15 | // var md = new markdownit().use(markdownitIncrementalDOM)
16 | specs = [];
17 | var opts = {"mode": "vega-lite",
18 | "renderer": "svg",
19 | "actions": {export: false, source: false, editor: false}
20 | };
21 |
22 | //Render the vega-lite chart for each json spec
23 | vegaliteRender = function () {
24 | specs = document.getElementsByClassName('lang-vis')
25 | var num = specs.length;
26 | for (var i=0; i < num; i++) {
27 | el = "#vis-" + i;
28 | jsonVis = YAML.parse(specs[i].textContent);
29 | console.log(vl.compile(jsonVis).spec == undefined)
30 | htmlString = ""
31 | specs[i].insertAdjacentHTML('beforebegin', htmlString);
32 | specs[i].style.display = 'none';
33 | vega.embed(el, jsonVis, opts);
34 | };
35 | };
36 |
37 | //Convert from Markdown to HTML
38 | var input = editor.getValue();
39 | var output = document.getElementById("visdown-output");
40 |
41 | visdown = function () {
42 | console.log('visdown');
43 | var markdownText = editor.getValue();
44 | output.innerHTML = marked(markdownText)
45 | // IncrementalDOM.patch(
46 | // output,
47 | // md.renderToIncrementalDOM(markdownText)
48 | // );
49 | vegaliteRender();
50 | }
51 |
52 | visdown()
53 |
54 | var waiting;
55 | editor.on("change", function() {
56 | visdown();
57 | });
58 |
59 | function viewSource(source) {
60 | var header = '' + " " + '' + '';
61 | var footer = '
' + " " + '';
62 | var doc = header + source + footer;
63 | var win = window.open('');
64 | //win.document.write(header + source + footer);
65 | //win.document.title = 'Vega JSON Source';
66 | return doc;
67 | }
68 |
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/static/css/visdown.css:
--------------------------------------------------------------------------------
1 | html {
2 | overflow: hidden;
3 | height: 100%
4 | }
5 |
6 | body {
7 | margin: 0;
8 | padding: 0;
9 | height: 100%;
10 | overflow-y: scroll;
11 | overflow-x: hidden;
12 | font-family: 'PT Sans', sans-serif;
13 | font-size: 16px;
14 | line-height: 1.4rem;
15 | text-rendering: optimizeLegibility;
16 | transition: all 700ms;
17 | }
18 |
19 | h1, h2, h3, h4, h5 {
20 | font-family: 'PT Serif', sans-serif;
21 | }
22 |
23 | h1 {
24 | font-size: 2rem;}
25 | h2 {
26 | font-size: 1.6rem;}
27 |
28 | .yin {
29 | color: #111;
30 | background-color: #FDFDFD;
31 | }
32 |
33 | .yang {
34 | color: #FDFDFD;
35 | background-color: #111;
36 | }
37 |
38 | header {
39 | width: 3.5rem;
40 | position: absolute;
41 | top: 0;
42 | bottom: 0;
43 | /* border-right: 1px solid lightgrey; */
44 | }
45 |
46 | nav {
47 | margin-top: 5rem;
48 | }
49 |
50 | .logo {
51 | display: block;
52 | position: absolute;
53 | width: 3.5rem;
54 | height: 3.5rem;
55 | margin: 0 auto;
56 | }
57 |
58 | .icon {
59 | display: block;
60 | width: 1.6rem;
61 | height: 1.6rem;
62 | margin: 1.2rem auto;
63 | cursor: pointer;
64 | }
65 |
66 | .icons-bottom {
67 | width: 3.5rem;
68 | position: absolute;
69 | bottom: 0;
70 | }
71 |
72 | #editor {
73 | padding: 0;
74 | margin: 0 0 0 3.5rem;
75 | }
76 |
77 | .CodeMirror {
78 | font-family: "Menlo", monospace;
79 | height: 100%;
80 | max-width: 52em;
81 | margin: 0 auto;
82 | vertical-align: top;
83 | box-sizing: border-box;
84 | padding: 20px 20px 0 20px;
85 | background-color: #FDFDFD;
86 | transition: all 700ms;
87 | }
88 |
89 | #output {
90 | display: none;
91 | height: 100%;
92 | max-width: 46em;
93 | margin: 0 auto;
94 | vertical-align: top;
95 | box-sizing: border-box;
96 | padding: 60px 20px 0 20px;
97 | }
98 |
99 | .cm-header {
100 | font-weight: 800;
101 | }
102 | .cm-header-1 { font-size: 150%; }
103 | .cm-header-2 { font-size: 130%; }
104 | .cm-header-3 { font-size: 120%; }
105 | .cm-header-4 { font-size: 110%; }
106 | .cm-header-5 { font-size: 100%; }
107 | .cm-header-6 { font-size: 90%; }
108 |
109 | /* .markdown-body pre {
110 | background-color: white;
111 | }
112 |
113 | code {
114 | color: #f66;
115 | }
116 |
117 | table {
118 | border-spacing: 0.7rem;
119 | }
120 |
121 | h1 {font-size: 2rem;}
122 | h2 {font-size: 1.6rem;}
123 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Visdown - Markdown for Visualisation
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
47 |
48 |
49 |
50 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/pages/visual-layer.md:
--------------------------------------------------------------------------------
1 | # Visual Layer
2 |
3 | - Marks: Points, Ticks, Lines, Bar, Area, Glyphs, Polygon, ...
4 | - Channels: Position, Size, Color, Shape, Path, ...
5 | - Position: Identity, Stacked, Jitter, Dodge, ...
6 | - Scale: Linear, Log, ...
7 | - Coordinate: Cartesian, Polar, Geo, Parallel
8 | - Layout: Single, Facetting, Multi-Chart
9 |
10 |
11 | ## Marks
12 |
13 | Marks are the basic shapes used to represent the data. Play around and see if you change the `mark` to `point`, `circle`, `square`, `text`, `tick`, `bar`, `line`, and `area`.
14 |
15 |
16 | ```vis
17 | data:
18 | url: "data/notes.csv"
19 | mark: line
20 | encoding:
21 | x:
22 | type: temporal
23 | field: year
24 | y:
25 | type: quantitative
26 | field: money
27 | color:
28 | type: nominal
29 | field: denom
30 | ```
31 |
32 | ## Channels
33 |
34 | These properties are used to set the position and appearance of the mark
35 |
36 | - Position x
37 | - Position y
38 | - Color
39 | - Shape
40 | - Size
41 |
42 |
43 | Change the `fields` in `x` ,`y`, `shape`, `size` and `color`
44 |
45 | ```vis
46 | data:
47 | url: "data/notes.csv"
48 | transform:
49 | -
50 | filter: datum.year > 2010
51 | mark: circle
52 | encoding:
53 | x:
54 | type: quantitative
55 | field: money
56 | y:
57 | type: quantitative
58 | field: number
59 | color:
60 | type: nominal
61 | field: denom
62 | size:
63 | type: quantitative
64 | field: value
65 | ```
66 |
67 | ## Position
68 |
69 | - Identity
70 | - Stacked
71 | - Normalise
72 | - Jitter
73 |
74 | To stack the values, we can use `aggregate` as `sum`
75 |
76 | ```vis
77 | data:
78 | url: "data/notes.csv"
79 | mark: area
80 | encoding:
81 | x:
82 | type: temporal
83 | field: year
84 | y:
85 | type: quantitative
86 | field: money
87 | aggregate: sum
88 | color:
89 | type: nominal
90 | field: denom
91 | ```
92 |
93 | To normalize the values, we can use `config` to make the `stacked` as `normalize`
94 |
95 | ```vis
96 | data:
97 | url: "data/notes.csv"
98 | mark: area
99 | encoding:
100 | x:
101 | type: temporal
102 | field: year
103 | y:
104 | type: quantitative
105 | field: money
106 | aggregate: sum
107 | color:
108 | type: nominal
109 | field: denom
110 | config:
111 | mark:
112 | stacked: normalize
113 | ```
114 |
115 | ## Facet
116 |
117 | We can also create small multiple charts using `row` or `column` encoding
118 |
119 | - Row wise
120 | - Column wise
121 |
122 | ```vis
123 | data:
124 | url: "data/notes.csv"
125 | transform:
126 | -
127 | filter: datum.denom > 50
128 | mark: area
129 | encoding:
130 | x:
131 | type: temporal
132 | field: year
133 | y:
134 | type: quantitative
135 | field: money
136 | color:
137 | type: nominal
138 | field: denom
139 | column:
140 | type: nominal
141 | field: denom
142 | ```
143 |
--------------------------------------------------------------------------------
/experiments/datum.js:
--------------------------------------------------------------------------------
1 | /*
2 | * datum - a shorthand for vega-lite
3 | * Copyright (c) 2017, Amit Kapoor. (MIT Licensed)
4 | * https://github.com/amitkaps/visdown
5 | */
6 |
7 | ;(function() {
8 |
9 | // Create TOKENS by removing | or \n from raw spec
10 | function tokenizer(visCode) {
11 | let tokens = visCode.trim()
12 | .split(/[|\n]+/)
13 | .map(str => str.trim());
14 | return tokens;
15 | }
16 |
17 | // Create GRAMMAR FUNCTIONS
18 | function _data(type, exp) {
19 | let data = {"data": {"url": exp}};
20 | return data;
21 | }
22 |
23 | function _transform(type, exp) {
24 | let transform = {"transform": [{"filter": exp}]};
25 | return transform;
26 | }
27 |
28 | function _mark(type, exp) {
29 | let encode = _encoding(exp);
30 | let mark_encoding = {"mark": type, "encoding": encode}
31 | return mark_encoding
32 | }
33 |
34 | function _encoding(exp) {
35 | let etokens = exp.split(",").map(str => str.trim())
36 | let encode = {}
37 | for(let i = 0; i < etokens.length; i++){
38 | let etoken = etokens[i].split("=").map(str => str.trim());
39 | console.log(etoken)
40 | let posChannel = etoken[0];
41 | let fieldType = etoken[1].split(":").map(str => str.trim());
42 | let field = fieldType[0], type = fieldType[1], aggregate = fieldType[2]
43 | encode[posChannel] = {"field": field, "type": type, "aggregate": aggregate}
44 | }
45 | return encode;
46 | }
47 |
48 | // Set up TYPE to GRAMMAR FUNCTION mapping
49 | const grammarFunc = {
50 | "data" : _data,
51 | "filter": _transform, "bin": "_transform",
52 | "point" : _mark, "area" : _mark, "line": _mark,
53 | "bar" : _mark, "circle": _mark,
54 | "rect" : _mark, "line" : _mark,
55 | "single": "_selection", "multi": "_selection", "interval": "_selection"
56 | }
57 |
58 | // Use LEXER to create SEMANTIC of 'type' and 'grammar' from tokens
59 | function lexer(tokens) {
60 | let lex = [];
61 | for (let i = 0; i < tokens.length; i++) {
62 | let token = tokens[i].split("(");
63 | let type = token[0].trim();
64 | let exp = token[1].split(")")[0].trim();
65 | let grammar = grammarFunc[type](type, exp);
66 | lex[i] = {"type": type, "exp": exp, "grammar": grammar};
67 | }
68 | return lex;
69 | }
70 |
71 | function merge(obj) {
72 | let target, key;
73 | for (let i = 0; i < arguments.length; i++) {
74 | target = arguments[i];
75 | for (key in target) {
76 | if (Object.prototype.hasOwnProperty.call(target, key)) {
77 | obj[key] = target[key];
78 | }
79 | }
80 | }
81 | return obj;
82 | }
83 |
84 | // Use PARSER to generate the Vega-Lite spec
85 | function parser(lex) {
86 | let spec = {} ;
87 | for (let i = 0; i < lex.length; i++) {
88 | let type = lex[i].type;
89 | let grammar = lex[i].grammar;
90 | spec = merge(spec, grammar);
91 | }
92 | return spec;
93 | }
94 |
95 | // Create vlSpec from the visCode
96 | function datum(visCode) {
97 | let tokens = tokenizer(visCode);
98 | let lex = lexer(tokens);
99 | console.log(lex);
100 | let spec = parser(lex);
101 | console.log(spec)
102 | return spec;
103 | }
104 |
105 |
106 |
107 | if (typeof module !== 'undefined' && typeof exports === 'object') {
108 | module.exports = datum;
109 | } else if (typeof define === 'function' && define.amd) {
110 | define(function() { return datum; });
111 | } else {
112 | this.datum = datum;
113 | }
114 |
115 | }).call(function() {
116 | return this || (typeof window !== 'undefined' ? window : global);
117 | }());
--------------------------------------------------------------------------------
/pages/composition.md:
--------------------------------------------------------------------------------
1 | # Composition
2 |
3 | - Single View
4 | - Multiple View
5 | - Layering
6 | - Concatentation
7 | - Facetting
8 | - Repeat
9 |
10 | ## Single View - 1
11 |
12 | ```vis
13 | data:
14 | url: data/notes.csv
15 | transform:
16 | - filter: datum.year == 2015
17 | mark: bar
18 | encoding:
19 | y:
20 | type: nominal
21 | field: denom
22 | x:
23 | type: quantitative
24 | field: number
25 | color:
26 | type: nominal
27 | field: denom
28 | size:
29 | value: 3
30 | ```
31 |
32 | ## Single View - 2
33 |
34 |
35 | ```vis
36 | data:
37 | url: data/notes.csv
38 | transform:
39 | - filter: datum.year == 2015
40 | mark: circle
41 | encoding:
42 | y:
43 | type: nominal
44 | field: denom
45 | x:
46 | type: quantitative
47 | field: number
48 | color:
49 | type: nominal
50 | field: denom
51 | size:
52 | value: 100
53 |
54 | ```
55 |
56 | ## Layered View
57 |
58 | Simple Example
59 |
60 | ```vis
61 | data:
62 | url: data/notes.csv
63 | transform:
64 | - filter: datum.year == 2015
65 | layer:
66 | - mark: bar
67 | encoding:
68 | y:
69 | type: nominal
70 | field: denom
71 | x:
72 | type: quantitative
73 | field: number
74 | color:
75 | type: nominal
76 | field: denom
77 | size:
78 | value: 2
79 | - mark: circle
80 | encoding:
81 | y:
82 | type: nominal
83 | field: denom
84 | x:
85 | type: quantitative
86 | field: number
87 | color:
88 | type: nominal
89 | field: denom
90 | size:
91 | value: 100
92 |
93 | ```
94 |
95 | ## Concat
96 |
97 |
98 | ```vis
99 | hconcat:
100 | - data:
101 | url: data/notes.csv
102 | transform:
103 | - filter: datum.year == 2015
104 | mark: bar
105 | encoding:
106 | x:
107 | type: nominal
108 | field: denom
109 | y:
110 | type: quantitative
111 | field: number
112 | color:
113 | type: nominal
114 | field: denom
115 | - data:
116 | url: data/notes.csv
117 | transform:
118 | - filter: datum.year == 2015
119 | mark: circle
120 | encoding:
121 | x:
122 | type: nominal
123 | field: denom
124 | y:
125 | type: quantitative
126 | field: number
127 | color:
128 | type: nominal
129 | field: denom
130 | size:
131 | value: 100
132 |
133 | ```
134 |
135 | ## Facet
136 |
137 | ```vis
138 | data:
139 | url: data/notes.csv
140 | transform:
141 | - filter: datum.year > 2013
142 | mark: bar
143 | encoding:
144 | x:
145 | type: nominal
146 | field: denom
147 | y:
148 | type: quantitative
149 | field: number
150 | color:
151 | type: nominal
152 | field: denom
153 | column:
154 | type: nominal
155 | field: year
156 | ```
157 |
158 |
159 | ## Repeat
160 |
161 | ```vis
162 | data:
163 | url: data/notes.csv
164 | transform:
165 | - filter: datum.year == 2015
166 | repeat:
167 | column:
168 | - money
169 | - number
170 | spec:
171 | mark: bar
172 | encoding:
173 | x:
174 | type: nominal
175 | field: denom
176 | y:
177 | type: quantitative
178 | field:
179 | repeat: column
180 | color:
181 | type: nominal
182 | field: denom
183 | config:
184 | axis:
185 | orient: bottom
186 | ```
187 |
188 | ## Resolve
189 |
190 | e.g. layering charts with different scales
191 |
192 | **First Layer**
193 |
194 | ```vis
195 | width: 400
196 | height: 300
197 | data:
198 | url: data/notes.csv
199 | mark: area
200 | encoding:
201 | x:
202 | field: year
203 | type: temporal
204 | axis:
205 | format: %Y
206 | labelAngle: 0
207 | y:
208 | aggregate: sum
209 | field: money
210 | type: quantitative
211 | stack: normalize
212 | axis:
213 | format: %
214 | color:
215 | field: denom
216 | type: nominal
217 | ```
218 |
219 | **Second Layer**
220 |
221 | ```vis
222 | width: 400
223 | height: 300
224 | data:
225 | url: data/notes.csv
226 | mark: line
227 | encoding:
228 | x:
229 | field: year
230 | type: temporal
231 | axis:
232 | format: %Y
233 | labelAngle: 0
234 | y:
235 | aggregate: sum
236 | field: number
237 | type: quantitative
238 | size:
239 | value: 3
240 | color:
241 | value: black
242 |
243 | ```
244 |
245 | **Combined**
246 |
247 | ```vis
248 | width: 400
249 | height: 300
250 | data:
251 | url: data/notes.csv
252 | layer:
253 | - mark: area
254 | encoding:
255 | x:
256 | field: year
257 | type: temporal
258 | axis:
259 | format: %Y
260 | labelAngle: 0
261 | y:
262 | aggregate: sum
263 | field: money
264 | type: quantitative
265 | stack: normalize
266 | axis:
267 | format: %
268 | color:
269 | field: denom
270 | type: nominal
271 | - mark: line
272 | encoding:
273 | x:
274 | field: year
275 | type: temporal
276 | axis:
277 | format: %Y
278 | labelAngle: 0
279 | y:
280 | aggregate: sum
281 | field: number
282 | type: quantitative
283 | size:
284 | value: 3
285 | color:
286 | value: black
287 | resolve:
288 | y:
289 | scale: independent
290 | ```
291 |
--------------------------------------------------------------------------------
/pages/data.md:
--------------------------------------------------------------------------------
1 | # Datasets
2 |
3 | You can use external datasets or use the following datasets to try out Visdown.
4 |
5 | ## Loading data
6 | You can use any csv, tsv or json file to load your data set.
7 |
8 | ```
9 | data:
10 |
11 | ## Sample
12 |
13 | This the most simple dataset available.
14 |
15 | | area | sales | profit |
16 | |:--------|-------:|-------:|
17 | | North | 5 | 2 |
18 | | East | 25 | 8 |
19 | | West | 15 | 6 |
20 | | South | 20 | 5 |
21 | | Central | 10 | 3 |
22 |
23 | Metadata
24 | - Filename: `sample.csv`
25 | - Observations `(n)` : 5
26 | - Dimensions `(p)` : 3
27 |
28 | ```vis
29 | data:
30 | - url: sample.csv
31 | mark: point
32 | encoding:
33 | x:
34 | (data/sample.csv) | point(x=sales:Q, y=profit:Q, color=area:N)
35 | ```
36 |
37 | ## Cars
38 |
39 | A list of Indian cars and basic stats
40 |
41 | | brand | model | price | kmpl | type | bhp |
42 | |:--------|:-------|-------:|-------:|:----------|-------:|
43 | | Tata | Nano | 199 | 23.9 | Hatchback | 38 |
44 | | Suzuki | Alto800| 248 | 22.7 | Hatchback | 47 |
45 | | Hyundai | EON | 302 | 21.1 | Hatchback | 55 |
46 | | Nissan | Datsun | 312 | 20.6 | Hatchback | 67 |
47 | | ... | ... | ... | ... | ... | ... |
48 | | Suzuki | Ciaz | 725 | 20.7 | Sedan | 91 |
49 | | Skoda | Rapid | 756 | 15.0 | Sedan | 104 |
50 | | Hyundai | Verna | 774 | 17.4 | Sedan | 106 |
51 | | VW | Vento | 785 | 16.1 | Sedan | 104 |
52 |
53 | Metadata
54 | - Filename: `cars.csv`
55 | - Observations `(n)`: 42
56 | - Dimensions `(p)` : 6
57 | - `brand`: brand
58 | - `model`: model name
59 | - `price`: price in '000 INR
60 | - `kmpl` : efficiency of the car in km per liter
61 | - `type` : type either Hatchback or Sedan
62 | - `bhp` : brake horsepower
63 | - Source: Adapted from a car comparison website
64 |
65 | ```vis
66 | data(data/cars.csv) | point(x=kmpl:Q, y = price:Q)
67 | ```
68 |
69 | ## Flights
70 |
71 | This dataset was is about flight punctuality from 5 London Airport to 5 major US airports
72 |
73 | | source| dest | airline | flights| onTimePerf| delayAvg | year |
74 | |:------|:-----|:--------|-------:|----------:|---------:|-----:|
75 | | LHR | ORD | AA | 2490 | 63.33 | 21.11 | 2010 |
76 | | LHR | ORD | BA | 1413 | 57.36 | 23.30 | 2010 |
77 | | LHR | ORD | UA | 2105 | 73.24 | 14.57 | 2010 |
78 | | LHR | ORD | VS | 218 | 77.06 | 11.10 | 2010 |
79 | | ... | ... | ... | ... | ... | ... | ... |
80 | | LHR | IAD | US | 2134 | 82.05 | 13.24 | 2016 |
81 | | LHR | IAD | VS | 699 | 84.69 | 8.02 | 2016 |
82 | | LCY | JFK | BA | 921 | 90.01 | 5.26 | 2016 |
83 | | LTN | EWR | DJT | 333 | 87.05 | 8.44 | 2016 |
84 |
85 | Metadata
86 | - Filename: `flights.csv`
87 | - Observations `(n)`: 157
88 | - Dimensions `(p)` : 7
89 | - `source` : The source IATA airport code
90 | - `dest` : The destination IATA airport code
91 | - `airline` : The two letter IATA code for the airline
92 | - `flights` : The number of flights in that year
93 | - `onTimePerf` : The precentage of flights on-time in that route
94 | - `delayAvg`: The average delay in minutes for that route and airline
95 | - `year` : The year of data
96 | - Source: Adapted from flight punctuality statistics from the London Civil Aviation Authority
97 |
98 | ```vis
99 | data(london.csv)
100 | filter(datum.year == 2016)
101 | rect(x=source:N, y=dest:N, color=sum(flights):Q)
102 | ```
103 |
104 | ## Notes
105 |
106 | This dataset was inspired by the demonetisation of INR 500 and INR 1000 notes in India conducted in 2016.
107 |
108 | | year | type | denom | value | money | number |
109 | |--------:|:-------|-------:|-------:|--------:|-------:|
110 | | 1977 | Notes | 0001 | 1 | 2.72 | 2.720 |
111 | | 1977 | Notes | 1000 | 1000 | 0.55 | 0.001 |
112 | | 1977 | Notes | 0002 | 2 | 1.48 | 0.740 |
113 | | 1977 | Notes | 0050 | 50 | 9.95 | 0.199 |
114 | | ... | ... | ... | ... | ... | ... |
115 | | 2015 | Notes | 0500 | 500 | 7853.75 | 15.708 |
116 | | 2015 | Notes | 0001 | 1 | 3.09 | 3.090 |
117 | | 2015 | Notes | 0010 | 10 | 320.15 | 32.015 |
118 | | 2015 | Notes | 1000 | 1000 | 6325.68 | 6.326 |
119 |
120 | Metadata
121 | - Filename: `notes.csv`
122 | - Observations `(n)`: 351
123 | - Features `(p)` : 6
124 | - `year` : The year of circulation
125 | - `type` : The type of currency
126 | - `denom` : The denomination of the currency
127 | - `value` : The face value of the currency
128 | - `money` : The monetary value of currency in circulation (in INR Billion)
129 | - `number`: The number of currency in circulation (in INR Billion)
130 | - Source: It is taken from Reserve Bank of India’s - Handbook of Statistics on Indian Economy 2016. Within it, Table 160 deals with [Notes and Coins in Circulation](https://www.rbi.org.in/scripts/PublicationsView.aspx?id=17293) and this dataset is only about the Notes circulation.
131 |
132 | ```vis
133 | data(data/notes.csv)
134 | filter(datum.year == 2015)
135 | bar(x=denom:N, y=money:Q, color=denom:N)
136 | ```
137 |
138 |
139 |
--------------------------------------------------------------------------------
/pages/interact-layer.md:
--------------------------------------------------------------------------------
1 | # Interaction Layer
2 |
3 | - *Selection*: Discrete (single, multi), Continuous (interval), Voronoi (nearest), Remove (toggle)
4 | - *Events*: `click`, `dblclick`, `mouseover`, `drag`,...
5 | - *Condition*: Change encoding, scale, filter, ...
6 | - *Bind*: Input elements (range, radio-box,...)
7 | - *Project*: default, fields
8 | - *Translate*: scale
9 |
10 |
11 | **Interaction Patterns**
12 |
13 | - **Select**: mark something as interesting e.g. *Highlighting*
14 | - **Explore**: show me something else e.g. *Pan or Zoom*
15 | - **Encode**: show me a different representation e.g. *change Color, Position*
16 | - **Abstract/Elaborate**: show me more or less detail e.g. *Overview & Details*
17 | - **Filter**: show me something conditionally e.g. *Dynamic Queries*, *Cross Filter*
18 | - **Connect**: show me related items e.g. *Brushing & Linking*
19 | - **Reconfigure**: show me a different arrangement e.g. *Sorting*, *Indexing*
20 | - **Transition**: move between different views e.g. *Staging & Animation*
21 |
22 |
23 | ## Select: **Highlighting**
24 |
25 | **Single**
26 |
27 | Select single value using `click`
28 |
29 | ```vis
30 | data:
31 | url: data/notes.csv
32 | transform:
33 | - filter: datum.year == 2015
34 | selection:
35 | pts:
36 | type: single
37 | mark: circle
38 | encoding:
39 | x:
40 | type: nominal
41 | field: denom
42 | y:
43 | type: quantitative
44 | field: number
45 | color:
46 | condition:
47 | selection: pts
48 | type: nominal
49 | field: denom
50 | value: grey
51 | size:
52 | value: 250
53 | ```
54 |
55 | **Multiple**
56 |
57 | Select multiple value using `click` & `shift` + `click`
58 |
59 | ```vis
60 | data:
61 | url: data/notes.csv
62 | transform:
63 | - filter: datum.year == 2015
64 | selection:
65 | pts:
66 | type: multi
67 | mark: circle
68 | encoding:
69 | x:
70 | type: nominal
71 | field: denom
72 | y:
73 | type: quantitative
74 | field: number
75 | color:
76 | condition:
77 | selection: pts
78 | type: nominal
79 | field: denom
80 | value: grey
81 | size:
82 | value: 250
83 | ```
84 |
85 | ## Brushing
86 |
87 | **Interval / Brushing**
88 |
89 | Select an interval by dragging the mouse
90 |
91 | ```vis
92 | data:
93 | url: data/notes.csv
94 | transform:
95 | - filter: datum.year == 2015
96 | selection:
97 | pts:
98 | type: interval
99 | mark: circle
100 | encoding:
101 | x:
102 | type: nominal
103 | field: denom
104 | y:
105 | type: quantitative
106 | field: number
107 | color:
108 | condition:
109 | selection: pts
110 | type: nominal
111 | field: denom
112 | value: grey
113 | size:
114 | value: 250
115 | ```
116 |
117 | ## Highlighting
118 |
119 | **Direct**
120 |
121 | Select direct value using `hover`
122 |
123 | ```vis
124 | data:
125 | url: data/cars.csv
126 | selection:
127 | pts:
128 | type: single
129 | on: mouseover
130 | mark: circle
131 | encoding:
132 | x:
133 | type: quantitative
134 | field: kmpl
135 | scale:
136 | domain: [12,25]
137 | y:
138 | type: quantitative
139 | field: price
140 | scale:
141 | domain: [100,900]
142 | color:
143 | condition:
144 | selection: pts
145 | field: type
146 | type: nominal
147 | value: grey
148 | size:
149 | value: 200
150 | width: 450
151 | height: 300
152 | ```
153 |
154 | **Nearest**
155 |
156 | Select nearest value using `hover`
157 |
158 |
159 | ```vis
160 | data:
161 | url: data/cars.csv
162 | selection:
163 | pts:
164 | type: single
165 | on: mouseover
166 | nearest: true
167 | mark: circle
168 | encoding:
169 | x:
170 | type: quantitative
171 | field: kmpl
172 | scale:
173 | domain: [12,25]
174 | y:
175 | type: quantitative
176 | field: price
177 | scale:
178 | domain: [100,900]
179 | color:
180 | condition:
181 | selection: pts
182 | field: type
183 | type: nominal
184 | value: grey
185 | size:
186 | value: 200
187 | width: 450
188 | height: 300
189 | ```
190 |
191 | **Multi Line Highlight**
192 |
193 | ```vis
194 | width: 500
195 | height: 300
196 | data:
197 | url: data/notes.csv
198 | config:
199 | point:
200 | opacity: 0
201 | layer:
202 | - selection:
203 | highlight:
204 | type: single
205 | 'on': mouseover
206 | nearest: 'true'
207 | fields:
208 | - denom
209 | mark: point
210 | encoding:
211 | x:
212 | field: year
213 | type: temporal
214 | axis:
215 | format: "%Y"
216 | labelAngle: 0
217 | y:
218 | field: number
219 | type: quantitative
220 | color:
221 | field: denom
222 | type: nominal
223 | - mark: line
224 | encoding:
225 | x:
226 | field: year
227 | type: temporal
228 | axis:
229 | y:
230 | field: number
231 | type: quantitative
232 | color:
233 | field: denom
234 | type: nominal
235 | size:
236 | condition:
237 | selection:
238 | not: highlight
239 | value: 1
240 | value: 3
241 | ```
242 |
243 |
244 |
245 | ## Dynamic Queries: Input Binding
246 |
247 | Two-way binding between Input Types and Selection
248 |
249 | ```vis
250 | data:
251 | url: data/cars.csv
252 | selection:
253 | pts:
254 | type: single
255 | fields:
256 | - type
257 | bind:
258 | input: select
259 | options:
260 | - Hatchback
261 | - Sedan
262 | mark: circle
263 | encoding:
264 | x:
265 | type: quantitative
266 | field: kmpl
267 | scale:
268 | domain: [12,25]
269 | y:
270 | type: quantitative
271 | field: price
272 | scale:
273 | domain: [100,900]
274 | color:
275 | condition:
276 | selection: pts
277 | field: type
278 | type: nominal
279 | value: grey
280 | size:
281 | value: 200
282 | width: 450
283 | height: 300
284 | ```
285 |
--------------------------------------------------------------------------------
/data/flights.csv:
--------------------------------------------------------------------------------
1 | "source","dest","airline","flights","onTimePerf","delayAvg","year"
2 | "LHR","ORD","AA",2490,66.33,21.11,2010
3 | "LHR","ORD","BA",1413,57.63,23.3,2010
4 | "LHR","ORD","UA",2105,73.24,14.57,2010
5 | "LHR","ORD","VS",218,77.06,11.1,2010
6 | "LHR","LAX","AA",706,66.38,17.66,2010
7 | "LHR","LAX","BA",1914,50.18,31.01,2010
8 | "LHR","LAX","UA",698,81.81,13.62,2010
9 | "LHR","LAX","VS",1285,56.86,21.92,2010
10 | "LHR","JFK","AA",3205,67.36,20.31,2010
11 | "LHR","JFK","BA",4181,66.59,20.84,2010
12 | "LHR","JFK","DL",1611,62.12,23.74,2010
13 | "LHR","JFK","KU",305,46.56,38.75,2010
14 | "LHR","JFK","VS",2067,59.62,23.69,2010
15 | "LHR","EWR","BA",1828,70.25,17.67,2010
16 | "LHR","EWR","CO",2697,69.28,18.87,2010
17 | "LHR","EWR","VS",1399,65.62,23.15,2010
18 | "LHR","IAD","BA",2011,62.11,21.71,2010
19 | "LHR","IAD","UA",2094,74.67,14.11,2010
20 | "LHR","IAD","VS",700,66.24,19.75,2010
21 | "LCY","JFK","BA",1012,89.12,5.67,2010
22 | "LHR","ORD","AA",2532,76.87,13.34,2011
23 | "LHR","ORD","BA",1440,76.32,14.42,2011
24 | "LHR","ORD","UA",2106,79.36,15.2,2011
25 | "LHR","ORD","VS",302,82.72,8.66,2011
26 | "LHR","LAX","AA",730,75.48,13.66,2011
27 | "LHR","LAX","BA",1984,63.46,18.47,2011
28 | "LHR","LAX","UA",698,83.52,11.7,2011
29 | "LHR","LAX","VS",1397,79,11.2,2011
30 | "LHR","JFK","AA",2917,75.8,14.77,2011
31 | "LHR","JFK","BA",4944,73.56,14.65,2011
32 | "LHR","JFK","DL",2144,80.91,13.05,2011
33 | "LHR","JFK","KU",302,52.65,30.02,2011
34 | "LHR","JFK","VS",2104,76.32,15.09,2011
35 | "LHR","EWR","BA",2129,80.7,11.24,2011
36 | "LHR","EWR","CO",3503,78.42,14.19,2011
37 | "LHR","EWR","VS",1410,77.52,13.39,2011
38 | "LHR","IAD","BA",2157,74.08,14.11,2011
39 | "LHR","IAD","UA",2516,80.79,14,2011
40 | "LHR","IAD","VS",711,82.42,9.73,2011
41 | "LCY","JFK","BA",1031,92.05,4.12,2011
42 | "LHR","ORD","AA",2523,72.07,20.03,2012
43 | "LHR","ORD","BA",1445,70.03,17.73,2012
44 | "LHR","ORD","UA",2102,76.08,15.35,2012
45 | "LHR","ORD","VS",308,83.77,8.31,2012
46 | "LHR","LAX","AA",714,75.35,12.03,2012
47 | "LHR","LAX","BA",1874,63.48,18.34,2012
48 | "LHR","LAX","UA",693,76.16,14.88,2012
49 | "LHR","LAX","VS",1324,76.13,14.08,2012
50 | "LHR","JFK","AA",3367,75.72,12.75,2012
51 | "LHR","JFK","BA",5129,69.28,17.68,2012
52 | "LHR","JFK","DL",2151,77.63,13.59,2012
53 | "LHR","JFK","KU",307,52.12,32.02,2012
54 | "LHR","JFK","VS",2227,81.9,11.32,2012
55 | "LHR","EWR","BA",1920,73.02,15.88,2012
56 | "LHR","EWR","CO",612,84.48,9.24,2012
57 | "LHR","EWR","UA",2872,69.76,17.91,2012
58 | "LHR","EWR","VS",1421,76.14,16.68,2012
59 | "LHR","IAD","BA",2014,71.45,16.23,2012
60 | "LHR","IAD","UA",2444,69.04,18.98,2012
61 | "LHR","IAD","VS",703,87.06,7.71,2012
62 | "LCY","JFK","BA",474,91.33,3.74,2012
63 | "LCY","JFK","BA",537,89.37,4.71,2012
64 | "LHR","ORD","AA",2513,74.69,15.29,2013
65 | "LHR","ORD","BA",1440,65.35,20.84,2013
66 | "LHR","ORD","UA",2110,78.39,14.13,2013
67 | "LHR","ORD","VS",324,83.02,9.05,2013
68 | "LHR","LAX","AA",728,76.48,12.56,2013
69 | "LHR","LAX","BA",1864,59.5,27.43,2013
70 | "LHR","LAX","UA",702,85.47,9.86,2013
71 | "LHR","LAX","VS",1288,79,13.76,2013
72 | "LHR","JFK","AA",2991,76.4,13.73,2013
73 | "LHR","JFK","BA",5350,66.97,18.95,2013
74 | "LHR","JFK","DL",2166,82.09,10.81,2013
75 | "LHR","JFK","KU",306,62.42,21.53,2013
76 | "LHR","JFK","VS",2825,81.91,10.53,2013
77 | "LHR","EWR","BA",1838,71.44,16.72,2013
78 | "LHR","EWR","UA",3494,80.59,12.36,2013
79 | "LHR","EWR","VS",1419,81.66,11.7,2013
80 | "LHR","IAD","BA",2012,71.02,18.67,2013
81 | "LHR","IAD","UA",2496,80.39,12.82,2013
82 | "LHR","IAD","VS",702,86.89,7.1,2013
83 | "LCY","JFK","BA",945,90.64,4.58,2013
84 | "LGW","LAX","DY",105,72.38,36.83,2014
85 | "LGW","JFK","DY",156,51.92,27.79,2014
86 | "LHR","ORD","AA",2476,73.5,22.09,2014
87 | "LHR","ORD","BA",1444,65.28,18.7,2014
88 | "LHR","ORD","UA",2110,77.56,13.68,2014
89 | "LHR","ORD","VS",348,81.32,8.86,2014
90 | "LHR","LAX","AA",728,76.79,18.56,2014
91 | "LHR","LAX","BA",1450,56.84,23.1,2014
92 | "LHR","LAX","DL",127,92.13,6.92,2014
93 | "LHR","LAX","UA",698,85.1,8.53,2014
94 | "LHR","LAX","VS",1217,80.99,12.58,2014
95 | "LHR","JFK","AA",2287,78.18,14.74,2014
96 | "LHR","JFK","BA",6018,71.29,16.59,2014
97 | "LHR","JFK","DL",2123,82.13,11.19,2014
98 | "LHR","JFK","KU",310,48.22,33.17,2014
99 | "LHR","JFK","VS",2820,79.77,12.45,2014
100 | "LHR","EWR","BA",1943,71.46,19.7,2014
101 | "LHR","EWR","UA",3485,78.3,15.19,2014
102 | "LHR","EWR","VS",1420,86.6,8.37,2014
103 | "LHR","IAD","BA",1807,74.58,15.31,2014
104 | "LHR","IAD","UA",2130,81.13,13.61,2014
105 | "LHR","IAD","VS",695,89.06,6.9,2014
106 | "LCY","JFK","BA",1003,91.23,4.43,2014
107 | "LGW","LAX","DY",328,66.46,21.41,2015
108 | "LGW","JFK","DY",543,64.09,31.78,2015
109 | "LHR","ORD","AA",2062,72.09,27.59,2015
110 | "LHR","ORD","BA",1442,71.4,16.24,2015
111 | "LHR","ORD","UA",2099,83.94,10.37,2015
112 | "LHR","ORD","VS",330,78.79,11.61,2015
113 | "LHR","LAX","AA",1265,75.42,14.5,2015
114 | "LHR","LAX","BA",1450,66.9,17.67,2015
115 | "LHR","LAX","DL",540,79.44,10.97,2015
116 | "LHR","LAX","UA",704,89.2,7.5,2015
117 | "LHR","LAX","VS",1230,80.81,12.74,2015
118 | "LHR","JFK","AA",2130,77.45,15.21,2015
119 | "LHR","JFK","BA",5994,77.84,13.61,2015
120 | "LHR","JFK","DL",2069,80.75,13.51,2015
121 | "LHR","JFK","KU",310,59.22,32.67,2015
122 | "LHR","JFK","VS",3363,76.35,13.82,2015
123 | "LHR","EWR","BA",1459,76.47,14.03,2015
124 | "LHR","EWR","DL",381,95.54,2.88,2015
125 | "LHR","EWR","UA",3493,79.23,16.31,2015
126 | "LHR","EWR","VS",871,81.75,10.7,2015
127 | "LHR","IAD","BA",1421,76.89,12.03,2015
128 | "LHR","IAD","UA",2126,81.74,14.02,2015
129 | "LHR","IAD","VS",703,85.49,12.59,2015
130 | "LCY","JFK","BA",937,92.74,4.52,2015
131 | "LTN","EWR","DJT",316,81.53,18.18,2015
132 | "LGW","LAX","DY",421,59.86,23.64,2016
133 | "LGW","LAX","DI",38,65.79,14.39,2016
134 | "LGW","JFK","BA",486,69.75,18.02,2016
135 | "LGW","JFK","DY",689,65.31,28.18,2016
136 | "LGW","JFK","DI",39,69.23,15.49,2016
137 | "LHR","ORD","AA",2453,71.82,26.15,2016
138 | "LHR","ORD","BA",1443,68.88,17.58,2016
139 | "LHR","ORD","UA",2085,82.25,14.2,2016
140 | "LHR","ORD","VS",333,89.79,5.07,2016
141 | "LHR","LAX","AA",1411,68.25,19.46,2016
142 | "LHR","LAX","BA",1452,54.34,24.89,2016
143 | "LHR","LAX","UA",700,87,8.48,2016
144 | "LHR","LAX","VS",1376,79.58,10.13,2016
145 | "LHR","JFK","AA",2623,76.82,21.41,2016
146 | "LHR","JFK","BA",5625,69.97,17.15,2016
147 | "LHR","JFK","DL",2081,80.37,13.42,2016
148 | "LHR","JFK","KU",253,19.76,71.96,2016
149 | "LHR","JFK","VS",3489,79.67,11.44,2016
150 | "LHR","EWR","AI",118,65.25,21.14,2016
151 | "LHR","EWR","BA",1444,76.11,13.49,2016
152 | "LHR","EWR","UA",3472,79.03,15.71,2016
153 | "LHR","EWR","VS",722,82.27,9.48,2016
154 | "LHR","IAD","BA",1415,71.59,17.44,2016
155 | "LHR","IAD","UA",2134,82.05,13.24,2016
156 | "LHR","IAD","VS",699,84.69,8.02,2016
157 | "LCY","JFK","BA",921,90.01,5.26,2016
158 | "LTN","EWR","DJT",333,87.05,8.44,2016
159 |
--------------------------------------------------------------------------------
/js/editor.js:
--------------------------------------------------------------------------------
1 | // For Editor Operations
2 | // const visdown = window.visdown
3 | // const vega = window.vega
4 | // const vl = window.vl
5 | // const marked = window.marked
6 | // const YAML = window.yaml
7 |
8 | /**
9 | * Calculate a 32 bit FNV-1a hash
10 | * Found here: https://gist.github.com/vaiorabbit/5657561
11 | * Ref.: http://isthe.com/chongo/tech/comp/fnv/
12 | *
13 | * @param {string} str the input value
14 | * @param {integer} [seed] optionally pass the hash of the previous chunk
15 | * @returns {string}
16 | */
17 | function _hashFnv32a(str, seed) {
18 | /*jshint bitwise:false */
19 | var i, l, hval = (seed === undefined) ? 0x811c9dc5 : seed;
20 | for (i = 0, l = str.length; i < l; i++) {
21 | hval ^= str.charCodeAt(i);
22 | hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
23 | }
24 | // Convert to 8 digit hex string
25 | return ("0000000" + (hval >>> 0).toString(16)).substr(-8);
26 | }
27 |
28 |
29 | // Regex for getting vis code blocks and extracting viscode
30 | const re = /^((```)vis\s([\s\S]+?)(^\2)\s)/gm
31 | const newline = /\n/gm
32 | const visStart = /^```vis\s*\n/gm
33 | const visEnd = /^```\s*\n/gm
34 |
35 | function _countNewline(str){
36 | if (str === "") {return 0 } else {
37 | let newlineMatch = str.match(newline)
38 | if (newlineMatch === null) {return 0}
39 | let len = newlineMatch.length
40 | return len
41 | }
42 | }
43 |
44 | function _getVisText(str){
45 | let visText = str.split(visStart)[1].split(visEnd)[0]
46 | return visText
47 | }
48 |
49 | // Create Keys to work with CodeMirror Lines
50 | function _keys(str) {
51 | let visCode = str.match(re) || [];
52 | let nCount = str.match(newline);
53 | let keys = []
54 | let checkString = str
55 | let start = 0
56 | visCode.forEach(function(code, i){
57 | let visText = _getVisText(code);
58 | let spec = YAML.parse(visText)
59 | let hash = _hashFnv32a(visText.trim());
60 | console.log(spec, code, hash);
61 | startIndex = checkString.indexOf(code)
62 | codeLength = code.length
63 | endIndex = startIndex + codeLength;
64 | beforeString = checkString.substring(0, startIndex+1);
65 | startLine = start + _countNewline(beforeString);
66 | codeLine = _countNewline(code)
67 | endLine = startLine + codeLine - 1
68 | checkString = checkString.substring(endIndex);
69 | keys.push({
70 | "key": i, "code": code, "spec": spec, "hash": hash,
71 | "lines": codeLine, "start": startLine, "end": endLine})
72 | start = endLine + 1
73 | })
74 | console.log(keys);
75 | return keys
76 | }
77 |
78 | const opts = {
79 | "mode": "vega-lite",
80 | "renderer": "svg",
81 | "actions": {export: true, source: false, editor: false}
82 | };
83 |
84 | let widgets = []
85 | function update() {
86 |
87 | editor.operation(function(){
88 |
89 | keys = _keys(editor.getValue());
90 |
91 | // ENTER + UPDATE - Add all new widgets and Update Vis if changed
92 | keys.forEach(function(key, i){
93 | let endLine = key.end
94 | let spec = key.spec
95 | let el;
96 | console.log(editor.lineInfo(endLine)[widgets])
97 | // ENTER - Add new widget when none exists
98 | if (editor.lineInfo(endLine).widgets === undefined) {
99 | el = document.createElement("div");
100 | el.style.minHeight = 256 + 'px';
101 | elVis = el.appendChild(document.createElement("div"));
102 | elVis.id = "vis-editor-" + i;
103 | elVis.setAttribute('data-hash', key.hash);
104 | editor.addLineWidget(endLine, el);
105 | vegaEmbed(elVis, spec, opts)
106 | console.log(el);
107 | } else {
108 | node = editor.lineInfo(endLine).widgets[0].node
109 | console.log(node)
110 | hash = node.getAttribute('data-hash')
111 | console.log(hash, key.hash)
112 | if (hash != key.hash) {
113 | node.setAttribute('data-hash', key.hash);
114 | vegaEmbed(node, spec, opts);
115 | }
116 | }
117 | })
118 |
119 | // EXIT - Remove all widgets that should no longer exist
120 |
121 |
122 | })
123 |
124 | }
125 |
126 |
127 | // Returns a function, that, as long as it continues to be invoked, will not
128 | // be triggered. The function will be called after it stops being called for
129 | // N milliseconds. If `immediate` is passed, trigger the function on the
130 | // leading edge, instead of the trailing.
131 | function _debounce(func, wait, immediate) {
132 | var timeout;
133 | return function() {
134 | var context = this, args = arguments;
135 | var later = function() {
136 | timeout = null;
137 | if (!immediate) func.apply(context, args);
138 | };
139 | var callNow = immediate && !timeout;
140 | clearTimeout(timeout);
141 | timeout = setTimeout(later, wait);
142 | if (callNow) func.apply(context, args);
143 | };
144 | };
145 |
146 |
147 |
148 | window.onload = function () {
149 |
150 | // Need to have vega, vega-lite and marked as dependencies
151 | const vega = window.vega
152 | const vl = window.vl
153 | const marked = window.marked
154 | const YAML = window.yaml
155 |
156 | // Codemirror setup
157 | let sc = document.getElementById("input-text");
158 | let content = sc.textContent || sc.innerText || sc.innerHTML;
159 |
160 | window.editor = CodeMirror.fromTextArea(sc, {
161 | lineNumbers: false,
162 | lineWrapping: true,
163 | mode: "markdown",
164 | value: content,
165 | });
166 |
167 | function _getChapter () {
168 | let hash = window.location.hash
169 | let file = hash.replace("#", "");
170 | let fileName = file == "" ? "intro.md" : file + ".md";
171 | let fileUrl = "pages/" + fileName;
172 |
173 | fetch(fileUrl).then(data => data.text()).then(data => {
174 | editor.setValue(data);
175 | });
176 | }
177 |
178 | window.onhashchange = function () {_getChapter();}
179 | _getChapter();
180 |
181 | text = editor.getValue()
182 | elInput = document.getElementById("input");
183 | elCodemirror = editor.getWrapperElement()
184 | elOutput = document.getElementById("output");
185 | elEditor = document.getElementById("editor");
186 | elView = document.getElementById("view")
187 | elEdit = document.getElementById("edit")
188 | elContrast = document.getElementById("contrast")
189 |
190 | // function changeContrast( event ){
191 | // elEditor.style.backgroundColor = "white";
192 |
193 | // }
194 |
195 | // let darkLayout = false;
196 | // function changeContrast ( event ) {
197 | // if ( darkLayout === false ) {
198 | // document.body.className = 'yang';
199 | // elCodemirror.style.backgroundColor = "#111"
200 | // elCodemirror.style.color = "#FDFDFD"
201 | // } else {
202 | // document.body.className = 'yin';
203 | // elCodemirror.style.backgroundColor = "#FDFDFD"
204 | // elCodemirror.style.color = "#111"
205 | // }
206 | // console.log(darkLayout)
207 | // darkLayout = !darkLayout;
208 | // }
209 |
210 | function showOutput( event ) {
211 | console.log("showOutput")
212 | elView.style.display = "none"
213 | elEdit.style.display = "block"
214 | elInput.style.display = "none";
215 | elOutput.style.display = "block";
216 | visdown(text, elOutput);
217 | }
218 |
219 | function showInput( event) {
220 | elView.style.display = "block"
221 | elEdit.style.display = "none"
222 | elInput.style.display = "block";
223 | elOutput.style.display = "none";
224 | }
225 |
226 | elView.onclick = showOutput
227 | elEdit.onclick = showInput
228 | // elContrast.onclick = changeContrast
229 |
230 | var waiting;
231 | //Run on editor change
232 | editor.on("change", function() {
233 | text = editor.getValue();
234 | clearTimeout(waiting);
235 | waiting = setTimeout(update, 500);
236 | });
237 |
238 | //setTimeout(update, 100);
239 |
240 | }
--------------------------------------------------------------------------------
/static/css/codemirror.css:
--------------------------------------------------------------------------------
1 | /* BASICS */
2 |
3 | .CodeMirror {
4 | /* Set height, width, borders, and global font properties here */
5 | font-family: monospace;
6 | height: 300px;
7 | color: black;
8 | }
9 |
10 | /* PADDING */
11 |
12 | .CodeMirror-lines {
13 | padding: 4px 0; /* Vertical padding around content */
14 | }
15 | .CodeMirror pre {
16 | padding: 0 4px; /* Horizontal padding of content */
17 | }
18 |
19 | .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
20 | background-color: white; /* The little square between H and V scrollbars */
21 | }
22 |
23 | /* GUTTER */
24 |
25 | .CodeMirror-gutters {
26 | border-right: 1px solid #ddd;
27 | background-color: #f7f7f7;
28 | white-space: nowrap;
29 | }
30 | .CodeMirror-linenumbers {}
31 | .CodeMirror-linenumber {
32 | padding: 0 3px 0 5px;
33 | min-width: 20px;
34 | text-align: right;
35 | color: #999;
36 | white-space: nowrap;
37 | }
38 |
39 | .CodeMirror-guttermarker { color: black; }
40 | .CodeMirror-guttermarker-subtle { color: #999; }
41 |
42 | /* CURSOR */
43 |
44 | .CodeMirror-cursor {
45 | border-left: 1px solid black;
46 | border-right: none;
47 | width: 0;
48 | }
49 | /* Shown when moving in bi-directional text */
50 | .CodeMirror div.CodeMirror-secondarycursor {
51 | border-left: 1px solid silver;
52 | }
53 | .cm-fat-cursor .CodeMirror-cursor {
54 | width: auto;
55 | border: 0 !important;
56 | background: #7e7;
57 | }
58 | .cm-fat-cursor div.CodeMirror-cursors {
59 | z-index: 1;
60 | }
61 |
62 | .cm-animate-fat-cursor {
63 | width: auto;
64 | border: 0;
65 | -webkit-animation: blink 1.06s steps(1) infinite;
66 | -moz-animation: blink 1.06s steps(1) infinite;
67 | animation: blink 1.06s steps(1) infinite;
68 | background-color: #7e7;
69 | }
70 | @-moz-keyframes blink {
71 | 0% {}
72 | 50% { background-color: transparent; }
73 | 100% {}
74 | }
75 | @-webkit-keyframes blink {
76 | 0% {}
77 | 50% { background-color: transparent; }
78 | 100% {}
79 | }
80 | @keyframes blink {
81 | 0% {}
82 | 50% { background-color: transparent; }
83 | 100% {}
84 | }
85 |
86 | /* Can style cursor different in overwrite (non-insert) mode */
87 | .CodeMirror-overwrite .CodeMirror-cursor {}
88 |
89 | .cm-tab { display: inline-block; text-decoration: inherit; }
90 |
91 | .CodeMirror-rulers {
92 | position: absolute;
93 | left: 0; right: 0; top: -50px; bottom: -20px;
94 | overflow: hidden;
95 | }
96 | .CodeMirror-ruler {
97 | border-left: 1px solid #ccc;
98 | top: 0; bottom: 0;
99 | position: absolute;
100 | }
101 |
102 | /* DEFAULT THEME */
103 |
104 | .cm-s-default .cm-header {color: blue;}
105 | .cm-s-default .cm-quote {color: #090;}
106 | .cm-negative {color: #d44;}
107 | .cm-positive {color: #292;}
108 | .cm-header, .cm-strong {font-weight: bold;}
109 | .cm-em {font-style: italic;}
110 | .cm-link {text-decoration: underline;}
111 | .cm-strikethrough {text-decoration: line-through;}
112 |
113 | .cm-s-default .cm-keyword {color: #708;}
114 | .cm-s-default .cm-atom {color: #219;}
115 | .cm-s-default .cm-number {color: #164;}
116 | .cm-s-default .cm-def {color: #00f;}
117 | .cm-s-default .cm-variable,
118 | .cm-s-default .cm-punctuation,
119 | .cm-s-default .cm-property,
120 | .cm-s-default .cm-operator {}
121 | .cm-s-default .cm-variable-2 {color: #05a;}
122 | .cm-s-default .cm-variable-3 {color: #085;}
123 | .cm-s-default .cm-comment {color: #a50;}
124 | .cm-s-default .cm-string {color: #a11;}
125 | .cm-s-default .cm-string-2 {color: #f50;}
126 | .cm-s-default .cm-meta {color: #555;}
127 | .cm-s-default .cm-qualifier {color: #555;}
128 | .cm-s-default .cm-builtin {color: #30a;}
129 | .cm-s-default .cm-bracket {color: #997;}
130 | .cm-s-default .cm-tag {color: #170;}
131 | .cm-s-default .cm-attribute {color: #00c;}
132 | .cm-s-default .cm-hr {color: #999;}
133 | .cm-s-default .cm-link {color: #00c;}
134 |
135 | .cm-s-default .cm-error {color: #f00;}
136 | .cm-invalidchar {color: #f00;}
137 |
138 | .CodeMirror-composing { border-bottom: 2px solid; }
139 |
140 | /* Default styles for common addons */
141 |
142 | div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
143 | div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
144 | .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
145 | .CodeMirror-activeline-background {background: #e8f2ff;}
146 |
147 | /* STOP */
148 |
149 | /* The rest of this file contains styles related to the mechanics of
150 | the editor. You probably shouldn't touch them. */
151 |
152 | .CodeMirror {
153 | position: relative;
154 | overflow: hidden;
155 | background: white;
156 | }
157 |
158 | .CodeMirror-scroll {
159 | overflow: scroll !important; /* Things will break if this is overridden */
160 | /* 30px is the magic margin used to hide the element's real scrollbars */
161 | /* See overflow: hidden in .CodeMirror */
162 | margin-bottom: -30px; margin-right: -30px;
163 | padding-bottom: 30px;
164 | height: 100%;
165 | outline: none; /* Prevent dragging from highlighting the element */
166 | position: relative;
167 | }
168 | .CodeMirror-sizer {
169 | position: relative;
170 | border-right: 30px solid transparent;
171 | }
172 |
173 | /* The fake, visible scrollbars. Used to force redraw during scrolling
174 | before actual scrolling happens, thus preventing shaking and
175 | flickering artifacts. */
176 | .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
177 | position: absolute;
178 | z-index: 6;
179 | display: none;
180 | }
181 | .CodeMirror-vscrollbar {
182 | right: 0; top: 0;
183 | overflow-x: hidden;
184 | overflow-y: scroll;
185 | }
186 | .CodeMirror-hscrollbar {
187 | bottom: 0; left: 0;
188 | overflow-y: hidden;
189 | overflow-x: scroll;
190 | }
191 | .CodeMirror-scrollbar-filler {
192 | right: 0; bottom: 0;
193 | }
194 | .CodeMirror-gutter-filler {
195 | left: 0; bottom: 0;
196 | }
197 |
198 | .CodeMirror-gutters {
199 | position: absolute; left: 0; top: 0;
200 | min-height: 100%;
201 | z-index: 3;
202 | }
203 | .CodeMirror-gutter {
204 | white-space: normal;
205 | height: 100%;
206 | display: inline-block;
207 | vertical-align: top;
208 | margin-bottom: -30px;
209 | }
210 | .CodeMirror-gutter-wrapper {
211 | position: absolute;
212 | z-index: 4;
213 | background: none !important;
214 | border: none !important;
215 | }
216 | .CodeMirror-gutter-background {
217 | position: absolute;
218 | top: 0; bottom: 0;
219 | z-index: 4;
220 | }
221 | .CodeMirror-gutter-elt {
222 | position: absolute;
223 | cursor: default;
224 | z-index: 4;
225 | }
226 | .CodeMirror-gutter-wrapper {
227 | -webkit-user-select: none;
228 | -moz-user-select: none;
229 | user-select: none;
230 | }
231 |
232 | .CodeMirror-lines {
233 | cursor: text;
234 | min-height: 1px; /* prevents collapsing before first draw */
235 | }
236 | .CodeMirror pre {
237 | /* Reset some styles that the rest of the page might have set */
238 | -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
239 | border-width: 0;
240 | background: transparent;
241 | font-family: inherit;
242 | font-size: inherit;
243 | margin: 0;
244 | white-space: pre;
245 | word-wrap: normal;
246 | line-height: inherit;
247 | color: inherit;
248 | z-index: 2;
249 | position: relative;
250 | overflow: visible;
251 | -webkit-tap-highlight-color: transparent;
252 | -webkit-font-variant-ligatures: contextual;
253 | font-variant-ligatures: contextual;
254 | }
255 | .CodeMirror-wrap pre {
256 | word-wrap: break-word;
257 | white-space: pre-wrap;
258 | word-break: normal;
259 | }
260 |
261 | .CodeMirror-linebackground {
262 | position: absolute;
263 | left: 0; right: 0; top: 0; bottom: 0;
264 | z-index: 0;
265 | }
266 |
267 | .CodeMirror-linewidget {
268 | position: relative;
269 | z-index: 2;
270 | overflow: auto;
271 | }
272 |
273 | .CodeMirror-widget {}
274 |
275 | .CodeMirror-code {
276 | outline: none;
277 | }
278 |
279 | /* Force content-box sizing for the elements where we expect it */
280 | .CodeMirror-scroll,
281 | .CodeMirror-sizer,
282 | .CodeMirror-gutter,
283 | .CodeMirror-gutters,
284 | .CodeMirror-linenumber {
285 | -moz-box-sizing: content-box;
286 | box-sizing: content-box;
287 | }
288 |
289 | .CodeMirror-measure {
290 | position: absolute;
291 | width: 100%;
292 | height: 0;
293 | overflow: hidden;
294 | visibility: hidden;
295 | }
296 |
297 | .CodeMirror-cursor {
298 | position: absolute;
299 | pointer-events: none;
300 | }
301 | .CodeMirror-measure pre { position: static; }
302 |
303 | div.CodeMirror-cursors {
304 | visibility: hidden;
305 | position: relative;
306 | z-index: 3;
307 | }
308 | div.CodeMirror-dragcursors {
309 | visibility: visible;
310 | }
311 |
312 | .CodeMirror-focused div.CodeMirror-cursors {
313 | visibility: visible;
314 | }
315 |
316 | .CodeMirror-selected { background: #d9d9d9; }
317 | .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
318 | .CodeMirror-crosshair { cursor: crosshair; }
319 | .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
320 | .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
321 |
322 | .cm-searching {
323 | background: #ffa;
324 | background: rgba(255, 255, 0, .4);
325 | }
326 |
327 | /* Used to force a border model for a node */
328 | .cm-force-border { padding-right: .1px; }
329 |
330 | @media print {
331 | /* Hide the cursor when printing */
332 | .CodeMirror div.CodeMirror-cursors {
333 | visibility: hidden;
334 | }
335 | }
336 |
337 | /* See issue #2901 */
338 | .cm-tab-wrap-hack:after { content: ''; }
339 |
340 | /* Help users use markselection to safely style text background */
341 | span.CodeMirror-selectedtext { background: none; }
342 |
--------------------------------------------------------------------------------
/static/css/github-markdown.css:
--------------------------------------------------------------------------------
1 | @font-face{font-family:octicons-link;src:url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format('woff')}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;line-height:1.5;color:#24292e;font-family:-apple-system,system-ui,BlinkMacSystemFont,segoe ui,Helvetica,Arial,sans-serif,apple color emoji,segoe ui emoji,segoe ui symbol;font-size:16px;line-height:1.5;word-wrap:break-word}.markdown-body .pl-c{color:#969896}.markdown-body .pl-c1,.markdown-body .pl-s .pl-v{color:#0086b3}.markdown-body .pl-e,.markdown-body .pl-en{color:#795da3}.markdown-body .pl-smi,.markdown-body .pl-s .pl-s1{color:#333}.markdown-body .pl-ent{color:#63a35c}.markdown-body .pl-k{color:#a71d5d}.markdown-body .pl-s,.markdown-body .pl-pds,.markdown-body .pl-s .pl-pse .pl-s1,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sre,.markdown-body .pl-sr .pl-sra{color:#183691}.markdown-body .pl-v,.markdown-body .pl-smw{color:#ed6a43}.markdown-body .pl-bu{color:#b52a1d}.markdown-body .pl-ii{color:#f8f8f8;background-color:#b52a1d}.markdown-body .pl-c2{color:#f8f8f8;background-color:#b52a1d}.markdown-body .pl-c2::before{content:"^M"}.markdown-body .pl-sr .pl-cce{font-weight:700;color:#63a35c}.markdown-body .pl-ml{color:#693a17}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{font-weight:700;color:#1d3e81}.markdown-body .pl-mq{color:teal}.markdown-body .pl-mi{font-style:italic;color:#333}.markdown-body .pl-mb{font-weight:700;color:#333}.markdown-body .pl-md{color:#bd2c00;background-color:#ffecec}.markdown-body .pl-mi1{color:#55a532;background-color:#eaffea}.markdown-body .pl-mc{color:#ef9700;background-color:#ffe3b4}.markdown-body .pl-mi2{color:#d8d8d8;background-color:gray}.markdown-body .pl-mdr{font-weight:700;color:#795da3}.markdown-body .pl-mo{color:#1d3e81}.markdown-body .pl-ba{color:#595e62}.markdown-body .pl-sg{color:silver}.markdown-body .pl-corl{text-decoration:underline;color:#183691}.markdown-body .octicon{display:inline-block;vertical-align:text-top;fill:currentColor}.markdown-body a{background-color:transparent;-webkit-text-decoration-skip:objects}.markdown-body a:active,.markdown-body a:hover{outline-width:0}.markdown-body strong{font-weight:inherit}.markdown-body strong{font-weight:bolder}.markdown-body h1{font-size:2em;margin:.67em 0}.markdown-body img{border-style:none}.markdown-body svg:not(:root){overflow:hidden}.markdown-body code,.markdown-body kbd,.markdown-body pre{font-family:monospace,monospace;font-size:1em}.markdown-body hr{box-sizing:content-box;height:0;overflow:visible}.markdown-body input{font:inherit;margin:0}.markdown-body input{overflow:visible}.markdown-body [type=checkbox]{box-sizing:border-box;padding:0}.markdown-body *{box-sizing:border-box}.markdown-body input{font-family:inherit;font-size:inherit;line-height:inherit}.markdown-body a{color:#0366d6;text-decoration:none}.markdown-body a:hover{text-decoration:underline}.markdown-body strong{font-weight:600}.markdown-body hr{height:0;margin:15px 0;overflow:hidden;background:transparent;border:0;border-bottom:1px solid #dfe2e5}.markdown-body hr::before{display:table;content:""}.markdown-body hr::after{display:table;clear:both;content:""}.markdown-body table{border-spacing:0;border-collapse:collapse}.markdown-body td,.markdown-body th{padding:0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:0;margin-bottom:0}.markdown-body h1{font-size:32px;font-weight:600}.markdown-body h2{font-size:24px;font-weight:600}.markdown-body h3{font-size:20px;font-weight:600}.markdown-body h4{font-size:16px;font-weight:600}.markdown-body h5{font-size:14px;font-weight:600}.markdown-body h6{font-size:12px;font-weight:600}.markdown-body p{margin-top:0;margin-bottom:10px}.markdown-body blockquote{margin:0}.markdown-body ul,.markdown-body ol{padding-left:0;margin-top:0;margin-bottom:0}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ul ul ol,.markdown-body ul ol ol,.markdown-body ol ul ol,.markdown-body ol ol ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code{font-family:sfmono-regular,Consolas,liberation mono,Menlo,Courier,monospace;font-size:12px}.markdown-body pre{margin-top:0;margin-bottom:0;font:12px sfmono-regular,Consolas,liberation mono,Menlo,Courier,monospace}.markdown-body .octicon{vertical-align:text-bottom}.markdown-body .pl-0{padding-left:0!important}.markdown-body .pl-1{padding-left:4px!important}.markdown-body .pl-2{padding-left:8px!important}.markdown-body .pl-3{padding-left:16px!important}.markdown-body .pl-4{padding-left:24px!important}.markdown-body .pl-5{padding-left:32px!important}.markdown-body .pl-6{padding-left:40px!important}.markdown-body::before{display:table;content:""}.markdown-body::after{display:table;clear:both;content:""}.markdown-body>*:first-child{margin-top:0!important}.markdown-body>*:last-child{margin-bottom:0!important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body .anchor{float:left;padding-right:4px;margin-left:-20px;line-height:1}.markdown-body .anchor:focus{outline:0}.markdown-body p,.markdown-body blockquote,.markdown-body ul,.markdown-body ol,.markdown-body dl,.markdown-body table,.markdown-body pre{margin-top:0;margin-bottom:16px}.markdown-body hr{height:.25em;padding:0;margin:24px 0;background-color:#e1e4e8;border:0}.markdown-body blockquote{padding:0 1em;color:#6a737d;border-left:.25em solid #dfe2e5}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body kbd{display:inline-block;padding:3px 5px;font-size:11px;line-height:10px;color:#444d56;vertical-align:middle;background-color:#fafbfc;border:solid 1px #c6cbd1;border-bottom-color:#959da5;border-radius:3px;box-shadow:inset 0 -1px 0 #959da5}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:24px;margin-bottom:16px;font-weight:600;line-height:1.25}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{color:#1b1f23;vertical-align:middle;visibility:hidden}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{visibility:visible}.markdown-body h1{padding-bottom:.3em;font-size:2em;border-bottom:1px solid #eaecef}.markdown-body h2{padding-bottom:.3em;font-size:1.5em;border-bottom:1px solid #eaecef}.markdown-body h3{font-size:1.25em}.markdown-body h4{font-size:1em}.markdown-body h5{font-size:.875em}.markdown-body h6{font-size:.85em;color:#6a737d}.markdown-body ul,.markdown-body ol{padding-left:2em}.markdown-body ul ul,.markdown-body ul ol,.markdown-body ol ol,.markdown-body ol ul{margin-top:0;margin-bottom:0}.markdown-body li>p{margin-top:16px}.markdown-body li+li{margin-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:600}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body table{display:block;width:100%;overflow:auto}.markdown-body table th{font-weight:600}.markdown-body table th,.markdown-body table td{padding:6px 13px;border:1px solid #dfe2e5}.markdown-body table tr{background-color:#fff;border-top:1px solid #c6cbd1}.markdown-body table tr:nth-child(2n){background-color:#f6f8fa}.markdown-body img{max-width:100%;box-sizing:content-box;background-color:#fff}.markdown-body code{padding:0;padding-top:.2em;padding-bottom:.2em;margin:0;font-size:85%;background-color:rgba(27,31,35,.05);border-radius:3px}.markdown-body code::before,.markdown-body code::after{letter-spacing:-.2em;content:"\00a0"}.markdown-body pre{word-wrap:normal}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:transparent;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f6f8fa;border-radius:3px}.markdown-body pre code{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body pre code::before,.markdown-body pre code::after{content:normal}.markdown-body .full-commit .btn-outline:not(:disabled):hover{color:#005cc5;border-color:#005cc5}.markdown-body kbd{display:inline-block;padding:3px 5px;font:11px sfmono-regular,Consolas,liberation mono,Menlo,Courier,monospace;line-height:10px;color:#444d56;vertical-align:middle;background-color:#fcfcfc;border:solid 1px #c6cbd1;border-bottom-color:#959da5;border-radius:3px;box-shadow:inset 0 -1px 0 #959da5}.markdown-body :checked+.radio-label{position:relative;z-index:1;border-color:#0366d6}.markdown-body .task-list-item{list-style-type:none}.markdown-body .task-list-item+.task-list-item{margin-top:3px}.markdown-body .task-list-item input{margin:0 .2em .25em -1.6em;vertical-align:middle}.markdown-body hr{border-bottom-color:#eee}
--------------------------------------------------------------------------------
/data/notes.csv:
--------------------------------------------------------------------------------
1 | year,money,type,denom,value,number
2 | 1977,2.72,Notes,0001,1,2.72
3 | 1977,0.55,Notes,1000,1000,0.001
4 | 1977,1.48,Notes,0002,2,0.74
5 | 1977,9.95,Notes,0050,50,0.199
6 | 1977,6.9,Notes,0020,20,0.345
7 | 1977,43.02,Notes,0100,100,0.43
8 | 1977,,Notes,0500,500,
9 | 1977,18.25,Notes,0010,10,1.825
10 | 1977,5.72,Notes,0005,5,1.144
11 | 1978,,Notes,0500,500,
12 | 1978,19.57,Notes,0010,10,1.957
13 | 1978,14.4,Notes,0050,50,0.288
14 | 1978,5.76,Notes,0005,5,1.152
15 | 1978,7.79,Notes,0020,20,0.39
16 | 1978,2.56,Notes,0001,1,2.56
17 | 1978,,Notes,1000,1000,
18 | 1978,53.69,Notes,0100,100,0.537
19 | 1978,1.74,Notes,0002,2,0.87
20 | 1979,59.51,Notes,0100,100,0.595
21 | 1979,,Notes,1000,1000,
22 | 1979,9.61,Notes,0020,20,0.48
23 | 1979,2.15,Notes,0002,2,1.075
24 | 1979,5.88,Notes,0005,5,1.176
25 | 1979,19.83,Notes,0050,50,0.397
26 | 1979,,Notes,0500,500,
27 | 1979,21.23,Notes,0010,10,2.123
28 | 1979,2.14,Notes,0001,1,2.14
29 | 1980,6.34,Notes,0005,5,1.268
30 | 1980,74.06,Notes,0100,100,0.741
31 | 1980,,Notes,0500,500,
32 | 1980,20.97,Notes,0010,10,2.097
33 | 1980,,Notes,1000,1000,
34 | 1980,2.99,Notes,0002,2,1.495
35 | 1980,2.07,Notes,0001,1,2.07
36 | 1980,10.9,Notes,0020,20,0.545
37 | 1980,22.06,Notes,0050,50,0.441
38 | 1981,,Notes,1000,1000,
39 | 1981,6.92,Notes,0005,5,1.384
40 | 1981,2.12,Notes,0001,1,2.12
41 | 1981,,Notes,0500,500,
42 | 1981,27.24,Notes,0050,50,0.545
43 | 1981,19.91,Notes,0010,10,1.991
44 | 1981,78.29,Notes,0100,100,0.783
45 | 1981,3.92,Notes,0002,2,1.96
46 | 1981,12.14,Notes,0020,20,0.607
47 | 1982,,Notes,1000,1000,
48 | 1982,30.17,Notes,0050,50,0.603
49 | 1982,97.77,Notes,0100,100,0.978
50 | 1982,2.05,Notes,0001,1,2.05
51 | 1982,,Notes,0500,500,
52 | 1982,17.98,Notes,0010,10,1.798
53 | 1982,14.33,Notes,0020,20,0.716
54 | 1982,4.31,Notes,0002,2,2.155
55 | 1982,8.07,Notes,0005,5,1.614
56 | 1983,5.6,Notes,0005,5,1.12
57 | 1983,1.98,Notes,0001,1,1.98
58 | 1983,4.5,Notes,0002,2,2.25
59 | 1983,,Notes,1000,1000,
60 | 1983,14.63,Notes,0020,20,0.732
61 | 1983,36.26,Notes,0050,50,0.725
62 | 1983,116.9,Notes,0100,100,1.169
63 | 1983,,Notes,0500,500,
64 | 1983,17.7,Notes,0010,10,1.77
65 | 1984,,Notes,1000,1000,
66 | 1984,2.04,Notes,0001,1,2.04
67 | 1984,39.2,Notes,0050,50,0.784
68 | 1984,,Notes,0500,500,
69 | 1984,22.17,Notes,0010,10,2.217
70 | 1984,12.34,Notes,0005,5,2.468
71 | 1984,139.04,Notes,0100,100,1.39
72 | 1984,16.36,Notes,0020,20,0.818
73 | 1984,5.8,Notes,0002,2,2.9
74 | 1985,25.36,Notes,0010,10,2.536
75 | 1985,,Notes,1000,1000,
76 | 1985,6.5,Notes,0002,2,3.25
77 | 1985,13.03,Notes,0005,5,2.606
78 | 1985,2.38,Notes,0001,1,2.38
79 | 1985,17.84,Notes,0020,20,0.892
80 | 1985,43.1,Notes,0050,50,0.862
81 | 1985,150.18,Notes,0100,100,1.502
82 | 1985,,Notes,0500,500,
83 | 1986,52.47,Notes,0050,50,1.049
84 | 1986,25.1,Notes,0010,10,2.51
85 | 1986,18.99,Notes,0020,20,0.949
86 | 1986,171.16,Notes,0100,100,1.712
87 | 1986,12.87,Notes,0005,5,2.574
88 | 1986,6.83,Notes,0002,2,3.415
89 | 1986,,Notes,1000,1000,
90 | 1986,,Notes,0500,500,
91 | 1986,3.01,Notes,0001,1,3.01
92 | 1987,1.8,Notes,0500,500,0.004
93 | 1987,6.53,Notes,0002,2,3.265
94 | 1987,28.25,Notes,0010,10,2.825
95 | 1987,190.77,Notes,0100,100,1.908
96 | 1987,,Notes,1000,1000,
97 | 1987,72.67,Notes,0050,50,1.453
98 | 1987,14.29,Notes,0005,5,2.858
99 | 1987,23.31,Notes,0020,20,1.166
100 | 1987,3.52,Notes,0001,1,3.52
101 | 1988,3.6,Notes,0001,1,3.6
102 | 1988,14.82,Notes,0005,5,2.964
103 | 1988,29.96,Notes,0010,10,2.996
104 | 1988,,Notes,1000,1000,
105 | 1988,6.81,Notes,0002,2,3.405
106 | 1988,212.08,Notes,0100,100,2.121
107 | 1988,26.13,Notes,0020,20,1.306
108 | 1988,2.3,Notes,0500,500,0.005
109 | 1988,94.59,Notes,0050,50,1.892
110 | 1989,17.39,Notes,0005,5,3.478
111 | 1989,35.15,Notes,0010,10,3.515
112 | 1989,31.0,Notes,0020,20,1.55
113 | 1989,12.57,Notes,0500,500,0.025
114 | 1989,125.53,Notes,0050,50,2.511
115 | 1989,237.78,Notes,0100,100,2.378
116 | 1989,,Notes,1000,1000,
117 | 1989,3.48,Notes,0001,1,3.48
118 | 1989,8.04,Notes,0002,2,4.02
119 | 1990,,Notes,1000,1000,
120 | 1990,3.35,Notes,0001,1,3.35
121 | 1990,29.52,Notes,0020,20,1.476
122 | 1990,148.12,Notes,0050,50,2.962
123 | 1990,37.85,Notes,0010,10,3.785
124 | 1990,245.7,Notes,0100,100,2.457
125 | 1990,21.77,Notes,0500,500,0.044
126 | 1990,18.1,Notes,0005,5,3.62
127 | 1990,8.83,Notes,0002,2,4.415
128 | 1991,9.42,Notes,0002,2,4.71
129 | 1991,18.54,Notes,0500,500,0.037
130 | 1991,27.43,Notes,0020,20,1.372
131 | 1991,24.0,Notes,0005,5,4.8
132 | 1991,177.19,Notes,0050,50,3.544
133 | 1991,52.02,Notes,0010,10,5.202
134 | 1991,3.35,Notes,0001,1,3.35
135 | 1991,322.66,Notes,0100,100,3.227
136 | 1991,,Notes,1000,1000,
137 | 1992,49.1,Notes,0500,500,0.098
138 | 1992,225.77,Notes,0050,50,4.515
139 | 1992,3.35,Notes,0001,1,3.35
140 | 1992,42.85,Notes,0010,10,4.285
141 | 1992,20.22,Notes,0005,5,4.044
142 | 1992,23.4,Notes,0020,20,1.17
143 | 1992,7.2,Notes,0002,2,3.6
144 | 1992,,Notes,1000,1000,
145 | 1992,326.63,Notes,0100,100,3.266
146 | 1993,,Notes,1000,1000,
147 | 1993,3.28,Notes,0001,1,3.28
148 | 1993,18.6,Notes,0005,5,3.72
149 | 1993,16.31,Notes,0020,20,0.815
150 | 1993,377.84,Notes,0100,100,3.778
151 | 1993,6.24,Notes,0002,2,3.12
152 | 1993,53.34,Notes,0010,10,5.334
153 | 1993,249.91,Notes,0050,50,4.998
154 | 1993,113.03,Notes,0500,500,0.226
155 | 1994,464.57,Notes,0100,100,4.646
156 | 1994,285.37,Notes,0050,50,5.707
157 | 1994,6.02,Notes,0002,2,3.01
158 | 1994,,Notes,1000,1000,
159 | 1994,11.2,Notes,0020,20,0.56
160 | 1994,3.2,Notes,0001,1,3.2
161 | 1994,168.82,Notes,0500,500,0.338
162 | 1994,69.43,Notes,0010,10,6.943
163 | 1994,17.65,Notes,0005,5,3.53
164 | 1995,5.15,Notes,0002,2,2.575
165 | 1995,208.73,Notes,0500,500,0.417
166 | 1995,551.05,Notes,0100,100,5.51
167 | 1995,92.18,Notes,0010,10,9.218
168 | 1995,3.22,Notes,0001,1,3.22
169 | 1995,,Notes,1000,1000,
170 | 1995,316.59,Notes,0050,50,6.332
171 | 1995,16.51,Notes,0005,5,3.302
172 | 1995,7.18,Notes,0020,20,0.359
173 | 1996,626.0,Notes,0100,100,6.26
174 | 1996,242.7,Notes,0500,500,0.485
175 | 1996,,Notes,1000,1000,
176 | 1996,336.23,Notes,0050,50,6.725
177 | 1996,7.03,Notes,0020,20,0.352
178 | 1996,15.54,Notes,0005,5,3.108
179 | 1996,3.16,Notes,0001,1,3.16
180 | 1996,5.27,Notes,0002,2,2.635
181 | 1996,110.63,Notes,0010,10,11.063
182 | 1997,3.19,Notes,0001,1,3.19
183 | 1997,,Notes,1000,1000,
184 | 1997,342.45,Notes,0050,50,6.849
185 | 1997,5.5,Notes,0002,2,2.75
186 | 1997,14.27,Notes,0005,5,2.854
187 | 1997,701.59,Notes,0100,100,7.016
188 | 1997,9.79,Notes,0020,20,0.489
189 | 1997,279.75,Notes,0500,500,0.56
190 | 1997,124.12,Notes,0010,10,12.412
191 | 1998,333.16,Notes,0050,50,6.663
192 | 1998,12.9,Notes,0005,5,2.58
193 | 1998,448.27,Notes,0500,500,0.897
194 | 1998,5.3,Notes,0002,2,2.65
195 | 1998,,Notes,1000,1000,
196 | 1998,129.9,Notes,0010,10,12.99
197 | 1998,8.99,Notes,0020,20,0.45
198 | 1998,3.16,Notes,0001,1,3.16
199 | 1998,781.97,Notes,0100,100,7.82
200 | 1999,132.82,Notes,0010,10,13.282
201 | 1999,11.52,Notes,0005,5,2.304
202 | 1999,,Notes,1000,1000,
203 | 1999,3.08,Notes,0001,1,3.08
204 | 1999,5.12,Notes,0002,2,2.56
205 | 1999,858.31,Notes,0100,100,8.583
206 | 1999,572.5,Notes,0500,500,1.145
207 | 1999,10.1,Notes,0020,20,0.505
208 | 1999,332.3,Notes,0050,50,6.646
209 | 2000,328.18,Notes,0050,50,6.564
210 | 2000,529.47,Notes,0500,500,1.059
211 | 2000,123.36,Notes,0010,10,12.336
212 | 2000,10.16,Notes,0005,5,2.032
213 | 2000,4.71,Notes,0002,2,2.355
214 | 2000,10.12,Notes,0020,20,0.506
215 | 2000,1081.41,Notes,0100,100,10.814
216 | 2000,37.19,Notes,1000,1000,0.037
217 | 2000,3.07,Notes,0001,1,3.07
218 | 2001,15.31,Notes,0020,20,0.766
219 | 2001,1180.41,Notes,0100,100,11.804
220 | 2001,71.79,Notes,1000,1000,0.072
221 | 2001,356.01,Notes,0050,50,7.12
222 | 2001,3.08,Notes,0001,1,3.08
223 | 2001,685.12,Notes,0500,500,1.37
224 | 2001,12.64,Notes,0005,5,2.528
225 | 2001,5.38,Notes,0002,2,2.69
226 | 2001,119.89,Notes,0010,10,11.989
227 | 2002,17.39,Notes,0005,5,3.478
228 | 2002,1153.86,Notes,0100,100,11.539
229 | 2002,4.83,Notes,0002,2,2.415
230 | 2002,938.13,Notes,0500,500,1.876
231 | 2002,351.91,Notes,0050,50,7.038
232 | 2002,159.71,Notes,1000,1000,0.16
233 | 2002,3.05,Notes,0001,1,3.05
234 | 2002,34.25,Notes,0020,20,1.712
235 | 2002,90.88,Notes,0010,10,9.088
236 | 2003,1214.42,Notes,0100,100,12.144
237 | 2003,2.99,Notes,0001,1,2.99
238 | 2003,330.27,Notes,0050,50,6.605
239 | 2003,43.83,Notes,0020,20,2.192
240 | 2003,77.5,Notes,0010,10,7.75
241 | 2003,274.73,Notes,1000,1000,0.275
242 | 2003,4.72,Notes,0002,2,2.36
243 | 2003,1229.38,Notes,0500,500,2.459
244 | 2003,22.76,Notes,0005,5,4.552
245 | 2004,1527.28,Notes,0500,500,3.055
246 | 2004,2.99,Notes,0001,1,2.99
247 | 2004,38.76,Notes,0020,20,1.938
248 | 2004,4.62,Notes,0002,2,2.31
249 | 2004,67.7,Notes,0010,10,6.77
250 | 2004,299.41,Notes,0050,50,5.988
251 | 2004,1232.82,Notes,0100,100,12.328
252 | 2004,20.86,Notes,0005,5,4.172
253 | 2004,420.82,Notes,1000,1000,0.421
254 | 2005,40.77,Notes,0020,20,2.038
255 | 2005,1346.37,Notes,0100,100,13.464
256 | 2005,2.99,Notes,0001,1,2.99
257 | 2005,19.8,Notes,0005,5,3.96
258 | 2005,62.74,Notes,0010,10,6.274
259 | 2005,4.51,Notes,0002,2,2.255
260 | 2005,278.42,Notes,0050,50,5.568
261 | 2005,1823.32,Notes,0500,500,3.647
262 | 2005,643.46,Notes,1000,1000,0.643
263 | 2006,936.76,Notes,1000,1000,0.937
264 | 2006,3.01,Notes,0001,1,3.01
265 | 2006,2254.0,Notes,0500,500,4.508
266 | 2006,4.47,Notes,0002,2,2.235
267 | 2006,1354.44,Notes,0100,100,13.544
268 | 2006,18.87,Notes,0005,5,3.774
269 | 2006,279.51,Notes,0050,50,5.59
270 | 2006,71.55,Notes,0010,10,7.155
271 | 2006,41.78,Notes,0020,20,2.089
272 | 2007,1345.75,Notes,0100,100,13.458
273 | 2007,21.11,Notes,0005,5,4.222
274 | 2007,2631.08,Notes,0500,500,5.262
275 | 2007,6.36,Notes,0002,2,3.18
276 | 2007,265.08,Notes,0050,50,5.302
277 | 2007,41.08,Notes,0020,20,2.054
278 | 2007,93.33,Notes,0010,10,9.333
279 | 2007,3.0,Notes,0001,1,3.0
280 | 2007,1412.19,Notes,1000,1000,1.412
281 | 2008,1370.28,Notes,0100,100,13.703
282 | 2008,122.22,Notes,0010,10,12.222
283 | 2008,1917.84,Notes,1000,1000,1.918
284 | 2008,6.65,Notes,0002,2,3.325
285 | 2008,244.4,Notes,0050,50,4.888
286 | 2008,43.99,Notes,0020,20,2.2
287 | 2008,3.0,Notes,0001,1,3.0
288 | 2008,22.71,Notes,0005,5,4.542
289 | 2008,3083.04,Notes,0500,500,6.166
290 | 2009,210.57,Notes,0050,50,4.211
291 | 2009,3644.79,Notes,0500,500,7.29
292 | 2009,1383.64,Notes,0100,100,13.836
293 | 2009,22.33,Notes,0005,5,4.466
294 | 2009,185.36,Notes,0010,10,18.536
295 | 2009,6.98,Notes,0002,2,3.49
296 | 2009,2382.52,Notes,1000,1000,2.383
297 | 2009,2.99,Notes,0001,1,2.99
298 | 2009,46.81,Notes,0020,20,2.34
299 | 2010,4453.11,Notes,0500,500,8.906
300 | 2010,159.8,Notes,0050,50,3.196
301 | 2010,60.4,Notes,0020,20,3.02
302 | 2010,212.88,Notes,0010,10,21.288
303 | 2010,1402.43,Notes,0100,100,14.024
304 | 2010,3027.13,Notes,1000,1000,3.027
305 | 2010,8.51,Notes,0002,2,4.255
306 | 2010,34.3,Notes,0005,5,6.86
307 | 2010,2.99,Notes,0001,1,2.99
308 | 2011,2.99,Notes,0001,1,2.99
309 | 2011,36.43,Notes,0005,5,7.286
310 | 2011,5128.07,Notes,0500,500,10.256
311 | 2011,174.38,Notes,0050,50,3.488
312 | 2011,8.51,Notes,0002,2,4.255
313 | 2011,3468.81,Notes,1000,1000,3.469
314 | 2011,1411.88,Notes,0100,100,14.119
315 | 2011,230.02,Notes,0010,10,23.002
316 | 2011,70.2,Notes,0020,20,3.51
317 | 2012,76.5,Notes,0020,20,3.825
318 | 2012,251.68,Notes,0010,10,25.168
319 | 2012,4299.0,Notes,1000,1000,4.299
320 | 2012,5359.5,Notes,0500,500,10.719
321 | 2012,1442.1,Notes,0100,100,14.421
322 | 2012,8.51,Notes,0002,2,4.255
323 | 2012,173.05,Notes,0050,50,3.461
324 | 2012,36.87,Notes,0005,5,7.374
325 | 2012,2.99,Notes,0001,1,2.99
326 | 2013,2.99,Notes,0001,1,2.99
327 | 2013,5081.37,Notes,1000,1000,5.081
328 | 2013,1476.46,Notes,0100,100,14.765
329 | 2013,8.51,Notes,0002,2,4.255
330 | 2013,37.14,Notes,0005,5,7.428
331 | 2013,85.69,Notes,0020,20,4.284
332 | 2013,5702.48,Notes,0500,500,11.405
333 | 2013,266.48,Notes,0010,10,26.648
334 | 2013,172.42,Notes,0050,50,3.448
335 | 2014,2.99,Notes,0001,1,2.99
336 | 2014,1502.65,Notes,0100,100,15.026
337 | 2014,8.54,Notes,0002,2,4.27
338 | 2014,6563.91,Notes,0500,500,13.128
339 | 2014,5612.45,Notes,1000,1000,5.612
340 | 2014,303.04,Notes,0010,10,30.304
341 | 2014,37.02,Notes,0005,5,7.404
342 | 2014,86.99,Notes,0020,20,4.35
343 | 2014,174.36,Notes,0050,50,3.487
344 | 2015,36.8,Notes,0005,5,7.36
345 | 2015,194.5,Notes,0050,50,3.89
346 | 2015,8.53,Notes,0002,2,4.265
347 | 2015,1577.83,Notes,0100,100,15.778
348 | 2015,98.47,Notes,0020,20,4.924
349 | 2015,7853.75,Notes,0500,500,15.708
350 | 2015,3.09,Notes,0001,1,3.09
351 | 2015,320.15,Notes,0010,10,32.015
352 | 2015,6325.68,Notes,1000,1000,6.326
353 |
--------------------------------------------------------------------------------
/static/lib/markdown.min.js:
--------------------------------------------------------------------------------
1 | !function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror"),require("../xml/xml"),require("../meta")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","../xml/xml","../meta"],t):t(CodeMirror)}(function(t){"use strict";t.defineMode("markdown",function(e,i){function n(i){if(t.findModeByName){var n=t.findModeByName(i);n&&(i=n.mime||n.mimes[0])}var r=t.getMode(e,i);return"null"==r.name?null:r}function r(t,e,i){return e.f=e.inline=i,i(t,e)}function a(t,e,i){return e.f=e.block=i,i(t,e)}function l(t){return!t||!/\S/.test(t.string)}function o(t){return t.linkTitle=!1,t.em=!1,t.strong=!1,t.strikethrough=!1,t.quote=0,t.indentedCode=!1,t.f==s&&(t.f=f,t.block=h),t.trailingSpace=0,t.trailingSpaceNewLine=!1,t.prevLine=t.thisLine,t.thisLine={stream:null},null}function h(e,a){var o=e.column()===a.indentation,h=l(a.prevLine.stream),s=a.indentedCode,u=a.prevLine.hr,f=!1!==a.list,c=(a.listStack[a.listStack.length-1]||0)+3;a.indentedCode=!1;var d=a.indentation;if(null===a.indentationDiff&&(a.indentationDiff=a.indentation,f)){for(a.list=null;d=4&&(s||a.prevLine.fencedCodeEnd||a.prevLine.header||h))return e.skipToEnd(),a.indentedCode=!0,T.code;if(e.eatSpace())return null;if(o&&a.indentation<=c&&(S=e.match(E))&&S[1].length<=6)return a.quote=0,a.header=S[1].length,a.thisLine.header=!0,i.highlightFormatting&&(a.formatting="header"),a.f=a.inline,m(a);if(a.indentation<=c&&e.eat(">"))return a.quote=o?1:a.quote+1,i.highlightFormatting&&(a.formatting="quote"),e.eatSpace(),m(a);if(!x&&!a.setext&&o&&a.indentation<=c&&(S=e.match(M))){var v=S[1]?"ol":"ul";return a.indentation=d+e.current().length,a.list=!0,a.quote=0,a.listStack.push(a.indentation),i.taskLists&&e.match(b,!1)&&(a.taskList=!0),a.f=a.inline,i.highlightFormatting&&(a.formatting=["list","list-"+v]),m(a)}return o&&a.indentation<=c&&(S=e.match(y,!0))?(a.quote=0,a.fencedEndRE=new RegExp(S[1]+"+ *$"),a.localMode=i.fencedCodeBlockHighlighting&&n(S[2]),a.localMode&&(a.localState=t.startState(a.localMode)),a.f=a.block=g,i.highlightFormatting&&(a.formatting="code-block"),a.code=-1,m(a)):a.setext||!(k&&f||a.quote||!1!==a.list||a.code||x||C.test(e.string))&&(S=e.lookAhead(1))&&(S=S.match(w))?(a.setext?(a.header=a.setext,a.setext=0,e.skipToEnd(),i.highlightFormatting&&(a.formatting="header")):(a.header="="==S[0].charAt(0)?1:2,a.setext=a.header),a.thisLine.header=!0,a.f=a.inline,m(a)):x?(e.skipToEnd(),a.hr=!0,a.thisLine.hr=!0,T.hr):"["===e.peek()?r(e,a,p):r(e,a,a.inline)}function s(e,i){var n=v.token(e,i.htmlState);if(!L){var r=t.innerMode(v,i.htmlState);("xml"==r.mode.name&&null===r.state.tagStart&&!r.state.context&&r.state.tokenize.isInText||i.md_inside&&e.current().indexOf(">")>-1)&&(i.f=f,i.block=h,i.htmlState=null)}return n}function g(t,e){var n=e.listStack[e.listStack.length-1]||0,r=e.indentation=t.quote?e.push(T.formatting+"-"+t.formatting[n]+"-"+t.quote):e.push("error"))}if(t.taskOpen)return e.push("meta"),e.length?e.join(" "):null;if(t.taskClosed)return e.push("property"),e.length?e.join(" "):null;if(t.linkHref?e.push(T.linkHref,"url"):(t.strong&&e.push(T.strong),t.em&&e.push(T.em),t.strikethrough&&e.push(T.strikethrough),t.emoji&&e.push(T.emoji),t.linkText&&e.push(T.linkText),t.code&&e.push(T.code),t.image&&e.push(T.image),t.imageAltText&&e.push(T.imageAltText,"link"),t.imageMarker&&e.push(T.imageMarker)),t.header&&e.push(T.header,T.header+"-"+t.header),t.quote&&(e.push(T.quote),!i.maxBlockquoteDepth||i.maxBlockquoteDepth>=t.quote?e.push(T.quote+"-"+t.quote):e.push(T.quote+"-"+i.maxBlockquoteDepth)),!1!==t.list){var r=(t.listStack.length-1)%3;r?1===r?e.push(T.list2):e.push(T.list3):e.push(T.list1)}return t.trailingSpaceNewLine?e.push("trailing-space-new-line"):t.trailingSpace&&e.push("trailing-space-"+(t.trailingSpace%2?"a":"b")),e.length?e.join(" "):null}function u(t,e){if(t.match(j,!0))return m(e)}function f(e,n){var r=n.text(e,n);if(void 0!==r)return r;if(n.list)return n.list=null,m(n);if(n.taskList)return"x"!==e.match(b,!0)[1]?n.taskOpen=!0:n.taskClosed=!0,i.highlightFormatting&&(n.formatting="task"),n.taskList=!1,m(n);if(n.taskOpen=!1,n.taskClosed=!1,n.header&&e.match(/^#+$/,!0))return i.highlightFormatting&&(n.formatting="header"),m(n);var l=e.next();if(n.linkTitle){n.linkTitle=!1;var o=l;"("===l&&(o=")");var h="^\\s*(?:[^"+(o=(o+"").replace(/([.?*+^\[\]\\(){}|-])/g,"\\$1"))+"\\\\]+|\\\\\\\\|\\\\.)"+o;if(e.match(new RegExp(h),!0))return T.linkHref}if("`"===l){var g=n.formatting;i.highlightFormatting&&(n.formatting="code"),e.eatWhile("`");var u=e.current().length;if(0!=n.code||n.quote&&1!=u){if(u==n.code){y=m(n);return n.code=0,y}return n.formatting=g,m(n)}return n.code=u,m(n)}if(n.code)return m(n);if("\\"===l&&(e.next(),i.highlightFormatting)){var k=m(n),p=T.formatting+"-escape";return k?k+" "+p:p}if("!"===l&&e.match(/\[[^\]]*\] ?(?:\(|\[)/,!1))return n.imageMarker=!0,n.image=!0,i.highlightFormatting&&(n.formatting="image"),m(n);if("["===l&&n.imageMarker&&e.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/,!1))return n.imageMarker=!1,n.imageAltText=!0,i.highlightFormatting&&(n.formatting="image"),m(n);if("]"===l&&n.imageAltText){i.highlightFormatting&&(n.formatting="image");k=m(n);return n.imageAltText=!1,n.image=!1,n.inline=n.f=d,k}if("["===l&&!n.image)return n.linkText=!0,i.highlightFormatting&&(n.formatting="link"),m(n);if("]"===l&&n.linkText){i.highlightFormatting&&(n.formatting="link");k=m(n);return n.linkText=!1,n.inline=n.f=e.match(/\(.*?\)| ?\[.*?\]/,!1)?d:f,k}if("<"===l&&e.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/,!1))return n.f=n.inline=c,i.highlightFormatting&&(n.formatting="link"),(k=m(n))?k+=" ":k="",k+T.linkInline;if("<"===l&&e.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/,!1))return n.f=n.inline=c,i.highlightFormatting&&(n.formatting="link"),(k=m(n))?k+=" ":k="",k+T.linkEmail;if(i.xml&&"<"===l&&e.match(/^(!--|[a-z]+(?:\s+[a-z_:.\-]+(?:\s*=\s*[^ >]+)?)*\s*>)/i,!1)){var x=e.string.indexOf(">",e.pos);if(-1!=x){var S=e.string.substring(e.start,x);/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(S)&&(n.md_inside=!0)}return e.backUp(1),n.htmlState=t.startState(v),a(e,n,s)}if(i.xml&&"<"===l&&e.match(/^\/\w*?>/))return n.md_inside=!1,"tag";if("*"===l||"_"===l){for(var L=1,q=1==e.pos?" ":e.string.charAt(e.pos-2);L<3&&e.eat(l);)L++;var F=e.peek()||" ",M=!/\s/.test(F)&&(!B.test(F)||/\s/.test(q)||B.test(q)),E=!/\s/.test(q)&&(!B.test(q)||/\s/.test(F)||B.test(F)),w=null,j=null;if(L%2&&(n.em||!M||"*"!==l&&E&&!B.test(q)?n.em!=l||!E||"*"!==l&&M&&!B.test(F)||(w=!1):w=!0),L>1&&(n.strong||!M||"*"!==l&&E&&!B.test(q)?n.strong!=l||!E||"*"!==l&&M&&!B.test(F)||(j=!1):j=!0),null!=j||null!=w){i.highlightFormatting&&(n.formatting=null==w?"strong":null==j?"em":"strong em"),!0===w&&(n.em=l),!0===j&&(n.strong=l);y=m(n);return!1===w&&(n.em=!1),!1===j&&(n.strong=!1),y}}else if(" "===l&&(e.eat("*")||e.eat("_"))){if(" "===e.peek())return m(n);e.backUp(1)}if(i.strikethrough)if("~"===l&&e.eatWhile(l)){if(n.strikethrough){i.highlightFormatting&&(n.formatting="strikethrough");var y=m(n);return n.strikethrough=!1,y}if(e.match(/^[^\s]/,!1))return n.strikethrough=!0,i.highlightFormatting&&(n.formatting="strikethrough"),m(n)}else if(" "===l&&e.match(/^~~/,!0)){if(" "===e.peek())return m(n);e.backUp(2)}if(i.emoji&&":"===l&&e.match(/^[a-z_\d+-]+:/)){n.emoji=!0,i.highlightFormatting&&(n.formatting="emoji");var C=m(n);return n.emoji=!1,C}return" "===l&&(e.match(/ +$/,!1)?n.trailingSpace++:n.trailingSpace&&(n.trailingSpaceNewLine=!0)),m(n)}function c(t,e){if(">"===t.next()){e.f=e.inline=f,i.highlightFormatting&&(e.formatting="link");var n=m(e);return n?n+=" ":n="",n+T.linkInline}return t.match(/^[^>]+/,!0),T.linkInline}function d(t,e){if(t.eatSpace())return null;var n=t.next();return"("===n||"["===n?(e.f=e.inline=k("("===n?")":"]"),i.highlightFormatting&&(e.formatting="link-string"),e.linkHref=!0,m(e)):"error"}function k(t){return function(e,n){if(e.next()===t){n.f=n.inline=f,i.highlightFormatting&&(n.formatting="link-string");var r=m(n);return n.linkHref=!1,r}return e.match(H[t]),n.linkHref=!0,m(n)}}function p(t,e){return t.match(/^([^\]\\]|\\.)*\]:/,!1)?(e.f=x,t.next(),i.highlightFormatting&&(e.formatting="link"),e.linkText=!0,m(e)):r(t,e,f)}function x(t,e){if(t.match(/^\]:/,!0)){e.f=e.inline=S,i.highlightFormatting&&(e.formatting="link");var n=m(e);return e.linkText=!1,n}return t.match(/^([^\]\\]|\\.)+/,!0),T.linkText}function S(t,e){return t.eatSpace()?null:(t.match(/^[^\s]+/,!0),void 0===t.peek()?e.linkTitle=!0:t.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/,!0),e.f=e.inline=f,T.linkHref+" url")}var v=t.getMode(e,"text/html"),L="null"==v.name;void 0===i.highlightFormatting&&(i.highlightFormatting=!1),void 0===i.maxBlockquoteDepth&&(i.maxBlockquoteDepth=0),void 0===i.taskLists&&(i.taskLists=!1),void 0===i.strikethrough&&(i.strikethrough=!1),void 0===i.emoji&&(i.emoji=!1),void 0===i.fencedCodeBlockHighlighting&&(i.fencedCodeBlockHighlighting=!0),void 0===i.xml&&(i.xml=!0),void 0===i.tokenTypeOverrides&&(i.tokenTypeOverrides={});var T={header:"header",code:"comment",quote:"quote",list1:"variable-2",list2:"variable-3",list3:"keyword",hr:"hr",image:"image",imageAltText:"image-alt-text",imageMarker:"image-marker",formatting:"formatting",linkInline:"link",linkEmail:"link",linkText:"link",linkHref:"string",em:"em",strong:"strong",strikethrough:"strikethrough",emoji:"builtin"};for(var q in T)T.hasOwnProperty(q)&&i.tokenTypeOverrides[q]&&(T[q]=i.tokenTypeOverrides[q]);var F=/^([*\-_])(?:\s*\1){2,}\s*$/,M=/^(?:[*\-+]|^[0-9]+([.)]))\s+/,b=/^\[(x| )\](?=\s)/,E=i.allowAtxHeaderWithoutSpace?/^(#+)/:/^(#+)(?: |$)/,w=/^ *(?:\={1,}|-{1,})\s*$/,j=/^[^#!\[\]*_\\<>` "'(~:]+/,y=/^(~~~+|```+)[ \t]*([\w+#-]*)[^\n`]*$/,C=/^\s*\[[^\]]+?\]:\s*\S+(\s*\S*\s*)?$/,B=/[!\"#$%&\'()*+,\-\.\/:;<=>?@\[\\\]^_`{|}~—]/,H={")":/^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,"]":/^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/},D={startState:function(){return{f:h,prevLine:{stream:null},thisLine:{stream:null},block:h,htmlState:null,indentation:0,inline:f,text:u,formatting:!1,linkText:!1,linkHref:!1,linkTitle:!1,code:0,em:!1,strong:!1,header:0,setext:0,hr:!1,taskList:!1,list:!1,listStack:[],quote:0,trailingSpace:0,trailingSpaceNewLine:!1,strikethrough:!1,emoji:!1,fencedEndRE:null}},copyState:function(e){return{f:e.f,prevLine:e.prevLine,thisLine:e.thisLine,block:e.block,htmlState:e.htmlState&&t.copyState(v,e.htmlState),indentation:e.indentation,localMode:e.localMode,localState:e.localMode?t.copyState(e.localMode,e.localState):null,inline:e.inline,text:e.text,formatting:!1,linkText:e.linkText,linkTitle:e.linkTitle,code:e.code,em:e.em,strong:e.strong,strikethrough:e.strikethrough,emoji:e.emoji,header:e.header,setext:e.setext,hr:e.hr,taskList:e.taskList,list:e.list,listStack:e.listStack.slice(0),quote:e.quote,indentedCode:e.indentedCode,trailingSpace:e.trailingSpace,trailingSpaceNewLine:e.trailingSpaceNewLine,md_inside:e.md_inside,fencedEndRE:e.fencedEndRE}},token:function(t,e){if(e.formatting=!1,t!=e.thisLine.stream){if(e.header=0,e.hr=!1,t.match(/^\s*$/,!0))return o(e),null;if(e.prevLine=e.thisLine,e.thisLine={stream:t},e.taskList=!1,e.trailingSpace=0,e.trailingSpaceNewLine=!1,e.f=e.block,e.f!=s){var i=t.match(/^\s*/,!0)[0].replace(/\t/g," ").length;if(e.indentation=i,e.indentationDiff=null,i>0)return null}}return e.f(t,e)},innerMode:function(t){return t.block==s?{state:t.htmlState,mode:v}:t.localState?{state:t.localState,mode:t.localMode}:{state:t,mode:D}},indent:function(e,i,n){return e.block==s?v.indent(e.htmlState,i,n):e.localState?e.localMode.indent(e.localState,i,n):t.Pass},blankLine:o,getType:m,closeBrackets:"()[]{}''\"\"``",fold:"markdown"};return D},"xml"),t.defineMIME("text/x-markdown","markdown")});
--------------------------------------------------------------------------------
/static/lib/highlight.pack.js:
--------------------------------------------------------------------------------
1 | /*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */
2 | !function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){s+=""+t(e)+">"}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"
":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/
/g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("r",function(e){var r="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[e.HCM,{b:r,l:r,k:{keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{b:"`",e:"`",r:0},{cN:"string",c:[e.BE],v:[{b:'"',e:'"'},{b:"'",e:"'"}]}]}});hljs.registerLanguage("python",function(e){var r={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},b={cN:"meta",b:/^(>>>|\.\.\.) /},c={cN:"subst",b:/\{/,e:/\}/,k:r,i:/#/},a={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[b],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[b],r:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[b,c]},{b:/(fr|rf|f)"""/,e:/"""/,c:[b,c]},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},{b:/(fr|rf|f)'/,e:/'/,c:[c]},{b:/(fr|rf|f)"/,e:/"/,c:[c]},e.ASM,e.QSM]},s={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},i={cN:"params",b:/\(/,e:/\)/,c:["self",b,s,a]};return c.c=[a,s,b],{aliases:["py","gyp"],k:r,i:/(<\/|->|\?)|=>/,c:[b,s,a,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,i,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b:/,e:/(\/\w+|\w+\/)>/,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/,r:0,c:[{cN:"attr",b:e,r:0},{b:/=\s*/,r:0,c:[{cN:"string",endsParent:!0,v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s"'=<>`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"?",e:"/?>",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});
--------------------------------------------------------------------------------
/static/lib/marked.min.js:
--------------------------------------------------------------------------------
1 | // https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.12/marked.min.js
2 | (function(){"use strict";var e={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:u,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:u,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:u,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};function t(t){this.tokens=[],this.tokens.links={},this.options=t||g.defaults,this.rules=e.normal,this.options.gfm&&(this.options.tables?this.rules=e.tables:this.rules=e.gfm)}e.bullet=/(?:[*+-]|\d+\.)/,e.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,e.item=o(e.item,"gm")(/bull/g,e.bullet)(),e.list=o(e.list)(/bull/g,e.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+e.def.source+")")(),e.blockquote=o(e.blockquote)("def",e.def)(),e._tag="(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b",e.html=o(e.html)("comment",//)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/])*?>/)(/tag/g,e._tag)(),e.paragraph=o(e.paragraph)("hr",e.hr)("heading",e.heading)("lheading",e.lheading)("blockquote",e.blockquote)("tag","<"+e._tag)("def",e.def)(),e.normal=c({},e),e.gfm=c({},e.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/}),e.gfm.paragraph=o(e.paragraph)("(?!","(?!"+e.gfm.fences.source.replace("\\1","\\2")+"|"+e.list.source.replace("\\1","\\3")+"|")(),e.tables=c({},e.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/}),t.rules=e,t.lex=function(e,n){return new t(n).lex(e)},t.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(e,!0)},t.prototype.token=function(t,n,s){var r,i,l,o,h,a,p,u,c;for(t=t.replace(/^ +$/gm,"");t;)if((l=this.rules.newline.exec(t))&&(t=t.substring(l[0].length),l[0].length>1&&this.tokens.push({type:"space"})),l=this.rules.code.exec(t))t=t.substring(l[0].length),l=l[0].replace(/^ {4}/gm,""),this.tokens.push({type:"code",text:this.options.pedantic?l:l.replace(/\n+$/,"")});else if(l=this.rules.fences.exec(t))t=t.substring(l[0].length),this.tokens.push({type:"code",lang:l[2],text:l[3]||""});else if(l=this.rules.heading.exec(t))t=t.substring(l[0].length),this.tokens.push({type:"heading",depth:l[1].length,text:l[2]});else if(n&&(l=this.rules.nptable.exec(t))){for(t=t.substring(l[0].length),a={type:"table",header:l[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:l[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:l[3].replace(/\n$/,"").split("\n")},u=0;u ?/gm,""),this.token(l,n,!0),this.tokens.push({type:"blockquote_end"});else if(l=this.rules.list.exec(t)){for(t=t.substring(l[0].length),o=l[2],this.tokens.push({type:"list_start",ordered:o.length>1}),r=!1,c=(l=l[0].match(this.rules.item)).length,u=0;u1&&h.length>1||(t=l.slice(u+1).join("\n")+t,u=c-1)),i=r||/\n\n(?!\s*$)/.test(a),u!==c-1&&(r="\n"===a.charAt(a.length-1),i||(i=r)),this.tokens.push({type:i?"loose_item_start":"list_item_start"}),this.token(a,!1,s),this.tokens.push({type:"list_item_end"});this.tokens.push({type:"list_end"})}else if(l=this.rules.html.exec(t))t=t.substring(l[0].length),this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&("pre"===l[1]||"script"===l[1]||"style"===l[1]),text:l[0]});else if(!s&&n&&(l=this.rules.def.exec(t)))t=t.substring(l[0].length),this.tokens.links[l[1].toLowerCase()]={href:l[2],title:l[3]};else if(n&&(l=this.rules.table.exec(t))){for(t=t.substring(l[0].length),a={type:"table",header:l[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:l[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:l[3].replace(/(?: *\| *)?\n$/,"").split("\n")},u=0;u])/,autolink:/^<([^ <>]+(@|:\/)[^ <>]+)>/,url:u,tag:/^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^<'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)([\s\S]*?[^`])\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:u,text:/^[\s\S]+?(?=[\\/g,">").replace(/"/g,""").replace(/'/g,"'")}function o(e,t){return e=e.source,t=t||"",function n(s,r){return s?(r=(r=r.source||r).replace(/(^|[^\[])\^/g,"$1"),e=e.replace(s,r),n):new RegExp(e,t)}}function h(e,t){return a[" "+e]||(/^[^:]+:\/*[^/]*$/.test(e)?a[" "+e]=e+"/":a[" "+e]=e.replace(/[^/]*$/,"")),e=a[" "+e],"//"===t.slice(0,2)?e.replace(/:[\s\S]*/,":")+t:"/"===t.charAt(0)?e.replace(/(:\/*[^/]*)[\s\S]*/,"$1")+t:e+t}n._inside=/(?:\[[^\]]*\]|\\[\[\]]|[^\[\]]|\](?=[^\[]*\]))*/,n._href=/\s*([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/,n.link=o(n.link)("inside",n._inside)("href",n._href)(),n.reflink=o(n.reflink)("inside",n._inside)(),n.normal=c({},n),n.pedantic=c({},n.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/}),n.gfm=c({},n.normal,{escape:o(n.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:o(n.text)("]|","~]|")("|","|https?://|")()}),n.breaks=c({},n.gfm,{br:o(n.br)("{2,}","*")(),text:o(n.gfm.text)("{2,}","*")()}),s.rules=n,s.output=function(e,t,n){return new s(t,n).output(e)},s.prototype.output=function(e){for(var t,n,s,r,i="";e;)if(r=this.rules.escape.exec(e))e=e.substring(r[0].length),i+=r[1];else if(r=this.rules.autolink.exec(e))e=e.substring(r[0].length),"@"===r[2]?(n=l(":"===r[1].charAt(6)?this.mangle(r[1].substring(7)):this.mangle(r[1])),s=this.mangle("mailto:")+n):s=n=l(r[1]),i+=this.renderer.link(s,null,n);else if(this.inLink||!(r=this.rules.url.exec(e))){if(r=this.rules.tag.exec(e))!this.inLink&&/^/i.test(r[0])&&(this.inLink=!1),e=e.substring(r[0].length),i+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(r[0]):l(r[0]):r[0];else if(r=this.rules.link.exec(e))e=e.substring(r[0].length),this.inLink=!0,i+=this.outputLink(r,{href:r[2],title:r[3]}),this.inLink=!1;else if((r=this.rules.reflink.exec(e))||(r=this.rules.nolink.exec(e))){if(e=e.substring(r[0].length),t=(r[2]||r[1]).replace(/\s+/g," "),!(t=this.links[t.toLowerCase()])||!t.href){i+=r[0].charAt(0),e=r[0].substring(1)+e;continue}this.inLink=!0,i+=this.outputLink(r,t),this.inLink=!1}else if(r=this.rules.strong.exec(e))e=e.substring(r[0].length),i+=this.renderer.strong(this.output(r[2]||r[1]));else if(r=this.rules.em.exec(e))e=e.substring(r[0].length),i+=this.renderer.em(this.output(r[2]||r[1]));else if(r=this.rules.code.exec(e))e=e.substring(r[0].length),i+=this.renderer.codespan(l(r[2].trim(),!0));else if(r=this.rules.br.exec(e))e=e.substring(r[0].length),i+=this.renderer.br();else if(r=this.rules.del.exec(e))e=e.substring(r[0].length),i+=this.renderer.del(this.output(r[1]));else if(r=this.rules.text.exec(e))e=e.substring(r[0].length),i+=this.renderer.text(l(this.smartypants(r[0])));else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0))}else e=e.substring(r[0].length),s=n=l(r[1]),i+=this.renderer.link(s,null,n);return i},s.prototype.outputLink=function(e,t){var n=l(t.href),s=t.title?l(t.title):null;return"!"!==e[0].charAt(0)?this.renderer.link(n,s,this.output(e[1])):this.renderer.image(n,s,l(e[1]))},s.prototype.smartypants=function(e){return this.options.smartypants?e.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):e},s.prototype.mangle=function(e){if(!this.options.mangle)return e;for(var t,n="",s=e.length,r=0;r.5&&(t="x"+t.toString(16)),n+=""+t+";";return n},r.prototype.code=function(e,t,n){if(this.options.highlight){var s=this.options.highlight(e,t);null!=s&&s!==e&&(n=!0,e=s)}return t?''+(n?e:l(e,!0))+"\n
\n":""+(n?e:l(e,!0))+"\n
"},r.prototype.blockquote=function(e){return"\n"+e+"
\n"},r.prototype.html=function(e){return e},r.prototype.heading=function(e,t,n){return"\n"},r.prototype.hr=function(){return this.options.xhtml?"
\n":"
\n"},r.prototype.list=function(e,t){var n=t?"ol":"ul";return"<"+n+">\n"+e+""+n+">\n"},r.prototype.listitem=function(e){return""+e+"\n"},r.prototype.paragraph=function(e){return""+e+"
\n"},r.prototype.table=function(e,t){return"\n"},r.prototype.tablerow=function(e){return"\n"+e+"
\n"},r.prototype.tablecell=function(e,t){var n=t.header?"th":"td";return(t.align?"<"+n+' style="text-align:'+t.align+'">':"<"+n+">")+e+""+n+">\n"},r.prototype.strong=function(e){return""+e+""},r.prototype.em=function(e){return""+e+""},r.prototype.codespan=function(e){return""+e+""},r.prototype.br=function(){return this.options.xhtml?"
":"
"},r.prototype.del=function(e){return""+e+""},r.prototype.link=function(e,t,n){if(this.options.sanitize){try{var s=decodeURIComponent((r=e,r.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi,function(e,t){return"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""}))).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return n}if(0===s.indexOf("javascript:")||0===s.indexOf("vbscript:")||0===s.indexOf("data:"))return n}var r;this.options.baseUrl&&!p.test(e)&&(e=h(this.options.baseUrl,e));var i='"+n+""},r.prototype.image=function(e,t,n){this.options.baseUrl&&!p.test(e)&&(e=h(this.options.baseUrl,e));var s='
":">"},r.prototype.text=function(e){return e},i.parse=function(e,t,n){return new i(t,n).parse(e)},i.prototype.parse=function(e){this.inline=new s(e.links,this.options,this.renderer),this.tokens=e.reverse();for(var t="";this.next();)t+=this.tok();return t},i.prototype.next=function(){return this.token=this.tokens.pop()},i.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0},i.prototype.parseText=function(){for(var e=this.token.text;"text"===this.peek().type;)e+="\n"+this.next().text;return this.inline.output(e)},i.prototype.tok=function(){switch(this.token.type){case"space":return"";case"hr":return this.renderer.hr();case"heading":return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text);case"code":return this.renderer.code(this.token.text,this.token.lang,this.token.escaped);case"table":var e,t,n,s,r="",i="";for(n="",e=0;eAn error occurred:"+l(e.message+"",!0)+"
";throw e}}u.exec=u,g.options=g.setOptions=function(e){return c(g.defaults,e),g},g.defaults={gfm:!0,tables:!0,breaks:!1,pedantic:!1,sanitize:!1,sanitizer:null,mangle:!0,smartLists:!1,silent:!1,highlight:null,langPrefix:"lang-",smartypants:!1,headerPrefix:"",renderer:new r,xhtml:!1,baseUrl:null},g.Parser=i,g.parser=i.parse,g.Renderer=r,g.Lexer=t,g.lexer=t.lex,g.InlineLexer=s,g.inlineLexer=s.output,g.parse=g,"undefined"!=typeof module&&"object"==typeof exports?module.exports=g:"function"==typeof define&&define.amd?define(function(){return g}):this.marked=g}).call(function(){return this||("undefined"!=typeof window?window:global)}());
--------------------------------------------------------------------------------
/static/lib/vega-embed.min.js:
--------------------------------------------------------------------------------
1 | // https://cdnjs.cloudflare.com/ajax/libs/vega-embed/3.0.0-rc7/vega-embed.min.js
2 |
3 | !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).vegaEmbed=e()}}(function(){return function e(t,n,r){function i(u,a){if(!n[u]){if(!t[u]){var s="function"==typeof require&&require;if(!a&&s)return s(u,!0);if(o)return o(u,!0);var c=new Error("Cannot find module '"+u+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return i(n||e)},l,l.exports,e,t,n,r)}return n[u].exports}for(var o="function"==typeof require&&require,u=0;ul)return 1;if(l>c)return-1}if([u[2],a[2]].every(i.test.bind(i))){var f=i.exec(u[2])[1].split(".").map(t),h=i.exec(a[2])[1].split(".").map(t);for(s=0;sh[s])return 1;if(h[s]>f[s])return-1}}else if([u[2],a[2]].some(i.test.bind(i)))return i.test(u[2])?-1:1;return 0}})},{}],2:[function(e,t,n){!function(e,r){r("object"==typeof n&&void 0!==t?n:e.d3=e.d3||{})}(this,function(e){"use strict";function t(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===K&&t.documentElement.namespaceURI===K?t.createElement(e):t.createElementNS(n,e)}}function n(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function r(){return new i}function i(){this._="@"+(++ne).toString(36)}function o(e,t,n){return e=u(e,t,n),function(t){var n=t.relatedTarget;n&&(n===this||8&n.compareDocumentPosition(this))||e.call(this,t)}}function u(t,n,r){return function(i){var o=e.event;e.event=i;try{t.call(this,this.__data__,n,r)}finally{e.event=o}}}function a(e){return e.trim().split(/^|\s+/).map(function(e){var t="",n=e.indexOf(".");return n>=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}function s(e){return function(){var t=this.__on;if(t){for(var n,r=0,i=-1,o=t.length;rt?1:e>=t?0:NaN}function g(e){return function(){this.removeAttribute(e)}}function m(e){return function(){this.removeAttributeNS(e.space,e.local)}}function y(e,t){return function(){this.setAttribute(e,t)}}function _(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function w(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttribute(e):this.setAttribute(e,n)}}function b(e,t){return function(){var n=t.apply(this,arguments);null==n?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function x(e){return function(){this.style.removeProperty(e)}}function A(e,t,n){return function(){this.style.setProperty(e,t,n)}}function S(e,t,n){return function(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function E(e,t){return e.style.getPropertyValue(t)||ve(e).getComputedStyle(e,null).getPropertyValue(t)}function N(e){return function(){delete this[e]}}function P(e,t){return function(){this[e]=t}}function O(e,t){return function(){var n=t.apply(this,arguments);null==n?delete this[e]:this[e]=n}}function L(e){return e.trim().split(/^|\s+/)}function M(e){return e.classList||new T(e)}function T(e){this._node=e,this._names=L(e.getAttribute("class")||"")}function j(e,t){for(var n=M(e),r=-1,i=t.length;++r=0&&"xmlns"!==(t=e.slice(0,n))&&(e=e.slice(n+1)),Q.hasOwnProperty(t)?{space:Q[t],local:e}:e},te=function(e){var r=ee(e);return(r.local?n:t)(r)},ne=0;i.prototype=r.prototype={constructor:i,get:function(e){for(var t=this._;!(t in e);)if(!(e=e.parentNode))return;return e[t]},set:function(e,t){return e[this._]=t},remove:function(e){return this._ in e&&delete e[this._]},toString:function(){return this._}};var re=function(e){return function(){return this.matches(e)}};if("undefined"!=typeof document){var ie=document.documentElement;if(!ie.matches){var oe=ie.webkitMatchesSelector||ie.msMatchesSelector||ie.mozMatchesSelector||ie.oMatchesSelector;re=function(e){return function(){return oe.call(this,e)}}}}var ue=re,ae={};e.event=null,"undefined"!=typeof document&&("onmouseenter"in document.documentElement||(ae={mouseenter:"mouseover",mouseleave:"mouseout"}));var se=function(){for(var t,n=e.event;t=n.sourceEvent;)n=t;return n},ce=function(e,t){var n=e.ownerSVGElement||e;if(n.createSVGPoint){var r=n.createSVGPoint();return r.x=t.clientX,r.y=t.clientY,r=r.matrixTransform(e.getScreenCTM().inverse()),[r.x,r.y]}var i=e.getBoundingClientRect();return[t.clientX-i.left-e.clientLeft,t.clientY-i.top-e.clientTop]},le=function(e){return null==e?l:function(){return this.querySelector(e)}},fe=function(e){return null==e?f:function(){return this.querySelectorAll(e)}},he=function(e){return new Array(e.length)};h.prototype={constructor:h,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};var pe=function(e){return function(){return e}},de="$",ve=function(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView};T.prototype={add:function(e){this._names.indexOf(e)<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};var ge=[null];W.prototype=Z.prototype={constructor:W,select:function(e){"function"!=typeof e&&(e=le(e));for(var t=this._groups,n=t.length,r=new Array(n),i=0;i=x&&(x=b+1);!(w=y[x])&&++x=0;)(r=i[o])&&(u&&u!==r.nextSibling&&u.parentNode.insertBefore(r,u),u=r);return this},sort:function(e){e||(e=v);for(var t=this._groups,n=t.length,r=new Array(n),i=0;i1?this.each((null==t?x:"function"==typeof t?S:A)(e,t,null==n?"":n)):E(this.node(),e)},property:function(e,t){return arguments.length>1?this.each((null==t?N:"function"==typeof t?O:P)(e,t)):this.node()[e]},classed:function(e,t){var n=L(e+"");if(arguments.length<2){for(var r=M(this.node()),i=-1,o=n.length;++i0&&console.warn("The input spec uses "+y+" "+_.version+", but the current version of "+f[y]+" is "+h[y]+".")):y=a.mode||"vega";var w=p[y](t);"vega-lite"===y&&w.$schema&&(_=c.default(w.$schema),o(_.version,h.vega)>0&&console.warn("The compiled spec uses Vega "+_.version+", but current version is "+h.vega+"."));var b=u.select(e).classed("vega-embed",!0).html("");a.onBeforeParse&&(w=a.onBeforeParse(w));var x=n.vega.parse(w,a.config),A=new n.vega.View(x,{loader:d,logLevel:g,renderer:v}).initialize(e);if("vega-lite"!==y&&A.hover(),a&&(a.width&&A.width(a.width),a.height&&A.height(a.height),a.padding&&A.padding(a.padding)),A.run(),!1!==s){var S=b.append("div").attr("class","vega-actions");if(!0===s||!1!==s.export){var E="canvas"===v?"png":"svg";S.append("a").text("Export as "+E.toUpperCase()).attr("href","#").attr("target","_blank").attr("download",(t.name||"vega")+"."+E).on("mousedown",function(){var e=this;A.toImageURL(E).then(function(t){e.href=t}).catch(function(e){throw e}),u.event.preventDefault()})}if(!0!==s&&!1===s.source||S.append("a").text("View Source").attr("href","#").on("click",function(){i(JSON.stringify(t,null,2),a.sourceHeader||"",a.sourceFooter||""),u.event.preventDefault()}),!0===s||!1!==s.editor){var N=a.editorUrl||"https://vega.github.io/editor/";S.append("a").text("Open in Vega Editor").attr("href","#").on("click",function(){l.post(window,N,{mode:y,spec:JSON.stringify(t,null,2)}),u.event.preventDefault()})}}return Promise.resolve({view:A,spec:t})}catch(e){return Promise.reject(e)}}function i(e,t,n){var r=""+t+"' + '",i="
"+n+"",o=window.open("");o.document.write(r+e+i),o.document.title="Vega JSON Source"}Object.defineProperty(n,"__esModule",{value:!0});var o=e("compare-versions"),u=e("d3-selection"),a="undefined"!=typeof window?window.vega:void 0!==t?t.vega:null,s="undefined"!=typeof window?window.vl:void 0!==t?t.vl:null,c=e("vega-schema-url-parser");n.vega=a,n.vl=s;var l=e("./post"),f={vega:"Vega","vega-lite":"Vega-Lite"},h={vega:n.vega.version,"vega-lite":n.vl?n.vl.version:"not available"},p={vega:function(e){return e},"vega-lite":function(e){return n.vl.compile(e).spec}};n.default=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./post":6,"compare-versions":1,"d3-selection":2,"vega-schema-url-parser":3}],5:[function(e,t,n){(function(n){"use strict";var r="undefined"!=typeof window?window.vega:void 0!==n?n.vega:null,i="undefined"!=typeof window?window.vl:void 0!==n?n.vl:null,o=e("./embed"),u=o.default;u.default=o.default,u.vega=r,u.vl=i,t.exports=u}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./embed":4}],6:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.post=function(e,t,n){function r(t){t.source===o&&(a=0,e.removeEventListener("message",r,!1))}function i(){a<=0||(o.postMessage(n,"*"),setTimeout(i,u),a-=1)}var o=e.open(t),u=250,a=~~(1e4/u);e.addEventListener("message",r,!1),setTimeout(i,u)}},{}]},{},[5])(5)});
--------------------------------------------------------------------------------
/static/lib/markdown.js:
--------------------------------------------------------------------------------
1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 | // Distributed under an MIT license: http://codemirror.net/LICENSE
3 |
4 | (function(mod) {
5 | if (typeof exports == "object" && typeof module == "object") // CommonJS
6 | mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta"));
7 | else if (typeof define == "function" && define.amd) // AMD
8 | define(["../../lib/codemirror", "../xml/xml", "../meta"], mod);
9 | else // Plain browser env
10 | mod(CodeMirror);
11 | })(function(CodeMirror) {
12 | "use strict";
13 |
14 | CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
15 |
16 | var htmlMode = CodeMirror.getMode(cmCfg, "text/html");
17 | var htmlModeMissing = htmlMode.name == "null"
18 |
19 | function getMode(name) {
20 | if (CodeMirror.findModeByName) {
21 | var found = CodeMirror.findModeByName(name);
22 | if (found) name = found.mime || found.mimes[0];
23 | }
24 | var mode = CodeMirror.getMode(cmCfg, name);
25 | return mode.name == "null" ? null : mode;
26 | }
27 |
28 | // Should characters that affect highlighting be highlighted separate?
29 | // Does not include characters that will be output (such as `1.` and `-` for lists)
30 | if (modeCfg.highlightFormatting === undefined)
31 | modeCfg.highlightFormatting = false;
32 |
33 | // Maximum number of nested blockquotes. Set to 0 for infinite nesting.
34 | // Excess `>` will emit `error` token.
35 | if (modeCfg.maxBlockquoteDepth === undefined)
36 | modeCfg.maxBlockquoteDepth = 0;
37 |
38 | // Should underscores in words open/close em/strong?
39 | if (modeCfg.underscoresBreakWords === undefined)
40 | modeCfg.underscoresBreakWords = true;
41 |
42 | // Use `fencedCodeBlocks` to configure fenced code blocks. false to
43 | // disable, string to specify a precise regexp that the fence should
44 | // match, and true to allow three or more backticks or tildes (as
45 | // per CommonMark).
46 |
47 | // Turn on task lists? ("- [ ] " and "- [x] ")
48 | if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
49 |
50 | // Turn on strikethrough syntax
51 | if (modeCfg.strikethrough === undefined)
52 | modeCfg.strikethrough = false;
53 |
54 | // Allow token types to be overridden by user-provided token types.
55 | if (modeCfg.tokenTypeOverrides === undefined)
56 | modeCfg.tokenTypeOverrides = {};
57 |
58 | var tokenTypes = {
59 | header: "header",
60 | code: "comment",
61 | quote: "quote",
62 | list1: "variable-2",
63 | list2: "variable-3",
64 | list3: "keyword",
65 | hr: "hr",
66 | image: "image",
67 | imageAltText: "image-alt-text",
68 | imageMarker: "image-marker",
69 | formatting: "formatting",
70 | linkInline: "link",
71 | linkEmail: "link",
72 | linkText: "link",
73 | linkHref: "string",
74 | em: "em",
75 | strong: "strong",
76 | strikethrough: "strikethrough"
77 | };
78 |
79 | for (var tokenType in tokenTypes) {
80 | if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) {
81 | tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType];
82 | }
83 | }
84 |
85 | var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
86 | , listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/
87 | , taskListRE = /^\[(x| )\](?=\s)/ // Must follow listRE
88 | , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
89 | , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
90 | , textRE = /^[^#!\[\]*_\\<>` "'(~]+/
91 | , fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
92 | ")[ \\t]*([\\w+#\-]*)");
93 |
94 | function switchInline(stream, state, f) {
95 | state.f = state.inline = f;
96 | return f(stream, state);
97 | }
98 |
99 | function switchBlock(stream, state, f) {
100 | state.f = state.block = f;
101 | return f(stream, state);
102 | }
103 |
104 | function lineIsEmpty(line) {
105 | return !line || !/\S/.test(line.string)
106 | }
107 |
108 | // Blocks
109 |
110 | function blankLine(state) {
111 | // Reset linkTitle state
112 | state.linkTitle = false;
113 | // Reset EM state
114 | state.em = false;
115 | // Reset STRONG state
116 | state.strong = false;
117 | // Reset strikethrough state
118 | state.strikethrough = false;
119 | // Reset state.quote
120 | state.quote = 0;
121 | // Reset state.indentedCode
122 | state.indentedCode = false;
123 | if (htmlModeMissing && state.f == htmlBlock) {
124 | state.f = inlineNormal;
125 | state.block = blockNormal;
126 | }
127 | // Reset state.trailingSpace
128 | state.trailingSpace = 0;
129 | state.trailingSpaceNewLine = false;
130 | // Mark this line as blank
131 | state.prevLine = state.thisLine
132 | state.thisLine = null
133 | return null;
134 | }
135 |
136 | function blockNormal(stream, state) {
137 |
138 | var sol = stream.sol();
139 |
140 | var prevLineIsList = state.list !== false,
141 | prevLineIsIndentedCode = state.indentedCode;
142 |
143 | state.indentedCode = false;
144 |
145 | if (prevLineIsList) {
146 | if (state.indentationDiff >= 0) { // Continued list
147 | if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
148 | state.indentation -= state.indentationDiff;
149 | }
150 | state.list = null;
151 | } else if (state.indentation > 0) {
152 | state.list = null;
153 | } else { // No longer a list
154 | state.list = false;
155 | }
156 | }
157 |
158 | var match = null;
159 | if (state.indentationDiff >= 4) {
160 | stream.skipToEnd();
161 | if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) {
162 | state.indentation -= 4;
163 | state.indentedCode = true;
164 | return tokenTypes.code;
165 | } else {
166 | return null;
167 | }
168 | } else if (stream.eatSpace()) {
169 | return null;
170 | } else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
171 | state.header = match[1].length;
172 | if (modeCfg.highlightFormatting) state.formatting = "header";
173 | state.f = state.inline;
174 | return getType(state);
175 | } else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList &&
176 | !prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) {
177 | state.header = match[0].charAt(0) == '=' ? 1 : 2;
178 | if (modeCfg.highlightFormatting) state.formatting = "header";
179 | state.f = state.inline;
180 | return getType(state);
181 | } else if (stream.eat('>')) {
182 | state.quote = sol ? 1 : state.quote + 1;
183 | if (modeCfg.highlightFormatting) state.formatting = "quote";
184 | stream.eatSpace();
185 | return getType(state);
186 | } else if (stream.peek() === '[') {
187 | return switchInline(stream, state, footnoteLink);
188 | } else if (stream.match(hrRE, true)) {
189 | state.hr = true;
190 | return tokenTypes.hr;
191 | } else if (match = stream.match(listRE)) {
192 | var listType = match[1] ? "ol" : "ul";
193 | state.indentation = stream.column() + stream.current().length;
194 | state.list = true;
195 |
196 | // While this list item's marker's indentation
197 | // is less than the deepest list item's content's indentation,
198 | // pop the deepest list item indentation off the stack.
199 | while (state.listStack && stream.column() < state.listStack[state.listStack.length - 1]) {
200 | state.listStack.pop();
201 | }
202 |
203 | // Add this list item's content's indentation to the stack
204 | state.listStack.push(state.indentation);
205 |
206 | if (modeCfg.taskLists && stream.match(taskListRE, false)) {
207 | state.taskList = true;
208 | }
209 | state.f = state.inline;
210 | if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
211 | return getType(state);
212 | } else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) {
213 | state.fencedChars = match[1]
214 | // try switching mode
215 | state.localMode = getMode(match[2]);
216 | if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
217 | state.f = state.block = local;
218 | if (modeCfg.highlightFormatting) state.formatting = "code-block";
219 | state.code = -1
220 | return getType(state);
221 | }
222 |
223 | return switchInline(stream, state, state.inline);
224 | }
225 |
226 | function htmlBlock(stream, state) {
227 | var style = htmlMode.token(stream, state.htmlState);
228 | if (!htmlModeMissing) {
229 | var inner = CodeMirror.innerMode(htmlMode, state.htmlState)
230 | if ((inner.mode.name == "xml" && inner.state.tagStart === null &&
231 | (!inner.state.context && inner.state.tokenize.isInText)) ||
232 | (state.md_inside && stream.current().indexOf(">") > -1)) {
233 | state.f = inlineNormal;
234 | state.block = blockNormal;
235 | state.htmlState = null;
236 | }
237 | }
238 | return style;
239 | }
240 |
241 | function local(stream, state) {
242 | if (state.fencedChars && stream.match(state.fencedChars, false)) {
243 | state.localMode = state.localState = null;
244 | state.f = state.block = leavingLocal;
245 | return null;
246 | } else if (state.localMode) {
247 | return state.localMode.token(stream, state.localState);
248 | } else {
249 | stream.skipToEnd();
250 | return tokenTypes.code;
251 | }
252 | }
253 |
254 | function leavingLocal(stream, state) {
255 | stream.match(state.fencedChars);
256 | state.block = blockNormal;
257 | state.f = inlineNormal;
258 | state.fencedChars = null;
259 | if (modeCfg.highlightFormatting) state.formatting = "code-block";
260 | state.code = 1
261 | var returnType = getType(state);
262 | state.code = 0
263 | return returnType;
264 | }
265 |
266 | // Inline
267 | function getType(state) {
268 | var styles = [];
269 |
270 | if (state.formatting) {
271 | styles.push(tokenTypes.formatting);
272 |
273 | if (typeof state.formatting === "string") state.formatting = [state.formatting];
274 |
275 | for (var i = 0; i < state.formatting.length; i++) {
276 | styles.push(tokenTypes.formatting + "-" + state.formatting[i]);
277 |
278 | if (state.formatting[i] === "header") {
279 | styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header);
280 | }
281 |
282 | // Add `formatting-quote` and `formatting-quote-#` for blockquotes
283 | // Add `error` instead if the maximum blockquote nesting depth is passed
284 | if (state.formatting[i] === "quote") {
285 | if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
286 | styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote);
287 | } else {
288 | styles.push("error");
289 | }
290 | }
291 | }
292 | }
293 |
294 | if (state.taskOpen) {
295 | styles.push("meta");
296 | return styles.length ? styles.join(' ') : null;
297 | }
298 | if (state.taskClosed) {
299 | styles.push("property");
300 | return styles.length ? styles.join(' ') : null;
301 | }
302 |
303 | if (state.linkHref) {
304 | styles.push(tokenTypes.linkHref, "url");
305 | } else { // Only apply inline styles to non-url text
306 | if (state.strong) { styles.push(tokenTypes.strong); }
307 | if (state.em) { styles.push(tokenTypes.em); }
308 | if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
309 | if (state.linkText) { styles.push(tokenTypes.linkText); }
310 | if (state.code) { styles.push(tokenTypes.code); }
311 | if (state.image) { styles.push(tokenTypes.image); }
312 | if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); }
313 | if (state.imageMarker) { styles.push(tokenTypes.imageMarker); }
314 | }
315 |
316 | if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
317 |
318 | if (state.quote) {
319 | styles.push(tokenTypes.quote);
320 |
321 | // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
322 | if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
323 | styles.push(tokenTypes.quote + "-" + state.quote);
324 | } else {
325 | styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth);
326 | }
327 | }
328 |
329 | if (state.list !== false) {
330 | var listMod = (state.listStack.length - 1) % 3;
331 | if (!listMod) {
332 | styles.push(tokenTypes.list1);
333 | } else if (listMod === 1) {
334 | styles.push(tokenTypes.list2);
335 | } else {
336 | styles.push(tokenTypes.list3);
337 | }
338 | }
339 |
340 | if (state.trailingSpaceNewLine) {
341 | styles.push("trailing-space-new-line");
342 | } else if (state.trailingSpace) {
343 | styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
344 | }
345 |
346 | return styles.length ? styles.join(' ') : null;
347 | }
348 |
349 | function handleText(stream, state) {
350 | if (stream.match(textRE, true)) {
351 | return getType(state);
352 | }
353 | return undefined;
354 | }
355 |
356 | function inlineNormal(stream, state) {
357 | var style = state.text(stream, state);
358 | if (typeof style !== 'undefined')
359 | return style;
360 |
361 | if (state.list) { // List marker (*, +, -, 1., etc)
362 | state.list = null;
363 | return getType(state);
364 | }
365 |
366 | if (state.taskList) {
367 | var taskOpen = stream.match(taskListRE, true)[1] !== "x";
368 | if (taskOpen) state.taskOpen = true;
369 | else state.taskClosed = true;
370 | if (modeCfg.highlightFormatting) state.formatting = "task";
371 | state.taskList = false;
372 | return getType(state);
373 | }
374 |
375 | state.taskOpen = false;
376 | state.taskClosed = false;
377 |
378 | if (state.header && stream.match(/^#+$/, true)) {
379 | if (modeCfg.highlightFormatting) state.formatting = "header";
380 | return getType(state);
381 | }
382 |
383 | // Get sol() value now, before character is consumed
384 | var sol = stream.sol();
385 |
386 | var ch = stream.next();
387 |
388 | // Matches link titles present on next line
389 | if (state.linkTitle) {
390 | state.linkTitle = false;
391 | var matchCh = ch;
392 | if (ch === '(') {
393 | matchCh = ')';
394 | }
395 | matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
396 | var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
397 | if (stream.match(new RegExp(regex), true)) {
398 | return tokenTypes.linkHref;
399 | }
400 | }
401 |
402 | // If this block is changed, it may need to be updated in GFM mode
403 | if (ch === '`') {
404 | var previousFormatting = state.formatting;
405 | if (modeCfg.highlightFormatting) state.formatting = "code";
406 | stream.eatWhile('`');
407 | var count = stream.current().length
408 | if (state.code == 0) {
409 | state.code = count
410 | return getType(state)
411 | } else if (count == state.code) { // Must be exact
412 | var t = getType(state)
413 | state.code = 0
414 | return t
415 | } else {
416 | state.formatting = previousFormatting
417 | return getType(state)
418 | }
419 | } else if (state.code) {
420 | return getType(state);
421 | }
422 |
423 | if (ch === '\\') {
424 | stream.next();
425 | if (modeCfg.highlightFormatting) {
426 | var type = getType(state);
427 | var formattingEscape = tokenTypes.formatting + "-escape";
428 | return type ? type + " " + formattingEscape : formattingEscape;
429 | }
430 | }
431 |
432 | if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
433 | state.imageMarker = true;
434 | state.image = true;
435 | if (modeCfg.highlightFormatting) state.formatting = "image";
436 | return getType(state);
437 | }
438 |
439 | if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) {
440 | state.imageMarker = false;
441 | state.imageAltText = true
442 | if (modeCfg.highlightFormatting) state.formatting = "image";
443 | return getType(state);
444 | }
445 |
446 | if (ch === ']' && state.imageAltText) {
447 | if (modeCfg.highlightFormatting) state.formatting = "image";
448 | var type = getType(state);
449 | state.imageAltText = false;
450 | state.image = false;
451 | state.inline = state.f = linkHref;
452 | return type;
453 | }
454 |
455 | if (ch === '[' && stream.match(/[^\]]*\](\(.*\)| ?\[.*?\])/, false) && !state.image) {
456 | state.linkText = true;
457 | if (modeCfg.highlightFormatting) state.formatting = "link";
458 | return getType(state);
459 | }
460 |
461 | if (ch === ']' && state.linkText && stream.match(/\(.*?\)| ?\[.*?\]/, false)) {
462 | if (modeCfg.highlightFormatting) state.formatting = "link";
463 | var type = getType(state);
464 | state.linkText = false;
465 | state.inline = state.f = linkHref;
466 | return type;
467 | }
468 |
469 | if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
470 | state.f = state.inline = linkInline;
471 | if (modeCfg.highlightFormatting) state.formatting = "link";
472 | var type = getType(state);
473 | if (type){
474 | type += " ";
475 | } else {
476 | type = "";
477 | }
478 | return type + tokenTypes.linkInline;
479 | }
480 |
481 | if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
482 | state.f = state.inline = linkInline;
483 | if (modeCfg.highlightFormatting) state.formatting = "link";
484 | var type = getType(state);
485 | if (type){
486 | type += " ";
487 | } else {
488 | type = "";
489 | }
490 | return type + tokenTypes.linkEmail;
491 | }
492 |
493 | if (ch === '<' && stream.match(/^(!--|\w)/, false)) {
494 | var end = stream.string.indexOf(">", stream.pos);
495 | if (end != -1) {
496 | var atts = stream.string.substring(stream.start, end);
497 | if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true;
498 | }
499 | stream.backUp(1);
500 | state.htmlState = CodeMirror.startState(htmlMode);
501 | return switchBlock(stream, state, htmlBlock);
502 | }
503 |
504 | if (ch === '<' && stream.match(/^\/\w*?>/)) {
505 | state.md_inside = false;
506 | return "tag";
507 | }
508 |
509 | var ignoreUnderscore = false;
510 | if (!modeCfg.underscoresBreakWords) {
511 | if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
512 | var prevPos = stream.pos - 2;
513 | if (prevPos >= 0) {
514 | var prevCh = stream.string.charAt(prevPos);
515 | if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
516 | ignoreUnderscore = true;
517 | }
518 | }
519 | }
520 | }
521 | if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
522 | if (sol && stream.peek() === ' ') {
523 | // Do nothing, surrounded by newline and space
524 | } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
525 | if (modeCfg.highlightFormatting) state.formatting = "strong";
526 | var t = getType(state);
527 | state.strong = false;
528 | return t;
529 | } else if (!state.strong && stream.eat(ch)) { // Add STRONG
530 | state.strong = ch;
531 | if (modeCfg.highlightFormatting) state.formatting = "strong";
532 | return getType(state);
533 | } else if (state.em === ch) { // Remove EM
534 | if (modeCfg.highlightFormatting) state.formatting = "em";
535 | var t = getType(state);
536 | state.em = false;
537 | return t;
538 | } else if (!state.em) { // Add EM
539 | state.em = ch;
540 | if (modeCfg.highlightFormatting) state.formatting = "em";
541 | return getType(state);
542 | }
543 | } else if (ch === ' ') {
544 | if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
545 | if (stream.peek() === ' ') { // Surrounded by spaces, ignore
546 | return getType(state);
547 | } else { // Not surrounded by spaces, back up pointer
548 | stream.backUp(1);
549 | }
550 | }
551 | }
552 |
553 | if (modeCfg.strikethrough) {
554 | if (ch === '~' && stream.eatWhile(ch)) {
555 | if (state.strikethrough) {// Remove strikethrough
556 | if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
557 | var t = getType(state);
558 | state.strikethrough = false;
559 | return t;
560 | } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough
561 | state.strikethrough = true;
562 | if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
563 | return getType(state);
564 | }
565 | } else if (ch === ' ') {
566 | if (stream.match(/^~~/, true)) { // Probably surrounded by space
567 | if (stream.peek() === ' ') { // Surrounded by spaces, ignore
568 | return getType(state);
569 | } else { // Not surrounded by spaces, back up pointer
570 | stream.backUp(2);
571 | }
572 | }
573 | }
574 | }
575 |
576 | if (ch === ' ') {
577 | if (stream.match(/ +$/, false)) {
578 | state.trailingSpace++;
579 | } else if (state.trailingSpace) {
580 | state.trailingSpaceNewLine = true;
581 | }
582 | }
583 |
584 | return getType(state);
585 | }
586 |
587 | function linkInline(stream, state) {
588 | var ch = stream.next();
589 |
590 | if (ch === ">") {
591 | state.f = state.inline = inlineNormal;
592 | if (modeCfg.highlightFormatting) state.formatting = "link";
593 | var type = getType(state);
594 | if (type){
595 | type += " ";
596 | } else {
597 | type = "";
598 | }
599 | return type + tokenTypes.linkInline;
600 | }
601 |
602 | stream.match(/^[^>]+/, true);
603 |
604 | return tokenTypes.linkInline;
605 | }
606 |
607 | function linkHref(stream, state) {
608 | // Check if space, and return NULL if so (to avoid marking the space)
609 | if(stream.eatSpace()){
610 | return null;
611 | }
612 | var ch = stream.next();
613 | if (ch === '(' || ch === '[') {
614 | state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]", 0);
615 | if (modeCfg.highlightFormatting) state.formatting = "link-string";
616 | state.linkHref = true;
617 | return getType(state);
618 | }
619 | return 'error';
620 | }
621 |
622 | var linkRE = {
623 | ")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,
624 | "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\\]]|\\.)*\])*?(?=\])/
625 | }
626 |
627 | function getLinkHrefInside(endChar) {
628 | return function(stream, state) {
629 | var ch = stream.next();
630 |
631 | if (ch === endChar) {
632 | state.f = state.inline = inlineNormal;
633 | if (modeCfg.highlightFormatting) state.formatting = "link-string";
634 | var returnState = getType(state);
635 | state.linkHref = false;
636 | return returnState;
637 | }
638 |
639 | stream.match(linkRE[endChar])
640 | state.linkHref = true;
641 | return getType(state);
642 | };
643 | }
644 |
645 | function footnoteLink(stream, state) {
646 | if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) {
647 | state.f = footnoteLinkInside;
648 | stream.next(); // Consume [
649 | if (modeCfg.highlightFormatting) state.formatting = "link";
650 | state.linkText = true;
651 | return getType(state);
652 | }
653 | return switchInline(stream, state, inlineNormal);
654 | }
655 |
656 | function footnoteLinkInside(stream, state) {
657 | if (stream.match(/^\]:/, true)) {
658 | state.f = state.inline = footnoteUrl;
659 | if (modeCfg.highlightFormatting) state.formatting = "link";
660 | var returnType = getType(state);
661 | state.linkText = false;
662 | return returnType;
663 | }
664 |
665 | stream.match(/^([^\]\\]|\\.)+/, true);
666 |
667 | return tokenTypes.linkText;
668 | }
669 |
670 | function footnoteUrl(stream, state) {
671 | // Check if space, and return NULL if so (to avoid marking the space)
672 | if(stream.eatSpace()){
673 | return null;
674 | }
675 | // Match URL
676 | stream.match(/^[^\s]+/, true);
677 | // Check for link title
678 | if (stream.peek() === undefined) { // End of line, set flag to check next line
679 | state.linkTitle = true;
680 | } else { // More content on line, check if link title
681 | stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
682 | }
683 | state.f = state.inline = inlineNormal;
684 | return tokenTypes.linkHref + " url";
685 | }
686 |
687 | var mode = {
688 | startState: function() {
689 | return {
690 | f: blockNormal,
691 |
692 | prevLine: null,
693 | thisLine: null,
694 |
695 | block: blockNormal,
696 | htmlState: null,
697 | indentation: 0,
698 |
699 | inline: inlineNormal,
700 | text: handleText,
701 |
702 | formatting: false,
703 | linkText: false,
704 | linkHref: false,
705 | linkTitle: false,
706 | code: 0,
707 | em: false,
708 | strong: false,
709 | header: 0,
710 | hr: false,
711 | taskList: false,
712 | list: false,
713 | listStack: [],
714 | quote: 0,
715 | trailingSpace: 0,
716 | trailingSpaceNewLine: false,
717 | strikethrough: false,
718 | fencedChars: null
719 | };
720 | },
721 |
722 | copyState: function(s) {
723 | return {
724 | f: s.f,
725 |
726 | prevLine: s.prevLine,
727 | thisLine: s.thisLine,
728 |
729 | block: s.block,
730 | htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
731 | indentation: s.indentation,
732 |
733 | localMode: s.localMode,
734 | localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
735 |
736 | inline: s.inline,
737 | text: s.text,
738 | formatting: false,
739 | linkTitle: s.linkTitle,
740 | code: s.code,
741 | em: s.em,
742 | strong: s.strong,
743 | strikethrough: s.strikethrough,
744 | header: s.header,
745 | hr: s.hr,
746 | taskList: s.taskList,
747 | list: s.list,
748 | listStack: s.listStack.slice(0),
749 | quote: s.quote,
750 | indentedCode: s.indentedCode,
751 | trailingSpace: s.trailingSpace,
752 | trailingSpaceNewLine: s.trailingSpaceNewLine,
753 | md_inside: s.md_inside,
754 | fencedChars: s.fencedChars
755 | };
756 | },
757 |
758 | token: function(stream, state) {
759 |
760 | // Reset state.formatting
761 | state.formatting = false;
762 |
763 | if (stream != state.thisLine) {
764 | var forceBlankLine = state.header || state.hr;
765 |
766 | // Reset state.header and state.hr
767 | state.header = 0;
768 | state.hr = false;
769 |
770 | if (stream.match(/^\s*$/, true) || forceBlankLine) {
771 | blankLine(state);
772 | if (!forceBlankLine) return null
773 | state.prevLine = null
774 | }
775 |
776 | state.prevLine = state.thisLine
777 | state.thisLine = stream
778 |
779 | // Reset state.taskList
780 | state.taskList = false;
781 |
782 | // Reset state.trailingSpace
783 | state.trailingSpace = 0;
784 | state.trailingSpaceNewLine = false;
785 |
786 | state.f = state.block;
787 | var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
788 | state.indentationDiff = Math.min(indentation - state.indentation, 4);
789 | state.indentation = state.indentation + state.indentationDiff;
790 | if (indentation > 0) return null;
791 | }
792 | return state.f(stream, state);
793 | },
794 |
795 | innerMode: function(state) {
796 | if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
797 | if (state.localState) return {state: state.localState, mode: state.localMode};
798 | return {state: state, mode: mode};
799 | },
800 |
801 | blankLine: blankLine,
802 |
803 | getType: getType,
804 |
805 | closeBrackets: "()[]{}''\"\"``",
806 | fold: "markdown"
807 | };
808 | return mode;
809 | }, "xml");
810 |
811 | CodeMirror.defineMIME("text/x-markdown", "markdown");
812 |
813 | });
814 |
--------------------------------------------------------------------------------