manyfest 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.config/code-server/config.yaml +4 -0
- package/.config/configstore/update-notifier-npm-check-updates.json +4 -0
- package/.config/configstore/update-notifier-npm.json +4 -0
- package/.config/installation/UI-Requirements.md +32 -0
- package/.config/installation/install_luxury_code.js +105 -0
- package/.config/installation/install_luxury_default_configuration.json +45 -0
- package/.config/installation/install_luxury_interaction.json +3 -0
- package/.config/installation/precedent.1.0.5.js +339 -0
- package/.config/luxury-extras/.vscode/launch.json +46 -0
- package/.config/luxury-extras/Dockerfile_LUXURYCode +39 -0
- package/.config/luxury-extras/MySQL/Dockerfile_LUXURYCODE_MySQL +65 -0
- package/.config/luxury-extras/MySQL/MySQL-Laden-Entry.sh +17 -0
- package/.config/luxury-extras/MySQL/MySQL-Security.sql +5 -0
- package/.vscode/launch.json +46 -0
- package/Dockerfile_LUXURYCode +39 -0
- package/LICENSE +21 -0
- package/README.md +234 -0
- package/debug/Harness.js +20 -0
- package/diagrams/Mascot.jpg +0 -0
- package/gulpfile.js +62 -0
- package/package.json +67 -0
- package/source/Manyfest-Browser-Shim.js +15 -0
- package/source/Manyfest-LogToConsole.js +19 -0
- package/source/Manyfest.js +357 -0
- package/test/Manyfest_tests.js +167 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Questions
|
|
2
|
+
|
|
3
|
+
. What would you like to call your luxury workspace? my_cool_software
|
|
4
|
+
. What would you like the default password for the code editor to be? 123456789
|
|
5
|
+
. What would you like the repository prefix for your docker images and containers to be? luxury
|
|
6
|
+
. What port would you like to expose the code editor on? 12345
|
|
7
|
+
. Would you like the code editor limited to the local device (explicitly mapping the exposed docker port to 127.0.0.1)? Y
|
|
8
|
+
. Would you like me to generate a Dockerfile? Y
|
|
9
|
+
a. What would you like the Dockerfile to be called? Dockerfile_LUXURY
|
|
10
|
+
b. Would you like to run Stricture on a folder/file? N
|
|
11
|
+
i. Which file? ./Model.ddl
|
|
12
|
+
c. Would you like MySQL in the Docker Environment? N
|
|
13
|
+
i. Would you like to expose the MySQL port? Y
|
|
14
|
+
ii. What port would you like to expose MySQL on? 3306
|
|
15
|
+
iii. What would you like the default mysql root password to be? 123456789
|
|
16
|
+
iv. What would you like the database name to be? luxury_database
|
|
17
|
+
v. Would you like to execute a SQL database population script on container creation (the database is created automatically)? N
|
|
18
|
+
vi. Which script would you like to run? ./Database-Initialization.sql
|
|
19
|
+
d. Would you like add-ons to be installed by default to Visual Studio Code? Y
|
|
20
|
+
i. hbenl.vscode-mocha-test-adapter (binding for mocha tests to the test explorer)
|
|
21
|
+
ii. hbenl.test-adapter-converter (mocha test suite conversion)
|
|
22
|
+
iii. hbenl.vscode-test-explorer (tree view for visualizing and executing tests)
|
|
23
|
+
iv. ritwickdey.LiveServer (static html web server)
|
|
24
|
+
v. daylerees.rainglow (tons of color themes like the freshest theme: freshcut)
|
|
25
|
+
vi. oderwat.indent-rainbow (rainbow-colored indent levels)
|
|
26
|
+
. Would you like me to edit the package.json? Y
|
|
27
|
+
a. Docker build statements
|
|
28
|
+
b. Mocha tdd test run statements
|
|
29
|
+
c. Mocha IDE test configurations
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const libReadline = require('readline');
|
|
2
|
+
|
|
3
|
+
/********************************************************************
|
|
4
|
+
* Stolen from Informary for basic management of values in the config
|
|
5
|
+
*/
|
|
6
|
+
const getValueAtAddress = (pObject, pAddress) =>
|
|
7
|
+
{
|
|
8
|
+
// Make sure pObject is an object
|
|
9
|
+
if (!typeof(pObject) === 'object') return false;
|
|
10
|
+
// Make sure pAddress is a string
|
|
11
|
+
if (!typeof(pAddress) === 'string') return false;
|
|
12
|
+
|
|
13
|
+
let tmpSeparatorIndex = pAddress.indexOf('.');
|
|
14
|
+
|
|
15
|
+
if (tmpSeparatorIndex === -1)
|
|
16
|
+
{
|
|
17
|
+
// Now is the time to return the value in the address
|
|
18
|
+
return pObject[pAddress];
|
|
19
|
+
}
|
|
20
|
+
else
|
|
21
|
+
{
|
|
22
|
+
let tmpSubObjectName = pAddress.substring(0, tmpSeparatorIndex);
|
|
23
|
+
let tmpNewAddress = pAddress.substring(tmpSeparatorIndex+1);
|
|
24
|
+
|
|
25
|
+
// If there is an object property already named for the sub object, but it isn't an object
|
|
26
|
+
// then the system can't set the value in there. Error and abort!
|
|
27
|
+
if (pObject.hasOwnProperty(tmpSubObjectName) && typeof(pObject[tmpSubObjectName]) !== 'object')
|
|
28
|
+
{
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
else if (pObject.hasOwnProperty(tmpSubObjectName))
|
|
32
|
+
{
|
|
33
|
+
// If there is already a subobject pass that to the recursive thingy
|
|
34
|
+
return getValueAtAddress(pObject[tmpSubObjectName], tmpNewAddress);
|
|
35
|
+
}
|
|
36
|
+
else
|
|
37
|
+
{
|
|
38
|
+
// Create a subobject and then pass that
|
|
39
|
+
pObject[tmpSubObjectName] = {};
|
|
40
|
+
return getValueAtAddress(pObject[tmpSubObjectName], tmpNewAddress);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const setValueAtAddress = (pObject, pAddress, pValue) =>
|
|
46
|
+
{
|
|
47
|
+
// Make sure pObject is an object
|
|
48
|
+
if (!typeof(pObject) === 'object') return false;
|
|
49
|
+
// Make sure pAddress is a string
|
|
50
|
+
if (!typeof(pAddress) === 'string') return false;
|
|
51
|
+
|
|
52
|
+
let tmpSeparatorIndex = pAddress.indexOf('.');
|
|
53
|
+
|
|
54
|
+
if (tmpSeparatorIndex === -1)
|
|
55
|
+
{
|
|
56
|
+
// Now is the time to set the value in the object
|
|
57
|
+
pObject[pAddress] = pValue;
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
else
|
|
61
|
+
{
|
|
62
|
+
let tmpSubObjectName = pAddress.substring(0, tmpSeparatorIndex);
|
|
63
|
+
let tmpNewAddress = pAddress.substring(tmpSeparatorIndex+1);
|
|
64
|
+
|
|
65
|
+
// If there is an object property already named for the sub object, but it isn't an object
|
|
66
|
+
// then the system can't set the value in there. Error and abort!
|
|
67
|
+
if (pObject.hasOwnProperty(tmpSubObjectName) && typeof(pObject[tmpSubObjectName]) !== 'object')
|
|
68
|
+
{
|
|
69
|
+
if (!pObject.hasOwnProperty('__ERROR'))
|
|
70
|
+
pObject['__ERROR'] = {};
|
|
71
|
+
// Put it in an error object so data isn't lost
|
|
72
|
+
pObject['__ERROR'][pAddress] = pValue;
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
else if (pObject.hasOwnProperty(tmpSubObjectName))
|
|
76
|
+
{
|
|
77
|
+
// If there is already a subobject pass that to the recursive thingy
|
|
78
|
+
return setValueAtAddress(pObject[tmpSubObjectName], tmpNewAddress, pValue);
|
|
79
|
+
}
|
|
80
|
+
else
|
|
81
|
+
{
|
|
82
|
+
// Create a subobject and then pass that
|
|
83
|
+
pObject[tmpSubObjectName] = {};
|
|
84
|
+
return setValueAtAddress(pObject[tmpSubObjectName], tmpNewAddress, pValue);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
/*
|
|
89
|
+
* End of Informary-stolen code
|
|
90
|
+
*******************************************************************/
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
const tmpConsoleInteraction = libReadline.createInterface(
|
|
94
|
+
{
|
|
95
|
+
input: process.stdin,
|
|
96
|
+
output: process.stdout
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
tmpConsoleInteraction.question(
|
|
100
|
+
'What do you think of Luxury? ',
|
|
101
|
+
(pResponse) =>
|
|
102
|
+
{
|
|
103
|
+
console.log(`--> You should think about why you think Luxury is [${pResponse}]`);
|
|
104
|
+
tmpConsoleInteraction.close();
|
|
105
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"WorkspaceName": "my_cool_software",
|
|
3
|
+
"Docker":
|
|
4
|
+
{
|
|
5
|
+
"ContainerPrefix": "luxury",
|
|
6
|
+
"ImagePrefix": "luxury",
|
|
7
|
+
|
|
8
|
+
"DockerfileName": "Dockerfile_LUXURY",
|
|
9
|
+
|
|
10
|
+
"AutoGenerateLuxuryDockerfile": true,
|
|
11
|
+
|
|
12
|
+
"WebEditor":
|
|
13
|
+
{
|
|
14
|
+
"Password": "123456789",
|
|
15
|
+
"ExternalPort": 12345,
|
|
16
|
+
|
|
17
|
+
"AutoInstallAddOns": true,
|
|
18
|
+
"AddonList":
|
|
19
|
+
{
|
|
20
|
+
"hbenl.vscode-mocha-test-adapter": true,
|
|
21
|
+
"hbenl.test-adapter-converter": true,
|
|
22
|
+
"hbenl.vscode-test-explorer": true,
|
|
23
|
+
"ritwickdey.LiveServer": true,
|
|
24
|
+
"daylerees.rainglow": true,
|
|
25
|
+
"oderwat.indent-rainbow": true
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
"MySQL":
|
|
30
|
+
{
|
|
31
|
+
"Installation": true,
|
|
32
|
+
"Password": "123456789",
|
|
33
|
+
"ExternalPort": 13306,
|
|
34
|
+
"DatabaseName": "luxury_database",
|
|
35
|
+
"RunPopulateScript": false,
|
|
36
|
+
"PopulateScriptFile": "Database-Initialization.sql"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"Package-json":
|
|
40
|
+
{
|
|
41
|
+
"AutoUpdate": true,
|
|
42
|
+
"MochaTestRunCommands": false,
|
|
43
|
+
"MochaIDEConfigurations": true
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
5
|
+
|
|
6
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Precedent Meta-Templating
|
|
10
|
+
*
|
|
11
|
+
* @license MIT
|
|
12
|
+
*
|
|
13
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
14
|
+
*
|
|
15
|
+
* @description Process text streams, parsing out meta-template expressions.
|
|
16
|
+
*/
|
|
17
|
+
var libWordTree = require("./WordTree.js");
|
|
18
|
+
var libStringParser = require("./StringParser.js");
|
|
19
|
+
|
|
20
|
+
var Precedent = function () {
|
|
21
|
+
/**
|
|
22
|
+
* Precedent Constructor
|
|
23
|
+
*/
|
|
24
|
+
function Precedent() {
|
|
25
|
+
_classCallCheck(this, Precedent);
|
|
26
|
+
|
|
27
|
+
this.WordTree = new libWordTree();
|
|
28
|
+
|
|
29
|
+
this.StringParser = new libStringParser();
|
|
30
|
+
|
|
31
|
+
this.ParseTree = this.WordTree.ParseTree;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Add a Pattern to the Parse Tree
|
|
36
|
+
* @method addPattern
|
|
37
|
+
* @param {Object} pTree - A node on the parse tree to push the characters into
|
|
38
|
+
* @param {string} pPattern - The string to add to the tree
|
|
39
|
+
* @param {number} pIndex - callback function
|
|
40
|
+
* @return {bool} True if adding the pattern was successful
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
_createClass(Precedent, [{
|
|
45
|
+
key: "addPattern",
|
|
46
|
+
value: function addPattern(pPatternStart, pPatternEnd, pParser) {
|
|
47
|
+
return this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Parse a string with the existing parse tree
|
|
52
|
+
* @method parseString
|
|
53
|
+
* @param {string} pString - The string to parse
|
|
54
|
+
* @return {string} The result from the parser
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
}, {
|
|
58
|
+
key: "parseString",
|
|
59
|
+
value: function parseString(pString) {
|
|
60
|
+
return this.StringParser.parseString(pString, this.ParseTree);
|
|
61
|
+
}
|
|
62
|
+
}]);
|
|
63
|
+
|
|
64
|
+
return Precedent;
|
|
65
|
+
}();
|
|
66
|
+
|
|
67
|
+
module.exports = Precedent;
|
|
68
|
+
|
|
69
|
+
},{"./StringParser.js":2,"./WordTree.js":3}],2:[function(require,module,exports){
|
|
70
|
+
'use strict';
|
|
71
|
+
|
|
72
|
+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
73
|
+
|
|
74
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* String Parser
|
|
78
|
+
*
|
|
79
|
+
* @license MIT
|
|
80
|
+
*
|
|
81
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
82
|
+
*
|
|
83
|
+
* @description Parse a string, properly processing each matched token in the word tree.
|
|
84
|
+
*/
|
|
85
|
+
|
|
86
|
+
var StringParser = function () {
|
|
87
|
+
/**
|
|
88
|
+
* StringParser Constructor
|
|
89
|
+
*/
|
|
90
|
+
function StringParser() {
|
|
91
|
+
_classCallCheck(this, StringParser);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Create a fresh parsing state object to work with.
|
|
96
|
+
* @method newParserState
|
|
97
|
+
* @param {Object} pParseTree - A node on the parse tree to begin parsing from (usually root)
|
|
98
|
+
* @return {Object} A new parser state object for running a character parser on
|
|
99
|
+
* @private
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
_createClass(StringParser, [{
|
|
104
|
+
key: 'newParserState',
|
|
105
|
+
value: function newParserState(pParseTree) {
|
|
106
|
+
return {
|
|
107
|
+
ParseTree: pParseTree,
|
|
108
|
+
|
|
109
|
+
Output: '',
|
|
110
|
+
OutputBuffer: '',
|
|
111
|
+
|
|
112
|
+
Pattern: false,
|
|
113
|
+
|
|
114
|
+
PatternMatch: false,
|
|
115
|
+
PatternMatchOutputBuffer: ''
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Assign a node of the parser tree to be the next potential match.
|
|
121
|
+
* If the node has a PatternEnd property, it is a valid match and supercedes the last valid match (or becomes the initial match).
|
|
122
|
+
* @method assignNode
|
|
123
|
+
* @param {Object} pNode - A node on the parse tree to assign
|
|
124
|
+
* @param {Object} pParserState - The state object for the current parsing task
|
|
125
|
+
* @private
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
}, {
|
|
129
|
+
key: 'assignNode',
|
|
130
|
+
value: function assignNode(pNode, pParserState) {
|
|
131
|
+
pParserState.PatternMatch = pNode;
|
|
132
|
+
|
|
133
|
+
// If the pattern has a END we can assume it has a parse function...
|
|
134
|
+
if (pParserState.PatternMatch.hasOwnProperty('PatternEnd')) {
|
|
135
|
+
// ... this is the legitimate start of a pattern.
|
|
136
|
+
pParserState.Pattern = pParserState.PatternMatch;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Append a character to the output buffer in the parser state.
|
|
142
|
+
* This output buffer is used when a potential match is being explored, or a match is being explored.
|
|
143
|
+
* @method appendOutputBuffer
|
|
144
|
+
* @param {string} pCharacter - The character to append
|
|
145
|
+
* @param {Object} pParserState - The state object for the current parsing task
|
|
146
|
+
* @private
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
}, {
|
|
150
|
+
key: 'appendOutputBuffer',
|
|
151
|
+
value: function appendOutputBuffer(pCharacter, pParserState) {
|
|
152
|
+
pParserState.OutputBuffer += pCharacter;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Flush the output buffer to the output and clear it.
|
|
157
|
+
* @method flushOutputBuffer
|
|
158
|
+
* @param {Object} pParserState - The state object for the current parsing task
|
|
159
|
+
* @private
|
|
160
|
+
*/
|
|
161
|
+
|
|
162
|
+
}, {
|
|
163
|
+
key: 'flushOutputBuffer',
|
|
164
|
+
value: function flushOutputBuffer(pParserState) {
|
|
165
|
+
pParserState.Output += pParserState.OutputBuffer;
|
|
166
|
+
pParserState.OutputBuffer = '';
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Check if the pattern has ended. If it has, properly flush the buffer and start looking for new patterns.
|
|
171
|
+
* @method checkPatternEnd
|
|
172
|
+
* @param {Object} pParserState - The state object for the current parsing task
|
|
173
|
+
* @private
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
}, {
|
|
177
|
+
key: 'checkPatternEnd',
|
|
178
|
+
value: function checkPatternEnd(pParserState) {
|
|
179
|
+
if (pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length + pParserState.Pattern.PatternStart.length && pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd) {
|
|
180
|
+
// ... this is the end of a pattern, cut off the end tag and parse it.
|
|
181
|
+
// Trim the start and end tags off the output buffer now
|
|
182
|
+
pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length + pParserState.Pattern.PatternEnd.length)));
|
|
183
|
+
// Flush the output buffer.
|
|
184
|
+
this.flushOutputBuffer(pParserState);
|
|
185
|
+
// End pattern mode
|
|
186
|
+
pParserState.Pattern = false;
|
|
187
|
+
pParserState.PatternMatch = false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Parse a character in the buffer.
|
|
193
|
+
* @method parseCharacter
|
|
194
|
+
* @param {string} pCharacter - The character to append
|
|
195
|
+
* @param {Object} pParserState - The state object for the current parsing task
|
|
196
|
+
* @private
|
|
197
|
+
*/
|
|
198
|
+
|
|
199
|
+
}, {
|
|
200
|
+
key: 'parseCharacter',
|
|
201
|
+
value: function parseCharacter(pCharacter, pParserState) {
|
|
202
|
+
// (1) If we aren't in a pattern match, and we aren't potentially matching, and this may be the start of a new pattern....
|
|
203
|
+
if (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter)) {
|
|
204
|
+
// ... assign the node as the matched node.
|
|
205
|
+
this.assignNode(pParserState.ParseTree[pCharacter], pParserState);
|
|
206
|
+
this.appendOutputBuffer(pCharacter, pParserState);
|
|
207
|
+
}
|
|
208
|
+
// (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)
|
|
209
|
+
else if (pParserState.PatternMatch) {
|
|
210
|
+
// If the pattern has a subpattern with this key
|
|
211
|
+
if (pParserState.PatternMatch.hasOwnProperty(pCharacter)) {
|
|
212
|
+
// Continue matching patterns.
|
|
213
|
+
this.assignNode(pParserState.PatternMatch[pCharacter], pParserState);
|
|
214
|
+
}
|
|
215
|
+
this.appendOutputBuffer(pCharacter, pParserState);
|
|
216
|
+
if (pParserState.Pattern) {
|
|
217
|
+
// ... Check if this is the end of the pattern (if we are matching a valid pattern)...
|
|
218
|
+
this.checkPatternEnd(pParserState);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....
|
|
222
|
+
else {
|
|
223
|
+
pParserState.Output += pCharacter;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Parse a string for matches, and process any template segments that occur.
|
|
229
|
+
* @method parseString
|
|
230
|
+
* @param {string} pString - The string to parse.
|
|
231
|
+
* @param {Object} pParseTree - The parse tree to begin parsing from (usually root)
|
|
232
|
+
*/
|
|
233
|
+
|
|
234
|
+
}, {
|
|
235
|
+
key: 'parseString',
|
|
236
|
+
value: function parseString(pString, pParseTree) {
|
|
237
|
+
var tmpParserState = this.newParserState(pParseTree);
|
|
238
|
+
|
|
239
|
+
for (var i = 0; i < pString.length; i++) {
|
|
240
|
+
// TODO: This is not fast.
|
|
241
|
+
this.parseCharacter(pString[i], tmpParserState);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
this.flushOutputBuffer(tmpParserState);
|
|
245
|
+
|
|
246
|
+
return tmpParserState.Output;
|
|
247
|
+
}
|
|
248
|
+
}]);
|
|
249
|
+
|
|
250
|
+
return StringParser;
|
|
251
|
+
}();
|
|
252
|
+
|
|
253
|
+
module.exports = StringParser;
|
|
254
|
+
|
|
255
|
+
},{}],3:[function(require,module,exports){
|
|
256
|
+
'use strict';
|
|
257
|
+
|
|
258
|
+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
259
|
+
|
|
260
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Word Tree
|
|
264
|
+
*
|
|
265
|
+
* @license MIT
|
|
266
|
+
*
|
|
267
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
268
|
+
*
|
|
269
|
+
* @description Create a tree (directed graph) of Javascript objects, one character per object.
|
|
270
|
+
*/
|
|
271
|
+
|
|
272
|
+
var WordTree = function () {
|
|
273
|
+
/**
|
|
274
|
+
* WordTree Constructor
|
|
275
|
+
*/
|
|
276
|
+
function WordTree() {
|
|
277
|
+
_classCallCheck(this, WordTree);
|
|
278
|
+
|
|
279
|
+
this.ParseTree = {};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Add a child character to a Parse Tree node
|
|
284
|
+
* @method addChild
|
|
285
|
+
* @param {Object} pTree - A parse tree to push the characters into
|
|
286
|
+
* @param {string} pPattern - The string to add to the tree
|
|
287
|
+
* @param {number} pIndex - callback function
|
|
288
|
+
* @returns {Object} The resulting leaf node that was added (or found)
|
|
289
|
+
* @private
|
|
290
|
+
*/
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
_createClass(WordTree, [{
|
|
294
|
+
key: 'addChild',
|
|
295
|
+
value: function addChild(pTree, pPattern, pIndex) {
|
|
296
|
+
if (pIndex > pPattern.length) return pTree;
|
|
297
|
+
|
|
298
|
+
if (!pTree.hasOwnProperty(pPattern[pIndex])) pTree[pPattern[pIndex]] = {};
|
|
299
|
+
|
|
300
|
+
return pTree[pPattern[pIndex]];
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** Add a Pattern to the Parse Tree
|
|
304
|
+
* @method addPattern
|
|
305
|
+
* @param {Object} pTree - A node on the parse tree to push the characters into
|
|
306
|
+
* @param {string} pPattern - The string to add to the tree
|
|
307
|
+
* @param {number} pIndex - callback function
|
|
308
|
+
* @return {bool} True if adding the pattern was successful
|
|
309
|
+
*/
|
|
310
|
+
|
|
311
|
+
}, {
|
|
312
|
+
key: 'addPattern',
|
|
313
|
+
value: function addPattern(pPatternStart, pPatternEnd, pParser) {
|
|
314
|
+
if (pPatternStart.length < 1) return false;
|
|
315
|
+
|
|
316
|
+
var tmpLeaf = this.ParseTree;
|
|
317
|
+
|
|
318
|
+
// Add the tree of leaves iteratively
|
|
319
|
+
for (var i = 0; i < pPatternStart.length; i++) {
|
|
320
|
+
tmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);
|
|
321
|
+
}tmpLeaf.PatternStart = pPatternStart;
|
|
322
|
+
tmpLeaf.PatternEnd = typeof pPatternEnd === 'string' && pPatternEnd.length > 0 ? pPatternEnd : pPatternStart;
|
|
323
|
+
tmpLeaf.Parse = typeof pParser === 'function' ? pParser : typeof pParser === 'string' ? function () {
|
|
324
|
+
return pParser;
|
|
325
|
+
} : function (pData) {
|
|
326
|
+
return pData;
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
}]);
|
|
332
|
+
|
|
333
|
+
return WordTree;
|
|
334
|
+
}();
|
|
335
|
+
|
|
336
|
+
module.exports = WordTree;
|
|
337
|
+
|
|
338
|
+
},{}]},{},[1])
|
|
339
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzb3VyY2UvUHJlY2VkZW50LmpzIiwic291cmNlL1N0cmluZ1BhcnNlci5qcyIsInNvdXJjZS9Xb3JkVHJlZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztBQ0FBOzs7Ozs7Ozs7QUFTQSxJQUFJLGNBQWMsd0JBQWxCO0FBQ0EsSUFBSSxrQkFBa0IsNEJBQXRCOztJQUVNLFM7QUFFTDs7O0FBR0Esc0JBQ0E7QUFBQTs7QUFDQyxPQUFLLFFBQUwsR0FBZ0IsSUFBSSxXQUFKLEVBQWhCOztBQUVBLE9BQUssWUFBTCxHQUFvQixJQUFJLGVBQUosRUFBcEI7O0FBRUEsT0FBSyxTQUFMLEdBQWlCLEtBQUssUUFBTCxDQUFjLFNBQS9CO0FBQ0E7O0FBRUQ7Ozs7Ozs7Ozs7Ozs2QkFRVyxhLEVBQWUsVyxFQUFhLE8sRUFDdkM7QUFDQyxVQUFPLEtBQUssUUFBTCxDQUFjLFVBQWQsQ0FBeUIsYUFBekIsRUFBd0MsV0FBeEMsRUFBcUQsT0FBckQsQ0FBUDtBQUNBOztBQUVEOzs7Ozs7Ozs7OEJBTVksTyxFQUNaO0FBQ0MsVUFBTyxLQUFLLFlBQUwsQ0FBa0IsV0FBbEIsQ0FBOEIsT0FBOUIsRUFBdUMsS0FBSyxTQUE1QyxDQUFQO0FBQ0E7Ozs7OztBQUdGLE9BQU8sT0FBUCxHQUFpQixTQUFqQjs7Ozs7Ozs7O0FDbkRBOzs7Ozs7Ozs7O0lBVU0sWTtBQUVMOzs7QUFHQSx5QkFDQTtBQUFBO0FBQ0M7O0FBRUQ7Ozs7Ozs7Ozs7O2lDQU9nQixVLEVBQ2hCO0FBQ0MsVUFDQTtBQUNJLGVBQVcsVUFEZjs7QUFHQyxZQUFRLEVBSFQ7QUFJQyxrQkFBYyxFQUpmOztBQU1DLGFBQVMsS0FOVjs7QUFRQyxrQkFBYyxLQVJmO0FBU0MsOEJBQTBCO0FBVDNCLElBREE7QUFZQTs7QUFFRDs7Ozs7Ozs7Ozs7NkJBUVksSyxFQUFPLFksRUFDbkI7QUFDQyxnQkFBYSxZQUFiLEdBQTRCLEtBQTVCOztBQUVBO0FBQ0EsT0FBSSxhQUFhLFlBQWIsQ0FBMEIsY0FBMUIsQ0FBeUMsWUFBekMsQ0FBSixFQUNBO0FBQ0M7QUFDQSxpQkFBYSxPQUFiLEdBQXVCLGFBQWEsWUFBcEM7QUFDQTtBQUNEOztBQUVEOzs7Ozs7Ozs7OztxQ0FRb0IsVSxFQUFZLFksRUFDaEM7QUFDQyxnQkFBYSxZQUFiLElBQTZCLFVBQTdCO0FBQ0E7O0FBRUQ7Ozs7Ozs7OztvQ0FNbUIsWSxFQUNuQjtBQUNDLGdCQUFhLE1BQWIsSUFBdUIsYUFBYSxZQUFwQztBQUNBLGdCQUFhLFlBQWIsR0FBNEIsRUFBNUI7QUFDQTs7QUFHRDs7Ozs7Ozs7O2tDQU1pQixZLEVBQ2pCO0FBQ0MsT0FBSyxhQUFhLFlBQWIsQ0FBMEIsTUFBMUIsSUFBb0MsYUFBYSxPQUFiLENBQXFCLFVBQXJCLENBQWdDLE1BQWhDLEdBQXVDLGFBQWEsT0FBYixDQUFxQixZQUFyQixDQUFrQyxNQUE5RyxJQUNGLGFBQWEsWUFBYixDQUEwQixNQUExQixDQUFpQyxDQUFDLGFBQWEsT0FBYixDQUFxQixVQUFyQixDQUFnQyxNQUFsRSxNQUE4RSxhQUFhLE9BQWIsQ0FBcUIsVUFEckcsRUFFQTtBQUNDO0FBQ0E7QUFDQSxpQkFBYSxZQUFiLEdBQTRCLGFBQWEsT0FBYixDQUFxQixLQUFyQixDQUEyQixhQUFhLFlBQWIsQ0FBMEIsTUFBMUIsQ0FBaUMsYUFBYSxPQUFiLENBQXFCLFlBQXJCLENBQWtDLE1BQW5FLEVBQTJFLGFBQWEsWUFBYixDQUEwQixNQUExQixJQUFvQyxhQUFhLE9BQWIsQ0FBcUIsWUFBckIsQ0FBa0MsTUFBbEMsR0FBeUMsYUFBYSxPQUFiLENBQXFCLFVBQXJCLENBQWdDLE1BQTdHLENBQTNFLENBQTNCLENBQTVCO0FBQ0E7QUFDQSxTQUFLLGlCQUFMLENBQXVCLFlBQXZCO0FBQ0E7QUFDQSxpQkFBYSxPQUFiLEdBQXVCLEtBQXZCO0FBQ0EsaUJBQWEsWUFBYixHQUE0QixLQUE1QjtBQUNBO0FBQ0Q7O0FBRUQ7Ozs7Ozs7Ozs7aUNBT2dCLFUsRUFBWSxZLEVBQzVCO0FBQ0M7QUFDQSxPQUFJLENBQUMsYUFBYSxZQUFkLElBQThCLGFBQWEsU0FBYixDQUF1QixjQUF2QixDQUFzQyxVQUF0QyxDQUFsQyxFQUNBO0FBQ0M7QUFDQSxTQUFLLFVBQUwsQ0FBZ0IsYUFBYSxTQUFiLENBQXVCLFVBQXZCLENBQWhCLEVBQW9ELFlBQXBEO0FBQ0EsU0FBSyxrQkFBTCxDQUF3QixVQUF4QixFQUFvQyxZQUFwQztBQUNBO0FBQ0Q7QUFOQSxRQU9LLElBQUksYUFBYSxZQUFqQixFQUNMO0FBQ0M7QUFDQSxTQUFJLGFBQWEsWUFBYixDQUEwQixjQUExQixDQUF5QyxVQUF6QyxDQUFKLEVBQ0E7QUFDQztBQUNBLFdBQUssVUFBTCxDQUFnQixhQUFhLFlBQWIsQ0FBMEIsVUFBMUIsQ0FBaEIsRUFBdUQsWUFBdkQ7QUFDQTtBQUNELFVBQUssa0JBQUwsQ0FBd0IsVUFBeEIsRUFBb0MsWUFBcEM7QUFDQSxTQUFJLGFBQWEsT0FBakIsRUFDQTtBQUNDO0FBQ0EsV0FBSyxlQUFMLENBQXFCLFlBQXJCO0FBQ0E7QUFDRDtBQUNEO0FBZkssU0FpQkw7QUFDQyxtQkFBYSxNQUFiLElBQXVCLFVBQXZCO0FBQ0E7QUFDRDs7QUFFRDs7Ozs7Ozs7OzhCQU1hLE8sRUFBUyxVLEVBQ3RCO0FBQ0MsT0FBSSxpQkFBaUIsS0FBSyxjQUFMLENBQW9CLFVBQXBCLENBQXJCOztBQUVBLFFBQUssSUFBSSxJQUFJLENBQWIsRUFBZ0IsSUFBSSxRQUFRLE1BQTVCLEVBQW9DLEdBQXBDLEVBQ0E7QUFDQztBQUNBLFNBQUssY0FBTCxDQUFvQixRQUFRLENBQVIsQ0FBcEIsRUFBZ0MsY0FBaEM7QUFDQTs7QUFFRCxRQUFLLGlCQUFMLENBQXVCLGNBQXZCOztBQUVBLFVBQU8sZUFBZSxNQUF0QjtBQUNBOzs7Ozs7QUFHRixPQUFPLE9BQVAsR0FBaUIsWUFBakI7Ozs7Ozs7OztBQzNLQTs7Ozs7Ozs7OztJQVVNLFE7QUFFTDs7O0FBR0EscUJBQ0E7QUFBQTs7QUFDQyxPQUFLLFNBQUwsR0FBaUIsRUFBakI7QUFDQTs7QUFFRDs7Ozs7Ozs7Ozs7OzsyQkFTVSxLLEVBQU8sUSxFQUFVLE0sRUFDM0I7QUFDQyxPQUFJLFNBQVMsU0FBUyxNQUF0QixFQUNDLE9BQU8sS0FBUDs7QUFFRCxPQUFJLENBQUMsTUFBTSxjQUFOLENBQXFCLFNBQVMsTUFBVCxDQUFyQixDQUFMLEVBQ0MsTUFBTSxTQUFTLE1BQVQsQ0FBTixJQUEwQixFQUExQjs7QUFFRCxVQUFPLE1BQU0sU0FBUyxNQUFULENBQU4sQ0FBUDtBQUNBOztBQUVEOzs7Ozs7Ozs7OzZCQU9ZLGEsRUFBZSxXLEVBQWEsTyxFQUN4QztBQUNDLE9BQUksY0FBYyxNQUFkLEdBQXVCLENBQTNCLEVBQ0MsT0FBTyxLQUFQOztBQUVELE9BQUksVUFBVSxLQUFLLFNBQW5COztBQUVBO0FBQ0EsUUFBSyxJQUFJLElBQUksQ0FBYixFQUFnQixJQUFJLGNBQWMsTUFBbEMsRUFBMEMsR0FBMUM7QUFDQyxjQUFVLEtBQUssUUFBTCxDQUFjLE9BQWQsRUFBdUIsYUFBdkIsRUFBc0MsQ0FBdEMsQ0FBVjtBQURELElBR0EsUUFBUSxZQUFSLEdBQXVCLGFBQXZCO0FBQ0EsV0FBUSxVQUFSLEdBQXVCLE9BQU8sV0FBUCxLQUF3QixRQUF6QixJQUF1QyxZQUFZLE1BQVosR0FBcUIsQ0FBN0QsR0FBbUUsV0FBbkUsR0FBaUYsYUFBdEc7QUFDQSxXQUFRLEtBQVIsR0FBaUIsT0FBTyxPQUFQLEtBQW9CLFVBQXJCLEdBQW1DLE9BQW5DLEdBQ1gsT0FBTyxPQUFQLEtBQW9CLFFBQXJCLEdBQWlDLFlBQU07QUFBRSxXQUFPLE9BQVA7QUFBaUIsSUFBMUQsR0FDQSxVQUFDLEtBQUQsRUFBVztBQUFFLFdBQU8sS0FBUDtBQUFlLElBRmhDOztBQUlBLFVBQU8sSUFBUDtBQUNBOzs7Ozs7QUFHRixPQUFPLE9BQVAsR0FBaUIsUUFBakIiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiLyoqXG4qIFByZWNlZGVudCBNZXRhLVRlbXBsYXRpbmdcbipcbiogQGxpY2Vuc2UgICAgIE1JVFxuKlxuKiBAYXV0aG9yICAgICAgU3RldmVuIFZlbG96byA8c3RldmVuQHZlbG96by5jb20+XG4qXG4qIEBkZXNjcmlwdGlvbiBQcm9jZXNzIHRleHQgc3RyZWFtcywgcGFyc2luZyBvdXQgbWV0YS10ZW1wbGF0ZSBleHByZXNzaW9ucy5cbiovXG52YXIgbGliV29yZFRyZWUgPSByZXF1aXJlKGAuL1dvcmRUcmVlLmpzYCk7XG52YXIgbGliU3RyaW5nUGFyc2VyID0gcmVxdWlyZShgLi9TdHJpbmdQYXJzZXIuanNgKTtcblxuY2xhc3MgUHJlY2VkZW50XG57XG5cdC8qKlxuXHQgKiBQcmVjZWRlbnQgQ29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHRcdHRoaXMuV29yZFRyZWUgPSBuZXcgbGliV29yZFRyZWUoKTtcblx0XHRcblx0XHR0aGlzLlN0cmluZ1BhcnNlciA9IG5ldyBsaWJTdHJpbmdQYXJzZXIoKTtcblxuXHRcdHRoaXMuUGFyc2VUcmVlID0gdGhpcy5Xb3JkVHJlZS5QYXJzZVRyZWU7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBBZGQgYSBQYXR0ZXJuIHRvIHRoZSBQYXJzZSBUcmVlXG5cdCAqIEBtZXRob2QgYWRkUGF0dGVyblxuXHQgKiBAcGFyYW0ge09iamVjdH0gcFRyZWUgLSBBIG5vZGUgb24gdGhlIHBhcnNlIHRyZWUgdG8gcHVzaCB0aGUgY2hhcmFjdGVycyBpbnRvXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwUGF0dGVybiAtIFRoZSBzdHJpbmcgdG8gYWRkIHRvIHRoZSB0cmVlXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBwSW5kZXggLSBjYWxsYmFjayBmdW5jdGlvblxuXHQgKiBAcmV0dXJuIHtib29sfSBUcnVlIGlmIGFkZGluZyB0aGUgcGF0dGVybiB3YXMgc3VjY2Vzc2Z1bFxuXHQgKi9cblx0YWRkUGF0dGVybihwUGF0dGVyblN0YXJ0LCBwUGF0dGVybkVuZCwgcFBhcnNlcilcblx0e1xuXHRcdHJldHVybiB0aGlzLldvcmRUcmVlLmFkZFBhdHRlcm4ocFBhdHRlcm5TdGFydCwgcFBhdHRlcm5FbmQsIHBQYXJzZXIpO1xuXHR9XG5cdFxuXHQvKipcblx0ICogUGFyc2UgYSBzdHJpbmcgd2l0aCB0aGUgZXhpc3RpbmcgcGFyc2UgdHJlZVxuXHQgKiBAbWV0aG9kIHBhcnNlU3RyaW5nXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwU3RyaW5nIC0gVGhlIHN0cmluZyB0byBwYXJzZVxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSByZXN1bHQgZnJvbSB0aGUgcGFyc2VyXG5cdCAqL1xuXHRwYXJzZVN0cmluZyhwU3RyaW5nKVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuU3RyaW5nUGFyc2VyLnBhcnNlU3RyaW5nKHBTdHJpbmcsIHRoaXMuUGFyc2VUcmVlKTtcblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFByZWNlZGVudDtcbiIsIi8qKlxuKiBTdHJpbmcgUGFyc2VyXG4qXG4qIEBsaWNlbnNlICAgICBNSVRcbipcbiogQGF1dGhvciAgICAgIFN0ZXZlbiBWZWxvem8gPHN0ZXZlbkB2ZWxvem8uY29tPlxuKlxuKiBAZGVzY3JpcHRpb24gUGFyc2UgYSBzdHJpbmcsIHByb3Blcmx5IHByb2Nlc3NpbmcgZWFjaCBtYXRjaGVkIHRva2VuIGluIHRoZSB3b3JkIHRyZWUuXG4qL1xuXG5jbGFzcyBTdHJpbmdQYXJzZXJcbntcblx0LyoqXG5cdCAqIFN0cmluZ1BhcnNlciBDb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBDcmVhdGUgYSBmcmVzaCBwYXJzaW5nIHN0YXRlIG9iamVjdCB0byB3b3JrIHdpdGguXG5cdCAqIEBtZXRob2QgbmV3UGFyc2VyU3RhdGVcblx0ICogQHBhcmFtIHtPYmplY3R9IHBQYXJzZVRyZWUgLSBBIG5vZGUgb24gdGhlIHBhcnNlIHRyZWUgdG8gYmVnaW4gcGFyc2luZyBmcm9tICh1c3VhbGx5IHJvb3QpXG5cdCAqIEByZXR1cm4ge09iamVjdH0gQSBuZXcgcGFyc2VyIHN0YXRlIG9iamVjdCBmb3IgcnVubmluZyBhIGNoYXJhY3RlciBwYXJzZXIgb25cblx0ICogQHByaXZhdGVcblx0ICovXG5cdG5ld1BhcnNlclN0YXRlIChwUGFyc2VUcmVlKVxuXHR7XG5cdFx0cmV0dXJuIChcblx0XHR7XG5cdFx0ICAgIFBhcnNlVHJlZTogcFBhcnNlVHJlZSxcblxuXHRcdFx0T3V0cHV0OiAnJyxcblx0XHRcdE91dHB1dEJ1ZmZlcjogJycsXG5cblx0XHRcdFBhdHRlcm46IGZhbHNlLFxuXG5cdFx0XHRQYXR0ZXJuTWF0Y2g6IGZhbHNlLFxuXHRcdFx0UGF0dGVybk1hdGNoT3V0cHV0QnVmZmVyOiAnJ1xuXHRcdH0pO1xuXHR9XG5cdFx0XG5cdC8qKlxuXHQgKiBBc3NpZ24gYSBub2RlIG9mIHRoZSBwYXJzZXIgdHJlZSB0byBiZSB0aGUgbmV4dCBwb3RlbnRpYWwgbWF0Y2guXG5cdCAqIElmIHRoZSBub2RlIGhhcyBhIFBhdHRlcm5FbmQgcHJvcGVydHksIGl0IGlzIGEgdmFsaWQgbWF0Y2ggYW5kIHN1cGVyY2VkZXMgdGhlIGxhc3QgdmFsaWQgbWF0Y2ggKG9yIGJlY29tZXMgdGhlIGluaXRpYWwgbWF0Y2gpLlxuXHQgKiBAbWV0aG9kIGFzc2lnbk5vZGVcblx0ICogQHBhcmFtIHtPYmplY3R9IHBOb2RlIC0gQSBub2RlIG9uIHRoZSBwYXJzZSB0cmVlIHRvIGFzc2lnblxuXHQgKiBAcGFyYW0ge09iamVjdH0gcFBhcnNlclN0YXRlIC0gVGhlIHN0YXRlIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgcGFyc2luZyB0YXNrXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRhc3NpZ25Ob2RlIChwTm9kZSwgcFBhcnNlclN0YXRlKVxuXHR7XG5cdFx0cFBhcnNlclN0YXRlLlBhdHRlcm5NYXRjaCA9IHBOb2RlO1xuXG5cdFx0Ly8gSWYgdGhlIHBhdHRlcm4gaGFzIGEgRU5EIHdlIGNhbiBhc3N1bWUgaXQgaGFzIGEgcGFyc2UgZnVuY3Rpb24uLi5cblx0XHRpZiAocFBhcnNlclN0YXRlLlBhdHRlcm5NYXRjaC5oYXNPd25Qcm9wZXJ0eSgnUGF0dGVybkVuZCcpKVxuXHRcdHtcblx0XHRcdC8vIC4uLiB0aGlzIGlzIHRoZSBsZWdpdGltYXRlIHN0YXJ0IG9mIGEgcGF0dGVybi5cblx0XHRcdHBQYXJzZXJTdGF0ZS5QYXR0ZXJuID0gcFBhcnNlclN0YXRlLlBhdHRlcm5NYXRjaDtcblx0XHR9XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBBcHBlbmQgYSBjaGFyYWN0ZXIgdG8gdGhlIG91dHB1dCBidWZmZXIgaW4gdGhlIHBhcnNlciBzdGF0ZS5cblx0ICogVGhpcyBvdXRwdXQgYnVmZmVyIGlzIHVzZWQgd2hlbiBhIHBvdGVudGlhbCBtYXRjaCBpcyBiZWluZyBleHBsb3JlZCwgb3IgYSBtYXRjaCBpcyBiZWluZyBleHBsb3JlZC5cblx0ICogQG1ldGhvZCBhcHBlbmRPdXRwdXRCdWZmZXJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHBDaGFyYWN0ZXIgLSBUaGUgY2hhcmFjdGVyIHRvIGFwcGVuZFxuXHQgKiBAcGFyYW0ge09iamVjdH0gcFBhcnNlclN0YXRlIC0gVGhlIHN0YXRlIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgcGFyc2luZyB0YXNrXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRhcHBlbmRPdXRwdXRCdWZmZXIgKHBDaGFyYWN0ZXIsIHBQYXJzZXJTdGF0ZSlcblx0e1xuXHRcdHBQYXJzZXJTdGF0ZS5PdXRwdXRCdWZmZXIgKz0gcENoYXJhY3Rlcjtcblx0fVxuXHRcblx0LyoqXG5cdCAqIEZsdXNoIHRoZSBvdXRwdXQgYnVmZmVyIHRvIHRoZSBvdXRwdXQgYW5kIGNsZWFyIGl0LlxuXHQgKiBAbWV0aG9kIGZsdXNoT3V0cHV0QnVmZmVyXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwUGFyc2VyU3RhdGUgLSBUaGUgc3RhdGUgb2JqZWN0IGZvciB0aGUgY3VycmVudCBwYXJzaW5nIHRhc2tcblx0ICogQHByaXZhdGVcblx0ICovXG5cdGZsdXNoT3V0cHV0QnVmZmVyIChwUGFyc2VyU3RhdGUpXG5cdHtcblx0XHRwUGFyc2VyU3RhdGUuT3V0cHV0ICs9IHBQYXJzZXJTdGF0ZS5PdXRwdXRCdWZmZXI7XG5cdFx0cFBhcnNlclN0YXRlLk91dHB1dEJ1ZmZlciA9ICcnO1xuXHR9XG5cblx0XG5cdC8qKlxuXHQgKiBDaGVjayBpZiB0aGUgcGF0dGVybiBoYXMgZW5kZWQuICBJZiBpdCBoYXMsIHByb3Blcmx5IGZsdXNoIHRoZSBidWZmZXIgYW5kIHN0YXJ0IGxvb2tpbmcgZm9yIG5ldyBwYXR0ZXJucy5cblx0ICogQG1ldGhvZCBjaGVja1BhdHRlcm5FbmRcblx0ICogQHBhcmFtIHtPYmplY3R9IHBQYXJzZXJTdGF0ZSAtIFRoZSBzdGF0ZSBvYmplY3QgZm9yIHRoZSBjdXJyZW50IHBhcnNpbmcgdGFza1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0Y2hlY2tQYXR0ZXJuRW5kIChwUGFyc2VyU3RhdGUpXG5cdHtcblx0XHRpZiAoKHBQYXJzZXJTdGF0ZS5PdXRwdXRCdWZmZXIubGVuZ3RoID49IHBQYXJzZXJTdGF0ZS5QYXR0ZXJuLlBhdHRlcm5FbmQubGVuZ3RoK3BQYXJzZXJTdGF0ZS5QYXR0ZXJuLlBhdHRlcm5TdGFydC5sZW5ndGgpICYmIFxuXHRcdFx0KHBQYXJzZXJTdGF0ZS5PdXRwdXRCdWZmZXIuc3Vic3RyKC1wUGFyc2VyU3RhdGUuUGF0dGVybi5QYXR0ZXJuRW5kLmxlbmd0aCkgPT09IHBQYXJzZXJTdGF0ZS5QYXR0ZXJuLlBhdHRlcm5FbmQpKVxuXHRcdHtcblx0XHRcdC8vIC4uLiB0aGlzIGlzIHRoZSBlbmQgb2YgYSBwYXR0ZXJuLCBjdXQgb2ZmIHRoZSBlbmQgdGFnIGFuZCBwYXJzZSBpdC5cblx0XHRcdC8vIFRyaW0gdGhlIHN0YXJ0IGFuZCBlbmQgdGFncyBvZmYgdGhlIG91dHB1dCBidWZmZXIgbm93XG5cdFx0XHRwUGFyc2VyU3RhdGUuT3V0cHV0QnVmZmVyID0gcFBhcnNlclN0YXRlLlBhdHRlcm4uUGFyc2UocFBhcnNlclN0YXRlLk91dHB1dEJ1ZmZlci5zdWJzdHIocFBhcnNlclN0YXRlLlBhdHRlcm4uUGF0dGVyblN0YXJ0Lmxlbmd0aCwgcFBhcnNlclN0YXRlLk91dHB1dEJ1ZmZlci5sZW5ndGggLSAocFBhcnNlclN0YXRlLlBhdHRlcm4uUGF0dGVyblN0YXJ0Lmxlbmd0aCtwUGFyc2VyU3RhdGUuUGF0dGVybi5QYXR0ZXJuRW5kLmxlbmd0aCkpKTtcblx0XHRcdC8vIEZsdXNoIHRoZSBvdXRwdXQgYnVmZmVyLlxuXHRcdFx0dGhpcy5mbHVzaE91dHB1dEJ1ZmZlcihwUGFyc2VyU3RhdGUpO1xuXHRcdFx0Ly8gRW5kIHBhdHRlcm4gbW9kZVxuXHRcdFx0cFBhcnNlclN0YXRlLlBhdHRlcm4gPSBmYWxzZTtcblx0XHRcdHBQYXJzZXJTdGF0ZS5QYXR0ZXJuTWF0Y2ggPSBmYWxzZTtcblx0XHR9XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBQYXJzZSBhIGNoYXJhY3RlciBpbiB0aGUgYnVmZmVyLlxuXHQgKiBAbWV0aG9kIHBhcnNlQ2hhcmFjdGVyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwQ2hhcmFjdGVyIC0gVGhlIGNoYXJhY3RlciB0byBhcHBlbmRcblx0ICogQHBhcmFtIHtPYmplY3R9IHBQYXJzZXJTdGF0ZSAtIFRoZSBzdGF0ZSBvYmplY3QgZm9yIHRoZSBjdXJyZW50IHBhcnNpbmcgdGFza1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0cGFyc2VDaGFyYWN0ZXIgKHBDaGFyYWN0ZXIsIHBQYXJzZXJTdGF0ZSlcblx0e1xuXHRcdC8vICgxKSBJZiB3ZSBhcmVuJ3QgaW4gYSBwYXR0ZXJuIG1hdGNoLCBhbmQgd2UgYXJlbid0IHBvdGVudGlhbGx5IG1hdGNoaW5nLCBhbmQgdGhpcyBtYXkgYmUgdGhlIHN0YXJ0IG9mIGEgbmV3IHBhdHRlcm4uLi4uXG5cdFx0aWYgKCFwUGFyc2VyU3RhdGUuUGF0dGVybk1hdGNoICYmIHBQYXJzZXJTdGF0ZS5QYXJzZVRyZWUuaGFzT3duUHJvcGVydHkocENoYXJhY3RlcikpXG5cdFx0e1xuXHRcdFx0Ly8gLi4uIGFzc2lnbiB0aGUgbm9kZSBhcyB0aGUgbWF0Y2hlZCBub2RlLlxuXHRcdFx0dGhpcy5hc3NpZ25Ob2RlKHBQYXJzZXJTdGF0ZS5QYXJzZVRyZWVbcENoYXJhY3Rlcl0sIHBQYXJzZXJTdGF0ZSk7XG5cdFx0XHR0aGlzLmFwcGVuZE91dHB1dEJ1ZmZlcihwQ2hhcmFjdGVyLCBwUGFyc2VyU3RhdGUpO1xuXHRcdH1cblx0XHQvLyAoMikgSWYgd2UgYXJlIGluIGEgcGF0dGVybiBtYXRjaCAoYWN0aXZlbHkgc2VlaW5nIGlmIHRoaXMgaXMgcGFydCBvZiBhIG5ldyBwYXR0ZXJuIHRva2VuKVxuXHRcdGVsc2UgaWYgKHBQYXJzZXJTdGF0ZS5QYXR0ZXJuTWF0Y2gpXG5cdFx0e1xuXHRcdFx0Ly8gSWYgdGhlIHBhdHRlcm4gaGFzIGEgc3VicGF0dGVybiB3aXRoIHRoaXMga2V5XG5cdFx0XHRpZiAocFBhcnNlclN0YXRlLlBhdHRlcm5NYXRjaC5oYXNPd25Qcm9wZXJ0eShwQ2hhcmFjdGVyKSlcblx0XHRcdHtcblx0XHRcdFx0Ly8gQ29udGludWUgbWF0Y2hpbmcgcGF0dGVybnMuXG5cdFx0XHRcdHRoaXMuYXNzaWduTm9kZShwUGFyc2VyU3RhdGUuUGF0dGVybk1hdGNoW3BDaGFyYWN0ZXJdLCBwUGFyc2VyU3RhdGUpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5hcHBlbmRPdXRwdXRCdWZmZXIocENoYXJhY3RlciwgcFBhcnNlclN0YXRlKTtcblx0XHRcdGlmIChwUGFyc2VyU3RhdGUuUGF0dGVybilcblx0XHRcdHtcblx0XHRcdFx0Ly8gLi4uIENoZWNrIGlmIHRoaXMgaXMgdGhlIGVuZCBvZiB0aGUgcGF0dGVybiAoaWYgd2UgYXJlIG1hdGNoaW5nIGEgdmFsaWQgcGF0dGVybikuLi5cblx0XHRcdFx0dGhpcy5jaGVja1BhdHRlcm5FbmQocFBhcnNlclN0YXRlKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gKDMpIElmIHdlIGFyZW4ndCBpbiBhIHBhdHRlcm4gbWF0Y2ggb3IgcGF0dGVybiwgYW5kIHRoaXMgaXNuJ3QgdGhlIHN0YXJ0IG9mIGEgbmV3IHBhdHRlcm4gKFJBVyBtb2RlKS4uLi5cblx0XHRlbHNlXG5cdFx0e1xuXHRcdFx0cFBhcnNlclN0YXRlLk91dHB1dCArPSBwQ2hhcmFjdGVyO1xuXHRcdH1cblx0fVxuXHRcblx0LyoqXG5cdCAqIFBhcnNlIGEgc3RyaW5nIGZvciBtYXRjaGVzLCBhbmQgcHJvY2VzcyBhbnkgdGVtcGxhdGUgc2VnbWVudHMgdGhhdCBvY2N1ci5cblx0ICogQG1ldGhvZCBwYXJzZVN0cmluZ1xuXHQgKiBAcGFyYW0ge3N0cmluZ30gcFN0cmluZyAtIFRoZSBzdHJpbmcgdG8gcGFyc2UuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwUGFyc2VUcmVlIC0gVGhlIHBhcnNlIHRyZWUgdG8gYmVnaW4gcGFyc2luZyBmcm9tICh1c3VhbGx5IHJvb3QpXG5cdCAqL1xuXHRwYXJzZVN0cmluZyAocFN0cmluZywgcFBhcnNlVHJlZSlcblx0e1xuXHRcdGxldCB0bXBQYXJzZXJTdGF0ZSA9IHRoaXMubmV3UGFyc2VyU3RhdGUocFBhcnNlVHJlZSk7XG5cblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHBTdHJpbmcubGVuZ3RoOyBpKyspXG5cdFx0e1xuXHRcdFx0Ly8gVE9ETzogVGhpcyBpcyBub3QgZmFzdC5cblx0XHRcdHRoaXMucGFyc2VDaGFyYWN0ZXIocFN0cmluZ1tpXSwgdG1wUGFyc2VyU3RhdGUpO1xuXHRcdH1cblx0XHRcblx0XHR0aGlzLmZsdXNoT3V0cHV0QnVmZmVyKHRtcFBhcnNlclN0YXRlKTtcblx0XHRcblx0XHRyZXR1cm4gdG1wUGFyc2VyU3RhdGUuT3V0cHV0O1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gU3RyaW5nUGFyc2VyO1xuIiwiLyoqXG4qIFdvcmQgVHJlZVxuKlxuKiBAbGljZW5zZSAgICAgTUlUXG4qXG4qIEBhdXRob3IgICAgICBTdGV2ZW4gVmVsb3pvIDxzdGV2ZW5AdmVsb3pvLmNvbT5cbipcbiogQGRlc2NyaXB0aW9uIENyZWF0ZSBhIHRyZWUgKGRpcmVjdGVkIGdyYXBoKSBvZiBKYXZhc2NyaXB0IG9iamVjdHMsIG9uZSBjaGFyYWN0ZXIgcGVyIG9iamVjdC5cbiovXG5cbmNsYXNzIFdvcmRUcmVlXG57XG5cdC8qKlxuXHQgKiBXb3JkVHJlZSBDb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdFx0dGhpcy5QYXJzZVRyZWUgPSB7fTtcblx0fVxuXHRcblx0LyoqIFxuXHQgKiBBZGQgYSBjaGlsZCBjaGFyYWN0ZXIgdG8gYSBQYXJzZSBUcmVlIG5vZGVcblx0ICogQG1ldGhvZCBhZGRDaGlsZFxuXHQgKiBAcGFyYW0ge09iamVjdH0gcFRyZWUgLSBBIHBhcnNlIHRyZWUgdG8gcHVzaCB0aGUgY2hhcmFjdGVycyBpbnRvXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwUGF0dGVybiAtIFRoZSBzdHJpbmcgdG8gYWRkIHRvIHRoZSB0cmVlXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBwSW5kZXggLSBjYWxsYmFjayBmdW5jdGlvblxuXHQgKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgcmVzdWx0aW5nIGxlYWYgbm9kZSB0aGF0IHdhcyBhZGRlZCAob3IgZm91bmQpXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRhZGRDaGlsZCAocFRyZWUsIHBQYXR0ZXJuLCBwSW5kZXgpXG5cdHtcblx0XHRpZiAocEluZGV4ID4gcFBhdHRlcm4ubGVuZ3RoKVxuXHRcdFx0cmV0dXJuIHBUcmVlO1xuXHRcdFxuXHRcdGlmICghcFRyZWUuaGFzT3duUHJvcGVydHkocFBhdHRlcm5bcEluZGV4XSkpXG5cdFx0XHRwVHJlZVtwUGF0dGVybltwSW5kZXhdXSA9IHt9O1xuXHRcdFxuXHRcdHJldHVybiBwVHJlZVtwUGF0dGVybltwSW5kZXhdXTtcblx0fVxuXHRcblx0LyoqIEFkZCBhIFBhdHRlcm4gdG8gdGhlIFBhcnNlIFRyZWVcblx0ICogQG1ldGhvZCBhZGRQYXR0ZXJuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwVHJlZSAtIEEgbm9kZSBvbiB0aGUgcGFyc2UgdHJlZSB0byBwdXNoIHRoZSBjaGFyYWN0ZXJzIGludG9cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBQYXR0ZXJuIC0gVGhlIHN0cmluZyB0byBhZGQgdG8gdGhlIHRyZWVcblx0ICogQHBhcmFtIHtudW1iZXJ9IHBJbmRleCAtIGNhbGxiYWNrIGZ1bmN0aW9uXG5cdCAqIEByZXR1cm4ge2Jvb2x9IFRydWUgaWYgYWRkaW5nIHRoZSBwYXR0ZXJuIHdhcyBzdWNjZXNzZnVsXG5cdCAqL1xuXHRhZGRQYXR0ZXJuIChwUGF0dGVyblN0YXJ0LCBwUGF0dGVybkVuZCwgcFBhcnNlcilcblx0e1xuXHRcdGlmIChwUGF0dGVyblN0YXJ0Lmxlbmd0aCA8IDEpXG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cblx0XHRsZXQgdG1wTGVhZiA9IHRoaXMuUGFyc2VUcmVlO1xuXG5cdFx0Ly8gQWRkIHRoZSB0cmVlIG9mIGxlYXZlcyBpdGVyYXRpdmVseVxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgcFBhdHRlcm5TdGFydC5sZW5ndGg7IGkrKylcblx0XHRcdHRtcExlYWYgPSB0aGlzLmFkZENoaWxkKHRtcExlYWYsIHBQYXR0ZXJuU3RhcnQsIGkpO1xuXG5cdFx0dG1wTGVhZi5QYXR0ZXJuU3RhcnQgPSBwUGF0dGVyblN0YXJ0O1xuXHRcdHRtcExlYWYuUGF0dGVybkVuZCA9ICgodHlwZW9mKHBQYXR0ZXJuRW5kKSA9PT0gJ3N0cmluZycpICYmIChwUGF0dGVybkVuZC5sZW5ndGggPiAwKSkgPyBwUGF0dGVybkVuZCA6IHBQYXR0ZXJuU3RhcnQ7XG5cdFx0dG1wTGVhZi5QYXJzZSA9ICh0eXBlb2YocFBhcnNlcikgPT09ICdmdW5jdGlvbicpID8gcFBhcnNlciA6IFxuXHRcdFx0XHRcdFx0KHR5cGVvZihwUGFyc2VyKSA9PT0gJ3N0cmluZycpID8gKCkgPT4geyByZXR1cm4gcFBhcnNlcjsgfSA6XG5cdFx0XHRcdFx0XHQocERhdGEpID0+IHsgcmV0dXJuIHBEYXRhOyB9O1xuXG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXb3JkVHJlZTtcbiJdfQ==
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"name": "Launch Debug Harness",
|
|
9
|
+
"type": "pwa-node",
|
|
10
|
+
"request": "launch",
|
|
11
|
+
"outputCapture": "std",
|
|
12
|
+
"skipFiles": [
|
|
13
|
+
"<node_internals>/**"
|
|
14
|
+
],
|
|
15
|
+
"program": "${workspaceFolder}/debug/Harness.js",
|
|
16
|
+
"presentation": {
|
|
17
|
+
"hidden": false,
|
|
18
|
+
"group": "",
|
|
19
|
+
"order": 1
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "Mocha Tests",
|
|
24
|
+
"args": [
|
|
25
|
+
"-u",
|
|
26
|
+
"tdd",
|
|
27
|
+
"--timeout",
|
|
28
|
+
"999999",
|
|
29
|
+
"--colors",
|
|
30
|
+
"${workspaceFolder}/test"
|
|
31
|
+
],
|
|
32
|
+
"internalConsoleOptions": "openOnSessionStart",
|
|
33
|
+
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
|
|
34
|
+
"request": "launch",
|
|
35
|
+
"skipFiles": [
|
|
36
|
+
"<node_internals>/**"
|
|
37
|
+
],
|
|
38
|
+
"type": "pwa-node",
|
|
39
|
+
"presentation": {
|
|
40
|
+
"hidden": false,
|
|
41
|
+
"group": "",
|
|
42
|
+
"order": 2
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Use the codercom/code-server image
|
|
2
|
+
FROM codercom/code-server:latest
|
|
3
|
+
MAINTAINER steven velozo
|
|
4
|
+
|
|
5
|
+
VOLUME /home/coder/.config
|
|
6
|
+
VOLUME /home/coder/.vscode
|
|
7
|
+
|
|
8
|
+
RUN echo "...installing debian dependencies..."
|
|
9
|
+
RUN sudo apt update
|
|
10
|
+
RUN sudo apt install vim curl tmux -y
|
|
11
|
+
|
|
12
|
+
RUN echo "Building development image..."
|
|
13
|
+
|
|
14
|
+
RUN echo "...installing vscode extensions..."
|
|
15
|
+
RUN code-server --install-extension ritwickdey.LiveServer \
|
|
16
|
+
code-server --install-extension hbenl.vscode-mocha-test-adapter \
|
|
17
|
+
code-server --install-extension hbenl.vscode-test-explorer \
|
|
18
|
+
code-server --install-extension hbenl.test-adapter-converter \
|
|
19
|
+
code-server --install-extension daylerees.rainglow \
|
|
20
|
+
code-server --install-extension oderwat.indent-rainbow
|
|
21
|
+
|
|
22
|
+
RUN echo "...mapping library specific volumes..."
|
|
23
|
+
# Volume mappings for code
|
|
24
|
+
VOLUME /home/coder/YOURLIBRARYNAMEHERE
|
|
25
|
+
# VOLUME /home/coder/YOURLIBRARYNAMEHERE/node_modules
|
|
26
|
+
|
|
27
|
+
SHELL ["/bin/bash", "-c"]
|
|
28
|
+
USER coder
|
|
29
|
+
|
|
30
|
+
RUN echo "...installing node version manager..."
|
|
31
|
+
# Because there is a .bashrc chicken/egg problem, we will create one here to simulate logging in. This is not great.
|
|
32
|
+
RUN touch ~/.bashrc && chmod +x ~/.bashrc
|
|
33
|
+
RUN curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
|
|
34
|
+
|
|
35
|
+
RUN echo "...installing node version 14 as the default..."
|
|
36
|
+
RUN . ~/.nvm/nvm.sh && source ~/.bashrc && nvm install 14
|
|
37
|
+
RUN . ~/.nvm/nvm.sh && source ~/.bashrc && nvm alias default 14
|
|
38
|
+
|
|
39
|
+
WORKDIR /home/coder/YOURLIBRARYNAMEHERE
|