Add stylelint dependency

This also adds CC-BY-4.0 to the list of accepted licenses.

DISABLE_THIRD_PARTY_CHECK=update dependencies

Bug: chromium:1083142
Change-Id: I8612de2fba52dae32eeb71af79d5aacfde52142b
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2220097
Reviewed-by: Paul Lewis <aerotwist@chromium.org>
Commit-Queue: Mathias Bynens <mathias@chromium.org>
diff --git a/node_modules/normalize-selector/.npmignore b/node_modules/normalize-selector/.npmignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/node_modules/normalize-selector/.npmignore
@@ -0,0 +1 @@
+node_modules
diff --git a/node_modules/normalize-selector/README.md b/node_modules/normalize-selector/README.md
new file mode 100644
index 0000000..a30ba08
--- /dev/null
+++ b/node_modules/normalize-selector/README.md
@@ -0,0 +1,34 @@
+# Normalize-Selector
+
+Normalize CSS selectors.
+
+Examples:
+
+* `#foo>.bar` -> `#foo > .bar`
+* ` 	#foo 	 > 	 .bar 	 ` -> `#foo > .bar`
+* `foo[ a = 'b' ]` -> `foo[a='b']`
+
+## Tests
+
+Run mocha tests on node.js with:
+
+```
+npm test
+```
+
+or:
+
+```
+node ./test/mocha/node-suite.js
+```
+
+## rawgithub
+
+View the browser suite directly on
+[rawgithub](https://rawgithub.com/getify/normalize-selector/master/test/mocha/browser-suite.html)
+
+## License
+
+The code and all the documentation are released under the MIT license.
+
+http://getify.mit-license.org/
diff --git a/node_modules/normalize-selector/lib/normalize-selector.js b/node_modules/normalize-selector/lib/normalize-selector.js
new file mode 100644
index 0000000..909cf54
--- /dev/null
+++ b/node_modules/normalize-selector/lib/normalize-selector.js
@@ -0,0 +1,163 @@
+/* normalize-selector v0.1.0 (c) 2014 Kyle Simpson */
+
+(function UMD(name,context,definition){
+	if (typeof module !== "undefined" && module.exports) { module.exports = definition(); }
+	else if (typeof define === "function" && define.amd) { define(definition); }
+	else { context[name] = definition(name,context); }
+})("normalizeSelector",this,function DEF(name,context){
+	"use strict";
+
+	function normalizeSelector(sel) {
+
+		// save unmatched text, if any
+		function saveUnmatched() {
+			if (unmatched) {
+				// whitespace needed after combinator?
+				if (tokens.length > 0 &&
+					/^[~+>]$/.test(tokens[tokens.length-1])
+				) {
+					tokens.push(" ");
+				}
+
+				// save unmatched text
+				tokens.push(unmatched);
+			}
+		}
+
+		var tokens = [], match, unmatched, regex, state = [0],
+			next_match_idx = 0, prev_match_idx,
+			not_escaped_pattern = /(?:[^\\]|(?:^|[^\\])(?:\\\\)+)$/,
+			whitespace_pattern = /^\s+$/,
+			attribute_nonspecial_pattern = /[^\s=~!^|$*\[\]\(\)]{2}/,
+			state_patterns = [
+				/\s+|\/\*|["'>~+\[\(]/g, // general
+				/\s+|\/\*|["'\[\]\(\)]/g, // [..] set
+				/\s+|\/\*|["'\[\]\(\)]/g, // (..) set
+				null, // string literal (placeholder)
+				/\*\//g // comment
+			]
+		;
+
+		sel = sel.trim();
+
+		while (true) {
+			unmatched = "";
+
+			regex = state_patterns[state[state.length-1]];
+
+			regex.lastIndex = next_match_idx;
+			match = regex.exec(sel);
+
+			// matched text to process?
+			if (match) {
+				prev_match_idx = next_match_idx;
+				next_match_idx = regex.lastIndex;
+
+				// collect the previous string chunk not matched before this token
+				if (prev_match_idx < next_match_idx - match[0].length) {
+					unmatched = sel.substring(prev_match_idx,next_match_idx - match[0].length);
+				}
+
+				// need to force a space (possibly skipped
+				// previously by the parser)?
+				if (
+					state[state.length-1] === 1 &&
+					attribute_nonspecial_pattern.test(
+						tokens[tokens.length-1].substr(-1) +
+						unmatched.charAt(0)
+					)
+				) {
+					tokens.push(" ");
+				}
+
+				// general, [ ] pair, ( ) pair?
+				if (state[state.length-1] < 3) {
+					saveUnmatched();
+
+					// starting a [ ] pair?
+					if (match[0] === "[") {
+						state.push(1);
+					}
+					// starting a ( ) pair?
+					else if (match[0] === "(") {
+						state.push(2);
+					}
+					// starting a string literal?
+					else if (/^["']$/.test(match[0])) {
+						state.push(3);
+						state_patterns[3] = new RegExp(match[0],"g");
+					}
+					// starting a comment?
+					else if (match[0] === "/*") {
+						state.push(4);
+					}
+					// ending a [ ] or ( ) pair?
+					else if (/^[\]\)]$/.test(match[0]) && state.length > 0) {
+						state.pop();
+					}
+					// handling whitespace or a combinator?
+					else if (/^(?:\s+|[~+>])$/.test(match[0])) {
+						// need to insert whitespace before?
+						if (tokens.length > 0 &&
+							!whitespace_pattern.test(tokens[tokens.length-1]) &&
+							state[state.length-1] === 0
+						) {
+							// add normalized whitespace
+							tokens.push(" ");
+						}
+
+						// whitespace token we can skip?
+						if (whitespace_pattern.test(match[0])) {
+							continue;
+						}
+					}
+
+					// save matched text
+					tokens.push(match[0]);
+				}
+				// otherwise, string literal or comment
+				else {
+					// save unmatched text
+					tokens[tokens.length-1] += unmatched;
+
+					// unescaped terminator to string literal or comment?
+					if (not_escaped_pattern.test(tokens[tokens.length-1])) {
+						// comment terminator?
+						if (state[state.length-1] === 4) {
+							// ok to drop comment?
+							if (tokens.length < 2 ||
+								whitespace_pattern.test(tokens[tokens.length-2])
+							) {
+								tokens.pop();
+							}
+							// otherwise, turn comment into whitespace
+							else {
+								tokens[tokens.length-1] = " ";
+							}
+
+							// handled already
+							match[0] = "";
+						}
+
+						state.pop();
+					}
+
+					// append matched text to existing token
+					tokens[tokens.length-1] += match[0];
+				}
+			}
+			// otherwise, end of processing (no more matches)
+			else {
+				unmatched = sel.substr(next_match_idx);
+				saveUnmatched();
+
+				break;
+			}
+		}
+
+		return tokens.join("").trim();
+	}
+
+	return normalizeSelector;
+});
+
diff --git a/node_modules/normalize-selector/package.json b/node_modules/normalize-selector/package.json
new file mode 100644
index 0000000..c6ed0ae
--- /dev/null
+++ b/node_modules/normalize-selector/package.json
@@ -0,0 +1,30 @@
+{
+  "author": "Kyle Simpson <getify@gmail.com>",
+  "bugs": {
+    "email": "getify@gmail.com",
+    "url": "https://github.com/getify/normalize-selector/issues"
+  },
+  "contributors": [
+    "David Kaye (https://github.com/dfkaye)"
+  ],
+  "description": "Normalize CSS Selectors",
+  "devDependencies": {
+    "assertik": "^1.0.0",
+    "mocha": "^2.2.5"
+  },
+  "homepage": "http://github.com/getify/normalize-selector",
+  "keywords": [
+    "CSS"
+  ],
+  "license": "MIT",
+  "main": "./lib/normalize-selector.js",
+  "name": "normalize-selector",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/getify/normalize-selector.git"
+  },
+  "scripts": {
+    "test": "node ./test/mocha/node-suite.js"
+  },
+  "version": "0.2.0"
+}
\ No newline at end of file
diff --git a/node_modules/normalize-selector/test/mocha/browser-suite.html b/node_modules/normalize-selector/test/mocha/browser-suite.html
new file mode 100644
index 0000000..f44c7c5
--- /dev/null
+++ b/node_modules/normalize-selector/test/mocha/browser-suite.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>mocha browser-suite: normalize-selector</title>
+    <link rel="stylesheet" href="../../node_modules/mocha/mocha.css" />
+  </head>
+  <body>
+    <div id="mocha"></div>
+    <script src="../../lib/normalize-selector.js"></script>
+    <script src="../../node_modules/assertik/assertik.js"></script>
+    <script src="../../node_modules/mocha/mocha.js"></script>
+    <script>mocha.setup('qunit')</script>
+
+    <!-- get tests and start -->
+    <script src="./suite.js"></script>
+    <script>
+      mocha.checkLeaks();
+      mocha.globals(['boilerplate']); // watch our boilerplate function
+      mocha.run();
+    </script>        
+  </body>
+</html>
\ No newline at end of file
diff --git a/node_modules/normalize-selector/test/mocha/node-suite.js b/node_modules/normalize-selector/test/mocha/node-suite.js
new file mode 100644
index 0000000..087a316
--- /dev/null
+++ b/node_modules/normalize-selector/test/mocha/node-suite.js
@@ -0,0 +1,18 @@
+// test/mocha/node-suite.js
+
+// This runs with mocha programmatically rather than from the command line.
+// how-to-with-comments taken from https://github.com/itaylor/qunit-mocha-ui
+
+//Load mocha
+var Mocha = require("mocha");
+
+//Tell mocha to use the interface.
+var mocha = new Mocha({ui:"qunit", reporter:"spec"});
+
+//Add your test files
+mocha.addFile("./test/mocha/suite.js");
+
+//Run your tests
+mocha.run(function(failures){
+  process.exit(failures);
+});
\ No newline at end of file
diff --git a/node_modules/normalize-selector/test/mocha/suite.js b/node_modules/normalize-selector/test/mocha/suite.js
new file mode 100644
index 0000000..2f568b2
--- /dev/null
+++ b/node_modules/normalize-selector/test/mocha/suite.js
@@ -0,0 +1,117 @@
+// mocha/suite.js for normalize-selector.js
+
+var normalizeSelector;
+var assert;
+
+if (typeof require == 'function') {
+  // enable to re-use in a browser without require.js
+  normalizeSelector = require('../../lib/normalize-selector.js');
+  assert = require('assertik');
+} else {
+  assert = window.assertik;
+}
+
+suite('normalizeSelector');
+
+test('should be function', function () {
+  assert.equal(typeof normalizeSelector, 'function', 'wrong type');
+});
+
+test('should normalize BIG SELECTOR', function () {
+  var selector = "*~*>*.foo[   href *=  \"/\"   ]:hover>*[  data-foo =   " +
+                 "\"bar\"      ]:focus+*.baz::after";
+  var expected = "* ~ * > *.foo[href*=\"/\"]:hover > *[data-foo=\"bar\"]:" +
+                 "focus + *.baz::after";
+  assert.equal(normalizeSelector(selector), expected);
+});
+
+test('should return optimized selector with no change', function () {
+  assert.equal(normalizeSelector("#foo .bar"), "#foo .bar");
+});
+
+test('should trim whitespace', function () {
+  assert.equal(normalizeSelector(" #foo   .bar "), "#foo .bar");
+});
+
+test('should separate between combinators', function () {
+  assert.equal(normalizeSelector("#foo>.bar+.baz"), "#foo > .bar + .baz");
+});
+
+test('should not separate concatenated classes', function () {
+  assert.equal(normalizeSelector("#foo.bar.baz"), "#foo.bar.baz");
+});
+
+test('should normalize asterisks', function () {
+  var selector = " *.class[ data * = 'data' ] ";
+  assert.equal(normalizeSelector(selector), "*.class[data*='data']");
+});
+
+test('should remove comments', function () {
+  assert.equal(normalizeSelector(".e1 /* c2 */ .e2"), ".e1 .e2");
+  assert.equal(normalizeSelector(" /*c1*/ .e1/*c2*/.e2 /*c3*/ .e3 /*c4*/ "), ".e1 .e2 .e3");
+  assert.equal(normalizeSelector(" /*c1*/ .e1/*c2*/.e2 /*c3*/ .e3 "), ".e1 .e2 .e3");
+  assert.equal(normalizeSelector("/*c1*/.e1/*c2*/.e2 /*c3*/ .e3"), ".e1 .e2 .e3");
+  assert.equal(normalizeSelector(".e1/*c2*/.e2 /*c3*/ .e3"), ".e1 .e2 .e3");
+});
+
+test('should replace comments with single whitespace', function () {
+  assert.equal(normalizeSelector("tag/* c2 */tag"), "tag tag");
+});
+
+test('should normalize parentheses', function() {
+  var selector = "((a ) (b(c ) ) d )>*[ data-foo = \"bar\" ]";
+  var expected = "((a)(b(c))d) > *[data-foo=\"bar\"]";
+  assert.equal(normalizeSelector(selector), expected);
+});
+
+test('should normalize @-rule parentheses', function () {
+  var selector = "@media  screen  and  ( color ),  projection  and  (color )";
+  var expected = "@media screen and (color), projection and (color)";
+  assert.equal(normalizeSelector(selector), expected);
+});
+
+test('should normalize @-rules with compound parentheses', function () {
+  var selector = "@media  handheld  and  ( min-width : 20em ),   screen  " +
+                 "and  ( min-width: 20em )";
+  var expected = "@media handheld and (min-width:20em), screen and " +
+                 "(min-width:20em)";
+  assert.equal(normalizeSelector(selector), expected);
+});
+
+test('should normalize @-rules with operations', function () {
+  var selector = "@media  screen  and  ( device-aspect-ratio : 2560 / 1440 )";
+  var expected = "@media screen and (device-aspect-ratio:2560/1440)";
+  assert.equal(normalizeSelector(selector), expected);
+});
+
+test('should normalize descriptors', function () {
+  var selector = "@counter-style    triangle";
+  assert.equal(normalizeSelector(selector), "@counter-style triangle");
+});
+
+test('should normalize case-insensitivity attribute selector', function () {
+  assert.equal(normalizeSelector("[ att ~= val  i ]"), "[att~=val i]");
+  assert.equal(normalizeSelector("#foo[  a  =  \"b\"  i  ]"), "#foo[a=\"b\" i]");
+});
+
+test('should normalize namespaced attribute selector', function () {
+  var selector = ' unit[ sh | quantity = "200" ] ';
+  var expected = 'unit[sh|quantity="200"]';
+  assert.equal(normalizeSelector(selector), expected);
+});
+
+test('should normalize pseudo-classes', function () {
+  var selector = "   :nth-last-of-type( )   ";
+  assert.equal(normalizeSelector(selector), ":nth-last-of-type()");
+});
+
+test('should normalize pseudo-elements', function () {
+  var selector = "   ::nth-fragment(   )   ";
+  assert.equal(normalizeSelector(selector), "::nth-fragment()");
+});
+
+test('should normalize backslashes', function () {
+  var selector = "#foo[ a = \" b \\\" c\\\\\" ]";
+  var expected = "#foo[a=\" b \\\" c\\\\\"]";
+  assert.equal(normalizeSelector(selector), expected);
+});
diff --git a/node_modules/normalize-selector/tests.js b/node_modules/normalize-selector/tests.js
new file mode 100644
index 0000000..f8b313a
--- /dev/null
+++ b/node_modules/normalize-selector/tests.js
@@ -0,0 +1,49 @@
+var normalize = require("./lib/normalize-selector.js");
+
+var tests = {
+	/*test*/"#foo .bar":
+	   /*expected*/"#foo .bar",
+	/*test*/" #foo   .bar ":
+	   /*expected*/"#foo .bar",
+	/*test*/"#foo>.bar":
+	   /*expected*/"#foo > .bar",
+	/*test*/" unit[ sh | quantity = \"200\" ] ":
+	   /*expected*/"unit[sh|quantity=\"200\"]",
+	/*test*/"*~*>*.foo[ href *= \"/\" ]:hover>*[ data-foo = \"bar\" ]:focus+*.baz::after":
+	   /*expected*/"* ~ * > *.foo[href*=\"/\"]:hover > *[data-foo=\"bar\"]:focus + *.baz::after",
+	/*test*/"@media  screen  and  ( color ),  projection  and  ( color )":
+	   /*expected*/"@media screen and (color), projection and (color)",
+	/*test*/"@media  handheld  and  ( min-width : 20em ),   screen  and  ( min-width: 20em )":
+	   /*expected*/"@media handheld and (min-width:20em), screen and (min-width:20em)",
+	/*test*/"@media  screen  and  ( device-aspect-ratio : 2560 / 1440 )":
+	   /*expected*/"@media screen and (device-aspect-ratio:2560/1440)",
+	/*test*/"((a ) (b(c ) ) d )>*[ data-foo = \"bar\" ]":
+	   /*expected*/"((a)(b(c))d) > *[data-foo=\"bar\"]",
+	/*test*/"#foo[ a = \" b \\\" c\\\\\" ]":
+	   /*expected*/"#foo[a=\" b \\\" c\\\\\"]",
+	/*test*/"#foo[  a  =  \"b\"  i  ]":
+	   /*expected*/"#foo[a=\"b\" i]",
+	/*test*/" /*c1*/ .e1/*c2*/.e2 /*c3*/ .e3 /*c4*/ ":
+	   /*expected*/".e1 .e2 .e3",
+	/*test*/" /*c1*/ .e1/*c2*/.e2 /*c3*/ .e3 ":
+	   /*expected*/".e1 .e2 .e3",
+	/*test*/" /*c1*/ .e1/*c2*/.e2 /*c3*/ .e3":
+	   /*expected*/".e1 .e2 .e3",
+	/*test*/"/*c1*/.e1/*c2*/.e2 /*c3*/ .e3":
+	   /*expected*/".e1 .e2 .e3",
+	/*test*/".e1/*c2*/.e2 /*c3*/ .e3":
+	   /*expected*/".e1 .e2 .e3"
+};
+
+var test, tmp;
+for (test in tests) {
+	if ((tmp = normalize(test)) && tmp === tests[test]) {
+		console.log("PASSED: " + test + " (" + tmp + ")");
+	}
+	else {
+		console.log("FAILED.\n Expected: " + tests[test] + "\n Received: " + tmp);
+		break;
+	}
+}
+
+console.log("Tests done.");