From aac69ee36405224ad51de6d34d54ce65ff05faf7 Mon Sep 17 00:00:00 2001 From: Aymeric Date: Mon, 15 Apr 2019 14:52:33 +0200 Subject: [PATCH] first commit --- .eslintrc.json | 14 + .gitignore | 21 + README.md | 164 ++++ browser.js | 707 +++++++++++++++ example.js | 131 +++ example.pdf | Bin 0 -> 20976 bytes index.js | 330 +++++++ package-lock.json | 2182 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 27 + test/unit.js | 244 +++++ 10 files changed, 3820 insertions(+) create mode 100644 .eslintrc.json create mode 100644 .gitignore create mode 100644 README.md create mode 100644 browser.js create mode 100644 example.js create mode 100644 example.pdf create mode 100644 index.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 test/unit.js diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..366a30e --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,14 @@ +{ + "env": { + "browser": true, + "amd": true, + "node": true + }, + "extends": [ + "eslint:recommended" + ], + "rules": { + "no-extra-semi": "off", + "no-console": "off" + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..185e663 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +.DS_Store +node_modules +/dist + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* diff --git a/README.md b/README.md new file mode 100644 index 0000000..6b0ed9f --- /dev/null +++ b/README.md @@ -0,0 +1,164 @@ +# html-to-pdfmake + +[pdfmake](https://pdfmake.github.io/docs/) permits to easily create a PDF with JavaScript, but the support of HTML was missing. After [reviewing issue #205](https://github.com/bpampuch/pdfmake/issues/205) I decided to create a module to handle this feature. + +## Install + +```bash +npm install html-to-pdfmake +``` + +## How to use + +This module will convert some basic and valid HTML code to its equivalent in *pdfmake*. + +```javascript +var pdfMake = require("pdfmake/build/pdfmake"); +var pdfFonts = require("pdfmake/build/vfs_fonts"); +pdfMake.vfs = pdfFonts.pdfMake.vfs; +var htmlToPdfMake = require("html-to-pdfmake"); + +var html = htmlToPdfMake(` +
+

My title

+

+ This is a sentence with a bold word, one in italic, and one with underline. And finally a link. +

+
+ `); + +/* +it will return: +{ stack: + [ + { text: 'My title', + fontSize: 24, + bold: true, + marginBottom: 5, + style: [ 'html-h1' ] + }, + { text: + [ + { text: 'This is a sentence with a ', margin: [ 0, 5, 0, 10 ] }, + { text: 'bold word', bold: true, style: [ 'html-strong' ] }, + { text: ', ', margin: [ 0, 5, 0, 10 ] }, + { text: 'one in italic', italics: true, style: [ 'html-em' ] }, + { text: ', and ', margin: [ 0, 5, 0, 10 ] }, + { text: 'one with underline', + decoration: 'underline', + style: [ 'html-u' ] }, + { text: '. And finally ', margin: [ 0, 5, 0, 10 ] }, + { text: 'a link', + color: 'blue', + decoration: 'underline', + link: 'https://www.somewhere.com', + style: [ 'html-a' ] }, + { text: '.', margin: [ 0, 5, 0, 10 ] } + ], + style: [ 'html-p' ] + } + ], + style: [ 'html-div' ] +} + */ +``` + +## Documentation + +### HTML tags supported + +The below HTML tags are supported: + - DIV / P / SPAN + - BR + - B / STRONG + - I / EM + - UL / OL / LI + - TABLE / THEAD / TBODY / TFOOTER / TR / TH / TD + - H1 to H6 + +### Default style + +I've defined some default styles for the supported element. + +For example, using a will display the word in **bold**. Or, a link will appear in blue with an underline... + +### Customize style + +Each converted element will have an associated style-class called `html-TAGNAME`. + +For example, if you want all **STRONG** tags to be highlighted with a yellow backgroud you can use `html-strong` in the `styles` definition: + +```javascript +var html = htmlToPdfMake(` +

+ This sentence has a highlighted word, but not only. +

+ `); + +var docDefinition = { + content: [ + html + ], + styles:{ + 'html-strong':{ + background:'yellow' // it will add a yellow background to all elements + } + } +}; + +var pdfDocGenerator = pdfMake.createPdf(docDefinition); +``` + +### CSS class and style + +The classed passed to the elements will be added, as well as the `style`. + +```javascript +var html = htmlToPdfMake(` +

+ This sentence has a bold and red word. +

+ `); + +/* +It returns: +{ + text: [{ + text: 'This sentence has ', + margin: [0, 5, 0, 10] + }, + { + text: 'a bold and red word', + style: ['red', 'html-span'], // two classes will be applied: 'red' and 'html-span' + bold: true // the `font-weight:bold` has been translated to `bold:true` + }, + { + text: '.', + margin: [0, 5, 0, 10] + } + ], + style: ['html-p'] +} + */ + +var docDefinition = { + content: [ + html + ], + styles:{ + red:{ // we define the class called "red" + color:'red' + } + } +}; + +var pdfDocGenerator = pdfMake.createPdf(docDefinition); +``` + +## Examples + +You can find more examples in [example.js](example.js) which will create [example.pdf](example.pdf): + +```bash +node example.js +``` diff --git a/browser.js b/browser.js new file mode 100644 index 0000000..012d5a1 --- /dev/null +++ b/browser.js @@ -0,0 +1,707 @@ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;imy bold text'); +*/ + +var LineNumberingMode = { + None: 'none', + Inside: 'inline', + Outside: 'outside' +} + +module.exports = function(htmlText, lnMode) { + // holds the desired line number mode + var lineNumberingMode = LineNumberingMode.None; + + // Space between list elements + var LI_MARGIN_BOTTOM = 0; + + // Normal line height for paragraphs + var LINE_HEIGHT = 1; + + // space above paragraphs + var P_MARGIN_TOP = 6.0; + + // space below paragraphs + var P_MARGIN_BOTTOM = 0; + + // Space above H + var H_MARGIN_TOP = 10.0; + + // Conversion of HTML tags into pdfmake directives + var elementStyles = { + // should be the same for most HTML code + b: ['font-weight:bold'], + strong: ['font-weight:bold'], + u: ['text-decoration:underline'], + em: ['font-style:italic'], + i: ['font-style:italic'], + h1: ['font-size:14', 'font-weight:bold'], + h2: ['font-size:12', 'font-weight:bold'], + h3: ['font-size:10', 'font-weight:bold'], + h4: ['font-size:10', 'font-style:italic'], + h5: ['font-size:10'], + h6: ['font-size:10'], + a: ['color:blue', 'text-decoration:underline'], + strike: ['text-decoration:line-through'], + // Pretty specific stuff that might be excluded for other projects than OpenSlides + del: ['color:red', 'text-decoration:line-through'], + ins: ['color:green', 'text-decoration:underline'] + }; + + /** + * Treatment of required CSS-Classes + * Checking CSS is not possible + */ + var classStyles = { + delete: ['color:red', 'text-decoration:line-through'], + insert: ['color:green', 'text-decoration:underline'], + paragraphcontext: ['color:grey'] + }; + + + /** + * Determine the ideal top margin for a given node + * + * @param nodeName the node to parse + * @returns the margin tip as number + */ + var getMarginTop = function(nodeName) { + switch (nodeName) { + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': { + return H_MARGIN_TOP; + } + case 'p': { + return P_MARGIN_TOP; + } + default: { + return 0; + } + } + } + + /** + * Determine the ideal margin for a given node + * + * @param nodeName the node to parse + * @returns the margin bottom as number + */ + var getMarginBottom = function(nodeName) { + switch (nodeName) { + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': { + return P_MARGIN_BOTTOM; + } + case 'li': { + return LI_MARGIN_BOTTOM; + } + default: { + return P_MARGIN_BOTTOM; + } + } + } + + /** + * Takes an HTML string, converts to HTML using a DOM parser and recursivly parses + * the content into pdfmake compatible doc definition + * + * @param htmlText the html text to translate as string + * @param lnMode determines the line numbering + * @returns pdfmake doc definition as object + */ + var convertHtml = function(htmlText, lnMode) { + var docDef = []; + lineNumberingMode = lnMode || LineNumberingMode.None; + + // Cleanup of dirty html would happen here + + // Create a HTML DOM tree out of html string + var parser = new DOMParser(); + var parsedHtml = parser.parseFromString(htmlText, 'text/html'); + // Go thru each child + [].forEach.call(parsedHtml.body.childNodes, function(child) { + var parsedElement = parseElement(child); + docDef.push(parsedElement); + }); + + return docDef; + } + + /** + * Converts a single HTML element to pdfmake, calls itself recursively for child html elements + * + * @param element can be an HTML element (

) or plain text ("Hello World") + * @param currentParagraph usually holds the parent element, to allow nested structures + * @param styles holds the style attributes of HTML elements (`

...`) + * @returns the doc def to the given element in consideration to the given paragraph and styles + */ + var parseElement = function(element, styles) { + var nodeName = element.nodeName.toLowerCase(); + var classes = []; + var newParagraph={}, k; + + // extract explicit style information + styles = styles || []; + + // to leave out plain text elements + if (element.getAttribute) { + var nodeStyle = element.getAttribute('style'); + var nodeClass = element.getAttribute('class'); + + // add styles like `color:#ff00ff` content into styles array + if (nodeStyle) { + styles = nodeStyle + .split(';') + .map(function(style) { return style.replace(/\s/g, '') }) + .concat(styles); + } + + // Handle CSS classes + if (nodeClass) { + classes = nodeClass.toLowerCase().split(' '); + + for (var cssClass of classes) { + if (classStyles[cssClass]) { + classStyles[cssClass].forEach(function(style) { + styles.push(style); + }); + } + } + } + } + + switch (nodeName) { + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + case 'li': + case 'p': + case 'div': { + var children = parseChildren(element, styles); + + // this introduces a bug with rendering sub-lists in PDF + if ( + lineNumberingMode === LineNumberingMode.Outside && + !isInsideAList(element) && + classes.indexOf('insert')===-1 + ) { + newParagraph = create('stack'); + newParagraph.stack = children; + } else { + newParagraph = create('text'); + newParagraph.text = children; + } + + newParagraph.margin = [0, 0, 0, 0]; + + // determine the "normal" top and button margins + newParagraph.margin[1] = getMarginTop(nodeName); + newParagraph.margin[3] = getMarginBottom(nodeName); + + if (lineNumberingMode === LineNumberingMode.Outside) { + // that is usually the case for inserted change which should appear + // under a set of line numbers with correct alignment + if (classes.indexOf('insert')!==-1) { + newParagraph.margin[0] = 20; + newParagraph.margin[3] = P_MARGIN_BOTTOM; + } + } + + // stop enumeration if the list was inserted + if (classes.indexOf('os-split-before')!==-1) { + newParagraph.listType = 'none'; + } + + // if the list ends (usually due to a new insert cr) prevent margins + if (classes.indexOf('os-split-after')!==-1) { + newParagraph.margin[3] = 0; + } + + newParagraph.lineHeight = LINE_HEIGHT; + + var computedStyles = computeStyle(styles); + var nodeStyles = computeStyle(elementStyles[nodeName]); + for (k in computedStyles) { + if (computedStyles.hasOwnProperty(k)) { + newParagraph[k] = computedStyles[k]; + } + } + for (k in nodeStyles) { + if (nodeStyles.hasOwnProperty(k)) { + newParagraph[k] = nodeStyles[k]; + } + } + break; + } + case 'a': + case 'b': + case 'strong': + case 'u': + case 'em': + case 'i': + case 'ins': + case 'del': + case 'strike': { + var children = parseChildren(element, styles.concat(elementStyles[nodeName])); + newParagraph = create('text'); + newParagraph.text = children; + break; + } + case 'span': { + // Line numbering feature, will prevent compatibility to most other projects + if (element.getAttribute('data-line-number') && !isInsideAList(element)) { + if (lineNumberingMode === LineNumberingMode.Inside) { + // TODO: algorithm for "inline" line numbers is not yet implemented + } else if (lineNumberingMode === LineNumberingMode.Outside) { + var currentLineNumber = element.getAttribute('data-line-number'); + newParagraph = { + columns: [ + // the line number column + getLineNumberObject({ + lineNumber: +currentLineNumber + }), { + text: [] + } + ] + }; + } + } else { + var children = parseChildren(element, styles); + var crt = create('text'); + var computedStyles = computeStyle(styles); + for (k in crt) { + if (crt.hasOwnProperty(k)) { + newParagraph[k] = crt[k]; + } + } + for (k in computedStyles) { + if (computedStyles.hasOwnProperty(k)) { + newParagraph[k] = computedStyles[k]; + } + } + + newParagraph.text = children; + } + break; + } + case 'br': { + if (lineNumberingMode === LineNumberingMode.None && classes.includes('os-line-break')) { + break; + } else { + newParagraph = create('text'); + // yep thats all + newParagraph.text = '\n'; + newParagraph.lineHeight = LINE_HEIGHT; + } + break; + } + case 'ul': + case 'ol': { + var list = create(nodeName); + + // keep the numbers of the ol list + if (nodeName === 'ol') { + var start = element.getAttribute('start'); + if (start) { + list.start = +start; + } + } + + // in case of line numbers and only of the list is not nested in another list. + if (lineNumberingMode === LineNumberingMode.Outside && !isInsideAList(element)) { + var lines = extractLineNumbers(element); + + var cleanedChildDom = cleanLineNumbers(element); + var cleanedChildren = parseChildren(cleanedChildDom, styles); + + if (lines.length > 0) { + var listCol = { + columns: [{ + width: 20, + stack: [] + }], + margin: [0, 0, 0, 0] + }; + + // This has the effect that changed complex lists will look good with line numbers, + // but simple lists will be too close. The information in the HTML is highly redundant and + // there is currently no clear way to determine what to do with the lists. + if (classes.includes('os-split-after')) { + listCol.margin[3] = -LI_MARGIN_BOTTOM; + } + + for (var line of lines) { + listCol.columns[0].stack.push(getLineNumberObject(line)); + } + + list[nodeName] = cleanedChildren; + listCol.columns.push(list); + newParagraph = listCol; + } else { + // that is usually the case for "inserted" lists during change recomendations + list.margin = [20, 0, 0, 0]; + newParagraph = list; + newParagraph[nodeName] = cleanedChildren; + } + } else { + var children = parseChildren(element, styles); + newParagraph = list; + newParagraph[nodeName] = children; + } + break; + } + default: { + var crt = create('text', element.textContent.replace(/\n/g, '')); + var computedStyles = computeStyle(styles); + for (k in crt) { + if (crt.hasOwnProperty(k)) { + newParagraph[k] = crt[k]; + } + } + for (k in computedStyles) { + if (computedStyles.hasOwnProperty(k)) { + newParagraph[k] = computedStyles[k]; + } + } + break; + } + } + return newParagraph; + } + + /** + * Helper routine to parse an elements children and return the children as parsed pdfmake doc string + * + * @param element the parent element to parse + * @param currentParagraph the context of the element + * @param styles the styles array, usually just to parse back into the `parseElement` function + * @returns an array of parsed children + */ + var parseChildren = function(element, styles) { + var childNodes = [].slice.call(element.childNodes, 0); + var paragraph = []; + var childNodesLen = childNodes.length; + if (childNodesLen > 0) { + for (var i=0; i 0) { + var cleanChildren = cleanLineNumbers(children[i]); + elementCopy.replaceChild(cleanChildren, children[i]); + } + } + + return elementCopy; + } + + /** + * Helper function to extract line numbers from child elements + * + * TODO: Cleanup + * + * @param element element to check for containing line numbers (usually a list) + * @returns a list with the line numbers + */ + var extractLineNumbers = function(element) { + var foundLineNumbers = []; + var lineNumber = getLineNumber(element); + if (lineNumber) { + foundLineNumbers.push({ + lineNumber: lineNumber + }); + } else if (element.nodeName === 'BR') { + // Check if there is a new line, but it does not get a line number. + // If so, insert a dummy line, so the line numbers stays aligned with + // the text. + if (!getLineNumber(element.nextSibling)) { + foundLineNumbers.push({ + lineNumber: '' + }); + } + } else { + var children = [].slice.call(element.childNodes, 0); + var childrenLength = children.length; + var childrenLineNumbers = []; + for (var i = 0; i < children.length; i++) { + childrenLineNumbers = childrenLineNumbers.concat(extractLineNumbers(children[i])); + if (children.length < childrenLength) { + i -= childrenLength - children.length; + childrenLength = children.length; + } + } + + // If this is an list item, add some space to the lineNumbers: + if (childrenLineNumbers.length && element.nodeName === 'LI') { + childrenLineNumbers[childrenLineNumbers.length - 1].marginBottom = LI_MARGIN_BOTTOM; + } + + foundLineNumbers = foundLineNumbers.concat(childrenLineNumbers); + } + return foundLineNumbers; + } + + /** + * Recursive helper function to determine if the element is inside a list + * + * @param element the current html node + * @returns wether the element is inside a list or not + */ + var isInsideAList = function(element) { + var parent = element.parentNode; + while (parent !== null) { + if (parent.nodeName === 'UL' || parent.nodeName === 'OL') { + return true; + } + parent = parent.parentNode; + } + return false; + } + + /** + * Helper function to safer extract a line number from an element + * + * @param element + * @returns the line number of the element + */ + var getLineNumber = function(element) { + if ( + element && + element.nodeName === 'SPAN' && + element.getAttribute('class') && + element.getAttribute('class').indexOf('os-line-number') > -1 + ) { + return +element.getAttribute('data-line-number'); + } + } + + /** + * Extracts the style information from the given array + * + * @param styles an array of inline css styles (i.e. `style="margin: 10px"`) + * @returns an object with style pdfmake compatible style information + */ + var computeStyle = function(styles) { + var styleObject = {}; + if (styles && styles.length > 0) { + for (var style of styles) { + var styleDefinition = style + .trim() + .toLowerCase() + .split(':'); + var key = styleDefinition[0]; + var value = styleDefinition[1]; + + if (styleDefinition.length === 2) { + switch (key) { + case 'padding-left': { + styleObject.margin = [+value, 0, 0, 0]; + break; + } + case 'font-size': { + styleObject.fontSize = +value; + break; + } + case 'text-align': { + switch (value) { + case 'right': + case 'center': + case 'justify': + { + styleObject.alignment = value; + break; + } + } + break; + } + case 'font-weight': { + switch (value) { + case 'bold': + { + styleObject.bold = true; + break; + } + } + break; + } + case 'text-decoration': { + switch (value) { + case 'underline': { + styleObject.decoration = 'underline'; + break; + } + case 'line-through': { + styleObject.decoration = 'lineThrough'; + break; + } + } + break; + } + case 'font-style': { + switch (value) { + case 'italic': { + styleObject.italics = true; + break; + } + } + break; + } + case 'color': { + styleObject.color = parseColor(value); + break; + } + case 'background-color': { + styleObject.background = parseColor(value); + break; + } + } + } + } + } + return styleObject; + } + + /** + * Returns the color in a hex format (e.g. #12ff00). + * Also tries to convert RGB colors into hex values + * + * @param color color as string representation + * @returns color as hex values for pdfmake + */ + var parseColor = function(color) { + var haxRegex = new RegExp('^#([0-9a-f]{3}|[0-9a-f]{6})$'); + + // e.g. `#fff` or `#ff0048` + var rgbRegex = new RegExp('^rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)$'); + + // e.g. rgb(0,255,34) or rgb(22, 0, 0) + var nameRegex = new RegExp('^[a-z]+$'); + + if (haxRegex.test(color)) { + return color; + } else if (rgbRegex.test(color)) { + var decimalColors = rgbRegex.exec(color).slice(1); + for (var i = 0; i < 3; i++) { + var decimalValue = +decimalColors[i]; + if (decimalValue > 255) { + decimalValue = 255; + } + var hexString = '0' + decimalValue.toString(16); + hexString = hexString.slice(-2); + decimalColors[i] = hexString; + } + return '#' + decimalColors.join(''); + } else if (nameRegex.test(color)) { + return color; + } else { + console.error('Could not parse color "' + color + '"'); + return color; + } + } + + /** + * Helper function to create valid doc definitions container elements for pdfmake + * + * @param name should be a pdfMake container element, like 'text' or 'stack' + * @param content + */ + var create = function(name, content) { + var container = {}; + var docDef = content || []; + container[name] = docDef; + return container; + } + + return convertHtml(htmlText, lnMode) +} + +},{}]},{},[1]); diff --git a/example.js b/example.js new file mode 100644 index 0000000..91c4841 --- /dev/null +++ b/example.js @@ -0,0 +1,131 @@ +var pdfMake = require("pdfmake/build/pdfmake"); +var pdfFonts = require("pdfmake/build/vfs_fonts"); +pdfMake.vfs = pdfFonts.pdfMake.vfs; +var fs = require("fs"); +var jsdom = require("jsdom"); +var { JSDOM } = jsdom; +var { window } = new JSDOM(""); +var htmlToPdfMake = require("./index.js"); + +var html = htmlToPdfMake(` + Simple text +
+

Title Level 1

+

Title Level 2

+

Title Level 3

+

Title Level 4

+
Title Level 5
+
Title Level 6
+
+

+ This is a sentence with a bold word, one in italic, and one with underline. And finally a link. +

+ An orange bold span with margins. +

+ Below is a unordered list: +

    +
  • First item
  • +
  • Second item
  • +
  • + With a sub unordered list: +
      +
    • Sub First item
    • +
    • Sub Second item
    • +
    • With a sub sub unordered list: +
        +
      • Sub Sub First item
      • +
      • Sub Sub Second item
      • +
      +
    • +
    +
  • +
  • + With a sub order list: +
      +
    1. Sub Item 1
    2. +
    3. Sub Item 2
    4. +
    5. With a sub sub ordered list +
        +
      1. Sub Sub Item 1
      2. +
      3. Sub Sub Item 2
      4. +
      +
    +
  • +
+
This sentence is surrended by BR
+

+

+ A first level ordered list: +

    +
  1. Item 1
  2. +
  3. Item 2
  4. +
  5. Item 3
  6. +
+

+
+

+ Text in bold. + This is a red span +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
RegionResult Q1Result Q2
Americas+3%+6%
Europe+3.9%+5%
Asia+1.5%+0.9%
+ + + + + + + + + + +
Header Column 1Header Column 2
Value Column 1Value Column 2
+`, window); + +var docDefinition = { + content: [ + html + ], + styles:{ + red:{ + color:'red' + }, + bold:{ + bold:true + }, + 'html-p':{ + margin:[0, 5, 0, 5] + } + } +}; + +var pdfDocGenerator = pdfMake.createPdf(docDefinition); +pdfDocGenerator.getBuffer(function(buffer) { + fs.writeFileSync('example.pdf', buffer); + console.log('--> example.pdf') +}); diff --git a/example.pdf b/example.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f0cdfbf85cd312897a74e1f0ce2530edc394359d GIT binary patch literal 20976 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 literal 0 HcmV?d00001 diff --git a/index.js b/index.js new file mode 100644 index 0000000..0bc62a8 --- /dev/null +++ b/index.js @@ -0,0 +1,330 @@ +// source: https://github.com/OpenSlides/OpenSlides/blob/f4f8b8422f9b3fbab58e35ac3f8f870d35813b7d/client/src/app/core/ui-services/html-to-pdf.service.ts +// and https://github.com/bpampuch/pdfmake/issues/205 + +/** + To use it: + import htmlToPdfMake from 'html-to-pdfmake.js' + htmlToPdfMake('my bold text'); +*/ + +/** + * Transform HTML code to a PdfMake object + * @param {String} htmlText The HTML code to transform + * @param {Object} [window] The `window` object (only used for the tests) + * @return {Object} it returns a PdfMake object + * + * @example + * // Some styles are applied by defaults for the supported HTML elements + * // but you can pass your own styles if you prefer + * htmlToPdfMake('

My Title

My paragraph

') + */ +//var util = require("util"); // to debug +module.exports = function(htmlText, wndw) { + wndw = wndw || window; + + // set default styles + var defaultStyles = { + b: {bold:true}, + strong: {bold:true}, + u: {decoration:'underline'}, + em: {italics:true}, + i: {italics:true}, + h1: {fontSize:24, bold:true, marginBottom:5}, + h2: {fontSize:22, bold:true, marginBottom:5}, + h3: {fontSize:20, bold:true, marginBottom:5}, + h4: {fontSize:18, bold:true, marginBottom:5}, + h5: {fontSize:16, bold:true, marginBottom:5}, + h6: {fontSize:14, bold:true, marginBottom:5}, + a: {color:'blue', decoration:'underline'}, + strike: {decoration: 'lineThrough'}, + p: {margin:[0, 5, 0, 10]}, + ul: {marginBottom:5}, + li: {marginLeft:5}, + table: {marginBottom:5}, + th: {bold:true, fillColor:'#EEEEEE'} + } + + /** + * Takes an HTML string, converts to HTML using a DOM parser and recursivly parses + * the content into pdfmake compatible doc definition + * + * @param htmlText the html text to translate as string + * @returns pdfmake doc definition as object + */ + var convertHtml = function(htmlText) { + var docDef = []; + + // Cleanup of dirty html would happen here + + // Create a HTML DOM tree out of html string + var parser = new wndw.DOMParser(); + var parsedHtml = parser.parseFromString(htmlText, 'text/html'); + + // Go thru each child + [].forEach.call(parsedHtml.body.childNodes, function(child) { + var ret = parseElement(child); + if (ret) { + // to reduce the amount of code + if (Array.isArray(ret) && ret.length === 1) ret=ret[0]; + //console.log(util.inspect(ret, {showHidden: false, depth: null})); // to debug + docDef.push(ret); + } + }); + + return docDef; + } + + /** + * Converts a single HTML element to pdfmake, calls itself recursively for child html elements + * + * @param element can be an HTML element (

) or plain text ("Hello World") + * @param currentParagraph usually holds the parent element, to allow nested structures + * @param styles holds the style attributes of HTML elements (`

...`) + * @returns the doc def to the given element in consideration to the given paragraph and styles + */ + var parseElement = function(element, parentNode) { + var nodeName = element.nodeName.toLowerCase(); + var parentNodeName = (parentNode ? parentNode.nodeName.toLowerCase() : ''); + var ret, text, cssClass, cssStyle, style; + + // check the node type + switch(element.nodeType) { + case 3: { // TEXT_NODE + if (element.textContent) { + text = element.textContent.replace(/\n(\s+)?/g, ""); + if (text) { + ret = {'text': text}; + if (parentNodeName) { + // do we have a default style to apply? + if (defaultStyles[parentNodeName]) { + for (style in defaultStyles[parentNodeName]) { + if (defaultStyles[parentNodeName].hasOwnProperty(style)) { + ret[style] = defaultStyles[parentNodeName][style]; + } + } + } + + // for links + if (parentNodeName === 'a') { + ret.link = parentNode.getAttribute("href"); + } + + // is there any class to this element? + cssClass = parentNode.getAttribute("class"); + if (cssClass) { + ret.style = cssClass.split(' '); + } + + // check if the element has a "style" attribute + if (ret.text) { + cssStyle = parentNode.getAttribute("style"); + if (cssStyle) { + cssStyle = computeStyle(cssStyle); + cssStyle.forEach(function(style) { + ret[style.key] = style.value; + }) + } + } + } else { + ret = text; + } + } + } + + return ret; + } + case 1: { // ELEMENT_NODE + ret = []; + + // check children + [].forEach.call(element.childNodes, function(child) { + // for THEAD and TBODY we go straight to the TR + //if (child.nodeName === "THEAD" || child.nodeName === "TBODY" || child.nodeName === "TFOOTER") continue; + child = parseElement(child, element); + if (child) { + if (Array.isArray(child) && child.length === 1) child=child[0]; + ret.push(child); + } + }); + + if (ret.length===0) ret=""; + + // check which kind of tag we have + switch (nodeName) { + case "br": { + // for BR we return '\n' + ret = '\n'; + break; + } + case "ol": + case "ul": { + ret = {"_":ret}; + ret[nodeName] = ret._; + delete ret._; + // add a custom class to let the user customize the element + ret.style = ['html-'+nodeName]; + // is there any class to this element? + cssClass = element.getAttribute("class"); + if (cssClass) { + ret.style = ret.style.concat(cssClass.split(' ')); + } + break; + } + case "table":{ + ret = {"_":ret, table:{body:[]}}; + ret._.forEach(function(re) { + if (re.stack) { + var tr=[]; + re.stack.forEach(function(r) { + if (r.stack) { + ret.table.body.push(r.stack) + } else { + tr.push(r); + } + }); + if (tr.length>0) ret.table.body.push(tr); + } + }); + delete ret._; + break; + } + } + // add a custom class to let the user customize the element + if (ret) { + if (Array.isArray(ret)) { + // add a custom class to let the user customize the element + if (ret.length === 1) { + ret=ret[0]; + ret.style = (ret.style||[]).concat(['html-'+nodeName]); + } else { + ret = (nodeName==='p' ? {text:ret} : {stack:ret}); + ret.style = ['html-'+nodeName]; + } + } else if (ret.table || ret.ol || ret.ul) { // for TABLE / UL / OL + ret.style = ['html-'+nodeName]; + // is there any class to this element? + cssClass = element.getAttribute("class"); + if (cssClass) { + ret.style = ret.style.concat(cssClass.split(' ')); + } + // do we have a default style to apply? + if (defaultStyles.table) { + for (style in defaultStyles.table) { + if (defaultStyles.table.hasOwnProperty(style)) { + ret[style] = defaultStyles.table[style]; + } + } + } + } + } + + return ret; + } + } + return ""; + } + + /** + * Transform a CSS expression (e.g. 'margin:10px') in the PDFMake version + * + * @param {String} style The CSS expression to transform + * @returns {Array} array of {key, value} + */ + var computeStyle = function(style) { + var styleDefs = style.split(';').map(function(style) { return style.replace(/\s/g, '').toLowerCase().split(':') }); + var ret = []; + styleDefs.forEach(function(styleDef) { + var key = styleDef[0]; + var value = styleDef[1]; + switch (key) { + case "margin": { + value = value.replace(/(\d+)([^\d]+)/g,"$1 ").trim().split(' '); + // pdfMake uses a different order than CSS + if (value.length===1) value=+value[0]; // single value + else if (value.length===2) value=[+value[1], +value[0]]; // vertical | horizontal ==> horizontal | vertical + else if (value.length===3) value=[+value[1], +value[0], +value[1], +value[2]]; // top | horizontal | bottom ==> left | top | right | bottom + else if (value.length===4) value=[+value[3], +value[0], +value[1], +value[2]]; // top | right | bottom | left ==> left | top | right | bottom + ret.push({key:key, value:value}); + break; + } + case "text-align": { + ret.push({key:"alignment", value:value}) + break; + } + case "font-weight": { + if (value === "bold") ret.push({key:"bold", value:true}); + break; + } + case "text-decoration": { + ret.push({key:"decoration", value:toCamelCase(value)}) + break; + } + case "font-style": { + if (value==="italic") ret.push({key:"italics", value:true}); + break; + } + case "color": { + ret.push({key:"color", value:parseColor(value)}) + break; + } + case "background-color": { + ret.push({key:"background", value:parseColor(value)}) + break; + } + default: { + if (key.indexOf("-") > -1) key=toCamelCase(key); + if (value) { + value = value.replace(/(\d+)([^\d]+)/g,"$1 ").trim(); + if (!isNaN(value)) value=+value; // turn it into a number + ret.push({key:key, value:value}); + } + } + } + }); + return ret; + } + + var toCamelCase = function(str) { + return str.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase() }); + } + + /** + * Returns the color in a hex format (e.g. #12ff00). + * Also tries to convert RGB colors into hex values + * + * @param color color as string representation + * @returns color as hex values for pdfmake + */ + var parseColor = function(color) { + var haxRegex = new RegExp('^#([0-9a-f]{3}|[0-9a-f]{6})$'); + + // e.g. `#fff` or `#ff0048` + var rgbRegex = new RegExp('^rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)$'); + + // e.g. rgb(0,255,34) or rgb(22, 0, 0) + var nameRegex = new RegExp('^[a-z]+$'); + + if (haxRegex.test(color)) { + return color; + } else if (rgbRegex.test(color)) { + var decimalColors = rgbRegex.exec(color).slice(1); + for (var i = 0; i < 3; i++) { + var decimalValue = +decimalColors[i]; + if (decimalValue > 255) { + decimalValue = 255; + } + var hexString = '0' + decimalValue.toString(16); + hexString = hexString.slice(-2); + decimalColors[i] = hexString; + } + return '#' + decimalColors.join(''); + } else if (nameRegex.test(color)) { + return color; + } else { + console.error('Could not parse color "' + color + '"'); + return color; + } + } + + return convertHtml(htmlText) +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4bebd6d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2182 @@ +{ + "name": "html-to-pdfmake", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "abab": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", + "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==", + "dev": true + }, + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + }, + "acorn-globals": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz", + "integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + } + }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true, + "optional": true + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "ast-transform": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/ast-transform/-/ast-transform-0.0.0.tgz", + "integrity": "sha1-dJRAWIh9goPhidlUYAlHvJj+AGI=", + "dev": true, + "requires": { + "escodegen": "~1.2.0", + "esprima": "~1.0.4", + "through": "~2.3.4" + }, + "dependencies": { + "escodegen": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.2.0.tgz", + "integrity": "sha1-Cd55Z3kcyVi3+Jot220jRRrzJ+E=", + "dev": true, + "requires": { + "esprima": "~1.0.4", + "estraverse": "~1.5.0", + "esutils": "~1.0.0", + "source-map": "~0.1.30" + } + }, + "esprima": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", + "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=", + "dev": true + }, + "estraverse": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.5.1.tgz", + "integrity": "sha1-hno+jlip+EYYr7bC3bzZFrfLr3E=", + "dev": true + }, + "esutils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.0.0.tgz", + "integrity": "sha1-gVHTWOIMisx/t0XnRywAJf5JZXA=", + "dev": true + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "ast-types": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.7.8.tgz", + "integrity": "sha1-kC0uDWDQcb3NRtwRXhgJ7RHBOKk=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", + "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brfs": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz", + "integrity": "sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==", + "dev": true, + "requires": { + "quote-stream": "^1.0.1", + "resolve": "^1.1.5", + "static-module": "^2.2.0", + "through2": "^2.0.0" + } + }, + "brotli": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.2.tgz", + "integrity": "sha1-UlqcrU/LqWR119OI9q7LE+7VL0Y=", + "dev": true, + "requires": { + "base64-js": "^1.1.2" + }, + "dependencies": { + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + } + } + }, + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "dev": true + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browserify-optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-optional/-/browserify-optional-1.0.1.tgz", + "integrity": "sha1-HhNyLP3g2F8SFnbCpyztUzoBiGk=", + "dev": true, + "requires": { + "ast-transform": "0.0.0", + "ast-types": "^0.7.0", + "browser-resolve": "^1.8.1" + } + }, + "buffer-equal": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "core-js": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", + "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-js": { + "version": "3.1.9-1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", + "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=", + "dev": true + }, + "cssom": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", + "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==", + "dev": true + }, + "cssstyle": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz", + "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "dfa": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.1.0.tgz", + "integrity": "sha1-0wIYvRDQMPpCHfPrvIIoVGOjF4E=", + "dev": true, + "requires": { + "babel-runtime": "^6.11.6" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz", + "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "falafel": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.1.0.tgz", + "integrity": "sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw=", + "dev": true, + "requires": { + "acorn": "^5.0.0", + "foreach": "^2.0.5", + "isarray": "0.0.1", + "object-keys": "^1.0.6" + }, + "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, + "fontkit": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-1.8.0.tgz", + "integrity": "sha512-EFDRCca7khfQWYu1iFhsqeABpi87f03MBdkT93ZE6YhqCdMzb5Eojb6c4dlJikGv5liuhByyzA7ikpIPTSBWbQ==", + "dev": true, + "requires": { + "babel-runtime": "^6.11.6", + "brfs": "^1.4.0", + "brotli": "^1.2.0", + "browserify-optional": "^1.0.0", + "clone": "^1.0.1", + "deep-equal": "^1.0.0", + "dfa": "^1.0.0", + "restructure": "^0.5.3", + "tiny-inflate": "^1.0.2", + "unicode-properties": "^1.0.0", + "unicode-trie": "^0.3.0" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", + "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz", + "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.11", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + } + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-14.0.0.tgz", + "integrity": "sha512-/VkyPmdtbwqpJSkwDx3YyJ3U1oawYNB/h5z8vTUZGAzjtu2OHTeFRfnJqyMHsJ5Cyes23trOmvUpM1GfHH1leA==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^6.0.4", + "acorn-globals": "^4.3.0", + "array-equal": "^1.0.0", + "cssom": "^0.3.4", + "cssstyle": "^1.1.1", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.0", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.0.9", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "saxes": "^3.1.5", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.5.0", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^6.1.2", + "xml-name-validator": "^3.0.0" + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "linebreak": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-0.3.0.tgz", + "integrity": "sha1-BSZICmLAW9Z58+nZmDDgnGp9DtY=", + "dev": true, + "requires": { + "base64-js": "0.0.8", + "brfs": "^1.3.0", + "unicode-trie": "^0.3.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "magic-string": { + "version": "0.22.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", + "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", + "dev": true, + "requires": { + "vlq": "^0.2.2" + } + }, + "merge-source-map": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz", + "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=", + "dev": true, + "requires": { + "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", + "dev": true + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "dev": true, + "requires": { + "mime-db": "~1.38.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "nwsapi": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.3.tgz", + "integrity": "sha512-RowAaJGEgYXEZfQ7tvvdtAQUKPyTR6T6wNu0fwlNsGQYr/h3yQc6oI8WnVZh3Y/Sylwc+dtAlvPqfFZjhTyk3A==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-inspect": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz", + "integrity": "sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pdfkit": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/pdfkit/-/pdfkit-0.9.0.tgz", + "integrity": "sha512-j/tJvvoEM7qMiOfodNkz6XRNBvAhVohWP1mUvgg+Xy8X8S3aMBpVGXJGZWNCoCUH2ywLidZSbHyn5mJaqv9umw==", + "dev": true, + "requires": { + "crypto-js": "^3.1.9-1", + "fontkit": "^1.0.0", + "linebreak": "^0.3.0", + "png-js": ">=0.1.0", + "saslprep": "1.0.1" + } + }, + "pdfmake": { + "version": "0.1.54", + "resolved": "https://registry.npmjs.org/pdfmake/-/pdfmake-0.1.54.tgz", + "integrity": "sha512-HO2FX+czmO+8LpWXQMFQfdUCCKnqwSvSEJExGkUKfsV34DRIV5PZjNg0xWS7ypGrnTY6RTTssWpdreX/pbyeyw==", + "dev": true, + "requires": { + "iconv-lite": "^0.4.24", + "linebreak": "^0.3.0", + "pdfkit": "^0.9.0" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "png-js": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/png-js/-/png-js-0.1.1.tgz", + "integrity": "sha1-HMfCEjA6yr50Jj7DrHgAlYAkLZM=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "quote-stream": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz", + "integrity": "sha1-hJY/jJwmuULhU/7rU6rnRlK34LI=", + "dev": true, + "requires": { + "buffer-equal": "0.0.1", + "minimist": "^1.1.3", + "through2": "^2.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "request-promise-core": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", + "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "request-promise-native": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", + "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", + "dev": true, + "requires": { + "request-promise-core": "1.1.2", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "restructure": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/restructure/-/restructure-0.5.4.tgz", + "integrity": "sha1-9U591WNZD7NP1r9Vh2EJrsyyjeg=", + "dev": true, + "requires": { + "browserify-optional": "^1.0.0" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "saslprep": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.1.tgz", + "integrity": "sha512-ntN6SbE3hRqd45PKKadRPgA+xHPWg5lPSj2JWJdJvjTwXDDfkPVtXWvP8jJojvnm+rAsZ2b299C5NwZqq818EA==", + "dev": true + }, + "saxes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.9.tgz", + "integrity": "sha512-FZeKhJglhJHk7eWG5YM0z46VHmI3KJpMBAQm3xa9meDvd+wevB5GuBB0wc0exPInZiBBHqi00DbS8AcvCGCFMw==", + "dev": true, + "requires": { + "xmlchars": "^1.3.1" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "shallow-copy": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", + "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-test-framework": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/simple-test-framework/-/simple-test-framework-0.1.7.tgz", + "integrity": "sha1-8cESkhIpQsGMooZljzGVrePwV/8=", + "dev": true, + "requires": { + "wordwrap": "0.0.2" + } + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "dev": true, + "requires": { + "escodegen": "^1.8.1" + } + }, + "static-module": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/static-module/-/static-module-2.2.5.tgz", + "integrity": "sha512-D8vv82E/Kpmz3TXHKG8PPsCPg+RAX6cbCOyvjM6x04qZtQ47EtJFVwRsdov3n5d6/6ynrOY9XB4JkaZwB2xoRQ==", + "dev": true, + "requires": { + "concat-stream": "~1.6.0", + "convert-source-map": "^1.5.1", + "duplexer2": "~0.1.4", + "escodegen": "~1.9.0", + "falafel": "^2.1.0", + "has": "^1.0.1", + "magic-string": "^0.22.4", + "merge-source-map": "1.0.4", + "object-inspect": "~1.4.0", + "quote-stream": "~1.0.2", + "readable-stream": "~2.3.3", + "shallow-copy": "~0.0.1", + "static-eval": "^2.0.0", + "through2": "~2.0.3" + }, + "dependencies": { + "escodegen": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true + }, + "table": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz", + "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==", + "dev": true, + "requires": { + "ajv": "^6.9.1", + "lodash": "^4.17.11", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "tiny-inflate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.2.tgz", + "integrity": "sha1-k9nez/yIBb1X6uQxDwt0Xptvs6c=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "unicode-properties": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.1.0.tgz", + "integrity": "sha1-epbu9J91aC6mnSMV7smsQ//fAME=", + "dev": true, + "requires": { + "brfs": "^1.4.0", + "unicode-trie": "^0.3.0" + } + }, + "unicode-trie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-0.3.1.tgz", + "integrity": "sha1-1nHd3YkQGgi6w3tqUWEBBgIFIIU=", + "dev": true, + "requires": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true + }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, + "requires": { + "browser-process-hrtime": "^0.1.2" + } + }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlchars": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-1.3.1.tgz", + "integrity": "sha512-tGkGJkN8XqCod7OT+EvGYK5Z4SfDQGD30zAa58OcnAa0RRWgzUEK72tkXhsX1FZd+rgnhRxFtmO+ihkp8LHSkw==", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..4c5ca03 --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "html-to-pdfmake", + "version": "1.0.0", + "description": "Convert HTML code to PDFMake", + "main": "index.js", + "scripts": { + "pretest": "eslint index.js", + "test": "node test/unit.js", + "pdf": "node test/create_pdf.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Aymkdn/html-to-pdfmake.git" + }, + "author": "Aymkdn", + "license": "MIT", + "bugs": { + "url": "https://github.com/Aymkdn/html-to-pdfmake/issues" + }, + "homepage": "https://github.com/Aymkdn/html-to-pdfmake#readme", + "devDependencies": { + "eslint": "^5.16.0", + "jsdom": "^14.0.0", + "pdfmake": "^0.1.54", + "simple-test-framework": "^0.1.7" + } +} diff --git a/test/unit.js b/test/unit.js new file mode 100644 index 0000000..5994c19 --- /dev/null +++ b/test/unit.js @@ -0,0 +1,244 @@ +var htmlToPdfMake = require('../index.js'); +var test = require("simple-test-framework"); +var jsdom = require("jsdom"); +var { JSDOM } = jsdom; +var { window } = new JSDOM(""); + +// { text: 'bold word', bold: true, style: [ 'html-b' ] } +test("b",function(t) { + var ret = htmlToPdfMake("bold word", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "bold word" && + ret.bold === true && + Array.isArray(ret.style) && + ret.style[0] === 'html-b', + ""); + + t.finish(); +}) + +test("strong",function(t) { + var ret = htmlToPdfMake("bold word", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "bold word" && + ret.bold === true && + Array.isArray(ret.style) && + ret.style[0] === 'html-strong', + ""); + + t.finish(); +}) + +// { text: 'underline word', decoration: 'underline', style: [ 'html-u' ] } +test("u",function(t) { + var ret = htmlToPdfMake("underline word", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "underline word" && + ret.decoration === "underline" && + Array.isArray(ret.style) && + ret.style[0] === 'html-u', + ""); + + t.finish(); +}) + +test("em",function(t) { + var ret = htmlToPdfMake("italic word", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "italic word" && + ret.italics === true && + Array.isArray(ret.style) && + ret.style[0] === 'html-em', + ""); + + t.finish(); +}) + +test("i",function(t) { + var ret = htmlToPdfMake("italic word", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "italic word" && + ret.italics === true && + Array.isArray(ret.style) && + ret.style[0] === 'html-i', + ""); + + t.finish(); +}) + +// [{"text":"level 1","fontSize":24,"bold":true,"marginBottom":5,"style":["html-h1"]}] +test("h1",function(t) { + var ret = htmlToPdfMake("

level 1

", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "level 1" && + ret.fontSize === 24 && + ret.bold === true && + ret.marginBottom === 5 && + Array.isArray(ret.style) && + ret.style[0] === 'html-h1', + "

"); + + t.finish(); +}) + +test("h2",function(t) { + var ret = htmlToPdfMake("

level 2

", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "level 2" && + ret.fontSize === 22 && + ret.bold === true && + ret.marginBottom === 5 && + Array.isArray(ret.style) && + ret.style[0] === 'html-h2', + "

"); + + t.finish(); +}) + +test("h3",function(t) { + var ret = htmlToPdfMake("

level 3

", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "level 3" && + ret.fontSize === 20 && + ret.bold === true && + ret.marginBottom === 5 && + Array.isArray(ret.style) && + ret.style[0] === 'html-h3', + "

"); + + t.finish(); +}) + +test("h4",function(t) { + var ret = htmlToPdfMake("

level 4

", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "level 4" && + ret.fontSize === 18 && + ret.bold === true && + ret.marginBottom === 5 && + Array.isArray(ret.style) && + ret.style[0] === 'html-h4', + "

"); + + t.finish(); +}) + +test("h5",function(t) { + var ret = htmlToPdfMake("

level 5
", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "level 5" && + ret.fontSize === 16 && + ret.bold === true && + ret.marginBottom === 5 && + Array.isArray(ret.style) && + ret.style[0] === 'html-h5', + "
"); + + t.finish(); +}) + +test("h6",function(t) { + var ret = htmlToPdfMake("
level 6
", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "level 6" && + ret.fontSize === 14 && + ret.bold === true && + ret.marginBottom === 5 && + Array.isArray(ret.style) && + ret.style[0] === 'html-h6', + "
"); + + t.finish(); +}) + +// { text: 'link', color: 'blue', decoration: 'underline', link: 'https://www.somewhere.com', style: [ 'html-a' ] } +test("a",function(t) { + var ret = htmlToPdfMake('link', window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "link" && + ret.color === "blue" && + ret.decoration === "underline" && + ret.link === "https://www.somewhere.com" && + Array.isArray(ret.style) && + ret.style[0] === 'html-a', + ""); + + t.finish(); +}) + +// { text: 'strike', decoration: 'lineThrough', style: [ 'html-strike' ] } +test("strike",function(t) { + var ret = htmlToPdfMake("strike", window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.text === "strike" && + ret.decoration === "lineThrough" && + Array.isArray(ret.style) && + ret.style[0] === 'html-strike', + ""); + + t.finish(); +}) + +// [{"table":{"body":[[{"text":"Header Column A","bold":true,"fillColor":"#EEEEEE","style":["html-th"]},{"text":"Header Column B","bold":true,"fillColor":"#EEEEEE","style":["html-th"]}],[{"text":"Value Cell A2","style":["html-td"]},{"text":"Value Cell B2","style":["html-td"]}],[{"text":"Value Cell A3","style":["html-td"]},{"text":"Value Cell B3","style":["html-td"]}]]},"style":"html-table","marginBottom":5}] +test("table",function(t) { + var html = ` + + + + + + + + + + + + + + + + +
Header Column AHeader Column B
Value Cell A2Value Cell B2
Value Cell A3Value Cell B3
`; + var ret = htmlToPdfMake(html, window); + t.check(Array.isArray(ret) && ret.length===1, "return is OK"); + ret = ret[0]; + t.check( + ret.table && + Array.isArray(ret.table.body) && + ret.table.body.length === 3 && + ret.table.body[0][0].text === "Header Column A" && + ret.table.body[0][0].style[0] === 'html-th' && + ret.table.body[1][1].text === "Value Cell B2" && + ret.table.body[1][1].style[0] === 'html-td' && + Array.isArray(ret.style) && + ret.style[0] === 'html-table', + ""); + + t.finish(); +})