From f9ced97a97f5bebec57545fbf611952026bf0d5d Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 16 Mar 2017 17:04:58 +0000 Subject: [PATCH 1/8] Started iPython notebook viewer Using NotebookLab library [ci skip] --- .../javascripts/blob/notebook_viewer.js | 20 + app/models/blob.rb | 6 + app/views/projects/blob/_notebook.html.haml | 5 + config/webpack.config.js | 2 + vendor/assets/javascripts/notebooklab.js | 2043 +++++++++++++++++ 5 files changed, 2076 insertions(+) create mode 100644 app/assets/javascripts/blob/notebook_viewer.js create mode 100644 app/views/projects/blob/_notebook.html.haml create mode 100644 vendor/assets/javascripts/notebooklab.js diff --git a/app/assets/javascripts/blob/notebook_viewer.js b/app/assets/javascripts/blob/notebook_viewer.js new file mode 100644 index 00000000000..dda137c6603 --- /dev/null +++ b/app/assets/javascripts/blob/notebook_viewer.js @@ -0,0 +1,20 @@ +import Vue from 'vue'; +import NotebookLab from 'vendor/notebooklab'; + +Vue.use(NotebookLab); + +$(() => { + new Vue({ + el: '#js-notebook-viewer', + data() { + return { + json: {}, + }; + }, + template: ` +
+ +
+ `, + }); +}); diff --git a/app/models/blob.rb b/app/models/blob.rb index 1376b86fdad..5b71ac21cc0 100644 --- a/app/models/blob.rb +++ b/app/models/blob.rb @@ -46,6 +46,10 @@ class Blob < SimpleDelegator text? && language && language.name == 'SVG' end + def ipython_notebook? + text? && language && language.name == 'Jupyter Notebook' + end + def size_within_svg_limits? size <= MAXIMUM_SVG_SIZE end @@ -63,6 +67,8 @@ class Blob < SimpleDelegator end elsif image? || svg? 'image' + elsif ipython_notebook? + 'notebook' elsif text? 'text' else diff --git a/app/views/projects/blob/_notebook.html.haml b/app/views/projects/blob/_notebook.html.haml new file mode 100644 index 00000000000..19d3e401d27 --- /dev/null +++ b/app/views/projects/blob/_notebook.html.haml @@ -0,0 +1,5 @@ +- content_for :page_specific_javascripts do + = page_specific_javascript_bundle_tag('common_vue') + = page_specific_javascript_bundle_tag('notebook_viewer') + +.file-content#js-notebook-viewer diff --git a/config/webpack.config.js b/config/webpack.config.js index 3cf94b9b435..2ea2b33511b 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -37,6 +37,7 @@ var config = { merge_request_widget: './merge_request_widget/ci_bundle.js', monitoring: './monitoring/monitoring_bundle.js', network: './network/network_bundle.js', + notebook_viewer: './blob/notebook_viewer.js', profile: './profile/profile_bundle.js', protected_branches: './protected_branches/protected_branches_bundle.js', snippet: './snippet/snippet_bundle.js', @@ -105,6 +106,7 @@ var config = { 'environments_folder', 'issuable', 'merge_conflicts', + 'notebook_viewer', 'vue_pipelines', ], minChunks: function(module, count) { diff --git a/vendor/assets/javascripts/notebooklab.js b/vendor/assets/javascripts/notebooklab.js new file mode 100644 index 00000000000..abcd6cd3d98 --- /dev/null +++ b/vendor/assets/javascripts/notebooklab.js @@ -0,0 +1,2043 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define("NotebookLab", [], factory); + else if(typeof exports === 'object') + exports["NotebookLab"] = factory(); + else + root["NotebookLab"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 19); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +module.exports = function normalizeComponent ( + rawScriptExports, + compiledTemplate, + scopeId, + cssModules +) { + var esModule + var scriptExports = rawScriptExports = rawScriptExports || {} + + // ES6 modules interop + var type = typeof rawScriptExports.default + if (type === 'object' || type === 'function') { + esModule = rawScriptExports + scriptExports = rawScriptExports.default + } + + // Vue.extend constructor export interop + var options = typeof scriptExports === 'function' + ? scriptExports.options + : scriptExports + + // render functions + if (compiledTemplate) { + options.render = compiledTemplate.render + options.staticRenderFns = compiledTemplate.staticRenderFns + } + + // scopedId + if (scopeId) { + options._scopeId = scopeId + } + + // inject cssModules + if (cssModules) { + var computed = Object.create(options.computed || null) + Object.keys(cssModules).forEach(function (key) { + var module = cssModules[key] + computed[key] = function () { return module } + }) + options.computed = computed + } + + return { + esModule: esModule, + exports: scriptExports, + options: options + } +} + + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +var Component = __webpack_require__(0)( + /* script */ + __webpack_require__(6), + /* template */ + __webpack_require__(15), + /* scopeId */ + null, + /* cssModules */ + null +) +Component.options.__file = "/Users/phil/Projects/notebooklab/src/cells/prompt.vue" +if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key !== "__esModule"})) {console.error("named exports are not supported in *.vue files.")} +if (Component.options.functional) {console.error("[vue-loader] prompt.vue: functional components are not supported with templates, they should use render functions.")} + +/* hot reload */ +if (false) {(function () { + var hotAPI = require("vue-hot-reload-api") + hotAPI.install(require("vue"), false) + if (!hotAPI.compatible) return + module.hot.accept() + if (!module.hot.data) { + hotAPI.createRecord("data-v-4f6bf458", Component.options) + } else { + hotAPI.reload("data-v-4f6bf458", Component.options) + } +})()} + +module.exports = Component.exports + + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +var Component = __webpack_require__(0)( + /* script */ + __webpack_require__(7), + /* template */ + __webpack_require__(14), + /* scopeId */ + null, + /* cssModules */ + null +) +Component.options.__file = "/Users/phil/Projects/notebooklab/src/index.vue" +if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key !== "__esModule"})) {console.error("named exports are not supported in *.vue files.")} +if (Component.options.functional) {console.error("[vue-loader] index.vue: functional components are not supported with templates, they should use render functions.")} + +/* hot reload */ +if (false) {(function () { + var hotAPI = require("vue-hot-reload-api") + hotAPI.install(require("vue"), false) + if (!hotAPI.compatible) return + module.hot.accept() + if (!module.hot.data) { + hotAPI.createRecord("data-v-4cb2b168", Component.options) + } else { + hotAPI.reload("data-v-4cb2b168", Component.options) + } +})()} + +module.exports = Component.exports + + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _index = __webpack_require__(11); + +var _index2 = _interopRequireDefault(_index); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + components: { + 'code-cell': _index2.default + }, + props: { + cell: { + type: Object, + required: true + } + }, + computed: { + rawInputCode: function rawInputCode() { + return this.cell.source.join(''); + }, + hasOutput: function hasOutput() { + return this.cell.outputs.length; + }, + output: function output() { + return this.cell.outputs[0]; + }, + outputText: function outputText() { + if (this.output.text) { + return this.output.text.join(''); + } else { + return this.output.data[Object.keys(this.output.data)[0]].join(''); + } + } + } +}; // +// +// +// +// +// +// +// +// +// +// +// +// +// + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _prompt = __webpack_require__(1); + +var _prompt2 = _interopRequireDefault(_prompt); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + components: { + 'prompt': _prompt2.default + }, + props: { + count: { + type: Number, + required: false + }, + type: { + type: String, + required: true + }, + rawCode: { + type: String, + required: true + } + }, + computed: { + code: function code() { + if (typeof hljs !== 'undefined' && this.promptType === 'In') { + return hljs.highlightAuto(this.rawCode).value; + } else { + return this.rawCode; + } + }, + promptType: function promptType() { + var type = this.type.split('put')[0]; + + return type.charAt(0).toUpperCase() + type.slice(1);; + } + } +}; // +// +// +// +// +// +// +// +// + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _marked = __webpack_require__(9); + +var _marked2 = _interopRequireDefault(_marked); + +var _prompt = __webpack_require__(1); + +var _prompt2 = _interopRequireDefault(_prompt); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// +// +// +// +// +// +// + +exports.default = { + components: { + 'prompt': _prompt2.default + }, + props: { + cell: { + type: Object, + required: true + } + }, + computed: { + markdown: function markdown() { + var regex = new RegExp(/^\$\$(.*)\$\$$/, 'g'); + + var source = this.cell.source.map(function (line) { + var matches = regex.exec(line.trim()); + + // Only render use the Katex library if it is actually loaded + if (matches && matches.length > 0 && katex) { + return katex.renderToString(matches[1]); + } else { + return line; + } + }); + + return (0, _marked2.default)(source.join('')); + } + } +}; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +// +// +// +// +// +// +// +// + +exports.default = { + props: { + type: { + type: String, + required: false + }, + count: { + type: Number, + required: false + } + } +}; + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _cells = __webpack_require__(8); + +exports.default = { + components: { + 'code-cell': _cells.CodeCell, + 'markdown-cell': _cells.MarkdownCell + }, + props: { + notebook: { + type: Object, + required: true + } + }, + methods: { + cellType: function cellType(type) { + return type + '-cell'; + } + }, + computed: { + hasNotebook: function hasNotebook() { + return Object.keys(this.notebook).length; + } + } +}; // +// +// +// +// +// +// +// +// +// + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _markdown = __webpack_require__(12); + +Object.defineProperty(exports, 'MarkdownCell', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_markdown).default; + } +}); + +var _code = __webpack_require__(10); + +Object.defineProperty(exports, 'CodeCell', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_code).default; + } +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(global) {/** + * marked - a markdown parser + * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed) + * https://github.com/chjj/marked + */ + +;(function() { + +/** + * Block-Level Grammar + */ + +var block = { + newline: /^\n+/, + code: /^( {4}[^\n]+\n*)+/, + fences: noop, + hr: /^( *[-*_]){3,} *(?:\n+|$)/, + heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/, + nptable: noop, + 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: /^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, + table: noop, + paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/, + text: /^[^\n]+/ +}; + +block.bullet = /(?:[*+-]|\d+\.)/; +block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/; +block.item = replace(block.item, 'gm') + (/bull/g, block.bullet) + (); + +block.list = replace(block.list) + (/bull/g, block.bullet) + ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))') + ('def', '\\n+(?=' + block.def.source + ')') + (); + +block.blockquote = replace(block.blockquote) + ('def', block.def) + (); + +block._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'; + +block.html = replace(block.html) + ('comment', //) + ('closed', /<(tag)[\s\S]+?<\/\1>/) + ('closing', /])*?>/) + (/tag/g, block._tag) + (); + +block.paragraph = replace(block.paragraph) + ('hr', block.hr) + ('heading', block.heading) + ('lheading', block.lheading) + ('blockquote', block.blockquote) + ('tag', '<' + block._tag) + ('def', block.def) + (); + +/** + * Normal Block Grammar + */ + +block.normal = merge({}, block); + +/** + * GFM Block Grammar + */ + +block.gfm = merge({}, block.normal, { + fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/, + paragraph: /^/, + heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/ +}); + +block.gfm.paragraph = replace(block.paragraph) + ('(?!', '(?!' + + block.gfm.fences.source.replace('\\1', '\\2') + '|' + + block.list.source.replace('\\1', '\\3') + '|') + (); + +/** + * GFM + Tables Block Grammar + */ + +block.tables = merge({}, block.gfm, { + nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/, + table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/ +}); + +/** + * Block Lexer + */ + +function Lexer(options) { + this.tokens = []; + this.tokens.links = {}; + this.options = options || marked.defaults; + this.rules = block.normal; + + if (this.options.gfm) { + if (this.options.tables) { + this.rules = block.tables; + } else { + this.rules = block.gfm; + } + } +} + +/** + * Expose Block Rules + */ + +Lexer.rules = block; + +/** + * Static Lex Method + */ + +Lexer.lex = function(src, options) { + var lexer = new Lexer(options); + return lexer.lex(src); +}; + +/** + * Preprocessing + */ + +Lexer.prototype.lex = function(src) { + src = src + .replace(/\r\n|\r/g, '\n') + .replace(/\t/g, ' ') + .replace(/\u00a0/g, ' ') + .replace(/\u2424/g, '\n'); + + return this.token(src, true); +}; + +/** + * Lexing + */ + +Lexer.prototype.token = function(src, top, bq) { + var src = src.replace(/^ +$/gm, '') + , next + , loose + , cap + , bull + , b + , item + , space + , i + , l; + + while (src) { + // newline + if (cap = this.rules.newline.exec(src)) { + src = src.substring(cap[0].length); + if (cap[0].length > 1) { + this.tokens.push({ + type: 'space' + }); + } + } + + // code + if (cap = this.rules.code.exec(src)) { + src = src.substring(cap[0].length); + cap = cap[0].replace(/^ {4}/gm, ''); + this.tokens.push({ + type: 'code', + text: !this.options.pedantic + ? cap.replace(/\n+$/, '') + : cap + }); + continue; + } + + // fences (gfm) + if (cap = this.rules.fences.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'code', + lang: cap[2], + text: cap[3] || '' + }); + continue; + } + + // heading + if (cap = this.rules.heading.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'heading', + depth: cap[1].length, + text: cap[2] + }); + continue; + } + + // table no leading pipe (gfm) + if (top && (cap = this.rules.nptable.exec(src))) { + src = src.substring(cap[0].length); + + item = { + type: 'table', + header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + cells: cap[3].replace(/\n$/, '').split('\n') + }; + + for (i = 0; i < item.align.length; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = item.cells[i].split(/ *\| */); + } + + this.tokens.push(item); + + continue; + } + + // lheading + if (cap = this.rules.lheading.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'heading', + depth: cap[2] === '=' ? 1 : 2, + text: cap[1] + }); + continue; + } + + // hr + if (cap = this.rules.hr.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'hr' + }); + continue; + } + + // blockquote + if (cap = this.rules.blockquote.exec(src)) { + src = src.substring(cap[0].length); + + this.tokens.push({ + type: 'blockquote_start' + }); + + cap = cap[0].replace(/^ *> ?/gm, ''); + + // Pass `top` to keep the current + // "toplevel" state. This is exactly + // how markdown.pl works. + this.token(cap, top, true); + + this.tokens.push({ + type: 'blockquote_end' + }); + + continue; + } + + // list + if (cap = this.rules.list.exec(src)) { + src = src.substring(cap[0].length); + bull = cap[2]; + + this.tokens.push({ + type: 'list_start', + ordered: bull.length > 1 + }); + + // Get each top-level item. + cap = cap[0].match(this.rules.item); + + next = false; + l = cap.length; + i = 0; + + for (; i < l; i++) { + item = cap[i]; + + // Remove the list item's bullet + // so it is seen as the next token. + space = item.length; + item = item.replace(/^ *([*+-]|\d+\.) +/, ''); + + // Outdent whatever the + // list item contains. Hacky. + if (~item.indexOf('\n ')) { + space -= item.length; + item = !this.options.pedantic + ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') + : item.replace(/^ {1,4}/gm, ''); + } + + // Determine whether the next list item belongs here. + // Backpedal if it does not belong in this list. + if (this.options.smartLists && i !== l - 1) { + b = block.bullet.exec(cap[i + 1])[0]; + if (bull !== b && !(bull.length > 1 && b.length > 1)) { + src = cap.slice(i + 1).join('\n') + src; + i = l - 1; + } + } + + // Determine whether item is loose or not. + // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/ + // for discount behavior. + loose = next || /\n\n(?!\s*$)/.test(item); + if (i !== l - 1) { + next = item.charAt(item.length - 1) === '\n'; + if (!loose) loose = next; + } + + this.tokens.push({ + type: loose + ? 'loose_item_start' + : 'list_item_start' + }); + + // Recurse. + this.token(item, false, bq); + + this.tokens.push({ + type: 'list_item_end' + }); + } + + this.tokens.push({ + type: 'list_end' + }); + + continue; + } + + // html + if (cap = this.rules.html.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: this.options.sanitize + ? 'paragraph' + : 'html', + pre: !this.options.sanitizer + && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'), + text: cap[0] + }); + continue; + } + + // def + if ((!bq && top) && (cap = this.rules.def.exec(src))) { + src = src.substring(cap[0].length); + this.tokens.links[cap[1].toLowerCase()] = { + href: cap[2], + title: cap[3] + }; + continue; + } + + // table (gfm) + if (top && (cap = this.rules.table.exec(src))) { + src = src.substring(cap[0].length); + + item = { + type: 'table', + header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') + }; + + for (i = 0; i < item.align.length; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = item.cells[i] + .replace(/^ *\| *| *\| *$/g, '') + .split(/ *\| */); + } + + this.tokens.push(item); + + continue; + } + + // top-level paragraph + if (top && (cap = this.rules.paragraph.exec(src))) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'paragraph', + text: cap[1].charAt(cap[1].length - 1) === '\n' + ? cap[1].slice(0, -1) + : cap[1] + }); + continue; + } + + // text + if (cap = this.rules.text.exec(src)) { + // Top-level should never reach here. + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'text', + text: cap[0] + }); + continue; + } + + if (src) { + throw new + Error('Infinite loop on byte: ' + src.charCodeAt(0)); + } + } + + return this.tokens; +}; + +/** + * Inline-Level Grammar + */ + +var inline = { + escape: /^\\([\\`*{}\[\]()#+\-.!_>])/, + autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, + url: noop, + tag: /^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/, + link: /^!?\[(inside)\]\(href\)/, + reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/, + nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/, + strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/, + em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, + code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/, + br: /^ {2,}\n(?!\s*$)/, + del: noop, + text: /^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/; + +inline.link = replace(inline.link) + ('inside', inline._inside) + ('href', inline._href) + (); + +inline.reflink = replace(inline.reflink) + ('inside', inline._inside) + (); + +/** + * Normal Inline Grammar + */ + +inline.normal = merge({}, inline); + +/** + * Pedantic Inline Grammar + */ + +inline.pedantic = merge({}, inline.normal, { + strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, + em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/ +}); + +/** + * GFM Inline Grammar + */ + +inline.gfm = merge({}, inline.normal, { + escape: replace(inline.escape)('])', '~|])')(), + url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, + del: /^~~(?=\S)([\s\S]*?\S)~~/, + text: replace(inline.text) + (']|', '~]|') + ('|', '|https?://|') + () +}); + +/** + * GFM + Line Breaks Inline Grammar + */ + +inline.breaks = merge({}, inline.gfm, { + br: replace(inline.br)('{2,}', '*')(), + text: replace(inline.gfm.text)('{2,}', '*')() +}); + +/** + * Inline Lexer & Compiler + */ + +function InlineLexer(links, options) { + this.options = options || marked.defaults; + this.links = links; + this.rules = inline.normal; + this.renderer = this.options.renderer || new Renderer; + this.renderer.options = this.options; + + if (!this.links) { + throw new + Error('Tokens array requires a `links` property.'); + } + + if (this.options.gfm) { + if (this.options.breaks) { + this.rules = inline.breaks; + } else { + this.rules = inline.gfm; + } + } else if (this.options.pedantic) { + this.rules = inline.pedantic; + } +} + +/** + * Expose Inline Rules + */ + +InlineLexer.rules = inline; + +/** + * Static Lexing/Compiling Method + */ + +InlineLexer.output = function(src, links, options) { + var inline = new InlineLexer(links, options); + return inline.output(src); +}; + +/** + * Lexing/Compiling + */ + +InlineLexer.prototype.output = function(src) { + var out = '' + , link + , text + , href + , cap; + + while (src) { + // escape + if (cap = this.rules.escape.exec(src)) { + src = src.substring(cap[0].length); + out += cap[1]; + continue; + } + + // autolink + if (cap = this.rules.autolink.exec(src)) { + src = src.substring(cap[0].length); + if (cap[2] === '@') { + text = cap[1].charAt(6) === ':' + ? this.mangle(cap[1].substring(7)) + : this.mangle(cap[1]); + href = this.mangle('mailto:') + text; + } else { + text = escape(cap[1]); + href = text; + } + out += this.renderer.link(href, null, text); + continue; + } + + // url (gfm) + if (!this.inLink && (cap = this.rules.url.exec(src))) { + src = src.substring(cap[0].length); + text = escape(cap[1]); + href = text; + out += this.renderer.link(href, null, text); + continue; + } + + // tag + if (cap = this.rules.tag.exec(src)) { + if (!this.inLink && /^/i.test(cap[0])) { + this.inLink = false; + } + src = src.substring(cap[0].length); + out += this.options.sanitize + ? this.options.sanitizer + ? this.options.sanitizer(cap[0]) + : escape(cap[0]) + : cap[0] + continue; + } + + // link + if (cap = this.rules.link.exec(src)) { + src = src.substring(cap[0].length); + this.inLink = true; + out += this.outputLink(cap, { + href: cap[2], + title: cap[3] + }); + this.inLink = false; + continue; + } + + // reflink, nolink + if ((cap = this.rules.reflink.exec(src)) + || (cap = this.rules.nolink.exec(src))) { + src = src.substring(cap[0].length); + link = (cap[2] || cap[1]).replace(/\s+/g, ' '); + link = this.links[link.toLowerCase()]; + if (!link || !link.href) { + out += cap[0].charAt(0); + src = cap[0].substring(1) + src; + continue; + } + this.inLink = true; + out += this.outputLink(cap, link); + this.inLink = false; + continue; + } + + // strong + if (cap = this.rules.strong.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.strong(this.output(cap[2] || cap[1])); + continue; + } + + // em + if (cap = this.rules.em.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.em(this.output(cap[2] || cap[1])); + continue; + } + + // code + if (cap = this.rules.code.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.codespan(escape(cap[2], true)); + continue; + } + + // br + if (cap = this.rules.br.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.br(); + continue; + } + + // del (gfm) + if (cap = this.rules.del.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.del(this.output(cap[1])); + continue; + } + + // text + if (cap = this.rules.text.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.text(escape(this.smartypants(cap[0]))); + continue; + } + + if (src) { + throw new + Error('Infinite loop on byte: ' + src.charCodeAt(0)); + } + } + + return out; +}; + +/** + * Compile Link + */ + +InlineLexer.prototype.outputLink = function(cap, link) { + var href = escape(link.href) + , title = link.title ? escape(link.title) : null; + + return cap[0].charAt(0) !== '!' + ? this.renderer.link(href, title, this.output(cap[1])) + : this.renderer.image(href, title, escape(cap[1])); +}; + +/** + * Smartypants Transformations + */ + +InlineLexer.prototype.smartypants = function(text) { + if (!this.options.smartypants) return text; + return text + // em-dashes + .replace(/---/g, '\u2014') + // en-dashes + .replace(/--/g, '\u2013') + // opening singles + .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018') + // closing singles & apostrophes + .replace(/'/g, '\u2019') + // opening doubles + .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c') + // closing doubles + .replace(/"/g, '\u201d') + // ellipses + .replace(/\.{3}/g, '\u2026'); +}; + +/** + * Mangle Links + */ + +InlineLexer.prototype.mangle = function(text) { + if (!this.options.mangle) return text; + var out = '' + , l = text.length + , i = 0 + , ch; + + for (; i < l; i++) { + ch = text.charCodeAt(i); + if (Math.random() > 0.5) { + ch = 'x' + ch.toString(16); + } + out += '&#' + ch + ';'; + } + + return out; +}; + +/** + * Renderer + */ + +function Renderer(options) { + this.options = options || {}; +} + +Renderer.prototype.code = function(code, lang, escaped) { + if (this.options.highlight) { + var out = this.options.highlight(code, lang); + if (out != null && out !== code) { + escaped = true; + code = out; + } + } + + if (!lang) { + return '
'
+      + (escaped ? code : escape(code, true))
+      + '\n
'; + } + + return '
'
+    + (escaped ? code : escape(code, true))
+    + '\n
\n'; +}; + +Renderer.prototype.blockquote = function(quote) { + return '
\n' + quote + '
\n'; +}; + +Renderer.prototype.html = function(html) { + return html; +}; + +Renderer.prototype.heading = function(text, level, raw) { + return '' + + text + + '\n'; +}; + +Renderer.prototype.hr = function() { + return this.options.xhtml ? '
\n' : '
\n'; +}; + +Renderer.prototype.list = function(body, ordered) { + var type = ordered ? 'ol' : 'ul'; + return '<' + type + '>\n' + body + '\n'; +}; + +Renderer.prototype.listitem = function(text) { + return '
  • ' + text + '
  • \n'; +}; + +Renderer.prototype.paragraph = function(text) { + return '

    ' + text + '

    \n'; +}; + +Renderer.prototype.table = function(header, body) { + return '\n' + + '\n' + + header + + '\n' + + '\n' + + body + + '\n' + + '
    \n'; +}; + +Renderer.prototype.tablerow = function(content) { + return '\n' + content + '\n'; +}; + +Renderer.prototype.tablecell = function(content, flags) { + var type = flags.header ? 'th' : 'td'; + var tag = flags.align + ? '<' + type + ' style="text-align:' + flags.align + '">' + : '<' + type + '>'; + return tag + content + '\n'; +}; + +// span level renderer +Renderer.prototype.strong = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.em = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.codespan = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.br = function() { + return this.options.xhtml ? '
    ' : '
    '; +}; + +Renderer.prototype.del = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.link = function(href, title, text) { + if (this.options.sanitize) { + try { + var prot = decodeURIComponent(unescape(href)) + .replace(/[^\w:]/g, '') + .toLowerCase(); + } catch (e) { + return ''; + } + if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) { + return ''; + } + } + var out = '
    '; + return out; +}; + +Renderer.prototype.image = function(href, title, text) { + var out = '' + text + '' : '>'; + return out; +}; + +Renderer.prototype.text = function(text) { + return text; +}; + +/** + * Parsing & Compiling + */ + +function Parser(options) { + this.tokens = []; + this.token = null; + this.options = options || marked.defaults; + this.options.renderer = this.options.renderer || new Renderer; + this.renderer = this.options.renderer; + this.renderer.options = this.options; +} + +/** + * Static Parse Method + */ + +Parser.parse = function(src, options, renderer) { + var parser = new Parser(options, renderer); + return parser.parse(src); +}; + +/** + * Parse Loop + */ + +Parser.prototype.parse = function(src) { + this.inline = new InlineLexer(src.links, this.options, this.renderer); + this.tokens = src.reverse(); + + var out = ''; + while (this.next()) { + out += this.tok(); + } + + return out; +}; + +/** + * Next Token + */ + +Parser.prototype.next = function() { + return this.token = this.tokens.pop(); +}; + +/** + * Preview Next Token + */ + +Parser.prototype.peek = function() { + return this.tokens[this.tokens.length - 1] || 0; +}; + +/** + * Parse Text Tokens + */ + +Parser.prototype.parseText = function() { + var body = this.token.text; + + while (this.peek().type === 'text') { + body += '\n' + this.next().text; + } + + return this.inline.output(body); +}; + +/** + * Parse Current Token + */ + +Parser.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 header = '' + , body = '' + , i + , row + , cell + , flags + , j; + + // header + cell = ''; + for (i = 0; i < this.token.header.length; i++) { + flags = { header: true, align: this.token.align[i] }; + cell += this.renderer.tablecell( + this.inline.output(this.token.header[i]), + { header: true, align: this.token.align[i] } + ); + } + header += this.renderer.tablerow(cell); + + for (i = 0; i < this.token.cells.length; i++) { + row = this.token.cells[i]; + + cell = ''; + for (j = 0; j < row.length; j++) { + cell += this.renderer.tablecell( + this.inline.output(row[j]), + { header: false, align: this.token.align[j] } + ); + } + + body += this.renderer.tablerow(cell); + } + return this.renderer.table(header, body); + } + case 'blockquote_start': { + var body = ''; + + while (this.next().type !== 'blockquote_end') { + body += this.tok(); + } + + return this.renderer.blockquote(body); + } + case 'list_start': { + var body = '' + , ordered = this.token.ordered; + + while (this.next().type !== 'list_end') { + body += this.tok(); + } + + return this.renderer.list(body, ordered); + } + case 'list_item_start': { + var body = ''; + + while (this.next().type !== 'list_item_end') { + body += this.token.type === 'text' + ? this.parseText() + : this.tok(); + } + + return this.renderer.listitem(body); + } + case 'loose_item_start': { + var body = ''; + + while (this.next().type !== 'list_item_end') { + body += this.tok(); + } + + return this.renderer.listitem(body); + } + case 'html': { + var html = !this.token.pre && !this.options.pedantic + ? this.inline.output(this.token.text) + : this.token.text; + return this.renderer.html(html); + } + case 'paragraph': { + return this.renderer.paragraph(this.inline.output(this.token.text)); + } + case 'text': { + return this.renderer.paragraph(this.parseText()); + } + } +}; + +/** + * Helpers + */ + +function escape(html, encode) { + return html + .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +function unescape(html) { + // explicitly match decimal, hex, and named HTML entities + return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) { + n = n.toLowerCase(); + if (n === 'colon') return ':'; + if (n.charAt(0) === '#') { + return n.charAt(1) === 'x' + ? String.fromCharCode(parseInt(n.substring(2), 16)) + : String.fromCharCode(+n.substring(1)); + } + return ''; + }); +} + +function replace(regex, opt) { + regex = regex.source; + opt = opt || ''; + return function self(name, val) { + if (!name) return new RegExp(regex, opt); + val = val.source || val; + val = val.replace(/(^|[^\[])\^/g, '$1'); + regex = regex.replace(name, val); + return self; + }; +} + +function noop() {} +noop.exec = noop; + +function merge(obj) { + var i = 1 + , target + , key; + + for (; i < arguments.length; i++) { + target = arguments[i]; + for (key in target) { + if (Object.prototype.hasOwnProperty.call(target, key)) { + obj[key] = target[key]; + } + } + } + + return obj; +} + + +/** + * Marked + */ + +function marked(src, opt, callback) { + if (callback || typeof opt === 'function') { + if (!callback) { + callback = opt; + opt = null; + } + + opt = merge({}, marked.defaults, opt || {}); + + var highlight = opt.highlight + , tokens + , pending + , i = 0; + + try { + tokens = Lexer.lex(src, opt) + } catch (e) { + return callback(e); + } + + pending = tokens.length; + + var done = function(err) { + if (err) { + opt.highlight = highlight; + return callback(err); + } + + var out; + + try { + out = Parser.parse(tokens, opt); + } catch (e) { + err = e; + } + + opt.highlight = highlight; + + return err + ? callback(err) + : callback(null, out); + }; + + if (!highlight || highlight.length < 3) { + return done(); + } + + delete opt.highlight; + + if (!pending) return done(); + + for (; i < tokens.length; i++) { + (function(token) { + if (token.type !== 'code') { + return --pending || done(); + } + return highlight(token.text, token.lang, function(err, code) { + if (err) return done(err); + if (code == null || code === token.text) { + return --pending || done(); + } + token.text = code; + token.escaped = true; + --pending || done(); + }); + })(tokens[i]); + } + + return; + } + try { + if (opt) opt = merge({}, marked.defaults, opt); + return Parser.parse(Lexer.lex(src, opt), opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/chjj/marked.'; + if ((opt || marked.defaults).silent) { + return '

    An error occured:

    '
    +        + escape(e.message + '', true)
    +        + '
    '; + } + throw e; + } +} + +/** + * Options + */ + +marked.options = +marked.setOptions = function(opt) { + merge(marked.defaults, opt); + return marked; +}; + +marked.defaults = { + gfm: true, + tables: true, + breaks: false, + pedantic: false, + sanitize: false, + sanitizer: null, + mangle: true, + smartLists: false, + silent: false, + highlight: null, + langPrefix: 'lang-', + smartypants: false, + headerPrefix: '', + renderer: new Renderer, + xhtml: false +}; + +/** + * Expose + */ + +marked.Parser = Parser; +marked.parser = Parser.parse; + +marked.Renderer = Renderer; + +marked.Lexer = Lexer; +marked.lexer = Lexer.lex; + +marked.InlineLexer = InlineLexer; +marked.inlineLexer = InlineLexer.output; + +marked.parse = marked; + +if (true) { + module.exports = marked; +} else if (typeof define === 'function' && define.amd) { + define(function() { return marked; }); +} else { + this.marked = marked; +} + +}).call(function() { + return this || (typeof window !== 'undefined' ? window : global); +}()); + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(18))) + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +var Component = __webpack_require__(0)( + /* script */ + __webpack_require__(3), + /* template */ + __webpack_require__(13), + /* scopeId */ + null, + /* cssModules */ + null +) +Component.options.__file = "/Users/phil/Projects/notebooklab/src/cells/code.vue" +if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key !== "__esModule"})) {console.error("named exports are not supported in *.vue files.")} +if (Component.options.functional) {console.error("[vue-loader] code.vue: functional components are not supported with templates, they should use render functions.")} + +/* hot reload */ +if (false) {(function () { + var hotAPI = require("vue-hot-reload-api") + hotAPI.install(require("vue"), false) + if (!hotAPI.compatible) return + module.hot.accept() + if (!module.hot.data) { + hotAPI.createRecord("data-v-3ac4c361", Component.options) + } else { + hotAPI.reload("data-v-3ac4c361", Component.options) + } +})()} + +module.exports = Component.exports + + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +var Component = __webpack_require__(0)( + /* script */ + __webpack_require__(4), + /* template */ + __webpack_require__(17), + /* scopeId */ + null, + /* cssModules */ + null +) +Component.options.__file = "/Users/phil/Projects/notebooklab/src/cells/code/index.vue" +if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key !== "__esModule"})) {console.error("named exports are not supported in *.vue files.")} +if (Component.options.functional) {console.error("[vue-loader] index.vue: functional components are not supported with templates, they should use render functions.")} + +/* hot reload */ +if (false) {(function () { + var hotAPI = require("vue-hot-reload-api") + hotAPI.install(require("vue"), false) + if (!hotAPI.compatible) return + module.hot.accept() + if (!module.hot.data) { + hotAPI.createRecord("data-v-d42105b8", Component.options) + } else { + hotAPI.reload("data-v-d42105b8", Component.options) + } +})()} + +module.exports = Component.exports + + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +var Component = __webpack_require__(0)( + /* script */ + __webpack_require__(5), + /* template */ + __webpack_require__(16), + /* scopeId */ + null, + /* cssModules */ + null +) +Component.options.__file = "/Users/phil/Projects/notebooklab/src/cells/markdown.vue" +if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key !== "__esModule"})) {console.error("named exports are not supported in *.vue files.")} +if (Component.options.functional) {console.error("[vue-loader] markdown.vue: functional components are not supported with templates, they should use render functions.")} + +/* hot reload */ +if (false) {(function () { + var hotAPI = require("vue-hot-reload-api") + hotAPI.install(require("vue"), false) + if (!hotAPI.compatible) return + module.hot.accept() + if (!module.hot.data) { + hotAPI.createRecord("data-v-7342b363", Component.options) + } else { + hotAPI.reload("data-v-7342b363", Component.options) + } +})()} + +module.exports = Component.exports + + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h; + return _c('div', { + staticClass: "cell" + }, [_c('code-cell', { + attrs: { + "type": "input", + "raw-code": _vm.rawInputCode, + "count": _vm.cell.execution_count + } + }), _vm._v(" "), (_vm.hasOutput) ? _c('code-cell', { + attrs: { + "type": "output", + "raw-code": _vm.outputText, + "count": _vm.output.execution_count + } + }) : _vm._e()], 1) +},staticRenderFns: []} +module.exports.render._withStripped = true +if (false) { + module.hot.accept() + if (module.hot.data) { + require("vue-hot-reload-api").rerender("data-v-3ac4c361", module.exports) + } +} + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h; + return (_vm.hasNotebook) ? _c('div', _vm._l((_vm.notebook.cells), function(cell, index) { + return _c(_vm.cellType(cell.cell_type), { + key: index, + tag: "component", + attrs: { + "cell": cell + } + }) + })) : _vm._e() +},staticRenderFns: []} +module.exports.render._withStripped = true +if (false) { + module.hot.accept() + if (module.hot.data) { + require("vue-hot-reload-api").rerender("data-v-4cb2b168", module.exports) + } +} + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h; + return _c('div', { + staticClass: "prompt" + }, [(_vm.type && _vm.count) ? _c('span', [_vm._v("\n " + _vm._s(_vm.type) + " [" + _vm._s(_vm.count) + "]:\n ")]) : _vm._e()]) +},staticRenderFns: []} +module.exports.render._withStripped = true +if (false) { + module.hot.accept() + if (module.hot.data) { + require("vue-hot-reload-api").rerender("data-v-4f6bf458", module.exports) + } +} + +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h; + return _c('div', { + staticClass: "cell text-cell" + }, [_c('prompt'), _vm._v(" "), _c('div', { + staticClass: "markdown", + domProps: { + "innerHTML": _vm._s(_vm.markdown) + } + })], 1) +},staticRenderFns: []} +module.exports.render._withStripped = true +if (false) { + module.hot.accept() + if (module.hot.data) { + require("vue-hot-reload-api").rerender("data-v-7342b363", module.exports) + } +} + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h; + return _c('div', { + class: _vm.type + }, [_c('prompt', { + attrs: { + "type": _vm.promptType, + "count": _vm.count + } + }), _vm._v(" "), _c('pre', { + domProps: { + "innerHTML": _vm._s(_vm.code) + } + })], 1) +},staticRenderFns: []} +module.exports.render._withStripped = true +if (false) { + module.hot.accept() + if (module.hot.data) { + require("vue-hot-reload-api").rerender("data-v-d42105b8", module.exports) + } +} + +/***/ }), +/* 18 */ +/***/ (function(module, exports) { + +var g; + +// This works in non-strict mode +g = (function() { + return this; +})(); + +try { + // This works if eval is allowed (see CSP) + g = g || Function("return this")() || (1,eval)("this"); +} catch(e) { + // This works if the window reference is available + if(typeof window === "object") + g = window; +} + +// g can still be undefined, but nothing to do about it... +// We return undefined, instead of nothing here, so it's +// easier to handle this case. if(!global) { ...} + +module.exports = g; + + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var Notebook = __webpack_require__(2); + +module.exports = { + install: function install(_vue) { + _vue.component('notebook-lab', Notebook); + } +}; + +/***/ }) +/******/ ]); +}); \ No newline at end of file From 33f26de56bca2c5c2d6a4da29ed2217b8abf1710 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 17 Mar 2017 17:00:55 +0000 Subject: [PATCH 2/8] Loads raw JSON & displays in the component [ci skip] --- .../javascripts/blob/notebook_viewer.js | 35 +++++++++++++++++-- app/assets/stylesheets/application.scss | 1 + app/views/projects/blob/_notebook.html.haml | 2 +- vendor/assets/stylesheets/notebooklab.css | 27 ++++++++++++++ 4 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 vendor/assets/stylesheets/notebooklab.css diff --git a/app/assets/javascripts/blob/notebook_viewer.js b/app/assets/javascripts/blob/notebook_viewer.js index dda137c6603..057afc9b2e5 100644 --- a/app/assets/javascripts/blob/notebook_viewer.js +++ b/app/assets/javascripts/blob/notebook_viewer.js @@ -1,20 +1,49 @@ import Vue from 'vue'; +import VueResource from 'vue-resource'; import NotebookLab from 'vendor/notebooklab'; +Vue.use(VueResource); Vue.use(NotebookLab); $(() => { + const el = document.getElementById('js-notebook-viewer'); + new Vue({ - el: '#js-notebook-viewer', + el, data() { return { + loading: true, json: {}, }; }, template: ` -
    - +
    + + +
    `, + mounted() { + $.get(gon.katex_css_url, () => { + const css = $('', { + rel: 'stylesheet', + type: 'text/css', + href: gon.katex_css_url, + }); + css.appendTo('head'); + }); + + $.getScript(gon.katex_js_url, () => { + this.$http.get(el.dataset.endpoint) + .then((res) => { + this.json = res.json(); + this.loading = false; + }); + }); + }, }); }); diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 83a8eeaafde..0a4c69bc5ac 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -7,6 +7,7 @@ *= require_self *= require dropzone/basic *= require cropper.css + *= require notebooklab.css */ /* diff --git a/app/views/projects/blob/_notebook.html.haml b/app/views/projects/blob/_notebook.html.haml index 19d3e401d27..ab1cf933944 100644 --- a/app/views/projects/blob/_notebook.html.haml +++ b/app/views/projects/blob/_notebook.html.haml @@ -2,4 +2,4 @@ = page_specific_javascript_bundle_tag('common_vue') = page_specific_javascript_bundle_tag('notebook_viewer') -.file-content#js-notebook-viewer +.file-content#js-notebook-viewer{ data: { endpoint: namespace_project_raw_path(@project.namespace, @project, @id) } } diff --git a/vendor/assets/stylesheets/notebooklab.css b/vendor/assets/stylesheets/notebooklab.css new file mode 100644 index 00000000000..0caf729a17f --- /dev/null +++ b/vendor/assets/stylesheets/notebooklab.css @@ -0,0 +1,27 @@ +.cell, +.input, +.output { + display: flex; + width: 100%; + margin-bottom: 10px; +} + +.cell:not(.text-cell) { + flex-direction: column; +} + +.prompt { + padding: 0 10px; + min-width: 7em; + font-family: monospace; +} + +.cell pre { + margin: 0; + width: 100%; +} + +.markdown .katex { + display: block; + text-align: center; +} From 313258fa423f9c3a03e793e2a7bc8686d0757e91 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 20 Mar 2017 14:44:07 +0000 Subject: [PATCH 3/8] Stops errors in the rendering breaking the page Fixed some output types [ci skip] --- .../javascripts/blob/notebook_viewer.js | 18 ++++---- vendor/assets/javascripts/notebooklab.js | 41 ++++++++++++++++++- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/blob/notebook_viewer.js b/app/assets/javascripts/blob/notebook_viewer.js index 057afc9b2e5..4bd80393d17 100644 --- a/app/assets/javascripts/blob/notebook_viewer.js +++ b/app/assets/javascripts/blob/notebook_viewer.js @@ -5,6 +5,10 @@ import NotebookLab from 'vendor/notebooklab'; Vue.use(VueResource); Vue.use(NotebookLab); +Vue.config.errorHandler = (err) => { + console.log(err); +} + $(() => { const el = document.getElementById('js-notebook-viewer'); @@ -12,6 +16,7 @@ $(() => { el, data() { return { + error: false, loading: true, json: {}, }; @@ -28,14 +33,11 @@ $(() => {
    `, mounted() { - $.get(gon.katex_css_url, () => { - const css = $('', { - rel: 'stylesheet', - type: 'text/css', - href: gon.katex_css_url, - }); - css.appendTo('head'); - }); + $('', { + rel: 'stylesheet', + type: 'text/css', + href: gon.katex_css_url, + }).appendTo('head'); $.getScript(gon.katex_js_url, () => { this.$http.get(el.dataset.endpoint) diff --git a/vendor/assets/javascripts/notebooklab.js b/vendor/assets/javascripts/notebooklab.js index abcd6cd3d98..06d41f03211 100644 --- a/vendor/assets/javascripts/notebooklab.js +++ b/vendor/assets/javascripts/notebooklab.js @@ -235,11 +235,24 @@ exports.default = { output: function output() { return this.cell.outputs[0]; }, + outputType: function outputType() { + if (!this.output.text) { + return Object.keys(this.output.data)[0]; + } + }, outputText: function outputText() { if (this.output.text) { return this.output.text.join(''); } else { - return this.output.data[Object.keys(this.output.data)[0]].join(''); + var output = this.output.data[this.outputType]; + + if (typeof output === 'array') { + return output.join(''); + } else if (typeof output === 'string') { + return output; + } else { + return ''; + } } } } @@ -257,6 +270,7 @@ exports.default = { // // // +// /***/ }), /* 4 */ @@ -284,6 +298,11 @@ exports.default = { type: Number, required: false }, + outputType: { + type: String, + required: false, + default: '' + }, type: { type: String, required: true @@ -305,6 +324,13 @@ exports.default = { var type = this.type.split('put')[0]; return type.charAt(0).toUpperCase() + type.slice(1);; + }, + isImage: function isImage() { + if (this.outputType) { + return this.outputType.indexOf('image/') === 0; + } else { + return false; + } } } }; // @@ -316,6 +342,12 @@ exports.default = { // // // +// +// +// +// +// +// /***/ }), /* 5 */ @@ -1896,6 +1928,7 @@ module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c attrs: { "type": "output", "raw-code": _vm.outputText, + "output-type": _vm.outputType, "count": _vm.output.execution_count } }) : _vm._e()], 1) @@ -1982,10 +2015,14 @@ module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c "type": _vm.promptType, "count": _vm.count } - }), _vm._v(" "), _c('pre', { + }), _vm._v(" "), (!_vm.isImage) ? _c('pre', { domProps: { "innerHTML": _vm._s(_vm.code) } + }, [_vm._v("\n ")]) : _c('img', { + attrs: { + "src": 'data:' + _vm.outputType + ';base64,' + _vm.rawCode + } })], 1) },staticRenderFns: []} module.exports.render._withStripped = true From e8949a1ee48b5589c1f82d4b8a6b4e20d43d51a3 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 22 Mar 2017 14:08:51 +0000 Subject: [PATCH 4/8] Updated notebooklab library Added error handling [ci skip] --- .../javascripts/blob/notebook_viewer.js | 56 +- vendor/assets/javascripts/notebooklab.js | 1937 +++++++++++++++-- 2 files changed, 1788 insertions(+), 205 deletions(-) diff --git a/app/assets/javascripts/blob/notebook_viewer.js b/app/assets/javascripts/blob/notebook_viewer.js index 4bd80393d17..45b838c700f 100644 --- a/app/assets/javascripts/blob/notebook_viewer.js +++ b/app/assets/javascripts/blob/notebook_viewer.js @@ -5,11 +5,7 @@ import NotebookLab from 'vendor/notebooklab'; Vue.use(VueResource); Vue.use(NotebookLab); -Vue.config.errorHandler = (err) => { - console.log(err); -} - -$(() => { +document.addEventListener('DOMContentLoaded', () => { const el = document.getElementById('js-notebook-viewer'); new Vue({ @@ -17,21 +13,53 @@ $(() => { data() { return { error: false, + loadError: false, loading: true, json: {}, }; }, template: ` -
    - - +
    +
    + +
    +

    + + An error occured whilst loading the file. Please try again later. + + + An error occured whilst parsing the file. + +

    `, + methods: { + loadFile() { + this.$http.get(el.dataset.endpoint) + .then((res) => { + this.json = res.json(); + this.loading = false; + }) + .catch((e) => { + if (e.status) { + this.loadError = true; + } + + this.error = true; + }); + }, + }, mounted() { $('', { rel: 'stylesheet', @@ -40,11 +68,7 @@ $(() => { }).appendTo('head'); $.getScript(gon.katex_js_url, () => { - this.$http.get(el.dataset.endpoint) - .then((res) => { - this.json = res.json(); - this.loading = false; - }); + this.loadFile(); }); }, }); diff --git a/vendor/assets/javascripts/notebooklab.js b/vendor/assets/javascripts/notebooklab.js index 06d41f03211..35e845657bd 100644 --- a/vendor/assets/javascripts/notebooklab.js +++ b/vendor/assets/javascripts/notebooklab.js @@ -73,7 +73,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 19); +/******/ return __webpack_require__(__webpack_require__.s = 32); /******/ }) /************************************************************************/ /******/ ([ @@ -136,9 +136,9 @@ module.exports = function normalizeComponent ( var Component = __webpack_require__(0)( /* script */ - __webpack_require__(6), + __webpack_require__(10), /* template */ - __webpack_require__(15), + __webpack_require__(28), /* scopeId */ null, /* cssModules */ @@ -170,9 +170,43 @@ module.exports = Component.exports var Component = __webpack_require__(0)( /* script */ - __webpack_require__(7), + __webpack_require__(5), /* template */ - __webpack_require__(14), + __webpack_require__(30), + /* scopeId */ + null, + /* cssModules */ + null +) +Component.options.__file = "/Users/phil/Projects/notebooklab/src/cells/code/index.vue" +if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key !== "__esModule"})) {console.error("named exports are not supported in *.vue files.")} +if (Component.options.functional) {console.error("[vue-loader] index.vue: functional components are not supported with templates, they should use render functions.")} + +/* hot reload */ +if (false) {(function () { + var hotAPI = require("vue-hot-reload-api") + hotAPI.install(require("vue"), false) + if (!hotAPI.compatible) return + module.hot.accept() + if (!module.hot.data) { + hotAPI.createRecord("data-v-d42105b8", Component.options) + } else { + hotAPI.reload("data-v-d42105b8", Component.options) + } +})()} + +module.exports = Component.exports + + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +var Component = __webpack_require__(0)( + /* script */ + __webpack_require__(11), + /* template */ + __webpack_require__(27), /* scopeId */ null, /* cssModules */ @@ -199,7 +233,7 @@ module.exports = Component.exports /***/ }), -/* 3 */ +/* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -209,15 +243,34 @@ Object.defineProperty(exports, "__esModule", { value: true }); -var _index = __webpack_require__(11); +var _index = __webpack_require__(2); var _index2 = _interopRequireDefault(_index); +var _index3 = __webpack_require__(22); + +var _index4 = _interopRequireDefault(_index3); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +// +// +// +// +// +// +// +// +// +// +// +// +// + exports.default = { components: { - 'code-cell': _index2.default + 'code-cell': _index2.default, + 'output-cell': _index4.default }, props: { cell: { @@ -234,120 +287,9 @@ exports.default = { }, output: function output() { return this.cell.outputs[0]; - }, - outputType: function outputType() { - if (!this.output.text) { - return Object.keys(this.output.data)[0]; - } - }, - outputText: function outputText() { - if (this.output.text) { - return this.output.text.join(''); - } else { - var output = this.output.data[this.outputType]; - - if (typeof output === 'array') { - return output.join(''); - } else if (typeof output === 'string') { - return output; - } else { - return ''; - } - } } } -}; // -// -// -// -// -// -// -// -// -// -// -// -// -// -// - -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _prompt = __webpack_require__(1); - -var _prompt2 = _interopRequireDefault(_prompt); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.default = { - components: { - 'prompt': _prompt2.default - }, - props: { - count: { - type: Number, - required: false - }, - outputType: { - type: String, - required: false, - default: '' - }, - type: { - type: String, - required: true - }, - rawCode: { - type: String, - required: true - } - }, - computed: { - code: function code() { - if (typeof hljs !== 'undefined' && this.promptType === 'In') { - return hljs.highlightAuto(this.rawCode).value; - } else { - return this.rawCode; - } - }, - promptType: function promptType() { - var type = this.type.split('put')[0]; - - return type.charAt(0).toUpperCase() + type.slice(1);; - }, - isImage: function isImage() { - if (this.outputType) { - return this.outputType.indexOf('image/') === 0; - } else { - return false; - } - } - } -}; // -// -// -// -// -// -// -// -// -// -// -// -// -// -// +}; /***/ }), /* 5 */ @@ -360,7 +302,89 @@ Object.defineProperty(exports, "__esModule", { value: true }); -var _marked = __webpack_require__(9); +var _highlight = __webpack_require__(13); + +var _highlight2 = _interopRequireDefault(_highlight); + +var _xml = __webpack_require__(16); + +var _xml2 = _interopRequireDefault(_xml); + +var _javascript = __webpack_require__(14); + +var _javascript2 = _interopRequireDefault(_javascript); + +var _python = __webpack_require__(15); + +var _python2 = _interopRequireDefault(_python); + +var _prompt = __webpack_require__(1); + +var _prompt2 = _interopRequireDefault(_prompt); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_highlight2.default.registerLanguage('xml', _xml2.default); // +// +// +// +// +// +// +// +// +// +// +// + +_highlight2.default.registerLanguage('javascript', _javascript2.default); +_highlight2.default.registerLanguage('python', _python2.default); + +exports.default = { + components: { + 'prompt': _prompt2.default + }, + props: { + count: { + type: Number, + required: false + }, + type: { + type: String, + required: true + }, + rawCode: { + type: String, + required: true + } + }, + computed: { + code: function code() { + return this.rawCode; + }, + promptType: function promptType() { + var type = this.type.split('put')[0]; + + return type.charAt(0).toUpperCase() + type.slice(1);; + } + }, + mounted: function mounted() { + _highlight2.default.highlightBlock(this.$refs.code); + } +}; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _marked = __webpack_require__(17); var _marked2 = _interopRequireDefault(_marked); @@ -409,7 +433,182 @@ exports.default = { }; /***/ }), -/* 6 */ +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _prompt = __webpack_require__(1); + +var _prompt2 = _interopRequireDefault(_prompt); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + props: { + rawCode: { + type: String, + required: true + } + }, + components: { + 'prompt': _prompt2.default + } +}; // +// +// +// +// +// +// + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _prompt = __webpack_require__(1); + +var _prompt2 = _interopRequireDefault(_prompt); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + props: { + outputType: { + type: String, + required: true + }, + rawCode: { + type: String, + required: true + } + }, + components: { + 'prompt': _prompt2.default + } +}; // +// +// +// +// +// +// +// + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; // +// +// +// +// +// +// +// + +var _index = __webpack_require__(2); + +var _index2 = _interopRequireDefault(_index); + +var _html = __webpack_require__(20); + +var _html2 = _interopRequireDefault(_html); + +var _image = __webpack_require__(21); + +var _image2 = _interopRequireDefault(_image); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + props: { + count: { + type: Number, + required: false, + default: false + }, + output: { + type: Object, + requred: true + } + }, + components: { + 'code-cell': _index2.default, + 'html-output': _html2.default, + 'image-output': _image2.default + }, + data: function data() { + return { + outputType: '' + }; + }, + + computed: { + componentName: function componentName() { + if (this.output.text) { + return 'code-cell'; + } else if (this.output.data['image/png']) { + this.outputType = 'image/png'; + + return 'image-output'; + } else if (this.output.data['text/html']) { + this.outputType = 'text/html'; + + return 'html-output'; + } else if (this.output.data['image/svg+xml']) { + this.outputType = 'image/svg+xml'; + + return 'html-output'; + } else { + this.outputType = 'text/plain'; + + return 'code-cell'; + } + }, + rawCode: function rawCode() { + if (this.output.text) { + return this.output.text.join(''); + } else { + return this.dataForType(this.outputType); + } + } + }, + methods: { + dataForType: function dataForType(type) { + var data = this.output.data[type]; + + if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') { + data = data.join(''); + } + + return data; + } + } +}; + +/***/ }), +/* 10 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -441,7 +640,7 @@ exports.default = { }; /***/ }), -/* 7 */ +/* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -451,7 +650,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); -var _cells = __webpack_require__(8); +var _cells = __webpack_require__(12); exports.default = { components: { @@ -486,7 +685,7 @@ exports.default = { // /***/ }), -/* 8 */ +/* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -496,7 +695,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); -var _markdown = __webpack_require__(12); +var _markdown = __webpack_require__(19); Object.defineProperty(exports, 'MarkdownCell', { enumerable: true, @@ -505,7 +704,7 @@ Object.defineProperty(exports, 'MarkdownCell', { } }); -var _code = __webpack_require__(10); +var _code = __webpack_require__(18); Object.defineProperty(exports, 'CodeCell', { enumerable: true, @@ -517,7 +716,1239 @@ Object.defineProperty(exports, 'CodeCell', { function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), -/* 9 */ +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +/* +Syntax highlighting with language autodetection. +https://highlightjs.org/ +*/ + +(function(factory) { + + // Find the global object for export to both the browser and web workers. + var globalObject = typeof window === 'object' && window || + typeof self === 'object' && self; + + // Setup highlight.js for different environments. First is Node.js or + // CommonJS. + if(true) { + factory(exports); + } else if(globalObject) { + // Export hljs globally even when using AMD for cases when this script + // is loaded with others that may still expect a global hljs. + globalObject.hljs = factory({}); + + // Finally register the global hljs with AMD. + if(typeof define === 'function' && define.amd) { + define([], function() { + return globalObject.hljs; + }); + } + } + +}(function(hljs) { + // Convenience variables for build-in objects + var ArrayProto = [], + objectKeys = Object.keys; + + // Global internal variables used within the highlight.js library. + var languages = {}, + aliases = {}; + + // Regular expressions used throughout the highlight.js library. + var noHighlightRe = /^(no-?highlight|plain|text)$/i, + languagePrefixRe = /\blang(?:uage)?-([\w-]+)\b/i, + fixMarkupRe = /((^(<[^>]+>|\t|)+|(?:\n)))/gm; + + var spanEndTag = ''; + + // Global options used when within external APIs. This is modified when + // calling the `hljs.configure` function. + var options = { + classPrefix: 'hljs-', + tabReplace: null, + useBR: false, + languages: undefined + }; + + // Object map that is used to escape some common HTML characters. + var escapeRegexMap = { + '&': '&', + '<': '<', + '>': '>' + }; + + /* Utility functions */ + + function escape(value) { + return value.replace(/[&<>]/gm, function(character) { + return escapeRegexMap[character]; + }); + } + + function tag(node) { + return node.nodeName.toLowerCase(); + } + + function testRe(re, lexeme) { + var match = re && re.exec(lexeme); + return match && match.index === 0; + } + + function isNotHighlighted(language) { + return noHighlightRe.test(language); + } + + function blockLanguage(block) { + var i, match, length, _class; + var classes = block.className + ' '; + + classes += block.parentNode ? block.parentNode.className : ''; + + // language-* takes precedence over non-prefixed class names. + match = languagePrefixRe.exec(classes); + if (match) { + return getLanguage(match[1]) ? match[1] : 'no-highlight'; + } + + classes = classes.split(/\s+/); + + for (i = 0, length = classes.length; i < length; i++) { + _class = classes[i] + + if (isNotHighlighted(_class) || getLanguage(_class)) { + return _class; + } + } + } + + function inherit(parent) { // inherit(parent, override_obj, override_obj, ...) + var key; + var result = {}; + var objects = Array.prototype.slice.call(arguments, 1); + + for (key in parent) + result[key] = parent[key]; + objects.forEach(function(obj) { + for (key in obj) + result[key] = obj[key]; + }); + return result; + } + + /* Stream merging */ + + function nodeStream(node) { + var result = []; + (function _nodeStream(node, offset) { + for (var child = node.firstChild; child; child = child.nextSibling) { + if (child.nodeType === 3) + offset += child.nodeValue.length; + else if (child.nodeType === 1) { + result.push({ + event: 'start', + offset: offset, + node: child + }); + offset = _nodeStream(child, offset); + // Prevent void elements from having an end tag that would actually + // double them in the output. There are more void elements in HTML + // but we list only those realistically expected in code display. + if (!tag(child).match(/br|hr|img|input/)) { + result.push({ + event: 'stop', + offset: offset, + node: child + }); + } + } + } + return offset; + })(node, 0); + return result; + } + + function mergeStreams(original, highlighted, value) { + var processed = 0; + var result = ''; + var nodeStack = []; + + function selectStream() { + if (!original.length || !highlighted.length) { + return original.length ? original : highlighted; + } + if (original[0].offset !== highlighted[0].offset) { + return (original[0].offset < highlighted[0].offset) ? original : highlighted; + } + + /* + To avoid starting the stream just before it should stop the order is + ensured that original always starts first and closes last: + + if (event1 == 'start' && event2 == 'start') + return original; + if (event1 == 'start' && event2 == 'stop') + return highlighted; + if (event1 == 'stop' && event2 == 'start') + return original; + if (event1 == 'stop' && event2 == 'stop') + return highlighted; + + ... which is collapsed to: + */ + return highlighted[0].event === 'start' ? original : highlighted; + } + + function open(node) { + function attr_str(a) {return ' ' + a.nodeName + '="' + escape(a.value) + '"';} + result += '<' + tag(node) + ArrayProto.map.call(node.attributes, attr_str).join('') + '>'; + } + + function close(node) { + result += ''; + } + + function render(event) { + (event.event === 'start' ? open : close)(event.node); + } + + while (original.length || highlighted.length) { + var stream = selectStream(); + result += escape(value.substring(processed, stream[0].offset)); + processed = stream[0].offset; + if (stream === original) { + /* + On any opening or closing tag of the original markup we first close + the entire highlighted node stack, then render the original tag along + with all the following original tags at the same offset and then + reopen all the tags on the highlighted stack. + */ + nodeStack.reverse().forEach(close); + do { + render(stream.splice(0, 1)[0]); + stream = selectStream(); + } while (stream === original && stream.length && stream[0].offset === processed); + nodeStack.reverse().forEach(open); + } else { + if (stream[0].event === 'start') { + nodeStack.push(stream[0].node); + } else { + nodeStack.pop(); + } + render(stream.splice(0, 1)[0]); + } + } + return result + escape(value.substr(processed)); + } + + /* Initialization */ + + function expand_mode(mode) { + if (mode.variants && !mode.cached_variants) { + mode.cached_variants = mode.variants.map(function(variant) { + return inherit(mode, {variants: null}, variant); + }); + } + return mode.cached_variants || (mode.endsWithParent && [inherit(mode)]) || [mode]; + } + + function compileLanguage(language) { + + function reStr(re) { + return (re && re.source) || re; + } + + function langRe(value, global) { + return new RegExp( + reStr(value), + 'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '') + ); + } + + function compileMode(mode, parent) { + if (mode.compiled) + return; + mode.compiled = true; + + mode.keywords = mode.keywords || mode.beginKeywords; + if (mode.keywords) { + var compiled_keywords = {}; + + var flatten = function(className, str) { + if (language.case_insensitive) { + str = str.toLowerCase(); + } + str.split(' ').forEach(function(kw) { + var pair = kw.split('|'); + compiled_keywords[pair[0]] = [className, pair[1] ? Number(pair[1]) : 1]; + }); + }; + + if (typeof mode.keywords === 'string') { // string + flatten('keyword', mode.keywords); + } else { + objectKeys(mode.keywords).forEach(function (className) { + flatten(className, mode.keywords[className]); + }); + } + mode.keywords = compiled_keywords; + } + mode.lexemesRe = langRe(mode.lexemes || /\w+/, true); + + if (parent) { + if (mode.beginKeywords) { + mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')\\b'; + } + if (!mode.begin) + mode.begin = /\B|\b/; + mode.beginRe = langRe(mode.begin); + if (!mode.end && !mode.endsWithParent) + mode.end = /\B|\b/; + if (mode.end) + mode.endRe = langRe(mode.end); + mode.terminator_end = reStr(mode.end) || ''; + if (mode.endsWithParent && parent.terminator_end) + mode.terminator_end += (mode.end ? '|' : '') + parent.terminator_end; + } + if (mode.illegal) + mode.illegalRe = langRe(mode.illegal); + if (mode.relevance == null) + mode.relevance = 1; + if (!mode.contains) { + mode.contains = []; + } + mode.contains = Array.prototype.concat.apply([], mode.contains.map(function(c) { + return expand_mode(c === 'self' ? mode : c) + })); + mode.contains.forEach(function(c) {compileMode(c, mode);}); + + if (mode.starts) { + compileMode(mode.starts, parent); + } + + var terminators = + mode.contains.map(function(c) { + return c.beginKeywords ? '\\.?(' + c.begin + ')\\.?' : c.begin; + }) + .concat([mode.terminator_end, mode.illegal]) + .map(reStr) + .filter(Boolean); + mode.terminators = terminators.length ? langRe(terminators.join('|'), true) : {exec: function(/*s*/) {return null;}}; + } + + compileMode(language); + } + + /* + Core highlighting function. Accepts a language name, or an alias, and a + string with the code to highlight. Returns an object with the following + properties: + + - relevance (int) + - value (an HTML string with highlighting markup) + + */ + function highlight(name, value, ignore_illegals, continuation) { + + function subMode(lexeme, mode) { + var i, length; + + for (i = 0, length = mode.contains.length; i < length; i++) { + if (testRe(mode.contains[i].beginRe, lexeme)) { + return mode.contains[i]; + } + } + } + + function endOfMode(mode, lexeme) { + if (testRe(mode.endRe, lexeme)) { + while (mode.endsParent && mode.parent) { + mode = mode.parent; + } + return mode; + } + if (mode.endsWithParent) { + return endOfMode(mode.parent, lexeme); + } + } + + function isIllegal(lexeme, mode) { + return !ignore_illegals && testRe(mode.illegalRe, lexeme); + } + + function keywordMatch(mode, match) { + var match_str = language.case_insensitive ? match[0].toLowerCase() : match[0]; + return mode.keywords.hasOwnProperty(match_str) && mode.keywords[match_str]; + } + + function buildSpan(classname, insideSpan, leaveOpen, noPrefix) { + var classPrefix = noPrefix ? '' : options.classPrefix, + openSpan = ''; + + return openSpan + insideSpan + closeSpan; + } + + function processKeywords() { + var keyword_match, last_index, match, result; + + if (!top.keywords) + return escape(mode_buffer); + + result = ''; + last_index = 0; + top.lexemesRe.lastIndex = 0; + match = top.lexemesRe.exec(mode_buffer); + + while (match) { + result += escape(mode_buffer.substring(last_index, match.index)); + keyword_match = keywordMatch(top, match); + if (keyword_match) { + relevance += keyword_match[1]; + result += buildSpan(keyword_match[0], escape(match[0])); + } else { + result += escape(match[0]); + } + last_index = top.lexemesRe.lastIndex; + match = top.lexemesRe.exec(mode_buffer); + } + return result + escape(mode_buffer.substr(last_index)); + } + + function processSubLanguage() { + var explicit = typeof top.subLanguage === 'string'; + if (explicit && !languages[top.subLanguage]) { + return escape(mode_buffer); + } + + var result = explicit ? + highlight(top.subLanguage, mode_buffer, true, continuations[top.subLanguage]) : + highlightAuto(mode_buffer, top.subLanguage.length ? top.subLanguage : undefined); + + // Counting embedded language score towards the host language may be disabled + // with zeroing the containing mode relevance. Usecase in point is Markdown that + // allows XML everywhere and makes every XML snippet to have a much larger Markdown + // score. + if (top.relevance > 0) { + relevance += result.relevance; + } + if (explicit) { + continuations[top.subLanguage] = result.top; + } + return buildSpan(result.language, result.value, false, true); + } + + function processBuffer() { + result += (top.subLanguage != null ? processSubLanguage() : processKeywords()); + mode_buffer = ''; + } + + function startNewMode(mode) { + result += mode.className? buildSpan(mode.className, '', true): ''; + top = Object.create(mode, {parent: {value: top}}); + } + + function processLexeme(buffer, lexeme) { + + mode_buffer += buffer; + + if (lexeme == null) { + processBuffer(); + return 0; + } + + var new_mode = subMode(lexeme, top); + if (new_mode) { + if (new_mode.skip) { + mode_buffer += lexeme; + } else { + if (new_mode.excludeBegin) { + mode_buffer += lexeme; + } + processBuffer(); + if (!new_mode.returnBegin && !new_mode.excludeBegin) { + mode_buffer = lexeme; + } + } + startNewMode(new_mode, lexeme); + return new_mode.returnBegin ? 0 : lexeme.length; + } + + var end_mode = endOfMode(top, lexeme); + if (end_mode) { + var origin = top; + if (origin.skip) { + mode_buffer += lexeme; + } else { + if (!(origin.returnEnd || origin.excludeEnd)) { + mode_buffer += lexeme; + } + processBuffer(); + if (origin.excludeEnd) { + mode_buffer = lexeme; + } + } + do { + if (top.className) { + result += spanEndTag; + } + if (!top.skip) { + relevance += top.relevance; + } + top = top.parent; + } while (top !== end_mode.parent); + if (end_mode.starts) { + startNewMode(end_mode.starts, ''); + } + return origin.returnEnd ? 0 : lexeme.length; + } + + if (isIllegal(lexeme, top)) + throw new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.className || '') + '"'); + + /* + Parser should not reach this point as all types of lexemes should be caught + earlier, but if it does due to some bug make sure it advances at least one + character forward to prevent infinite looping. + */ + mode_buffer += lexeme; + return lexeme.length || 1; + } + + var language = getLanguage(name); + if (!language) { + throw new Error('Unknown language: "' + name + '"'); + } + + compileLanguage(language); + var top = continuation || language; + var continuations = {}; // keep continuations for sub-languages + var result = '', current; + for(current = top; current !== language; current = current.parent) { + if (current.className) { + result = buildSpan(current.className, '', true) + result; + } + } + var mode_buffer = ''; + var relevance = 0; + try { + var match, count, index = 0; + while (true) { + top.terminators.lastIndex = index; + match = top.terminators.exec(value); + if (!match) + break; + count = processLexeme(value.substring(index, match.index), match[0]); + index = match.index + count; + } + processLexeme(value.substr(index)); + for(current = top; current.parent; current = current.parent) { // close dangling modes + if (current.className) { + result += spanEndTag; + } + } + return { + relevance: relevance, + value: result, + language: name, + top: top + }; + } catch (e) { + if (e.message && e.message.indexOf('Illegal') !== -1) { + return { + relevance: 0, + value: escape(value) + }; + } else { + throw e; + } + } + } + + /* + Highlighting with language detection. Accepts a string with the code to + highlight. Returns an object with the following properties: + + - language (detected language) + - relevance (int) + - value (an HTML string with highlighting markup) + - second_best (object with the same structure for second-best heuristically + detected language, may be absent) + + */ + function highlightAuto(text, languageSubset) { + languageSubset = languageSubset || options.languages || objectKeys(languages); + var result = { + relevance: 0, + value: escape(text) + }; + var second_best = result; + languageSubset.filter(getLanguage).forEach(function(name) { + var current = highlight(name, text, false); + current.language = name; + if (current.relevance > second_best.relevance) { + second_best = current; + } + if (current.relevance > result.relevance) { + second_best = result; + result = current; + } + }); + if (second_best.language) { + result.second_best = second_best; + } + return result; + } + + /* + Post-processing of the highlighted markup: + + - replace TABs with something more useful + - replace real line-breaks with '
    ' for non-pre containers + + */ + function fixMarkup(value) { + return !(options.tabReplace || options.useBR) + ? value + : value.replace(fixMarkupRe, function(match, p1) { + if (options.useBR && match === '\n') { + return '
    '; + } else if (options.tabReplace) { + return p1.replace(/\t/g, options.tabReplace); + } + return ''; + }); + } + + function buildClassName(prevClassName, currentLang, resultLang) { + var language = currentLang ? aliases[currentLang] : resultLang, + result = [prevClassName.trim()]; + + if (!prevClassName.match(/\bhljs\b/)) { + result.push('hljs'); + } + + if (prevClassName.indexOf(language) === -1) { + result.push(language); + } + + return result.join(' ').trim(); + } + + /* + Applies highlighting to a DOM node containing code. Accepts a DOM node and + two optional parameters for fixMarkup. + */ + function highlightBlock(block) { + var node, originalStream, result, resultNode, text; + var language = blockLanguage(block); + + if (isNotHighlighted(language)) + return; + + if (options.useBR) { + node = document.createElementNS('http://www.w3.org/1999/xhtml', 'div'); + node.innerHTML = block.innerHTML.replace(/\n/g, '').replace(//g, '\n'); + } else { + node = block; + } + text = node.textContent; + result = language ? highlight(language, text, true) : highlightAuto(text); + + originalStream = nodeStream(node); + if (originalStream.length) { + resultNode = document.createElementNS('http://www.w3.org/1999/xhtml', 'div'); + resultNode.innerHTML = result.value; + result.value = mergeStreams(originalStream, nodeStream(resultNode), text); + } + result.value = fixMarkup(result.value); + + block.innerHTML = result.value; + block.className = buildClassName(block.className, language, result.language); + block.result = { + language: result.language, + re: result.relevance + }; + if (result.second_best) { + block.second_best = { + language: result.second_best.language, + re: result.second_best.relevance + }; + } + } + + /* + Updates highlight.js global options with values passed in the form of an object. + */ + function configure(user_options) { + options = inherit(options, user_options); + } + + /* + Applies highlighting to all
    ..
    blocks on a page. + */ + function initHighlighting() { + if (initHighlighting.called) + return; + initHighlighting.called = true; + + var blocks = document.querySelectorAll('pre code'); + ArrayProto.forEach.call(blocks, highlightBlock); + } + + /* + Attaches highlighting to the page load event. + */ + function initHighlightingOnLoad() { + addEventListener('DOMContentLoaded', initHighlighting, false); + addEventListener('load', initHighlighting, false); + } + + function registerLanguage(name, language) { + var lang = languages[name] = language(hljs); + if (lang.aliases) { + lang.aliases.forEach(function(alias) {aliases[alias] = name;}); + } + } + + function listLanguages() { + return objectKeys(languages); + } + + function getLanguage(name) { + name = (name || '').toLowerCase(); + return languages[name] || languages[aliases[name]]; + } + + /* Interface definition */ + + hljs.highlight = highlight; + hljs.highlightAuto = highlightAuto; + hljs.fixMarkup = fixMarkup; + hljs.highlightBlock = highlightBlock; + hljs.configure = configure; + hljs.initHighlighting = initHighlighting; + hljs.initHighlightingOnLoad = initHighlightingOnLoad; + hljs.registerLanguage = registerLanguage; + hljs.listLanguages = listLanguages; + hljs.getLanguage = getLanguage; + hljs.inherit = inherit; + + // Common regexps + hljs.IDENT_RE = '[a-zA-Z]\\w*'; + hljs.UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\w*'; + hljs.NUMBER_RE = '\\b\\d+(\\.\\d+)?'; + hljs.C_NUMBER_RE = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)'; // 0x..., 0..., decimal, float + hljs.BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b... + hljs.RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~'; + + // Common modes + hljs.BACKSLASH_ESCAPE = { + begin: '\\\\[\\s\\S]', relevance: 0 + }; + hljs.APOS_STRING_MODE = { + className: 'string', + begin: '\'', end: '\'', + illegal: '\\n', + contains: [hljs.BACKSLASH_ESCAPE] + }; + hljs.QUOTE_STRING_MODE = { + className: 'string', + begin: '"', end: '"', + illegal: '\\n', + contains: [hljs.BACKSLASH_ESCAPE] + }; + hljs.PHRASAL_WORDS_MODE = { + begin: /\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|like)\b/ + }; + hljs.COMMENT = function (begin, end, inherits) { + var mode = hljs.inherit( + { + className: 'comment', + begin: begin, end: end, + contains: [] + }, + inherits || {} + ); + mode.contains.push(hljs.PHRASAL_WORDS_MODE); + mode.contains.push({ + className: 'doctag', + begin: '(?:TODO|FIXME|NOTE|BUG|XXX):', + relevance: 0 + }); + return mode; + }; + hljs.C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$'); + hljs.C_BLOCK_COMMENT_MODE = hljs.COMMENT('/\\*', '\\*/'); + hljs.HASH_COMMENT_MODE = hljs.COMMENT('#', '$'); + hljs.NUMBER_MODE = { + className: 'number', + begin: hljs.NUMBER_RE, + relevance: 0 + }; + hljs.C_NUMBER_MODE = { + className: 'number', + begin: hljs.C_NUMBER_RE, + relevance: 0 + }; + hljs.BINARY_NUMBER_MODE = { + className: 'number', + begin: hljs.BINARY_NUMBER_RE, + relevance: 0 + }; + hljs.CSS_NUMBER_MODE = { + className: 'number', + begin: hljs.NUMBER_RE + '(' + + '%|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' + + ')?', + relevance: 0 + }; + hljs.REGEXP_MODE = { + className: 'regexp', + begin: /\//, end: /\/[gimuy]*/, + illegal: /\n/, + contains: [ + hljs.BACKSLASH_ESCAPE, + { + begin: /\[/, end: /\]/, + relevance: 0, + contains: [hljs.BACKSLASH_ESCAPE] + } + ] + }; + hljs.TITLE_MODE = { + className: 'title', + begin: hljs.IDENT_RE, + relevance: 0 + }; + hljs.UNDERSCORE_TITLE_MODE = { + className: 'title', + begin: hljs.UNDERSCORE_IDENT_RE, + relevance: 0 + }; + hljs.METHOD_GUARD = { + // excludes method names from keyword processing + begin: '\\.\\s*' + hljs.UNDERSCORE_IDENT_RE, + relevance: 0 + }; + + return hljs; +})); + + +/***/ }), +/* 14 */ +/***/ (function(module, exports) { + +module.exports = function(hljs) { + var IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*'; + var KEYWORDS = { + 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 ' + + // ECMAScript 6 modules import + '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' + }; + var EXPRESSIONS; + var NUMBER = { + className: 'number', + variants: [ + { begin: '\\b(0[bB][01]+)' }, + { begin: '\\b(0[oO][0-7]+)' }, + { begin: hljs.C_NUMBER_RE } + ], + relevance: 0 + }; + var SUBST = { + className: 'subst', + begin: '\\$\\{', end: '\\}', + keywords: KEYWORDS, + contains: [] // defined later + }; + var TEMPLATE_STRING = { + className: 'string', + begin: '`', end: '`', + contains: [ + hljs.BACKSLASH_ESCAPE, + SUBST + ] + }; + SUBST.contains = [ + hljs.APOS_STRING_MODE, + hljs.QUOTE_STRING_MODE, + TEMPLATE_STRING, + NUMBER, + hljs.REGEXP_MODE + ] + var PARAMS_CONTAINS = SUBST.contains.concat([ + hljs.C_BLOCK_COMMENT_MODE, + hljs.C_LINE_COMMENT_MODE + ]); + + return { + aliases: ['js', 'jsx'], + keywords: KEYWORDS, + contains: [ + { + className: 'meta', + relevance: 10, + begin: /^\s*['"]use (strict|asm)['"]/ + }, + { + className: 'meta', + begin: /^#!/, end: /$/ + }, + hljs.APOS_STRING_MODE, + hljs.QUOTE_STRING_MODE, + TEMPLATE_STRING, + hljs.C_LINE_COMMENT_MODE, + hljs.C_BLOCK_COMMENT_MODE, + NUMBER, + { // object attr container + begin: /[{,]\s*/, relevance: 0, + contains: [ + { + begin: IDENT_RE + '\\s*:', returnBegin: true, + relevance: 0, + contains: [{className: 'attr', begin: IDENT_RE, relevance: 0}] + } + ] + }, + { // "value" container + begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*', + keywords: 'return throw case', + contains: [ + hljs.C_LINE_COMMENT_MODE, + hljs.C_BLOCK_COMMENT_MODE, + hljs.REGEXP_MODE, + { + className: 'function', + begin: '(\\(.*?\\)|' + IDENT_RE + ')\\s*=>', returnBegin: true, + end: '\\s*=>', + contains: [ + { + className: 'params', + variants: [ + { + begin: IDENT_RE + }, + { + begin: /\(\s*\)/, + }, + { + begin: /\(/, end: /\)/, + excludeBegin: true, excludeEnd: true, + keywords: KEYWORDS, + contains: PARAMS_CONTAINS + } + ] + } + ] + }, + { // E4X / JSX + begin: //, + subLanguage: 'xml', + contains: [ + {begin: /<\w+\s*\/>/, skip: true}, + { + begin: /<\w+/, end: /(\/\w+|\w+\/)>/, skip: true, + contains: [ + {begin: /<\w+\s*\/>/, skip: true}, + 'self' + ] + } + ] + } + ], + relevance: 0 + }, + { + className: 'function', + beginKeywords: 'function', end: /\{/, excludeEnd: true, + contains: [ + hljs.inherit(hljs.TITLE_MODE, {begin: IDENT_RE}), + { + className: 'params', + begin: /\(/, end: /\)/, + excludeBegin: true, + excludeEnd: true, + contains: PARAMS_CONTAINS + } + ], + illegal: /\[|%/ + }, + { + begin: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something` + }, + hljs.METHOD_GUARD, + { // ES6 class + className: 'class', + beginKeywords: 'class', end: /[{;=]/, excludeEnd: true, + illegal: /[:"\[\]]/, + contains: [ + {beginKeywords: 'extends'}, + hljs.UNDERSCORE_TITLE_MODE + ] + }, + { + beginKeywords: 'constructor', end: /\{/, excludeEnd: true + } + ], + illegal: /#(?!!)/ + }; +}; + +/***/ }), +/* 15 */ +/***/ (function(module, exports) { + +module.exports = function(hljs) { + var KEYWORDS = { + 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' + }; + var PROMPT = { + className: 'meta', begin: /^(>>>|\.\.\.) / + }; + var SUBST = { + className: 'subst', + begin: /\{/, end: /\}/, + keywords: KEYWORDS, + illegal: /#/ + }; + var STRING = { + className: 'string', + contains: [hljs.BACKSLASH_ESCAPE], + variants: [ + { + begin: /(u|b)?r?'''/, end: /'''/, + contains: [PROMPT], + relevance: 10 + }, + { + begin: /(u|b)?r?"""/, end: /"""/, + contains: [PROMPT], + relevance: 10 + }, + { + begin: /(fr|rf|f)'''/, end: /'''/, + contains: [PROMPT, SUBST] + }, + { + begin: /(fr|rf|f)"""/, end: /"""/, + contains: [PROMPT, SUBST] + }, + { + begin: /(u|r|ur)'/, end: /'/, + relevance: 10 + }, + { + begin: /(u|r|ur)"/, end: /"/, + relevance: 10 + }, + { + begin: /(b|br)'/, end: /'/ + }, + { + begin: /(b|br)"/, end: /"/ + }, + { + begin: /(fr|rf|f)'/, end: /'/, + contains: [SUBST] + }, + { + begin: /(fr|rf|f)"/, end: /"/, + contains: [SUBST] + }, + hljs.APOS_STRING_MODE, + hljs.QUOTE_STRING_MODE + ] + }; + var NUMBER = { + className: 'number', relevance: 0, + variants: [ + {begin: hljs.BINARY_NUMBER_RE + '[lLjJ]?'}, + {begin: '\\b(0o[0-7]+)[lLjJ]?'}, + {begin: hljs.C_NUMBER_RE + '[lLjJ]?'} + ] + }; + var PARAMS = { + className: 'params', + begin: /\(/, end: /\)/, + contains: ['self', PROMPT, NUMBER, STRING] + }; + SUBST.contains = [STRING, NUMBER, PROMPT]; + return { + aliases: ['py', 'gyp'], + keywords: KEYWORDS, + illegal: /(<\/|->|\?)|=>/, + contains: [ + PROMPT, + NUMBER, + STRING, + hljs.HASH_COMMENT_MODE, + { + variants: [ + {className: 'function', beginKeywords: 'def'}, + {className: 'class', beginKeywords: 'class'} + ], + end: /:/, + illegal: /[${=;\n,]/, + contains: [ + hljs.UNDERSCORE_TITLE_MODE, + PARAMS, + { + begin: /->/, endsWithParent: true, + keywords: 'None' + } + ] + }, + { + className: 'meta', + begin: /^[\t ]*@/, end: /$/ + }, + { + begin: /\b(print|exec)\(/ // don’t highlight keywords-turned-functions in Python 3 + } + ] + }; +}; + +/***/ }), +/* 16 */ +/***/ (function(module, exports) { + +module.exports = function(hljs) { + var XML_IDENT_RE = '[A-Za-z0-9\\._:-]+'; + var TAG_INTERNALS = { + endsWithParent: true, + illegal: /`]+/} + ] + } + ] + } + ] + }; + return { + aliases: ['html', 'xhtml', 'rss', 'atom', 'xjb', 'xsd', 'xsl', 'plist'], + case_insensitive: true, + contains: [ + { + className: 'meta', + begin: '', + relevance: 10, + contains: [{begin: '\\[', end: '\\]'}] + }, + hljs.COMMENT( + '', + { + relevance: 10 + } + ), + { + begin: '<\\!\\[CDATA\\[', end: '\\]\\]>', + relevance: 10 + }, + { + begin: /<\?(php)?/, end: /\?>/, + subLanguage: 'php', + contains: [{begin: '/\\*', end: '\\*/', skip: true}] + }, + { + className: 'tag', + /* + The lookahead pattern (?=...) ensures that 'begin' only matches + '|$)', end: '>', + keywords: {name: 'style'}, + contains: [TAG_INTERNALS], + starts: { + end: '', returnEnd: true, + subLanguage: ['css', 'xml'] + } + }, + { + className: 'tag', + // See the comment in the ', returnEnd: true, - subLanguage: ['css', 'xml'] - } - }, - { - className: 'tag', - // See the comment in the