diff --git a/.gitignore b/.gitignore
index 815f58d..f55b7a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ bower_components
!.gitignore
*.sublime-*
+dist/
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 18ae2d8..d6b8187 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,3 @@
language: node_js
node_js:
- - "0.11"
- - "0.10"
+ - node
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000..6e59fe7
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,46 @@
+const gulp = require('gulp');
+
+gulp.task('clean', () => {
+ const del = require('del');
+ return del('./dist/');
+});
+
+gulp.task('compile-ts', () => {
+ const ts = require('gulp-typescript');
+ const tsProject = ts.createProject('./tsconfig.json');
+ const dest = tsProject.options.outDir;
+ return tsProject.src()
+ .pipe(tsProject())
+ .pipe(gulp.dest(dest));
+});
+
+gulp.task('copy-files', () => {
+ return gulp.src(['./package.json', 'readme.md'])
+ .pipe(gulp.dest('./dist/'));
+});
+
+gulp.task('watch-ts', async () => {
+ const ts = require('gulp-typescript');
+ const tsProject = ts.createProject('./tsconfig.json');
+ const path = require('path');
+ const dest = tsProject.options.outDir;
+ await tsProject.src()
+ .pipe(tsProject())
+ .pipe(gulp.dest(dest));
+ return gulp.watch(['./src/**/*.ts'], (file) => {
+ const tsProject = ts.createProject('./tsconfig.json');
+ const relative = path.relative('./', path.dirname(file.path));
+ const outDir = tsProject.options.outDir;
+ const dest = path.join(outDir, relative);
+ return gulp.src(file.path)
+ .pipe(tsProject())
+ .pipe(gulp.dest(dest));
+ });
+});
+
+gulp.task('default', (cb) => {
+ const sequence = require('gulp-sequence');
+ sequence('clean', 'copy-files', 'compile-ts', cb);
+});
+
+gulp.task('dev', ['watch-ts']);
diff --git a/index.js b/index.js
deleted file mode 100644
index 38d7e04..0000000
--- a/index.js
+++ /dev/null
@@ -1,607 +0,0 @@
-require('apollojs');
-
-var entities = require('entities');
-
-/**
- * Node Class as base class for TextNode and HTMLElement.
- */
-function Node() {
-
-}
-$declare(Node, {
-
-});
-$defenum(Node, {
- ELEMENT_NODE: 1,
- TEXT_NODE: 3
-});
-
-/**
- * TextNode to contain a text element in DOM tree.
- * @param {string} value [description]
- */
-function TextNode(value) {
- this.rawText = value;
-}
-$inherit(TextNode, Node, {
-
- /**
- * Node Type declaration.
- * @type {Number}
- */
- nodeType: Node.TEXT_NODE,
-
- /**
- * Get unescaped text value of current node and its children.
- * @return {string} text content
- */
- get text() {
- return entities.decodeHTML5(this.rawText);
- },
-
- /**
- * Detect if the node contains only white space.
- * @return {bool}
- */
- get isWhitespace() {
- return /^(\s| )*$/.test(this.rawText);
- }
-
-});
-
-var kBlockElements = {
- div: true,
- p: true,
- // ul: true,
- // ol: true,
- li: true,
- // table: true,
- // tr: true,
- td: true,
- section: true,
- br: true
-};
-
-/**
- * HTMLElement, which contains a set of children.
- * Note: this is a minimalist implementation, no complete tree
- * structure provided (no parentNode, nextSibling,
- * previousSibling etc).
- * @param {string} name tagName
- * @param {Object} keyAttrs id and class attribute
- * @param {Object} rawAttrs attributes in string
- */
-function HTMLElement(name, keyAttrs, rawAttrs) {
- this.tagName = name;
- this.rawAttrs = rawAttrs || '';
- // this.parentNode = null;
- this.childNodes = [];
- if (keyAttrs.id)
- this.id = keyAttrs.id;
- if (keyAttrs.class)
- this.classNames = keyAttrs.class.split(/\s+/);
- else
- this.classNames = [];
-}
-$inherit(HTMLElement, Node, {
-
- /**
- * Node Type declaration.
- * @type {Number}
- */
- nodeType: Node.ELEMENT_NODE,
-
- /**
- * Get unescaped text value of current node and its children.
- * @return {string} text content
- */
- get text() {
- return entities.decodeHTML5(this.rawText);
- },
-
- /**
- * Get escpaed (as-it) text value of current node and its children.
- * @return {string} text content
- */
- get rawText() {
- var res = '';
- for (var i = 0; i < this.childNodes.length; i++)
- res += this.childNodes[i].rawText;
- return res;
- },
-
- /**
- * Get structured Text (with '\n' etc.)
- * @return {string} structured text
- */
- get structuredText() {
- var currentBlock = [];
- var blocks = [currentBlock];
- function dfs(node) {
- if (node.nodeType === Node.ELEMENT_NODE) {
- if (kBlockElements[node.tagName]) {
- if (currentBlock.length > 0)
- blocks.push(currentBlock = []);
- node.childNodes.forEach(dfs);
- if (currentBlock.length > 0)
- blocks.push(currentBlock = []);
- } else {
- node.childNodes.forEach(dfs);
- }
- } else if (node.nodeType === Node.TEXT_NODE) {
- if (node.isWhitespace) {
- // Whitespace node, postponed output
- currentBlock.prependWhitespace = true;
- } else {
- var text = node.text;
- if (currentBlock.prependWhitespace) {
- text = ' ' + text;
- currentBlock.prependWhitespace = false;
- }
- currentBlock.push(text);
- }
- }
- }
- dfs(this);
- return blocks
- .map(function(block) {
- // Normalize each line's whitespace
- return block.join('').trim().replace(/\s{2,}/g, ' ');
- })
- .join('\n').trimRight();
- },
-
- /**
- * Trim element from right (in block) after seeing pattern in a TextNode.
- * @param {RegExp} pattern pattern to find
- * @return {HTMLElement} reference to current node
- */
- trimRight: function(pattern) {
- function dfs(node) {
- for (var i = 0; i < node.childNodes.length; i++) {
- var childNode = node.childNodes[i];
- if (childNode.nodeType === Node.ELEMENT_NODE) {
- dfs(childNode);
- } else {
- var index = childNode.rawText.search(pattern);
- if (index > -1) {
- childNode.rawText = childNode.rawText.substr(0, index);
- // trim all following nodes.
- node.childNodes.length = i+1;
- }
- }
- }
- }
- dfs(this);
- return this;
- },
-
- /**
- * Get DOM structure
- * @return {string} strucutre
- */
- get structure() {
- var res = [];
- var indention = 0;
- function write(str) {
- res.push(' '.repeat(indention) + str);
- }
- function dfs(node) {
- var idStr = node.id ? ('#' + node.id) : '';
- var classStr = node.classNames.length ? ('.' + node.classNames.join('.')) : '';
- write(node.tagName + idStr + classStr);
- indention++;
- for (var i = 0; i < node.childNodes.length; i++) {
- var childNode = node.childNodes[i];
- if (childNode.nodeType === Node.ELEMENT_NODE) {
- dfs(childNode);
- } else if (childNode.nodeType === Node.TEXT_NODE) {
- if (!childNode.isWhitespace)
- write('#text');
- }
- }
- indention--;
- }
- dfs(this);
- return res.join('\n');
- },
-
- /**
- * Remove whitespaces in this sub tree.
- * @return {HTMLElement} pointer to this
- */
- removeWhitespace: function() {
- var i = 0, o = 0;
- for (; i < this.childNodes.length; i++) {
- var node = this.childNodes[i];
- if (node.nodeType === Node.TEXT_NODE) {
- if (node.isWhitespace)
- continue;
- node.rawText = node.rawText.trim();
- } else if (node.nodeType === Node.ELEMENT_NODE) {
- node.removeWhitespace();
- }
- this.childNodes[o++] = node;
- }
- this.childNodes.length = o;
- return this;
- },
-
- /**
- * Query CSS selector to find matching nodes.
- * @param {string} selector Simplified CSS selector
- * @param {Matcher} selector A Matcher instance
- * @return {HTMLElement[]} matching elements
- */
- querySelectorAll: function(selector) {
- var matcher;
- if (selector instanceof Matcher) {
- matcher = selector;
- matcher.reset();
- } else {
- matcher = new Matcher(selector);
- }
- var res = [];
- var stack = [];
- for (var i = 0; i < this.childNodes.length; i++) {
- stack.push([this.childNodes[i], 0, false]);
- while (stack.length) {
- var state = stack.back;
- var el = state[0];
- if (state[1] === 0) {
- // Seen for first time.
- if (el.nodeType !== Node.ELEMENT_NODE) {
- stack.pop();
- continue;
- }
- if (state[2] = matcher.advance(el)) {
- if (matcher.matched) {
- res.push(el);
- // no need to go further.
- matcher.rewind();
- stack.pop();
- continue;
- }
- }
- }
- if (state[1] < el.childNodes.length) {
- stack.push([el.childNodes[state[1]++], 0, false]);
- } else {
- if (state[2])
- matcher.rewind();
- stack.pop();
- }
- }
- }
- return res;
- },
-
- /**
- * Query CSS Selector to find matching node.
- * @param {string} selector Simplified CSS selector
- * @param {Matcher} selector A Matcher instance
- * @return {HTMLElement} matching node
- */
- querySelector: function(selector) {
- var matcher;
- if (selector instanceof Matcher) {
- matcher = selector;
- matcher.reset();
- } else {
- matcher = new Matcher(selector);
- }
- var stack = [];
- for (var i = 0; i < this.childNodes.length; i++) {
- stack.push([this.childNodes[i], 0, false]);
- while (stack.length) {
- var state = stack.back;
- var el = state[0];
- if (state[1] === 0) {
- // Seen for first time.
- if (el.nodeType !== Node.ELEMENT_NODE) {
- stack.pop();
- continue;
- }
- if (state[2] = matcher.advance(el)) {
- if (matcher.matched) {
- return el;
- }
- }
- }
- if (state[1] < el.childNodes.length) {
- stack.push([el.childNodes[state[1]++], 0, false]);
- } else {
- if (state[2])
- matcher.rewind();
- stack.pop();
- }
- }
- }
- return null;
- },
-
- /**
- * Append a child node to childNodes
- * @param {Node} node node to append
- * @return {Node} node appended
- */
- appendChild: function(node) {
- // node.parentNode = this;
- this.childNodes.push(node);
- return node;
- },
-
- /**
- * Get first child node
- * @return {Node} first child node
- */
- get firstChild() {
- return this.childNodes.front;
- },
-
- /**
- * Get last child node
- * @return {Node} last child node
- */
- get lastChild() {
- return this.childNodes.back;
- },
-
- /**
- * Get attributes
- * @return {Object} parsed and unescaped attributes
- */
- get attributes() {
- if (this._attrs)
- return this._attrs;
- this._attrs = {};
- var attrs = this.rawAttributes;
- for (var key in attrs) {
- this._attrs[key] = entities.decodeHTML5(attrs[key]);
- }
- return this._attrs;
- },
-
- /**
- * Get escaped (as-it) attributes
- * @return {Object} parsed attributes
- */
- get rawAttributes() {
- if (this._rawAttrs)
- return this._rawAttrs;
- var attrs = {};
- if (this.rawAttrs) {
- var re = /\b([a-z][a-z0-9\-]*)\s*=\s*("([^"]+)"|'([^']+)'|(\S+))/ig;
- for (var match; match = re.exec(this.rawAttrs); )
- attrs[match[1]] = match[3] || match[4] || match[5];
- }
- this._rawAttrs = attrs;
- return attrs;
- }
-
-});
-$define(HTMLElement, {
- __wrap: function(el) {
- el.childNodes.forEach(function(node) {
- if (node.rawText) {
- $wrap(node, TextNode);
- } else {
- $wrap(node, HTMLElement);
- }
- });
- }
-});
-
-/**
- * Cache to store generated match functions
- * @type {Object}
- */
-var pMatchFunctionCache = {};
-
-/**
- * Matcher class to make CSS match
- * @param {string} selector Selector
- */
-function Matcher(selector) {
- this.matchers = selector.split(' ').map(function(matcher) {
- if (pMatchFunctionCache[matcher])
- return pMatchFunctionCache[matcher];
- var parts = matcher.split('.');
- var tagName = parts[0];
- var classes = parts.slice(1).sort();
- var source = '';
- if (tagName && tagName != '*') {
- if (tagName[0] == '#')
- source += 'if (el.id != ' + JSON.stringify(tagName.substr(1)) + ') return false;';
- else
- source += 'if (el.tagName != ' + JSON.stringify(tagName) + ') return false;';
- }
- if (classes.length > 0)
- source += 'for (var cls = ' + JSON.stringify(classes) + ', i = 0; i < cls.length; i++) if (el.classNames.indexOf(cls[i]) === -1) return false;';
- source += 'return true;';
- return pMatchFunctionCache[matcher] = new Function('el', source);
- });
- this.nextMatch = 0;
-}
-$declare(Matcher, {
- /**
- * Trying to advance match pointer
- * @param {HTMLElement} el element to make the match
- * @return {bool} true when pointer advanced.
- */
- advance: function(el) {
- if (this.nextMatch < this.matchers.length &&
- this.matchers[this.nextMatch](el)) {
- this.nextMatch++;
- return true;
- }
- return false;
- },
- /**
- * Rewind the match pointer
- */
- rewind: function() {
- this.nextMatch--;
- },
- /**
- * Trying to determine if match made.
- * @return {bool} true when the match is made
- */
- get matched() {
- return this.nextMatch == this.matchers.length;
- },
- /**
- * Rest match pointer.
- * @return {[type]} [description]
- */
- reset: function() {
- this.nextMatch = 0;
- }
-});
-$define(Matcher, {
- /**
- * flush cache to free memory
- */
- flushCache: function() {
- pMatchFunctionCache = {};
- }
-});
-
-var kMarkupPattern = /)-->|<(\/?)([a-z][a-z0-9]*)\s*([^>]*?)(\/?)>/ig;
-var kAttributePattern = /\b(id|class)\s*=\s*("([^"]+)"|'([^']+)'|(\S+))/ig;
-var kSelfClosingElements = {
- meta: true,
- img: true,
- link: true,
- input: true,
- area: true,
- br: true,
- hr: true
-};
-var kElementsClosedByOpening = {
- li: {li: true},
- p: {p: true, div: true},
- td: {td: true, th: true},
- th: {td: true, th: true}
-};
-var kElementsClosedByClosing = {
- li: {ul: true, ol: true},
- a: {div: true},
- b: {div: true},
- i: {div: true},
- p: {div: true},
- td: {tr: true, table: true},
- th: {tr: true, table: true}
-};
-var kBlockTextElements = {
- script: true,
- noscript: true,
- style: true,
- pre: true
-};
-
-/**
- * Parses HTML and returns a root element
- */
-module.exports = {
-
- Matcher: Matcher,
- Node: Node,
- HTMLElement: HTMLElement,
- TextNode: TextNode,
-
- /**
- * Parse a chuck of HTML source.
- * @param {string} data html
- * @return {HTMLElement} root element
- */
- parse: function(data, options) {
-
- var root = new HTMLElement(null, {});
- var currentParent = root;
- var stack = [root];
- var lastTextPos = -1;
-
- options = options || {};
-
- for (var match, text; match = kMarkupPattern.exec(data); ) {
- if (lastTextPos > -1) {
- if (lastTextPos + match[0].length < kMarkupPattern.lastIndex) {
- // if has content
- text = data.substring(lastTextPos, kMarkupPattern.lastIndex - match[0].length);
- currentParent.appendChild(new TextNode(text));
- }
- }
- lastTextPos = kMarkupPattern.lastIndex;
- if (match[0][1] == '!') {
- // this is a comment
- continue;
- }
- if (options.lowerCaseTagName)
- match[2] = match[2].toLowerCase();
- if (!match[1]) {
- // not tags
- var attrs = {};
- for (var attMatch; attMatch = kAttributePattern.exec(match[3]); )
- attrs[attMatch[1]] = attMatch[3] || attMatch[4] || attMatch[5];
- // console.log(attrs);
- if (!match[4] && kElementsClosedByOpening[currentParent.tagName]) {
- if (kElementsClosedByOpening[currentParent.tagName][match[2]]) {
- stack.pop();
- currentParent = stack.back;
- }
- }
- currentParent = currentParent.appendChild(
- new HTMLElement(match[2], attrs, match[3]));
- stack.push(currentParent);
- if (kBlockTextElements[match[2]]) {
- // a little test to find next or ...
- var closeMarkup = '' + match[2] + '>';
- var index = data.indexOf(closeMarkup, kMarkupPattern.lastIndex);
- if (options[match[2]]) {
- if (index == -1) {
- // there is no matching ending for the text element.
- text = data.substr(kMarkupPattern.lastIndex);
- } else {
- text = data.substring(kMarkupPattern.lastIndex, index);
- }
- if (text.length > 0)
- currentParent.appendChild(new TextNode(text));
- }
- if (index == -1) {
- lastTextPos = kMarkupPattern.lastIndex = data.length + 1;
- } else {
- lastTextPos = kMarkupPattern.lastIndex = index + closeMarkup.length;
- match[1] = true;
- }
- }
- }
- if (match[1] || match[4] ||
- kSelfClosingElements[match[2]]) {
- // or /> or
etc.
- while (true) {
- if (currentParent.tagName == match[2]) {
- stack.pop();
- currentParent = stack.back;
- break;
- } else {
- // Trying to close current tag, and move on
- if (kElementsClosedByClosing[currentParent.tagName]) {
- if (kElementsClosedByClosing[currentParent.tagName][match[2]]) {
- stack.pop();
- currentParent = stack.back;
- continue;
- }
- }
- // Use aggressive strategy to handle unmatching markups.
- break;
- }
- }
- }
- }
-
- return root;
-
- }
-
-};
diff --git a/package.json b/package.json
index 5b4fb67..0e51611 100644
--- a/package.json
+++ b/package.json
@@ -1,43 +1,53 @@
{
- "name": "fast-html-parser",
- "version": "1.0.1",
- "description": "A very fast HTML parser, generating a simplified DOM, with basic element query support.",
- "main": "index.js",
- "scripts": {
- "test": "mocha",
- "posttest": "mocha -R travis-cov",
- "coverage": "mocha -R html-cov > coverage.html"
- },
- "author": "Xiaoyi Shi ",
- "license": "MIT",
- "dependencies": {
- "apollojs": "^1.3.0",
- "entities": "^1.1.1"
- },
- "devDependencies": {
- "mocha": "^1",
- "should": "*",
- "blanket": "*",
- "travis-cov": "*"
- },
- "config": {
- "blanket": {
- "pattern": "index.js",
- "data-cover-never": ["node_modules"]
- },
- "travis-cov": {
- "threshold": 70
- }
- },
- "directories": {
- "test": "test"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/ashi009/node-fast-html-parser.git"
- },
- "bugs": {
- "url": "https://github.com/ashi009/node-fast-html-parser/issues"
- },
- "homepage": "https://github.com/ashi009/node-fast-html-parser"
+ "name": "fast-html-parser",
+ "version": "1.0.1",
+ "description": "A very fast HTML parser, generating a simplified DOM, with basic element query support.",
+ "main": "index.js",
+ "scripts": {
+ "test": "gulp && mocha",
+ "posttest": "mocha -R travis-cov",
+ "coverage": "mocha -R html-cov > coverage.html",
+ "build": "gulp"
+ },
+ "author": "Xiaoyi Shi ",
+ "license": "MIT",
+ "dependencies": {
+ "entities": "latest"
+ },
+ "devDependencies": {
+ "@types/entities": "latest",
+ "@types/node": "latest",
+ "blanket": "latest",
+ "del": "latest",
+ "gulp": "latest",
+ "gulp-sequence": "latest",
+ "gulp-typescript": "latest",
+ "mocha": "latest",
+ "should": "latest",
+ "spec": "latest",
+ "travis-cov": "latest",
+ "typescript": "next"
+ },
+ "config": {
+ "blanket": {
+ "pattern": "./dist/index.js",
+ "data-cover-never": [
+ "node_modules"
+ ]
+ },
+ "travis-cov": {
+ "threshold": 70
+ }
+ },
+ "directories": {
+ "test": "test"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/ashi009/node-fast-html-parser.git"
+ },
+ "bugs": {
+ "url": "https://github.com/ashi009/node-fast-html-parser/issues"
+ },
+ "homepage": "https://github.com/ashi009/node-fast-html-parser"
}
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..c433416
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,655 @@
+import * as entities from 'entities';
+
+export enum NodeType {
+ ELEMENT_NODE = 1,
+ TEXT_NODE = 3
+}
+
+/**
+ * Node Class as base class for TextNode and HTMLElement.
+ */
+export abstract class Node {
+ nodeType: NodeType;
+ childNodes = [] as Node[];
+ text: string;
+ rawText: string;
+ abstract toString(): String;
+}
+/**
+ * TextNode to contain a text element in DOM tree.
+ * @param {string} value [description]
+ */
+export class TextNode extends Node {
+ constructor(value: string) {
+ super();
+ this.rawText = value;
+ }
+
+ /**
+ * Node Type declaration.
+ * @type {Number}
+ */
+ nodeType = NodeType.TEXT_NODE;
+
+ /**
+ * Get unescaped text value of current node and its children.
+ * @return {string} text content
+ */
+ get text() {
+ return entities.decodeHTML5(this.rawText);
+ }
+
+ /**
+ * Detect if the node contains only white space.
+ * @return {bool}
+ */
+ get isWhitespace() {
+ return /^(\s| )*$/.test(this.rawText);
+ }
+
+ toString() {
+ return this.text;
+ }
+}
+
+const kBlockElements = {
+ div: true,
+ p: true,
+ // ul: true,
+ // ol: true,
+ li: true,
+ // table: true,
+ // tr: true,
+ td: true,
+ section: true,
+ br: true
+};
+
+export interface KeyAttributes {
+ id?: string;
+ class?: string;
+}
+
+export interface Attributes {
+ [key: string]: string;
+}
+
+export interface RawAttributes {
+ [key: string]: string;
+}
+
+function arr_back(arr: T[]) {
+ return arr[arr.length - 1];
+}
+
+/**
+ * HTMLElement, which contains a set of children.
+ *
+ * Note: this is a minimalist implementation, no complete tree
+ * structure provided (no parentNode, nextSibling,
+ * previousSibling etc).
+ * @class HTMLElement
+ * @extends {Node}
+ */
+export class HTMLElement extends Node {
+ private _attrs: Attributes;
+ private _rawAttrs: RawAttributes;
+ id: string;
+ classNames = [] as string[];
+ tagName: string;
+ rawAttrs: string;
+ /**
+ * Node Type declaration.
+ * @type {Number}
+ */
+ nodeType = NodeType.ELEMENT_NODE;
+ /**
+ * Creates an instance of HTMLElement.
+ * @param {string} name tagName
+ * @param {KeyAttributes} keyAttrs id and class attribute
+ * @param {string} [rawAttrs] attributes in string
+ *
+ * @memberof HTMLElement
+ */
+ constructor(name: string, keyAttrs: KeyAttributes, rawAttrs?: string) {
+ super();
+ this.tagName = name;
+ this.rawAttrs = rawAttrs || '';
+ // this.parentNode = null;
+ this.childNodes = [];
+ if (keyAttrs.id) {
+ this.id = keyAttrs.id;
+ }
+ if (keyAttrs.class) {
+ this.classNames = keyAttrs.class.split(/\s+/);
+ }
+ }
+ /**
+ * Get escpaed (as-it) text value of current node and its children.
+ * @return {string} text content
+ */
+ get rawText() {
+ let res = '';
+ for (let i = 0; i < this.childNodes.length; i++)
+ res += this.childNodes[i].rawText;
+ return res;
+ }
+ /**
+ * Get unescaped text value of current node and its children.
+ * @return {string} text content
+ */
+ get text() {
+ return entities.decodeHTML5(this.rawText);
+ }
+ /**
+ * Get structured Text (with '\n' etc.)
+ * @return {string} structured text
+ */
+ get structuredText() {
+ let currentBlock = [] as string[];
+ const blocks = [currentBlock];
+ function dfs(node: Node) {
+ if (node.nodeType === NodeType.ELEMENT_NODE) {
+ if (kBlockElements[(node as HTMLElement).tagName]) {
+ if (currentBlock.length > 0) {
+ blocks.push(currentBlock = []);
+ }
+ node.childNodes.forEach(dfs);
+ if (currentBlock.length > 0) {
+ blocks.push(currentBlock = []);
+ }
+ } else {
+ node.childNodes.forEach(dfs);
+ }
+ } else if (node.nodeType === NodeType.TEXT_NODE) {
+ if ((node as TextNode).isWhitespace) {
+ // Whitespace node, postponed output
+ (currentBlock as any).prependWhitespace = true;
+ } else {
+ let text = node.text;
+ if ((currentBlock as any).prependWhitespace) {
+ text = ' ' + text;
+ (currentBlock as any).prependWhitespace = false;
+ }
+ currentBlock.push(text);
+ }
+ }
+ }
+ dfs(this);
+ return blocks
+ .map(function (block) {
+ // Normalize each line's whitespace
+ return block.join('').trim().replace(/\s{2,}/g, ' ');
+ })
+ .join('\n').replace(/\s+$/, ''); // trimRight;
+ }
+
+ toString() {
+ const tag = this.tagName;
+ if (tag) {
+ const is_un_closed = /^meta$/i.test(tag);
+ const is_self_closed = /^(img|br|hr|area|base|input|doctype|link)$/i.test(tag);
+ const attrs = this.rawAttrs ? ' ' + this.rawAttrs : '';
+ if (is_un_closed) {
+ return `<${tag}${attrs}>`;
+ } else if (is_self_closed) {
+ return `<${tag}${attrs} />`;
+ } else {
+ return `<${tag}${attrs}>${this.innerHTML}${tag}>`;
+ }
+ } else {
+ return this.innerHTML;
+ }
+ }
+
+ get innerHTML() {
+ return this.childNodes.map((child) => {
+ return child.toString();
+ }).join('');
+ }
+
+ get outerHTML() {
+ return this.toString();
+ }
+
+ /**
+ * Trim element from right (in block) after seeing pattern in a TextNode.
+ * @param {RegExp} pattern pattern to find
+ * @return {HTMLElement} reference to current node
+ */
+ trimRight(pattern: RegExp) {
+ function dfs(node: Node) {
+ for (let i = 0; i < node.childNodes.length; i++) {
+ const childNode = node.childNodes[i];
+ if (childNode.nodeType === NodeType.ELEMENT_NODE) {
+ dfs(childNode);
+ } else {
+ const index = childNode.rawText.search(pattern);
+ if (index > -1) {
+ childNode.rawText = childNode.rawText.substr(0, index);
+ // trim all following nodes.
+ node.childNodes.length = i + 1;
+ }
+ }
+ }
+ }
+ dfs(this);
+ return this;
+ }
+ /**
+ * Get DOM structure
+ * @return {string} strucutre
+ */
+ get structure() {
+ const res = [] as string[];
+ let indention = 0;
+ function write(str: string) {
+ res.push(' '.repeat(indention) + str);
+ }
+ function dfs(node: HTMLElement) {
+ const idStr = node.id ? ('#' + node.id) : '';
+ const classStr = node.classNames.length ? ('.' + node.classNames.join('.')) : '';
+ write(node.tagName + idStr + classStr);
+ indention++;
+ for (let i = 0; i < node.childNodes.length; i++) {
+ const childNode = node.childNodes[i];
+ if (childNode.nodeType === NodeType.ELEMENT_NODE) {
+ dfs(childNode as HTMLElement);
+ } else if (childNode.nodeType === NodeType.TEXT_NODE) {
+ if (!(childNode as TextNode).isWhitespace)
+ write('#text');
+ }
+ }
+ indention--;
+ }
+ dfs(this);
+ return res.join('\n');
+ }
+
+ /**
+ * Remove whitespaces in this sub tree.
+ * @return {HTMLElement} pointer to this
+ */
+ removeWhitespace() {
+ let o = 0;
+ for (let i = 0; i < this.childNodes.length; i++) {
+ const node = this.childNodes[i];
+ if (node.nodeType === NodeType.TEXT_NODE) {
+ if ((node as TextNode).isWhitespace)
+ continue;
+ node.rawText = node.rawText.trim();
+ } else if (node.nodeType === NodeType.ELEMENT_NODE) {
+ (node as HTMLElement).removeWhitespace();
+ }
+ this.childNodes[o++] = node;
+ }
+ this.childNodes.length = o;
+ return this;
+ }
+
+ /**
+ * Query CSS selector to find matching nodes.
+ * @param {string} selector Simplified CSS selector
+ * @param {Matcher} selector A Matcher instance
+ * @return {HTMLElement[]} matching elements
+ */
+ querySelectorAll(selector: string | Matcher) {
+ let matcher: Matcher;
+ if (selector instanceof Matcher) {
+ matcher = selector;
+ matcher.reset();
+ } else {
+ matcher = new Matcher(selector);
+ }
+ const res = [] as Node[];
+ const stack = [] as { 0: Node; 1: 0 | 1; 2: boolean; }[];
+ for (let i = 0; i < this.childNodes.length; i++) {
+ stack.push([this.childNodes[i], 0, false]);
+ while (stack.length) {
+ const state = arr_back(stack);
+ const el = state[0];
+ if (state[1] === 0) {
+ // Seen for first time.
+ if (el.nodeType !== NodeType.ELEMENT_NODE) {
+ stack.pop();
+ continue;
+ }
+ if (state[2] = matcher.advance(el)) {
+ if (matcher.matched) {
+ res.push(el);
+ // no need to go further.
+ matcher.rewind();
+ stack.pop();
+ continue;
+ }
+ }
+ }
+ if (state[1] < el.childNodes.length) {
+ stack.push([el.childNodes[state[1]++], 0, false]);
+ } else {
+ if (state[2])
+ matcher.rewind();
+ stack.pop();
+ }
+ }
+ }
+ return res;
+ }
+
+ /**
+ * Query CSS Selector to find matching node.
+ * @param {string} selector Simplified CSS selector
+ * @param {Matcher} selector A Matcher instance
+ * @return {HTMLElement} matching node
+ */
+ querySelector(selector: string | Matcher) {
+ let matcher: Matcher;
+ if (selector instanceof Matcher) {
+ matcher = selector;
+ matcher.reset();
+ } else {
+ matcher = new Matcher(selector);
+ }
+ const stack = [] as { 0: Node; 1: 0 | 1; 2: boolean; }[];
+ for (let i = 0; i < this.childNodes.length; i++) {
+ stack.push([this.childNodes[i], 0, false]);
+ while (stack.length) {
+ const state = arr_back(stack);
+ const el = state[0];
+ if (state[1] === 0) {
+ // Seen for first time.
+ if (el.nodeType !== NodeType.ELEMENT_NODE) {
+ stack.pop();
+ continue;
+ }
+ if (state[2] = matcher.advance(el)) {
+ if (matcher.matched) {
+ return el;
+ }
+ }
+ }
+ if (state[1] < el.childNodes.length) {
+ stack.push([el.childNodes[state[1]++], 0, false]);
+ } else {
+ if (state[2])
+ matcher.rewind();
+ stack.pop();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Append a child node to childNodes
+ * @param {Node} node node to append
+ * @return {Node} node appended
+ */
+ appendChild(node: Node) {
+ // node.parentNode = this;
+ this.childNodes.push(node);
+ return node;
+ }
+
+ /**
+ * Get first child node
+ * @return {Node} first child node
+ */
+ get firstChild() {
+ return this.childNodes[0];
+ }
+
+ /**
+ * Get last child node
+ * @return {Node} last child node
+ */
+ get lastChild() {
+ return arr_back(this.childNodes);
+ }
+
+ /**
+ * Get attributes
+ * @return {Object} parsed and unescaped attributes
+ */
+ get attributes() {
+ if (this._attrs)
+ return this._attrs;
+ this._attrs = {};
+ const attrs = this.rawAttributes;
+ for (const key in attrs) {
+ this._attrs[key] = entities.decodeHTML5(attrs[key]);
+ }
+ return this._attrs;
+ }
+
+ /**
+ * Get escaped (as-it) attributes
+ * @return {Object} parsed attributes
+ */
+ get rawAttributes() {
+ if (this._rawAttrs)
+ return this._rawAttrs;
+ const attrs = {} as RawAttributes;
+ if (this.rawAttrs) {
+ const re = /\b([a-z][a-z0-9\-]*)\s*=\s*("([^"]+)"|'([^']+)'|(\S+))/ig;
+ let match: RegExpExecArray;
+ while (match = re.exec(this.rawAttrs)) {
+ attrs[match[1]] = match[3] || match[4] || match[5];
+ }
+ }
+ this._rawAttrs = attrs;
+ return attrs;
+ }
+}
+
+interface MatherFunction {
+ (el: Node): boolean;
+}
+
+/**
+ * Cache to store generated match functions
+ * @type {Object}
+ */
+let pMatchFunctionCache = {} as { [name: string]: MatherFunction };
+/**
+ * Matcher class to make CSS match
+ *
+ * @class Matcher
+ */
+export class Matcher {
+ private matchers: MatherFunction[];
+ private nextMatch = 0;
+ /**
+ * Creates an instance of Matcher.
+ * @param {string} selector
+ *
+ * @memberof Matcher
+ */
+ constructor(selector: string) {
+ this.matchers = selector.split(' ').map((matcher) => {
+ if (pMatchFunctionCache[matcher])
+ return pMatchFunctionCache[matcher];
+ const parts = matcher.split('.');
+ const tagName = parts[0];
+ const classes = parts.slice(1).sort();
+ let source = '';
+ if (tagName && tagName != '*') {
+ if (tagName[0] == '#')
+ source += 'if (el.id != ' + JSON.stringify(tagName.substr(1)) + ') return false;';
+ else
+ source += 'if (el.tagName != ' + JSON.stringify(tagName) + ') return false;';
+ }
+ if (classes.length > 0)
+ source += 'for (var cls = ' + JSON.stringify(classes) + ', i = 0; i < cls.length; i++) if (el.classNames.indexOf(cls[i]) === -1) return false;';
+ source += 'return true;';
+ return pMatchFunctionCache[matcher] = new Function('el', source) as MatherFunction;
+ });
+ }
+ /**
+ * Trying to advance match pointer
+ * @param {HTMLElement} el element to make the match
+ * @return {bool} true when pointer advanced.
+ */
+ advance(el: Node) {
+ if (this.nextMatch < this.matchers.length &&
+ this.matchers[this.nextMatch](el)) {
+ this.nextMatch++;
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Rewind the match pointer
+ */
+ rewind() {
+ this.nextMatch--;
+ }
+ /**
+ * Trying to determine if match made.
+ * @return {bool} true when the match is made
+ */
+ get matched() {
+ return this.nextMatch == this.matchers.length;
+ }
+ /**
+ * Rest match pointer.
+ * @return {[type]} [description]
+ */
+ reset() {
+ this.nextMatch = 0;
+ }
+ /**
+ * flush cache to free memory
+ */
+ flushCache() {
+ pMatchFunctionCache = {};
+ }
+}
+
+const kMarkupPattern = /)-->|<(\/?)([a-z][a-z0-9]*)\s*([^>]*?)(\/?)>/ig;
+const kAttributePattern = /\b(id|class)\s*=\s*("([^"]+)"|'([^']+)'|(\S+))/ig;
+const kSelfClosingElements = {
+ meta: true,
+ img: true,
+ link: true,
+ input: true,
+ area: true,
+ br: true,
+ hr: true
+};
+const kElementsClosedByOpening = {
+ li: { li: true },
+ p: { p: true, div: true },
+ td: { td: true, th: true },
+ th: { td: true, th: true }
+};
+const kElementsClosedByClosing = {
+ li: { ul: true, ol: true },
+ a: { div: true },
+ b: { div: true },
+ i: { div: true },
+ p: { div: true },
+ td: { tr: true, table: true },
+ th: { tr: true, table: true }
+};
+const kBlockTextElements = {
+ script: true,
+ noscript: true,
+ style: true,
+ pre: true
+};
+
+/**
+ * Parses HTML and returns a root element
+ * Parse a chuck of HTML source.
+ * @param {string} data html
+ * @return {HTMLElement} root element
+ */
+export function parse(data: string, options?: {
+ lowerCaseTagName: boolean;
+}) {
+ const root = new HTMLElement(null, {});
+ let currentParent = root;
+ const stack = [root];
+ let lastTextPos = -1;
+
+ options = options || {} as any;
+ let match: RegExpExecArray;
+ while (match = kMarkupPattern.exec(data)) {
+ if (lastTextPos > -1) {
+ if (lastTextPos + match[0].length < kMarkupPattern.lastIndex) {
+ // if has content
+ const text = data.substring(lastTextPos, kMarkupPattern.lastIndex - match[0].length);
+ currentParent.appendChild(new TextNode(text));
+ }
+ }
+ lastTextPos = kMarkupPattern.lastIndex;
+ if (match[0][1] == '!') {
+ // this is a comment
+ continue;
+ }
+ if (options.lowerCaseTagName)
+ match[2] = match[2].toLowerCase();
+ if (!match[1]) {
+ // not tags
+ var attrs = {};
+ for (var attMatch; attMatch = kAttributePattern.exec(match[3]);)
+ attrs[attMatch[1]] = attMatch[3] || attMatch[4] || attMatch[5];
+ // console.log(attrs);
+ if (!match[4] && kElementsClosedByOpening[currentParent.tagName]) {
+ if (kElementsClosedByOpening[currentParent.tagName][match[2]]) {
+ stack.pop();
+ currentParent = arr_back(stack);
+ }
+ }
+ currentParent = currentParent.appendChild(
+ new HTMLElement(match[2], attrs, match[3])) as HTMLElement;
+ stack.push(currentParent);
+ if (kBlockTextElements[match[2]]) {
+ // a little test to find next or ...
+ var closeMarkup = '' + match[2] + '>';
+ var index = data.indexOf(closeMarkup, kMarkupPattern.lastIndex);
+ if (options[match[2]]) {
+ let text: string;
+ if (index == -1) {
+ // there is no matching ending for the text element.
+ text = data.substr(kMarkupPattern.lastIndex);
+ } else {
+ text = data.substring(kMarkupPattern.lastIndex, index);
+ }
+ if (text.length > 0)
+ currentParent.appendChild(new TextNode(text));
+ }
+ if (index == -1) {
+ lastTextPos = kMarkupPattern.lastIndex = data.length + 1;
+ } else {
+ lastTextPos = kMarkupPattern.lastIndex = index + closeMarkup.length;
+ match[1] = 'true';
+ }
+ }
+ }
+ if (match[1] || match[4] ||
+ kSelfClosingElements[match[2]]) {
+ // or /> or
etc.
+ while (true) {
+ if (currentParent.tagName == match[2]) {
+ stack.pop();
+ currentParent = arr_back(stack);
+ break;
+ } else {
+ // Trying to close current tag, and move on
+ if (kElementsClosedByClosing[currentParent.tagName]) {
+ if (kElementsClosedByClosing[currentParent.tagName][match[2]]) {
+ stack.pop();
+ currentParent = arr_back(stack);
+ continue;
+ }
+ }
+ // Use aggressive strategy to handle unmatching markups.
+ break;
+ }
+ }
+ }
+ }
+ return root;
+}
diff --git a/t.html b/t.html
new file mode 100644
index 0000000..eff4ade
--- /dev/null
+++ b/t.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+ Document
+
+
+
+
+
\ No newline at end of file
diff --git a/test/html.js b/test/html.js
index eaa22df..dcfff91 100644
--- a/test/html.js
+++ b/test/html.js
@@ -2,254 +2,261 @@ var should = require('should');
var fs = require('fs');
var util = require('util');
-var HTMLParser = require('../');
+var HTMLParser = require('../dist');
-describe('HTML Parser', function() {
+describe('HTML Parser', function () {
- var Matcher = HTMLParser.Matcher;
- var HTMLElement = HTMLParser.HTMLElement;
- var TextNode = HTMLParser.TextNode;
+ var Matcher = HTMLParser.Matcher;
+ var HTMLElement = HTMLParser.HTMLElement;
+ var TextNode = HTMLParser.TextNode;
- describe('Matcher', function() {
+ describe('Matcher', function () {
- it('should match corrent elements', function() {
+ it('should match corrent elements', function () {
- var matcher = new Matcher('#id .a a.b *.a.b .a.b * a');
- var MatchesNothingButStarEl = new HTMLElement('_', {});
- var withIdEl = new HTMLElement('p', { id: 'id' });
- var withClassNameEl = new HTMLElement('a', { class: 'a b' });
+ var matcher = new Matcher('#id .a a.b *.a.b .a.b * a');
+ var MatchesNothingButStarEl = new HTMLElement('_', {});
+ var withIdEl = new HTMLElement('p', { id: 'id' });
+ var withClassNameEl = new HTMLElement('a', { class: 'a b' });
- // console.log(util.inspect([withIdEl, withClassNameEl], {
- // showHidden: true,
- // depth: null
- // }));
+ // console.log(util.inspect([withIdEl, withClassNameEl], {
+ // showHidden: true,
+ // depth: null
+ // }));
- matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // #id
- matcher.advance(withClassNameEl).should.not.be.ok; // #id
- matcher.advance(withIdEl).should.be.ok; // #id
+ matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // #id
+ matcher.advance(withClassNameEl).should.not.be.ok; // #id
+ matcher.advance(withIdEl).should.be.ok; // #id
- matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // .a
- matcher.advance(withIdEl).should.not.be.ok; // .a
- matcher.advance(withClassNameEl).should.be.ok; // .a
+ matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // .a
+ matcher.advance(withIdEl).should.not.be.ok; // .a
+ matcher.advance(withClassNameEl).should.be.ok; // .a
- matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // a.b
- matcher.advance(withIdEl).should.not.be.ok; // a.b
- matcher.advance(withClassNameEl).should.be.ok; // a.b
+ matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // a.b
+ matcher.advance(withIdEl).should.not.be.ok; // a.b
+ matcher.advance(withClassNameEl).should.be.ok; // a.b
- matcher.advance(withIdEl).should.not.be.ok; // *.a.b
- matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // *.a.b
- matcher.advance(withClassNameEl).should.be.ok; // *.a.b
+ matcher.advance(withIdEl).should.not.be.ok; // *.a.b
+ matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // *.a.b
+ matcher.advance(withClassNameEl).should.be.ok; // *.a.b
- matcher.advance(withIdEl).should.not.be.ok; // .a.b
- matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // .a.b
- matcher.advance(withClassNameEl).should.be.ok; // .a.b
+ matcher.advance(withIdEl).should.not.be.ok; // .a.b
+ matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // .a.b
+ matcher.advance(withClassNameEl).should.be.ok; // .a.b
- matcher.advance(withIdEl).should.be.ok; // *
- matcher.rewind();
- matcher.advance(MatchesNothingButStarEl).should.be.ok; // *
- matcher.rewind();
- matcher.advance(withClassNameEl).should.be.ok; // *
+ matcher.advance(withIdEl).should.be.ok; // *
+ matcher.rewind();
+ matcher.advance(MatchesNothingButStarEl).should.be.ok; // *
+ matcher.rewind();
+ matcher.advance(withClassNameEl).should.be.ok; // *
- matcher.advance(withIdEl).should.not.be.ok; // a
- matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // a
- matcher.advance(withClassNameEl).should.be.ok; // a
+ matcher.advance(withIdEl).should.not.be.ok; // a
+ matcher.advance(MatchesNothingButStarEl).should.not.be.ok; // a
+ matcher.advance(withClassNameEl).should.be.ok; // a
- matcher.matched.should.be.ok;
+ matcher.matched.should.be.ok;
- });
+ });
- });
+ });
- var parseHTML = HTMLParser.parse;
+ var parseHTML = HTMLParser.parse;
- describe('parse()', function() {
+ describe('parse()', function () {
- it('should parse "Hello
" and return root element', function() {
+ it('should parse "Hello
" and return root element', function () {
- var root = parseHTML('Hello
');
+ var root = parseHTML('Hello
');
- var p = new HTMLElement('p', { id: 'id' }, 'id="id"');
- p.appendChild(new HTMLElement('a', { class: 'cls' }, 'class=\'cls\''))
- .appendChild(new TextNode('Hello'));
- var ul = p.appendChild(new HTMLElement('ul', {}, ''));
- ul.appendChild(new HTMLElement('li', {}, ''));
- ul.appendChild(new HTMLElement('li', {}, ''));
- p.appendChild(new HTMLElement('span', {}, ''));
+ var p = new HTMLElement('p', { id: 'id' }, 'id="id"');
+ p.appendChild(new HTMLElement('a', { class: 'cls' }, 'class=\'cls\''))
+ .appendChild(new TextNode('Hello'));
+ var ul = p.appendChild(new HTMLElement('ul', {}, ''));
+ ul.appendChild(new HTMLElement('li', {}, ''));
+ ul.appendChild(new HTMLElement('li', {}, ''));
+ p.appendChild(new HTMLElement('span', {}, ''));
- root.firstChild.should.eql(p);
+ root.firstChild.should.eql(p);
- });
+ });
- it('should parse "" and return root element', function() {
+ it('should parse "" and return root element', function () {
- var root = parseHTML('', {
- lowerCaseTagName: true
- });
+ var root = parseHTML('', {
+ lowerCaseTagName: true
+ });
- var div = new HTMLElement('div', {}, '');
- var a = div.appendChild(new HTMLElement('a', {}, ''));
- var img = a.appendChild(new HTMLElement('img', {}, ''));
- var p = div.appendChild(new HTMLElement('p', {}, ''));
+ var div = new HTMLElement('div', {}, '');
+ var a = div.appendChild(new HTMLElement('a', {}, ''));
+ var img = a.appendChild(new HTMLElement('img', {}, ''));
+ var p = div.appendChild(new HTMLElement('p', {}, ''));
- root.firstChild.should.eql(div);
+ root.firstChild.should.eql(div);
- });
+ });
- it('should parse "" and return root element', function() {
+ it('should parse "" and return root element', function () {
- var root = parseHTML('');
+ var root = parseHTML('');
- var div = new HTMLElement('div', {}, '');
- var a = div.appendChild(new HTMLElement('a', {}, ''));
- var img = a.appendChild(new HTMLElement('img', {}, ''));
- var p = div.appendChild(new HTMLElement('p', {}, ''));
+ var div = new HTMLElement('div', {}, '');
+ var a = div.appendChild(new HTMLElement('a', {}, ''));
+ var img = a.appendChild(new HTMLElement('img', {}, ''));
+ var p = div.appendChild(new HTMLElement('p', {}, ''));
- root.firstChild.should.eql(div);
+ root.firstChild.should.eql(div);
- });
+ });
- it('should not extract text in script and style by default', function() {
+ it('should not extract text in script and style by default', function () {
- var root = parseHTML('');
+ var root = parseHTML('');
- root.firstChild.childNodes.should.be.empty;
- root.lastChild.childNodes.should.be.empty;
+ root.firstChild.childNodes.should.be.empty;
+ root.lastChild.childNodes.should.be.empty;
- });
+ });
- it('should extract text in script and style when ask so', function() {
+ it('should extract text in script and style when ask so', function () {
- var root = parseHTML('', {
- script: true,
- style: true
- });
+ var root = parseHTML('', {
+ script: true,
+ style: true
+ });
- root.firstChild.childNodes.should.not.be.empty;
- root.firstChild.childNodes.should.eql([new TextNode('1')]);
- root.firstChild.text.should.eql('1');
- root.lastChild.childNodes.should.not.be.empty;
- root.lastChild.childNodes.should.eql([new TextNode('2&')]);
- root.lastChild.text.should.eql('2&');
- root.lastChild.rawText.should.eql('2&');
- });
+ root.firstChild.childNodes.should.not.be.empty;
+ root.firstChild.childNodes.should.eql([new TextNode('1')]);
+ root.firstChild.text.should.eql('1');
+ root.lastChild.childNodes.should.not.be.empty;
+ root.lastChild.childNodes.should.eql([new TextNode('2&')]);
+ root.lastChild.text.should.eql('2&');
+ root.lastChild.rawText.should.eql('2&');
+ });
- it('should be able to parse "html/incomplete-script" file', function() {
+ it('should be able to parse "html/incomplete-script" file', function () {
- var root = parseHTML(fs.readFileSync(__dirname + '/html/incomplete-script').toString(), {
- script: true
- });
+ var root = parseHTML(fs.readFileSync(__dirname + '/html/incomplete-script').toString(), {
+ script: true
+ });
- });
+ });
- it('should parse ".." very fast', function() {
+ it('should parse ".." very fast', function () {
- for (var i = 0; i < 100; i++)
- parseHTML('');
+ for (var i = 0; i < 100; i++)
+ parseHTML('');
- });
+ });
- it('should parse ".." fast', function() {
+ it('should parse ".." fast', function () {
- for (var i = 0; i < 100; i++)
- parseHTML('', {
- lowerCaseTagName: true
- });
+ for (var i = 0; i < 100; i++)
+ parseHTML('', {
+ lowerCaseTagName: true
+ });
- });
+ });
- });
+ });
- describe('TextNode', function() {
+ describe('TextNode', function () {
- describe('#isWhitespace', function() {
- var node = new TextNode('');
- node.isWhitespace.should.be.ok;
- node = new TextNode(' \t');
- node.isWhitespace.should.be.ok;
- node = new TextNode(' \t \t');
- node.isWhitespace.should.be.ok;
- });
+ describe('#isWhitespace', function () {
+ var node = new TextNode('');
+ node.isWhitespace.should.be.ok;
+ node = new TextNode(' \t');
+ node.isWhitespace.should.be.ok;
+ node = new TextNode(' \t \t');
+ node.isWhitespace.should.be.ok;
+ });
- });
+ });
- describe('HTMLElement', function() {
+ describe('HTMLElement', function () {
- describe('#removeWhitespace()', function() {
+ describe('#removeWhitespace()', function () {
- it('should remove whitespaces while preserving nodes with content', function() {
+ it('should remove whitespaces while preserving nodes with content', function () {
- var root = parseHTML(' \r \n \t
123
');
+ var root = parseHTML(' \r \n \t
123
');
- var p = new HTMLElement('p', {}, '');
- p.appendChild(new HTMLElement('h5', {}, ''))
- .appendChild(new TextNode('123'));
+ var p = new HTMLElement('p', {}, '');
+ p.appendChild(new HTMLElement('h5', {}, ''))
+ .appendChild(new TextNode('123'));
- root.firstChild.removeWhitespace().should.eql(p);
+ root.firstChild.removeWhitespace().should.eql(p);
- });
+ });
- });
+ });
- describe('#rawAttributes', function() {
+ describe('#rawAttributes', function () {
- it('should return escaped attributes of the element', function() {
+ it('should return escaped attributes of the element', function () {
- var root = parseHTML('');
+ var root = parseHTML('');
- root.firstChild.rawAttributes.should.eql({
- 'a': '12',
- 'data-id': '!$$&',
- 'yAz': '1'
- });
+ root.firstChild.rawAttributes.should.eql({
+ 'a': '12',
+ 'data-id': '!$$&',
+ 'yAz': '1'
+ });
- });
+ });
- });
+ });
- describe('#attributes', function() {
+ describe('#attributes', function () {
- it('should return attributes of the element', function() {
+ it('should return attributes of the element', function () {
- var root = parseHTML('');
+ var root = parseHTML('');
- root.firstChild.attributes.should.eql({
- 'a': '12',
- 'data-id': '!$$&',
- 'yAz': '1'
- });
+ root.firstChild.attributes.should.eql({
+ 'a': '12',
+ 'data-id': '!$$&',
+ 'yAz': '1'
+ });
- });
+ });
- });
+ });
- describe('#querySelectorAll()', function() {
+ describe('#querySelectorAll()', function () {
- it('should return correct elements in DOM tree', function() {
+ it('should return correct elements in DOM tree', function () {
- var root = parseHTML('
');
+ var root = parseHTML('
');
- root.querySelectorAll('#id').should.eql([root.firstChild]);
- root.querySelectorAll('span.a').should.eql([root.firstChild.firstChild.firstChild]);
- root.querySelectorAll('span.b').should.eql([root.firstChild.firstChild.firstChild]);
- root.querySelectorAll('span.a.b').should.eql([root.firstChild.firstChild.firstChild]);
- root.querySelectorAll('#id .b').should.eql([root.firstChild.firstChild.firstChild]);
- root.querySelectorAll('#id span').should.eql(root.firstChild.firstChild.childNodes);
+ root.querySelectorAll('#id').should.eql([root.firstChild]);
+ root.querySelectorAll('span.a').should.eql([root.firstChild.firstChild.firstChild]);
+ root.querySelectorAll('span.b').should.eql([root.firstChild.firstChild.firstChild]);
+ root.querySelectorAll('span.a.b').should.eql([root.firstChild.firstChild.firstChild]);
+ root.querySelectorAll('#id .b').should.eql([root.firstChild.firstChild.firstChild]);
+ root.querySelectorAll('#id span').should.eql(root.firstChild.firstChild.childNodes);
- });
+ });
- });
+ });
- describe('#structuredText', function() {
+ describe('#structuredText', function () {
- it('should return correct structured text', function() {
+ it('should return correct structured text', function () {
- var root = parseHTML('oa
b
c');
- root.structuredText.should.eql('o\na\nb\nc');
+ var root = parseHTML('oa
b
c');
+ root.structuredText.should.eql('o\na\nb\nc');
- });
+ });
- });
+ });
- });
+ });
+ describe('stringify', function () {
+ describe('toString', function () {
+ const html = 'Hello
bbb';
+ const root = parseHTML(html);
+ root.toString().should.eql(html)
+ });
+ });
});
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..337d9d9
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,78 @@
+{
+ "exclude": [
+ "./dist/"
+ ],
+ "include": [
+ "./src/**/*.ts"
+ ],
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "esnext",
+ "noImplicitAny": true,
+ "sourceMap": false,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "strictNullChecks": false,
+ "noImplicitThis": true,
+ "rootDir": "./src/",
+ "rootDirs": [
+ "./src/",
+ "./tests/"
+ ],
+ "allowJs": false,
+ "allowUnreachableCode": false,
+ "allowUnusedLabels": false,
+ "alwaysStrict": true,
+ "baseUrl": "",
+ "charset": "utf8",
+ "declaration": true,
+ // "declarationDir": "./dts/",
+ "inlineSourceMap": false,
+ "allowSyntheticDefaultImports": false,
+ "diagnostics": false,
+ "emitBOM": false,
+ "forceConsistentCasingInFileNames": false,
+ "importHelpers": false,
+ "inlineSources": false,
+ "isolatedModules": false,
+ "lib": [
+ // "es6",
+ "esnext"
+ ],
+ "listFiles": true, // default false
+ "listEmittedFiles": true, // default false
+ "locale": "zh_CN",
+ "newLine": "CRLF",
+ "noEmit": false,
+ "moduleResolution": "node",
+ "noEmitHelpers": false,
+ "noEmitOnError": false,
+ "noImplicitReturns": false,
+ "noImplicitUseStrict": false,
+ "maxNodeModuleJsDepth": 0,
+ "noLib": false,
+ "outDir": "./dist",
+ // "outFile": "./dist/tqf",
+ "noFallthroughCasesInSwitch": false,
+ "noResolve": false,
+ "noUnusedLocals": false,
+ "noUnusedParameters": false,
+ "paths": {},
+ "preserveConstEnums": false,
+ "pretty": true,
+ // "mapRoot": "",
+ "removeComments": false,
+ "skipDefaultLibCheck": true, // default false
+ "skipLibCheck": true, // default false
+ "stripInternal": false,
+ "suppressExcessPropertyErrors": false,
+ "suppressImplicitAnyIndexErrors": true, // default false
+ "traceResolution": true, // default false
+ "typeRoots": [
+ ],
+ "types": [
+ "node"
+ ],
+ "watch": false
+ }
+}
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000..e2947d8
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,1502 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@types/entities@latest":
+ version "1.1.0"
+ resolved "http://172.16.15.24:7001/@types/entities/download/@types/entities-1.1.0.tgz#07ad60479dff7e1b61d95ce96697987d53a662cd"
+
+"@types/node@latest":
+ version "7.0.29"
+ resolved "http://172.16.15.24:7001/@types/node/download/@types/node-7.0.29.tgz#ccfcec5b7135c7caf6c4ffb8c7f33102340d99df"
+
+acorn@^1.0.3:
+ version "1.2.2"
+ resolved "http://172.16.15.24:7001/acorn/download/acorn-1.2.2.tgz#c8ce27de0acc76d896d2b1fad3df588d9e82f014"
+
+ansi-regex@^2.0.0:
+ version "2.1.1"
+ resolved "http://172.16.15.24:7001/ansi-regex/download/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+
+ansi-styles@^2.2.1:
+ version "2.2.1"
+ resolved "http://172.16.15.24:7001/ansi-styles/download/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+
+archy@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/archy/download/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40"
+
+arr-diff@^2.0.0:
+ version "2.0.0"
+ resolved "http://172.16.15.24:7001/arr-diff/download/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
+ dependencies:
+ arr-flatten "^1.0.1"
+
+arr-flatten@^1.0.1:
+ version "1.0.3"
+ resolved "http://172.16.15.24:7001/arr-flatten/download/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1"
+
+array-differ@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/array-differ/download/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031"
+
+array-union@^1.0.1:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/array-union/download/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
+ dependencies:
+ array-uniq "^1.0.1"
+
+array-uniq@^1.0.1, array-uniq@^1.0.2:
+ version "1.0.3"
+ resolved "http://172.16.15.24:7001/array-uniq/download/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+
+array-unique@^0.2.1:
+ version "0.2.1"
+ resolved "http://172.16.15.24:7001/array-unique/download/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
+
+arrify@^1.0.0:
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/arrify/download/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
+
+balanced-match@^0.4.1:
+ version "0.4.2"
+ resolved "http://172.16.15.24:7001/balanced-match/download/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
+
+beeper@^1.0.0:
+ version "1.1.1"
+ resolved "http://172.16.15.24:7001/beeper/download/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809"
+
+blanket@^1.2.3:
+ version "1.2.3"
+ resolved "http://172.16.15.24:7001/blanket/download/blanket-1.2.3.tgz#151b4987c3bd84552bb5f03b90ef5f7e5931e473"
+ dependencies:
+ acorn "^1.0.3"
+ falafel "~1.2.0"
+ foreach "^2.0.5"
+ isarray "0.0.1"
+ object-keys "^1.0.6"
+ xtend "~4.0.0"
+
+brace-expansion@^1.0.0, brace-expansion@^1.1.7:
+ version "1.1.7"
+ resolved "http://172.16.15.24:7001/brace-expansion/download/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59"
+ dependencies:
+ balanced-match "^0.4.1"
+ concat-map "0.0.1"
+
+braces@^1.8.2:
+ version "1.8.5"
+ resolved "http://172.16.15.24:7001/braces/download/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
+ dependencies:
+ expand-range "^1.8.1"
+ preserve "^0.2.0"
+ repeat-element "^1.1.2"
+
+browser-stdout@1.3.0:
+ version "1.3.0"
+ resolved "http://172.16.15.24:7001/browser-stdout/download/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
+
+chalk@^1.0.0, chalk@^1.1.1:
+ version "1.1.3"
+ resolved "http://172.16.15.24:7001/chalk/download/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
+ dependencies:
+ ansi-styles "^2.2.1"
+ escape-string-regexp "^1.0.2"
+ has-ansi "^2.0.0"
+ strip-ansi "^3.0.0"
+ supports-color "^2.0.0"
+
+clone-stats@^0.0.1:
+ version "0.0.1"
+ resolved "http://172.16.15.24:7001/clone-stats/download/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1"
+
+clone@^0.2.0:
+ version "0.2.0"
+ resolved "http://172.16.15.24:7001/clone/download/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f"
+
+clone@^1.0.0, clone@^1.0.2:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/clone/download/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149"
+
+commander@2.9.0:
+ version "2.9.0"
+ resolved "http://172.16.15.24:7001/commander/download/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
+ dependencies:
+ graceful-readlink ">= 1.0.0"
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "http://172.16.15.24:7001/concat-map/download/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+
+convert-source-map@^1.1.1:
+ version "1.5.0"
+ resolved "http://172.16.15.24:7001/convert-source-map/download/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
+
+core-util-is@~1.0.0:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/core-util-is/download/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+
+dateformat@^2.0.0:
+ version "2.0.0"
+ resolved "http://172.16.15.24:7001/dateformat/download/dateformat-2.0.0.tgz#2743e3abb5c3fc2462e527dca445e04e9f4dee17"
+
+debug@2.6.0:
+ version "2.6.0"
+ resolved "http://172.16.15.24:7001/debug/download/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b"
+ dependencies:
+ ms "0.7.2"
+
+defaults@^1.0.0:
+ version "1.0.3"
+ resolved "http://172.16.15.24:7001/defaults/download/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
+ dependencies:
+ clone "^1.0.2"
+
+del@latest:
+ version "2.2.2"
+ resolved "http://172.16.15.24:7001/del/download/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
+ dependencies:
+ globby "^5.0.0"
+ is-path-cwd "^1.0.0"
+ is-path-in-cwd "^1.0.0"
+ object-assign "^4.0.1"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+ rimraf "^2.2.8"
+
+deprecated@^0.0.1:
+ version "0.0.1"
+ resolved "http://172.16.15.24:7001/deprecated/download/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19"
+
+detect-file@^0.1.0:
+ version "0.1.0"
+ resolved "http://172.16.15.24:7001/detect-file/download/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63"
+ dependencies:
+ fs-exists-sync "^0.1.0"
+
+diff@3.2.0:
+ version "3.2.0"
+ resolved "http://172.16.15.24:7001/diff/download/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
+
+duplexer2@0.0.2:
+ version "0.0.2"
+ resolved "http://172.16.15.24:7001/duplexer2/download/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db"
+ dependencies:
+ readable-stream "~1.1.9"
+
+duplexify@^3.2.0:
+ version "3.5.0"
+ resolved "http://172.16.15.24:7001/duplexify/download/duplexify-3.5.0.tgz#1aa773002e1578457e9d9d4a50b0ccaaebcbd604"
+ dependencies:
+ end-of-stream "1.0.0"
+ inherits "^2.0.1"
+ readable-stream "^2.0.0"
+ stream-shift "^1.0.0"
+
+end-of-stream@1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/end-of-stream/download/end-of-stream-1.0.0.tgz#d4596e702734a93e40e9af864319eabd99ff2f0e"
+ dependencies:
+ once "~1.3.0"
+
+end-of-stream@~0.1.5:
+ version "0.1.5"
+ resolved "http://172.16.15.24:7001/end-of-stream/download/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf"
+ dependencies:
+ once "~1.3.0"
+
+entities@latest:
+ version "1.1.1"
+ resolved "http://172.16.15.24:7001/entities/download/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
+
+escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2:
+ version "1.0.5"
+ resolved "http://172.16.15.24:7001/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+
+expand-brackets@^0.1.4:
+ version "0.1.5"
+ resolved "http://172.16.15.24:7001/expand-brackets/download/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
+ dependencies:
+ is-posix-bracket "^0.1.0"
+
+expand-range@^1.8.1:
+ version "1.8.2"
+ resolved "http://172.16.15.24:7001/expand-range/download/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
+ dependencies:
+ fill-range "^2.1.0"
+
+expand-tilde@^1.2.1, expand-tilde@^1.2.2:
+ version "1.2.2"
+ resolved "http://172.16.15.24:7001/expand-tilde/download/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449"
+ dependencies:
+ os-homedir "^1.0.1"
+
+extend-shallow@^2.0.1:
+ version "2.0.1"
+ resolved "http://172.16.15.24:7001/extend-shallow/download/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
+ dependencies:
+ is-extendable "^0.1.0"
+
+extend@^3.0.0:
+ version "3.0.1"
+ resolved "http://172.16.15.24:7001/extend/download/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
+
+extglob@^0.3.1:
+ version "0.3.2"
+ resolved "http://172.16.15.24:7001/extglob/download/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
+ dependencies:
+ is-extglob "^1.0.0"
+
+falafel@~1.2.0:
+ version "1.2.0"
+ resolved "http://172.16.15.24:7001/falafel/download/falafel-1.2.0.tgz#c18d24ef5091174a497f318cd24b026a25cddab4"
+ dependencies:
+ acorn "^1.0.3"
+ foreach "^2.0.5"
+ isarray "0.0.1"
+ object-keys "^1.0.6"
+
+fancy-log@^1.1.0:
+ version "1.3.0"
+ resolved "http://172.16.15.24:7001/fancy-log/download/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948"
+ dependencies:
+ chalk "^1.1.1"
+ time-stamp "^1.0.0"
+
+filename-regex@^2.0.0:
+ version "2.0.0"
+ resolved "http://172.16.15.24:7001/filename-regex/download/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775"
+
+fill-range@^2.1.0:
+ version "2.2.3"
+ resolved "http://172.16.15.24:7001/fill-range/download/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723"
+ dependencies:
+ is-number "^2.1.0"
+ isobject "^2.0.0"
+ randomatic "^1.1.3"
+ repeat-element "^1.1.2"
+ repeat-string "^1.5.2"
+
+find-index@^0.1.1:
+ version "0.1.1"
+ resolved "http://172.16.15.24:7001/find-index/download/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4"
+
+findup-sync@^0.4.2:
+ version "0.4.3"
+ resolved "http://172.16.15.24:7001/findup-sync/download/findup-sync-0.4.3.tgz#40043929e7bc60adf0b7f4827c4c6e75a0deca12"
+ dependencies:
+ detect-file "^0.1.0"
+ is-glob "^2.0.1"
+ micromatch "^2.3.7"
+ resolve-dir "^0.1.0"
+
+fined@^1.0.1:
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/fined/download/fined-1.0.1.tgz#c48af9ab5a8e0f400a0375e84154c37674dabfd4"
+ dependencies:
+ expand-tilde "^1.2.1"
+ lodash.assignwith "^4.0.7"
+ lodash.isarray "^4.0.0"
+ lodash.isempty "^4.2.1"
+ lodash.isplainobject "^4.0.4"
+ lodash.isstring "^4.0.1"
+ lodash.pick "^4.2.1"
+ parse-filepath "^1.0.1"
+
+first-chunk-stream@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/first-chunk-stream/download/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e"
+
+flagged-respawn@^0.3.2:
+ version "0.3.2"
+ resolved "http://172.16.15.24:7001/flagged-respawn/download/flagged-respawn-0.3.2.tgz#ff191eddcd7088a675b2610fffc976be9b8074b5"
+
+for-in@^0.1.5:
+ version "0.1.8"
+ resolved "http://172.16.15.24:7001/for-in/download/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
+
+for-own@^0.1.3:
+ version "0.1.4"
+ resolved "http://172.16.15.24:7001/for-own/download/for-own-0.1.4.tgz#0149b41a39088c7515f51ebe1c1386d45f935072"
+ dependencies:
+ for-in "^0.1.5"
+
+foreach@^2.0.5:
+ version "2.0.5"
+ resolved "http://172.16.15.24:7001/foreach/download/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
+
+fs-exists-sync@^0.1.0:
+ version "0.1.0"
+ resolved "http://172.16.15.24:7001/fs-exists-sync/download/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add"
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/fs.realpath/download/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+
+gaze@^0.5.1:
+ version "0.5.2"
+ resolved "http://172.16.15.24:7001/gaze/download/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f"
+ dependencies:
+ globule "~0.1.0"
+
+glob-base@^0.3.0:
+ version "0.3.0"
+ resolved "http://172.16.15.24:7001/glob-base/download/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
+ dependencies:
+ glob-parent "^2.0.0"
+ is-glob "^2.0.0"
+
+glob-parent@^2.0.0:
+ version "2.0.0"
+ resolved "http://172.16.15.24:7001/glob-parent/download/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28"
+ dependencies:
+ is-glob "^2.0.0"
+
+glob-parent@^3.0.0:
+ version "3.1.0"
+ resolved "http://172.16.15.24:7001/glob-parent/download/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
+ dependencies:
+ is-glob "^3.1.0"
+ path-dirname "^1.0.0"
+
+glob-stream@^3.1.5:
+ version "3.1.18"
+ resolved "http://172.16.15.24:7001/glob-stream/download/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b"
+ dependencies:
+ glob "^4.3.1"
+ glob2base "^0.0.12"
+ minimatch "^2.0.1"
+ ordered-read-streams "^0.1.0"
+ through2 "^0.6.1"
+ unique-stream "^1.0.0"
+
+glob-stream@^5.3.2:
+ version "5.3.5"
+ resolved "http://172.16.15.24:7001/glob-stream/download/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22"
+ dependencies:
+ extend "^3.0.0"
+ glob "^5.0.3"
+ glob-parent "^3.0.0"
+ micromatch "^2.3.7"
+ ordered-read-streams "^0.3.0"
+ through2 "^0.6.0"
+ to-absolute-glob "^0.1.1"
+ unique-stream "^2.0.2"
+
+glob-watcher@^0.0.6:
+ version "0.0.6"
+ resolved "http://172.16.15.24:7001/glob-watcher/download/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b"
+ dependencies:
+ gaze "^0.5.1"
+
+glob2base@^0.0.12:
+ version "0.0.12"
+ resolved "http://172.16.15.24:7001/glob2base/download/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56"
+ dependencies:
+ find-index "^0.1.1"
+
+glob@7.1.1, glob@^7.0.3, glob@^7.0.5:
+ version "7.1.1"
+ resolved "http://172.16.15.24:7001/glob/download/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.2"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+glob@^4.3.1:
+ version "4.5.3"
+ resolved "http://172.16.15.24:7001/glob/download/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f"
+ dependencies:
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^2.0.1"
+ once "^1.3.0"
+
+glob@^5.0.3:
+ version "5.0.15"
+ resolved "http://172.16.15.24:7001/glob/download/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
+ dependencies:
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "2 || 3"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+glob@~3.1.21:
+ version "3.1.21"
+ resolved "http://172.16.15.24:7001/glob/download/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd"
+ dependencies:
+ graceful-fs "~1.2.0"
+ inherits "1"
+ minimatch "~0.2.11"
+
+global-modules@^0.2.3:
+ version "0.2.3"
+ resolved "http://172.16.15.24:7001/global-modules/download/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d"
+ dependencies:
+ global-prefix "^0.1.4"
+ is-windows "^0.2.0"
+
+global-prefix@^0.1.4:
+ version "0.1.4"
+ resolved "http://172.16.15.24:7001/global-prefix/download/global-prefix-0.1.4.tgz#05158db1cde2dd491b455e290eb3ab8bfc45c6e1"
+ dependencies:
+ ini "^1.3.4"
+ is-windows "^0.2.0"
+ osenv "^0.1.3"
+ which "^1.2.10"
+
+globby@^5.0.0:
+ version "5.0.0"
+ resolved "http://172.16.15.24:7001/globby/download/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
+ dependencies:
+ array-union "^1.0.1"
+ arrify "^1.0.0"
+ glob "^7.0.3"
+ object-assign "^4.0.1"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+globule@~0.1.0:
+ version "0.1.0"
+ resolved "http://172.16.15.24:7001/globule/download/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5"
+ dependencies:
+ glob "~3.1.21"
+ lodash "~1.0.1"
+ minimatch "~0.2.11"
+
+glogg@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/glogg/download/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5"
+ dependencies:
+ sparkles "^1.0.0"
+
+graceful-fs@^3.0.0:
+ version "3.0.11"
+ resolved "http://172.16.15.24:7001/graceful-fs/download/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818"
+ dependencies:
+ natives "^1.1.0"
+
+graceful-fs@^4.0.0, graceful-fs@^4.1.2:
+ version "4.1.11"
+ resolved "http://172.16.15.24:7001/graceful-fs/download/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
+
+graceful-fs@~1.2.0:
+ version "1.2.3"
+ resolved "http://172.16.15.24:7001/graceful-fs/download/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364"
+
+"graceful-readlink@>= 1.0.0":
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/graceful-readlink/download/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
+
+growl@1.9.2:
+ version "1.9.2"
+ resolved "http://172.16.15.24:7001/growl/download/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f"
+
+gulp-sequence@^0.4.6:
+ version "0.4.6"
+ resolved "http://172.16.15.24:7001/gulp-sequence/download/gulp-sequence-0.4.6.tgz#e388d64311046e05547af43035352d9495501c50"
+ dependencies:
+ gulp-util ">=3.0.0"
+ thunks "^4.5.1"
+
+gulp-sourcemaps@1.6.0:
+ version "1.6.0"
+ resolved "http://172.16.15.24:7001/gulp-sourcemaps/download/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c"
+ dependencies:
+ convert-source-map "^1.1.1"
+ graceful-fs "^4.1.2"
+ strip-bom "^2.0.0"
+ through2 "^2.0.0"
+ vinyl "^1.0.0"
+
+gulp-typescript@latest:
+ version "3.1.6"
+ resolved "http://172.16.15.24:7001/gulp-typescript/download/gulp-typescript-3.1.6.tgz#6c67b84364cf3589a9ad6fdea2e3c0bc525c435e"
+ dependencies:
+ gulp-util "~3.0.7"
+ source-map "~0.5.3"
+ through2 "~2.0.1"
+ vinyl-fs "~2.4.3"
+
+gulp-util@>=3.0.0, gulp-util@^3.0.0, gulp-util@~3.0.7:
+ version "3.0.8"
+ resolved "http://172.16.15.24:7001/gulp-util/download/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f"
+ dependencies:
+ array-differ "^1.0.0"
+ array-uniq "^1.0.2"
+ beeper "^1.0.0"
+ chalk "^1.0.0"
+ dateformat "^2.0.0"
+ fancy-log "^1.1.0"
+ gulplog "^1.0.0"
+ has-gulplog "^0.1.0"
+ lodash._reescape "^3.0.0"
+ lodash._reevaluate "^3.0.0"
+ lodash._reinterpolate "^3.0.0"
+ lodash.template "^3.0.0"
+ minimist "^1.1.0"
+ multipipe "^0.1.2"
+ object-assign "^3.0.0"
+ replace-ext "0.0.1"
+ through2 "^2.0.0"
+ vinyl "^0.5.0"
+
+gulp@latest:
+ version "3.9.1"
+ resolved "http://172.16.15.24:7001/gulp/download/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4"
+ dependencies:
+ archy "^1.0.0"
+ chalk "^1.0.0"
+ deprecated "^0.0.1"
+ gulp-util "^3.0.0"
+ interpret "^1.0.0"
+ liftoff "^2.1.0"
+ minimist "^1.1.0"
+ orchestrator "^0.3.0"
+ pretty-hrtime "^1.0.0"
+ semver "^4.1.0"
+ tildify "^1.0.0"
+ v8flags "^2.0.2"
+ vinyl-fs "^0.3.0"
+
+gulplog@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/gulplog/download/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5"
+ dependencies:
+ glogg "^1.0.0"
+
+has-ansi@^2.0.0:
+ version "2.0.0"
+ resolved "http://172.16.15.24:7001/has-ansi/download/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+has-flag@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/has-flag/download/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
+
+has-gulplog@^0.1.0:
+ version "0.1.0"
+ resolved "http://172.16.15.24:7001/has-gulplog/download/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce"
+ dependencies:
+ sparkles "^1.0.0"
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "http://172.16.15.24:7001/inflight/download/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@1:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/inherits/download/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b"
+
+inherits@2, inherits@^2.0.1, inherits@~2.0.1:
+ version "2.0.3"
+ resolved "http://172.16.15.24:7001/inherits/download/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+ini@^1.3.4:
+ version "1.3.4"
+ resolved "http://172.16.15.24:7001/ini/download/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
+
+interpret@^1.0.0:
+ version "1.0.3"
+ resolved "http://172.16.15.24:7001/interpret/download/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90"
+
+is-absolute@^0.2.3:
+ version "0.2.6"
+ resolved "http://172.16.15.24:7001/is-absolute/download/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb"
+ dependencies:
+ is-relative "^0.2.1"
+ is-windows "^0.2.0"
+
+is-buffer@^1.1.5:
+ version "1.1.5"
+ resolved "http://172.16.15.24:7001/is-buffer/download/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
+
+is-dotfile@^1.0.0:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/is-dotfile/download/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d"
+
+is-equal-shallow@^0.1.3:
+ version "0.1.3"
+ resolved "http://172.16.15.24:7001/is-equal-shallow/download/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
+ dependencies:
+ is-primitive "^2.0.0"
+
+is-extendable@^0.1.0, is-extendable@^0.1.1:
+ version "0.1.1"
+ resolved "http://172.16.15.24:7001/is-extendable/download/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
+
+is-extglob@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/is-extglob/download/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
+
+is-extglob@^2.1.0:
+ version "2.1.1"
+ resolved "http://172.16.15.24:7001/is-extglob/download/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
+
+is-glob@^2.0.0, is-glob@^2.0.1:
+ version "2.0.1"
+ resolved "http://172.16.15.24:7001/is-glob/download/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
+ dependencies:
+ is-extglob "^1.0.0"
+
+is-glob@^3.1.0:
+ version "3.1.0"
+ resolved "http://172.16.15.24:7001/is-glob/download/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
+ dependencies:
+ is-extglob "^2.1.0"
+
+is-number@^2.0.2, is-number@^2.1.0:
+ version "2.1.0"
+ resolved "http://172.16.15.24:7001/is-number/download/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
+ dependencies:
+ kind-of "^3.0.2"
+
+is-path-cwd@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/is-path-cwd/download/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
+
+is-path-in-cwd@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/is-path-in-cwd/download/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc"
+ dependencies:
+ is-path-inside "^1.0.0"
+
+is-path-inside@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/is-path-inside/download/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f"
+ dependencies:
+ path-is-inside "^1.0.1"
+
+is-posix-bracket@^0.1.0:
+ version "0.1.1"
+ resolved "http://172.16.15.24:7001/is-posix-bracket/download/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
+
+is-primitive@^2.0.0:
+ version "2.0.0"
+ resolved "http://172.16.15.24:7001/is-primitive/download/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
+
+is-relative@^0.2.1:
+ version "0.2.1"
+ resolved "http://172.16.15.24:7001/is-relative/download/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5"
+ dependencies:
+ is-unc-path "^0.1.1"
+
+is-stream@^1.0.1:
+ version "1.1.0"
+ resolved "http://172.16.15.24:7001/is-stream/download/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+
+is-unc-path@^0.1.1:
+ version "0.1.1"
+ resolved "http://172.16.15.24:7001/is-unc-path/download/is-unc-path-0.1.1.tgz#ab2533d77ad733561124c3dc0f5cd8b90054c86b"
+ dependencies:
+ unc-path-regex "^0.1.0"
+
+is-utf8@^0.2.0:
+ version "0.2.1"
+ resolved "http://172.16.15.24:7001/is-utf8/download/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
+
+is-valid-glob@^0.3.0:
+ version "0.3.0"
+ resolved "http://172.16.15.24:7001/is-valid-glob/download/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe"
+
+is-windows@^0.2.0:
+ version "0.2.0"
+ resolved "http://172.16.15.24:7001/is-windows/download/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c"
+
+isarray@0.0.1:
+ version "0.0.1"
+ resolved "http://172.16.15.24:7001/isarray/download/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
+
+isarray@1.0.0, isarray@~1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+
+isexe@^2.0.0:
+ version "2.0.0"
+ resolved "http://172.16.15.24:7001/isexe/download/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+
+isobject@^2.0.0:
+ version "2.1.0"
+ resolved "http://172.16.15.24:7001/isobject/download/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
+ dependencies:
+ isarray "1.0.0"
+
+json-stable-stringify@^1.0.0:
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/json-stable-stringify/download/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
+ dependencies:
+ jsonify "~0.0.0"
+
+json3@3.3.2:
+ version "3.3.2"
+ resolved "http://172.16.15.24:7001/json3/download/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
+
+jsonify@~0.0.0:
+ version "0.0.0"
+ resolved "http://172.16.15.24:7001/jsonify/download/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+
+kind-of@^3.0.2:
+ version "3.2.2"
+ resolved "http://172.16.15.24:7001/kind-of/download/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
+ dependencies:
+ is-buffer "^1.1.5"
+
+lazystream@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/lazystream/download/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4"
+ dependencies:
+ readable-stream "^2.0.5"
+
+liftoff@^2.1.0:
+ version "2.3.0"
+ resolved "http://172.16.15.24:7001/liftoff/download/liftoff-2.3.0.tgz#a98f2ff67183d8ba7cfaca10548bd7ff0550b385"
+ dependencies:
+ extend "^3.0.0"
+ findup-sync "^0.4.2"
+ fined "^1.0.1"
+ flagged-respawn "^0.3.2"
+ lodash.isplainobject "^4.0.4"
+ lodash.isstring "^4.0.1"
+ lodash.mapvalues "^4.4.0"
+ rechoir "^0.6.2"
+ resolve "^1.1.7"
+
+lodash._baseassign@^3.0.0:
+ version "3.2.0"
+ resolved "http://172.16.15.24:7001/lodash._baseassign/download/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e"
+ dependencies:
+ lodash._basecopy "^3.0.0"
+ lodash.keys "^3.0.0"
+
+lodash._basecopy@^3.0.0:
+ version "3.0.1"
+ resolved "http://172.16.15.24:7001/lodash._basecopy/download/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
+
+lodash._basecreate@^3.0.0:
+ version "3.0.3"
+ resolved "http://172.16.15.24:7001/lodash._basecreate/download/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821"
+
+lodash._basetostring@^3.0.0:
+ version "3.0.1"
+ resolved "http://172.16.15.24:7001/lodash._basetostring/download/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5"
+
+lodash._basevalues@^3.0.0:
+ version "3.0.0"
+ resolved "http://172.16.15.24:7001/lodash._basevalues/download/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7"
+
+lodash._getnative@^3.0.0:
+ version "3.9.1"
+ resolved "http://172.16.15.24:7001/lodash._getnative/download/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
+
+lodash._isiterateecall@^3.0.0:
+ version "3.0.9"
+ resolved "http://172.16.15.24:7001/lodash._isiterateecall/download/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c"
+
+lodash._reescape@^3.0.0:
+ version "3.0.0"
+ resolved "http://172.16.15.24:7001/lodash._reescape/download/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a"
+
+lodash._reevaluate@^3.0.0:
+ version "3.0.0"
+ resolved "http://172.16.15.24:7001/lodash._reevaluate/download/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed"
+
+lodash._reinterpolate@^3.0.0:
+ version "3.0.0"
+ resolved "http://172.16.15.24:7001/lodash._reinterpolate/download/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
+
+lodash._root@^3.0.0:
+ version "3.0.1"
+ resolved "http://172.16.15.24:7001/lodash._root/download/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
+
+lodash.assignwith@^4.0.7:
+ version "4.2.0"
+ resolved "http://172.16.15.24:7001/lodash.assignwith/download/lodash.assignwith-4.2.0.tgz#127a97f02adc41751a954d24b0de17e100e038eb"
+
+lodash.create@3.1.1:
+ version "3.1.1"
+ resolved "http://172.16.15.24:7001/lodash.create/download/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7"
+ dependencies:
+ lodash._baseassign "^3.0.0"
+ lodash._basecreate "^3.0.0"
+ lodash._isiterateecall "^3.0.0"
+
+lodash.escape@^3.0.0:
+ version "3.2.0"
+ resolved "http://172.16.15.24:7001/lodash.escape/download/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698"
+ dependencies:
+ lodash._root "^3.0.0"
+
+lodash.isarguments@^3.0.0:
+ version "3.0.8"
+ resolved "http://172.16.15.24:7001/lodash.isarguments/download/lodash.isarguments-3.0.8.tgz#5bf8da887f01f2a9e49c0a175cdaeb318a0e43dc"
+
+lodash.isarray@^3.0.0:
+ version "3.0.4"
+ resolved "http://172.16.15.24:7001/lodash.isarray/download/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
+
+lodash.isarray@^4.0.0:
+ version "4.0.0"
+ resolved "http://172.16.15.24:7001/lodash.isarray/download/lodash.isarray-4.0.0.tgz#2aca496b28c4ca6d726715313590c02e6ea34403"
+
+lodash.isempty@^4.2.1:
+ version "4.4.0"
+ resolved "http://172.16.15.24:7001/lodash.isempty/download/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
+
+lodash.isequal@^4.0.0:
+ version "4.4.0"
+ resolved "http://172.16.15.24:7001/lodash.isequal/download/lodash.isequal-4.4.0.tgz#6295768e98e14dc15ce8d362ef6340db82852031"
+
+lodash.isplainobject@^4.0.4:
+ version "4.0.6"
+ resolved "http://172.16.15.24:7001/lodash.isplainobject/download/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
+
+lodash.isstring@^4.0.1:
+ version "4.0.1"
+ resolved "http://172.16.15.24:7001/lodash.isstring/download/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
+
+lodash.keys@^3.0.0:
+ version "3.1.2"
+ resolved "http://172.16.15.24:7001/lodash.keys/download/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
+ dependencies:
+ lodash._getnative "^3.0.0"
+ lodash.isarguments "^3.0.0"
+ lodash.isarray "^3.0.0"
+
+lodash.mapvalues@^4.4.0:
+ version "4.6.0"
+ resolved "http://172.16.15.24:7001/lodash.mapvalues/download/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c"
+
+lodash.pick@^4.2.1:
+ version "4.4.0"
+ resolved "http://172.16.15.24:7001/lodash.pick/download/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
+
+lodash.restparam@^3.0.0:
+ version "3.6.1"
+ resolved "http://172.16.15.24:7001/lodash.restparam/download/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
+
+lodash.template@^3.0.0:
+ version "3.6.2"
+ resolved "http://172.16.15.24:7001/lodash.template/download/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f"
+ dependencies:
+ lodash._basecopy "^3.0.0"
+ lodash._basetostring "^3.0.0"
+ lodash._basevalues "^3.0.0"
+ lodash._isiterateecall "^3.0.0"
+ lodash._reinterpolate "^3.0.0"
+ lodash.escape "^3.0.0"
+ lodash.keys "^3.0.0"
+ lodash.restparam "^3.0.0"
+ lodash.templatesettings "^3.0.0"
+
+lodash.templatesettings@^3.0.0:
+ version "3.1.1"
+ resolved "http://172.16.15.24:7001/lodash.templatesettings/download/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5"
+ dependencies:
+ lodash._reinterpolate "^3.0.0"
+ lodash.escape "^3.0.0"
+
+lodash@~1.0.1:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/lodash/download/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551"
+
+lru-cache@2:
+ version "2.7.3"
+ resolved "http://172.16.15.24:7001/lru-cache/download/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952"
+
+map-cache@^0.2.0:
+ version "0.2.2"
+ resolved "http://172.16.15.24:7001/map-cache/download/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
+
+merge-stream@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/merge-stream/download/merge-stream-1.0.0.tgz#9cfd156fef35421e2b5403ce11dc6eb1962b026e"
+ dependencies:
+ readable-stream "^2.0.1"
+
+micromatch@^2.3.7:
+ version "2.3.11"
+ resolved "http://172.16.15.24:7001/micromatch/download/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
+ dependencies:
+ arr-diff "^2.0.0"
+ array-unique "^0.2.1"
+ braces "^1.8.2"
+ expand-brackets "^0.1.4"
+ extglob "^0.3.1"
+ filename-regex "^2.0.0"
+ is-extglob "^1.0.0"
+ is-glob "^2.0.1"
+ kind-of "^3.0.2"
+ normalize-path "^2.0.1"
+ object.omit "^2.0.0"
+ parse-glob "^3.0.4"
+ regex-cache "^0.4.2"
+
+"minimatch@2 || 3", minimatch@^3.0.2:
+ version "3.0.4"
+ resolved "http://172.16.15.24:7001/minimatch/download/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+ dependencies:
+ brace-expansion "^1.1.7"
+
+minimatch@^2.0.1:
+ version "2.0.10"
+ resolved "http://172.16.15.24:7001/minimatch/download/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7"
+ dependencies:
+ brace-expansion "^1.0.0"
+
+minimatch@~0.2.11:
+ version "0.2.14"
+ resolved "http://172.16.15.24:7001/minimatch/download/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a"
+ dependencies:
+ lru-cache "2"
+ sigmund "~1.0.0"
+
+minimist@0.0.8:
+ version "0.0.8"
+ resolved "http://172.16.15.24:7001/minimist/download/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
+
+minimist@^1.1.0:
+ version "1.2.0"
+ resolved "http://172.16.15.24:7001/minimist/download/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+
+mkdirp@0.5.1, mkdirp@^0.5.0:
+ version "0.5.1"
+ resolved "http://172.16.15.24:7001/mkdirp/download/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
+ dependencies:
+ minimist "0.0.8"
+
+mocha@latest:
+ version "3.4.2"
+ resolved "http://172.16.15.24:7001/mocha/download/mocha-3.4.2.tgz#d0ef4d332126dbf18d0d640c9b382dd48be97594"
+ dependencies:
+ browser-stdout "1.3.0"
+ commander "2.9.0"
+ debug "2.6.0"
+ diff "3.2.0"
+ escape-string-regexp "1.0.5"
+ glob "7.1.1"
+ growl "1.9.2"
+ json3 "3.3.2"
+ lodash.create "3.1.1"
+ mkdirp "0.5.1"
+ supports-color "3.1.2"
+
+ms@0.7.2:
+ version "0.7.2"
+ resolved "http://172.16.15.24:7001/ms/download/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765"
+
+multipipe@^0.1.2:
+ version "0.1.2"
+ resolved "http://172.16.15.24:7001/multipipe/download/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b"
+ dependencies:
+ duplexer2 "0.0.2"
+
+natives@^1.1.0:
+ version "1.1.0"
+ resolved "http://172.16.15.24:7001/natives/download/natives-1.1.0.tgz#e9ff841418a6b2ec7a495e939984f78f163e6e31"
+
+normalize-path@^2.0.1:
+ version "2.1.1"
+ resolved "http://172.16.15.24:7001/normalize-path/download/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
+ dependencies:
+ remove-trailing-separator "^1.0.1"
+
+object-assign@^3.0.0:
+ version "3.0.0"
+ resolved "http://172.16.15.24:7001/object-assign/download/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2"
+
+object-assign@^4.0.0, object-assign@^4.0.1:
+ version "4.1.1"
+ resolved "http://172.16.15.24:7001/object-assign/download/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+
+object-keys@^1.0.6:
+ version "1.0.11"
+ resolved "http://172.16.15.24:7001/object-keys/download/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
+
+object.omit@^2.0.0:
+ version "2.0.0"
+ resolved "http://172.16.15.24:7001/object.omit/download/object.omit-2.0.0.tgz#868597333d54e60662940bb458605dd6ae12fe94"
+ dependencies:
+ for-own "^0.1.3"
+ is-extendable "^0.1.1"
+
+once@^1.3.0:
+ version "1.4.0"
+ resolved "http://172.16.15.24:7001/once/download/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ dependencies:
+ wrappy "1"
+
+once@~1.3.0:
+ version "1.3.3"
+ resolved "http://172.16.15.24:7001/once/download/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20"
+ dependencies:
+ wrappy "1"
+
+orchestrator@^0.3.0:
+ version "0.3.7"
+ resolved "http://172.16.15.24:7001/orchestrator/download/orchestrator-0.3.7.tgz#c45064e22c5a2a7b99734f409a95ffedc7d3c3df"
+ dependencies:
+ end-of-stream "~0.1.5"
+ sequencify "~0.0.7"
+ stream-consume "~0.1.0"
+
+ordered-read-streams@^0.1.0:
+ version "0.1.0"
+ resolved "http://172.16.15.24:7001/ordered-read-streams/download/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126"
+
+ordered-read-streams@^0.3.0:
+ version "0.3.0"
+ resolved "http://172.16.15.24:7001/ordered-read-streams/download/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b"
+ dependencies:
+ is-stream "^1.0.1"
+ readable-stream "^2.0.1"
+
+os-homedir@^1.0.0, os-homedir@^1.0.1:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/os-homedir/download/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
+
+os-tmpdir@^1.0.0:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/os-tmpdir/download/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
+
+osenv@^0.1.3:
+ version "0.1.4"
+ resolved "http://172.16.15.24:7001/osenv/download/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644"
+ dependencies:
+ os-homedir "^1.0.0"
+ os-tmpdir "^1.0.0"
+
+parse-filepath@^1.0.1:
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/parse-filepath/download/parse-filepath-1.0.1.tgz#159d6155d43904d16c10ef698911da1e91969b73"
+ dependencies:
+ is-absolute "^0.2.3"
+ map-cache "^0.2.0"
+ path-root "^0.1.1"
+
+parse-glob@^3.0.4:
+ version "3.0.4"
+ resolved "http://172.16.15.24:7001/parse-glob/download/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
+ dependencies:
+ glob-base "^0.3.0"
+ is-dotfile "^1.0.0"
+ is-extglob "^1.0.0"
+ is-glob "^2.0.0"
+
+path-dirname@^1.0.0:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/path-dirname/download/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
+
+path-is-absolute@^1.0.0:
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/path-is-absolute/download/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+
+path-is-inside@^1.0.1:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/path-is-inside/download/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
+
+path-parse@^1.0.5:
+ version "1.0.5"
+ resolved "http://172.16.15.24:7001/path-parse/download/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
+
+path-root-regex@^0.1.0:
+ version "0.1.2"
+ resolved "http://172.16.15.24:7001/path-root-regex/download/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d"
+
+path-root@^0.1.1:
+ version "0.1.1"
+ resolved "http://172.16.15.24:7001/path-root/download/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7"
+ dependencies:
+ path-root-regex "^0.1.0"
+
+pify@^2.0.0:
+ version "2.3.0"
+ resolved "http://172.16.15.24:7001/pify/download/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
+
+pinkie-promise@^2.0.0:
+ version "2.0.1"
+ resolved "http://172.16.15.24:7001/pinkie-promise/download/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
+ dependencies:
+ pinkie "^2.0.0"
+
+pinkie@^2.0.0:
+ version "2.0.4"
+ resolved "http://172.16.15.24:7001/pinkie/download/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
+
+preserve@^0.2.0:
+ version "0.2.0"
+ resolved "http://172.16.15.24:7001/preserve/download/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
+
+pretty-hrtime@^1.0.0:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/pretty-hrtime/download/pretty-hrtime-1.0.2.tgz#70ca96f4d0628a443b918758f79416a9a7bc9fa8"
+
+process-nextick-args@~1.0.6:
+ version "1.0.7"
+ resolved "http://172.16.15.24:7001/process-nextick-args/download/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
+
+randomatic@^1.1.3:
+ version "1.1.5"
+ resolved "http://172.16.15.24:7001/randomatic/download/randomatic-1.1.5.tgz#5e9ef5f2d573c67bd2b8124ae90b5156e457840b"
+ dependencies:
+ is-number "^2.0.2"
+ kind-of "^3.0.2"
+
+"readable-stream@>=1.0.33-1 <1.1.0-0":
+ version "1.0.34"
+ resolved "http://172.16.15.24:7001/readable-stream/download/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "0.0.1"
+ string_decoder "~0.10.x"
+
+readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.1.5:
+ version "2.2.11"
+ resolved "http://172.16.15.24:7001/readable-stream/download/readable-stream-2.2.11.tgz#0796b31f8d7688007ff0b93a8088d34aa17c0f72"
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "~1.0.0"
+ process-nextick-args "~1.0.6"
+ safe-buffer "~5.0.1"
+ string_decoder "~1.0.0"
+ util-deprecate "~1.0.1"
+
+readable-stream@~1.1.9:
+ version "1.1.14"
+ resolved "http://172.16.15.24:7001/readable-stream/download/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "0.0.1"
+ string_decoder "~0.10.x"
+
+rechoir@^0.6.2:
+ version "0.6.2"
+ resolved "http://172.16.15.24:7001/rechoir/download/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
+ dependencies:
+ resolve "^1.1.6"
+
+regex-cache@^0.4.2:
+ version "0.4.3"
+ resolved "http://172.16.15.24:7001/regex-cache/download/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145"
+ dependencies:
+ is-equal-shallow "^0.1.3"
+ is-primitive "^2.0.0"
+
+remove-trailing-separator@^1.0.1:
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/remove-trailing-separator/download/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4"
+
+repeat-element@^1.1.2:
+ version "1.1.2"
+ resolved "http://172.16.15.24:7001/repeat-element/download/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
+
+repeat-string@^1.5.2:
+ version "1.6.1"
+ resolved "http://172.16.15.24:7001/repeat-string/download/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
+
+replace-ext@0.0.1:
+ version "0.0.1"
+ resolved "http://172.16.15.24:7001/replace-ext/download/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924"
+
+resolve-dir@^0.1.0:
+ version "0.1.1"
+ resolved "http://172.16.15.24:7001/resolve-dir/download/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e"
+ dependencies:
+ expand-tilde "^1.2.2"
+ global-modules "^0.2.3"
+
+resolve@^1.1.6, resolve@^1.1.7:
+ version "1.3.3"
+ resolved "http://172.16.15.24:7001/resolve/download/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
+ dependencies:
+ path-parse "^1.0.5"
+
+rimraf@^2.2.8:
+ version "2.6.1"
+ resolved "http://172.16.15.24:7001/rimraf/download/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
+ dependencies:
+ glob "^7.0.5"
+
+safe-buffer@~5.0.1:
+ version "5.0.1"
+ resolved "http://172.16.15.24:7001/safe-buffer/download/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7"
+
+semver@^4.1.0:
+ version "4.3.6"
+ resolved "http://172.16.15.24:7001/semver/download/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da"
+
+sequencify@~0.0.7:
+ version "0.0.7"
+ resolved "http://172.16.15.24:7001/sequencify/download/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c"
+
+should-equal@^1.0.0:
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/should-equal/download/should-equal-1.0.1.tgz#0b6e9516f2601a9fb0bb2dcc369afa1c7e200af7"
+ dependencies:
+ should-type "^1.0.0"
+
+should-format@^3.0.2:
+ version "3.0.3"
+ resolved "http://172.16.15.24:7001/should-format/download/should-format-3.0.3.tgz#9bfc8f74fa39205c53d38c34d717303e277124f1"
+ dependencies:
+ should-type "^1.3.0"
+ should-type-adaptors "^1.0.1"
+
+should-type-adaptors@^1.0.1:
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/should-type-adaptors/download/should-type-adaptors-1.0.1.tgz#efe5553cdf68cff66e5c5f51b712dc351c77beaa"
+ dependencies:
+ should-type "^1.3.0"
+ should-util "^1.0.0"
+
+should-type@^1.0.0, should-type@^1.3.0, should-type@^1.4.0:
+ version "1.4.0"
+ resolved "http://172.16.15.24:7001/should-type/download/should-type-1.4.0.tgz#0756d8ce846dfd09843a6947719dfa0d4cff5cf3"
+
+should-util@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/should-util/download/should-util-1.0.0.tgz#c98cda374aa6b190df8ba87c9889c2b4db620063"
+
+should@latest:
+ version "11.2.1"
+ resolved "http://172.16.15.24:7001/should/download/should-11.2.1.tgz#90f55145552d01cfc200666e4e818a1c9670eda2"
+ dependencies:
+ should-equal "^1.0.0"
+ should-format "^3.0.2"
+ should-type "^1.4.0"
+ should-type-adaptors "^1.0.1"
+ should-util "^1.0.0"
+
+sigmund@~1.0.0:
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/sigmund/download/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"
+
+source-map@~0.5.3:
+ version "0.5.6"
+ resolved "http://172.16.15.24:7001/source-map/download/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
+
+sparkles@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/sparkles/download/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3"
+
+spec@latest:
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/spec/download/spec-1.0.1.tgz#dbf7504aa1fc3fb295b64f2f87fed79096bc1b04"
+
+stream-consume@~0.1.0:
+ version "0.1.0"
+ resolved "http://172.16.15.24:7001/stream-consume/download/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f"
+
+stream-shift@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/stream-shift/download/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952"
+
+string_decoder@~0.10.x:
+ version "0.10.31"
+ resolved "http://172.16.15.24:7001/string_decoder/download/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
+
+string_decoder@~1.0.0:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/string_decoder/download/string_decoder-1.0.2.tgz#b29e1f4e1125fa97a10382b8a533737b7491e179"
+ dependencies:
+ safe-buffer "~5.0.1"
+
+strip-ansi@^3.0.0:
+ version "3.0.1"
+ resolved "http://172.16.15.24:7001/strip-ansi/download/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+strip-bom-stream@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/strip-bom-stream/download/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee"
+ dependencies:
+ first-chunk-stream "^1.0.0"
+ strip-bom "^2.0.0"
+
+strip-bom@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/strip-bom/download/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794"
+ dependencies:
+ first-chunk-stream "^1.0.0"
+ is-utf8 "^0.2.0"
+
+strip-bom@^2.0.0:
+ version "2.0.0"
+ resolved "http://172.16.15.24:7001/strip-bom/download/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
+ dependencies:
+ is-utf8 "^0.2.0"
+
+supports-color@3.1.2:
+ version "3.1.2"
+ resolved "http://172.16.15.24:7001/supports-color/download/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5"
+ dependencies:
+ has-flag "^1.0.0"
+
+supports-color@^2.0.0:
+ version "2.0.0"
+ resolved "http://172.16.15.24:7001/supports-color/download/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
+
+through2-filter@^2.0.0:
+ version "2.0.0"
+ resolved "http://172.16.15.24:7001/through2-filter/download/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec"
+ dependencies:
+ through2 "~2.0.0"
+ xtend "~4.0.0"
+
+through2@^0.6.0, through2@^0.6.1:
+ version "0.6.5"
+ resolved "http://172.16.15.24:7001/through2/download/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48"
+ dependencies:
+ readable-stream ">=1.0.33-1 <1.1.0-0"
+ xtend ">=4.0.0 <4.1.0-0"
+
+through2@^2.0.0, through2@~2.0.0, through2@~2.0.1:
+ version "2.0.3"
+ resolved "http://172.16.15.24:7001/through2/download/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
+ dependencies:
+ readable-stream "^2.1.5"
+ xtend "~4.0.1"
+
+thunks@^4.5.1:
+ version "4.8.0"
+ resolved "http://172.16.15.24:7001/thunks/download/thunks-4.8.0.tgz#63d5fff7f6a957d6953c46dc72829dd5462a8ab4"
+
+tildify@^1.0.0:
+ version "1.2.0"
+ resolved "http://172.16.15.24:7001/tildify/download/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a"
+ dependencies:
+ os-homedir "^1.0.0"
+
+time-stamp@^1.0.0:
+ version "1.0.1"
+ resolved "http://172.16.15.24:7001/time-stamp/download/time-stamp-1.0.1.tgz#9f4bd23559c9365966f3302dbba2b07c6b99b151"
+
+to-absolute-glob@^0.1.1:
+ version "0.1.1"
+ resolved "http://172.16.15.24:7001/to-absolute-glob/download/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f"
+ dependencies:
+ extend-shallow "^2.0.1"
+
+travis-cov@latest:
+ version "0.2.5"
+ resolved "http://172.16.15.24:7001/travis-cov/download/travis-cov-0.2.5.tgz#ab236f36fc68259263bb92e91044000dd5cbb736"
+
+typescript@next:
+ version "2.4.0-dev.20170608"
+ resolved "http://172.16.15.24:7001/typescript/download/typescript-2.4.0-dev.20170608.tgz#a6e7eff5ec3ba9f43eb10907b2d1bda4326bb65a"
+
+unc-path-regex@^0.1.0:
+ version "0.1.2"
+ resolved "http://172.16.15.24:7001/unc-path-regex/download/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
+
+unique-stream@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/unique-stream/download/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b"
+
+unique-stream@^2.0.2:
+ version "2.2.1"
+ resolved "http://172.16.15.24:7001/unique-stream/download/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369"
+ dependencies:
+ json-stable-stringify "^1.0.0"
+ through2-filter "^2.0.0"
+
+user-home@^1.1.1:
+ version "1.1.1"
+ resolved "http://172.16.15.24:7001/user-home/download/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
+
+util-deprecate@~1.0.1:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/util-deprecate/download/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+
+v8flags@^2.0.2:
+ version "2.1.1"
+ resolved "http://172.16.15.24:7001/v8flags/download/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4"
+ dependencies:
+ user-home "^1.1.1"
+
+vali-date@^1.0.0:
+ version "1.0.0"
+ resolved "http://172.16.15.24:7001/vali-date/download/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6"
+
+vinyl-fs@^0.3.0:
+ version "0.3.14"
+ resolved "http://172.16.15.24:7001/vinyl-fs/download/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6"
+ dependencies:
+ defaults "^1.0.0"
+ glob-stream "^3.1.5"
+ glob-watcher "^0.0.6"
+ graceful-fs "^3.0.0"
+ mkdirp "^0.5.0"
+ strip-bom "^1.0.0"
+ through2 "^0.6.1"
+ vinyl "^0.4.0"
+
+vinyl-fs@~2.4.3:
+ version "2.4.4"
+ resolved "http://172.16.15.24:7001/vinyl-fs/download/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239"
+ dependencies:
+ duplexify "^3.2.0"
+ glob-stream "^5.3.2"
+ graceful-fs "^4.0.0"
+ gulp-sourcemaps "1.6.0"
+ is-valid-glob "^0.3.0"
+ lazystream "^1.0.0"
+ lodash.isequal "^4.0.0"
+ merge-stream "^1.0.0"
+ mkdirp "^0.5.0"
+ object-assign "^4.0.0"
+ readable-stream "^2.0.4"
+ strip-bom "^2.0.0"
+ strip-bom-stream "^1.0.0"
+ through2 "^2.0.0"
+ through2-filter "^2.0.0"
+ vali-date "^1.0.0"
+ vinyl "^1.0.0"
+
+vinyl@^0.4.0:
+ version "0.4.6"
+ resolved "http://172.16.15.24:7001/vinyl/download/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847"
+ dependencies:
+ clone "^0.2.0"
+ clone-stats "^0.0.1"
+
+vinyl@^0.5.0:
+ version "0.5.3"
+ resolved "http://172.16.15.24:7001/vinyl/download/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde"
+ dependencies:
+ clone "^1.0.0"
+ clone-stats "^0.0.1"
+ replace-ext "0.0.1"
+
+vinyl@^1.0.0:
+ version "1.2.0"
+ resolved "http://172.16.15.24:7001/vinyl/download/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884"
+ dependencies:
+ clone "^1.0.0"
+ clone-stats "^0.0.1"
+ replace-ext "0.0.1"
+
+which@^1.2.10:
+ version "1.2.14"
+ resolved "http://172.16.15.24:7001/which/download/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
+ dependencies:
+ isexe "^2.0.0"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "http://172.16.15.24:7001/wrappy/download/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+
+"xtend@>=4.0.0 <4.1.0-0", xtend@~4.0.0, xtend@~4.0.1:
+ version "4.0.1"
+ resolved "http://172.16.15.24:7001/xtend/download/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"