diff --git a/.vagrant/machines/default/virtualbox/action_set_name b/.vagrant/machines/default/virtualbox/action_set_name new file mode 100644 index 00000000..5fac2784 --- /dev/null +++ b/.vagrant/machines/default/virtualbox/action_set_name @@ -0,0 +1 @@ +1603378776 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/creator_uid b/.vagrant/machines/default/virtualbox/creator_uid new file mode 100644 index 00000000..e37d32ab --- /dev/null +++ b/.vagrant/machines/default/virtualbox/creator_uid @@ -0,0 +1 @@ +1000 \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/id b/.vagrant/machines/default/virtualbox/id new file mode 100644 index 00000000..9dda7302 --- /dev/null +++ b/.vagrant/machines/default/virtualbox/id @@ -0,0 +1 @@ +ed29e797-7ce8-4059-8e00-c212b0b4e26d \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/index_uuid b/.vagrant/machines/default/virtualbox/index_uuid new file mode 100644 index 00000000..0979f16d --- /dev/null +++ b/.vagrant/machines/default/virtualbox/index_uuid @@ -0,0 +1 @@ +5511a5040f9649188ea4b617db9be33d \ No newline at end of file diff --git a/.vagrant/machines/default/virtualbox/vagrant_cwd b/.vagrant/machines/default/virtualbox/vagrant_cwd new file mode 100644 index 00000000..9e4c8c98 --- /dev/null +++ b/.vagrant/machines/default/virtualbox/vagrant_cwd @@ -0,0 +1 @@ +/home/alpcentaur/ProjektA/PrototypeWebApp \ No newline at end of file diff --git a/.vagrant/rgloader/loader.rb b/.vagrant/rgloader/loader.rb new file mode 100644 index 00000000..c3c05b09 --- /dev/null +++ b/.vagrant/rgloader/loader.rb @@ -0,0 +1,9 @@ +# This file loads the proper rgloader/loader.rb file that comes packaged +# with Vagrant so that encoded files can properly run with Vagrant. + +if ENV["VAGRANT_INSTALLER_EMBEDDED_DIR"] + require File.expand_path( + "rgloader/loader", ENV["VAGRANT_INSTALLER_EMBEDDED_DIR"]) +else + raise "Encoded files can't be read outside of the Vagrant installer." +end diff --git a/cuda-repo-ubuntu1804_10.1.243-1_amd64.deb b/cuda-repo-ubuntu1804_10.1.243-1_amd64.deb new file mode 100644 index 00000000..9010cfbf Binary files /dev/null and b/cuda-repo-ubuntu1804_10.1.243-1_amd64.deb differ diff --git a/nodefrontend/Prototyp.html b/nodefrontend/Prototyp.html new file mode 100644 index 00000000..15d73806 --- /dev/null +++ b/nodefrontend/Prototyp.html @@ -0,0 +1,826 @@ + + + +Prototyp Leichte Sprache + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Ein Klick auf das Logo - und es geht zum Code

+ + + + + + + + + + + +
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+ +
+ +
+
+
+ + + + + + + + + + diff --git a/nodefrontend/jslib/pathformer.js b/nodefrontend/jslib/pathformer.js new file mode 100644 index 00000000..922fd780 --- /dev/null +++ b/nodefrontend/jslib/pathformer.js @@ -0,0 +1,276 @@ + 'use strict'; + + /** + * Pathformer + * Beta version + * + * Take any SVG version 1.1 and transform + * child elements to 'path' elements + * + * This code is purely forked from + * https://github.com/Waest/SVGPathConverter + */ + + /** + * Class constructor + * + * @param {DOM|String} element Dom element of the SVG or id of it + */ + function Pathformer(element) { + // Test params + if (typeof element === 'undefined') { + throw new Error('Pathformer [constructor]: "element" parameter is required'); + } + + // Set the element + if (element.constructor === String) { + element = document.getElementById(element); + if (!element) { + throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID'); + } + } + if (element instanceof window.SVGElement || + element instanceof window.SVGGElement || + /^svg$/i.test(element.nodeName)) { + this.el = element; + } else { + throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'); + } + + // Start + this.scan(element); + } + + /** + * List of tags which can be transformed + * to path elements + * + * @type {Array} + */ + Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect']; + + /** + * List of attribute names which contain + * data. This array list them to check if + * they contain bad values, like percentage. + * + * @type {Array} + */ + Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', 'y1', 'y2']; + + /** + * Finds the elements compatible for transform + * and apply the liked method + * + * @param {object} options Object from the constructor + */ + Pathformer.prototype.scan = function (svg) { + var fn, element, pathData, pathDom, + elements = svg.querySelectorAll(this.TYPES.join(',')); + + for (var i = 0; i < elements.length; i++) { + element = elements[i]; + fn = this[element.tagName.toLowerCase() + 'ToPath']; + pathData = fn(this.parseAttr(element.attributes)); + pathDom = this.pathMaker(element, pathData); + element.parentNode.replaceChild(pathDom, element); + } + }; + + + /** + * Read `line` element to extract and transform + * data, to make it ready for a `path` object. + * + * @param {DOMelement} element Line element to transform + * @return {object} Data for a `path` element + */ + Pathformer.prototype.lineToPath = function (element) { + var newElement = {}, + x1 = element.x1 || 0, + y1 = element.y1 || 0, + x2 = element.x2 || 0, + y2 = element.y2 || 0; + + newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2; + return newElement; + }; + + /** + * Read `rect` element to extract and transform + * data, to make it ready for a `path` object. + * The radius-border is not taken in charge yet. + * (your help is more than welcomed) + * + * @param {DOMelement} element Rect element to transform + * @return {object} Data for a `path` element + */ + Pathformer.prototype.rectToPath = function (element) { + var newElement = {}, + x = parseFloat(element.x) || 0, + y = parseFloat(element.y) || 0, + width = parseFloat(element.width) || 0, + height = parseFloat(element.height) || 0; + + if (element.rx || element.ry) { + var rx = parseInt(element.rx, 10) || -1, + ry = parseInt(element.ry, 10) || -1; + rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2); + ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2); + + newElement.d = 'M ' + (x + rx) + ',' + y + ' ' + + 'L ' + (x + width - rx) + ',' + y + ' ' + + 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' + + 'L ' + (x + width) + ',' + (y + height - ry) + ' ' + + 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' + + 'L ' + (x + rx) + ',' + (y + height) + ' ' + + 'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' + + 'L ' + x + ',' + (y + ry) + ' ' + + 'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y; + } + else { + newElement.d = 'M' + x + ' ' + y + ' ' + + 'L' + (x + width) + ' ' + y + ' ' + + 'L' + (x + width) + ' ' + (y + height) + ' ' + + 'L' + x + ' ' + (y + height) + ' Z'; + } + return newElement; + }; + + /** + * Read `polyline` element to extract and transform + * data, to make it ready for a `path` object. + * + * @param {DOMelement} element Polyline element to transform + * @return {object} Data for a `path` element + */ + Pathformer.prototype.polylineToPath = function (element) { + var newElement = {}, + points = element.points.trim().split(' '), + i, path; + + // Reformatting if points are defined without commas + if (element.points.indexOf(',') === -1) { + var formattedPoints = []; + for (i = 0; i < points.length; i+=2) { + formattedPoints.push(points[i] + ',' + points[i+1]); + } + points = formattedPoints; + } + + // Generate the path.d value + path = 'M' + points[0]; + for(i = 1; i < points.length; i++) { + if (points[i].indexOf(',') !== -1) { + path += 'L' + points[i]; + } + } + newElement.d = path; + return newElement; + }; + + /** + * Read `polygon` element to extract and transform + * data, to make it ready for a `path` object. + * This method rely on polylineToPath, because the + * logic is similar. The path created is just closed, + * so it needs an 'Z' at the end. + * + * @param {DOMelement} element Polygon element to transform + * @return {object} Data for a `path` element + */ + Pathformer.prototype.polygonToPath = function (element) { + var newElement = Pathformer.prototype.polylineToPath(element); + + newElement.d += 'Z'; + return newElement; + }; + + /** + * Read `ellipse` element to extract and transform + * data, to make it ready for a `path` object. + * + * @param {DOMelement} element ellipse element to transform + * @return {object} Data for a `path` element + */ + Pathformer.prototype.ellipseToPath = function (element) { + var newElement = {}, + rx = parseFloat(element.rx) || 0, + ry = parseFloat(element.ry) || 0, + cx = parseFloat(element.cx) || 0, + cy = parseFloat(element.cy) || 0, + startX = cx - rx, + startY = cy, + endX = parseFloat(cx) + parseFloat(rx), + endY = cy; + + newElement.d = 'M' + startX + ',' + startY + + 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY + + 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY; + return newElement; + }; + + /** + * Read `circle` element to extract and transform + * data, to make it ready for a `path` object. + * + * @param {DOMelement} element Circle element to transform + * @return {object} Data for a `path` element + */ + Pathformer.prototype.circleToPath = function (element) { + var newElement = {}, + r = parseFloat(element.r) || 0, + cx = parseFloat(element.cx) || 0, + cy = parseFloat(element.cy) || 0, + startX = cx - r, + startY = cy, + endX = parseFloat(cx) + parseFloat(r), + endY = cy; + + newElement.d = 'M' + startX + ',' + startY + + 'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY + + 'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY; + return newElement; + }; + + /** + * Create `path` elements form original element + * and prepared objects + * + * @param {DOMelement} element Original element to transform + * @param {object} pathData Path data (from `toPath` methods) + * @return {DOMelement} Path element + */ + Pathformer.prototype.pathMaker = function (element, pathData) { + var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path'); + for(i = 0; i < element.attributes.length; i++) { + attr = element.attributes[i]; + if (this.ATTR_WATCH.indexOf(attr.name) === -1) { + pathTag.setAttribute(attr.name, attr.value); + } + } + for(i in pathData) { + pathTag.setAttribute(i, pathData[i]); + } + return pathTag; + }; + + /** + * Parse attributes of a DOM element to + * get an object of attribute => value + * + * @param {NamedNodeMap} attributes Attributes object from DOM element to parse + * @return {object} Object of attributes + */ + Pathformer.prototype.parseAttr = function (element) { + var attr, output = {}; + for (var i = 0; i < element.length; i++) { + attr = element[i]; + // Check if no data attribute contains '%', or the transformation is impossible + if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) { + throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.'); + } + output[attr.name] = attr.value; + } + return output; + }; diff --git a/nodefrontend/jslib/vivus.js b/nodefrontend/jslib/vivus.js new file mode 100644 index 00000000..dc0c8615 --- /dev/null +++ b/nodefrontend/jslib/vivus.js @@ -0,0 +1,859 @@ + 'use strict'; + + var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt; + + /** + * Vivus + * Beta version + * + * Take any SVG and make the animation + * to give give the impression of live drawing + * + * This in more than just inspired from codrops + * At that point, it's a pure fork. + */ + + /** + * Class constructor + * option structure + * type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed) + * duration: (in frames) + * start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport) + * delay: (delay between the drawing of first and last path) + * dashGap whitespace extra margin between dashes + * pathTimingFunction timing animation function for each path element of the SVG + * animTimingFunction timing animation function for the complete SVG + * forceRender force the browser to re-render all updated path items + * selfDestroy removes all extra styling on the SVG, and leaves it as original + * + * The attribute 'type' is by default on 'delayed'. + * - 'delayed' + * all paths are draw at the same time but with a + * little delay between them before start + * - 'sync' + * all path are start and finish at the same time + * - 'oneByOne' + * only one path is draw at the time + * the end of the first one will trigger the draw + * of the next one + * + * All these values can be overwritten individually + * for each path item in the SVG + * The value of frames will always take the advantage of + * the duration value. + * If you fail somewhere, an error will be thrown. + * Good luck. + * + * @constructor + * @this {Vivus} + * @param {DOM|String} element Dom element of the SVG or id of it + * @param {Object} options Options about the animation + * @param {Function} callback Callback for the end of the animation + */ + function Vivus(element, options, callback) { + setupEnv(); + + // Setup + this.isReady = false; + this.setElement(element, options); + this.setOptions(options); + this.setCallback(callback); + + if (this.isReady) { + this.init(); + } + } + + /** + * Timing functions + ************************************** + * + * Default functions to help developers. + * It always take a number as parameter (between 0 to 1) then + * return a number (between 0 and 1) + */ + Vivus.LINEAR = function(x) { + return x; + }; + Vivus.EASE = function(x) { + return -Math.cos(x * Math.PI) / 2 + 0.5; + }; + Vivus.EASE_OUT = function(x) { + return 1 - Math.pow(1 - x, 3); + }; + Vivus.EASE_IN = function(x) { + return Math.pow(x, 3); + }; + Vivus.EASE_OUT_BOUNCE = function(x) { + var base = -Math.cos(x * (0.5 * Math.PI)) + 1, + rate = Math.pow(base, 1.5), + rateR = Math.pow(1 - x, 2), + progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI))) + 1; + return 1 - rateR + progress * rateR; + }; + + /** + * Setters + ************************************** + */ + + /** + * Check and set the element in the instance + * The method will not return anything, but will throw an + * error if the parameter is invalid + * + * @param {DOM|String} element SVG Dom element or id of it + */ + Vivus.prototype.setElement = function(element, options) { + var onLoad, self; + + // Basic check + if (typeof element === 'undefined') { + throw new Error('Vivus [constructor]: "element" parameter is required'); + } + + // Set the element + if (element.constructor === String) { + element = document.getElementById(element); + if (!element) { + throw new Error( + 'Vivus [constructor]: "element" parameter is not related to an existing ID' + ); + } + } + this.parentEl = element; + + // Load the SVG with XMLHttpRequest and extract the SVG + if (options && options.file) { + self = this; + onLoad = function() { + var domSandbox = document.createElement('div'); + domSandbox.innerHTML = this.responseText; + + var svgTag = domSandbox.querySelector('svg'); + if (!svgTag) { + throw new Error( + 'Vivus [load]: Cannot find the SVG in the loaded file : ' + + options.file + ); + } + + self.el = svgTag; + self.el.setAttribute('width', '100%'); + self.el.setAttribute('height', '100%'); + self.parentEl.appendChild(self.el); + self.isReady = true; + self.init(); + self = null; + }; + + var oReq = new window.XMLHttpRequest(); + oReq.addEventListener('load', onLoad); + oReq.open('GET', options.file); + oReq.send(); + return; + } + + switch (element.constructor) { + case window.SVGSVGElement: + case window.SVGElement: + case window.SVGGElement: + this.el = element; + this.isReady = true; + break; + + case window.HTMLObjectElement: + self = this; + onLoad = function(e) { + if (self.isReady) { + return; + } + self.el = + element.contentDocument && + element.contentDocument.querySelector('svg'); + if (!self.el && e) { + throw new Error( + 'Vivus [constructor]: object loaded does not contain any SVG' + ); + } else if (self.el) { + if (element.getAttribute('built-by-vivus')) { + self.parentEl.insertBefore(self.el, element); + self.parentEl.removeChild(element); + self.el.setAttribute('width', '100%'); + self.el.setAttribute('height', '100%'); + } + self.isReady = true; + self.init(); + self = null; + } + }; + + if (!onLoad()) { + element.addEventListener('load', onLoad); + } + break; + + default: + throw new Error( + 'Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)' + ); + } + }; + + /** + * Set up user option to the instance + * The method will not return anything, but will throw an + * error if the parameter is invalid + * + * @param {object} options Object from the constructor + */ + Vivus.prototype.setOptions = function(options) { + var allowedTypes = [ + 'delayed', + 'sync', + 'async', + 'nsync', + 'oneByOne', + 'scenario', + 'scenario-sync' + ]; + var allowedStarts = ['inViewport', 'manual', 'autostart']; + + // Basic check + if (options !== undefined && options.constructor !== Object) { + throw new Error( + 'Vivus [constructor]: "options" parameter must be an object' + ); + } else { + options = options || {}; + } + + // Set the animation type + if (options.type && allowedTypes.indexOf(options.type) === -1) { + throw new Error( + 'Vivus [constructor]: ' + + options.type + + ' is not an existing animation `type`' + ); + } else { + this.type = options.type || allowedTypes[0]; + } + + // Set the start type + if (options.start && allowedStarts.indexOf(options.start) === -1) { + throw new Error( + 'Vivus [constructor]: ' + + options.start + + ' is not an existing `start` option' + ); + } else { + this.start = options.start || allowedStarts[0]; + } + + this.isIE = + window.navigator.userAgent.indexOf('MSIE') !== -1 || + window.navigator.userAgent.indexOf('Trident/') !== -1 || + window.navigator.userAgent.indexOf('Edge/') !== -1; + this.duration = parsePositiveInt(options.duration, 120); + this.delay = parsePositiveInt(options.delay, null); + this.dashGap = parsePositiveInt(options.dashGap, 1); + this.forceRender = options.hasOwnProperty('forceRender') + ? !!options.forceRender + : this.isIE; + this.reverseStack = !!options.reverseStack; + this.selfDestroy = !!options.selfDestroy; + this.onReady = options.onReady; + this.map = []; + this.frameLength = this.currentFrame = this.delayUnit = this.speed = this.handle = null; + + this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') + ? !!options.ignoreInvisible + : false; + + this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR; + this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR; + + if (this.delay >= this.duration) { + throw new Error('Vivus [constructor]: delay must be shorter than duration'); + } + }; + + /** + * Set up callback to the instance + * The method will not return enything, but will throw an + * error if the parameter is invalid + * + * @param {Function} callback Callback for the animation end + */ + Vivus.prototype.setCallback = function(callback) { + // Basic check + if (!!callback && callback.constructor !== Function) { + throw new Error( + 'Vivus [constructor]: "callback" parameter must be a function' + ); + } + this.callback = callback || function() {}; + }; + + /** + * Core + ************************************** + */ + + /** + * Map the svg, path by path. + * The method return nothing, it just fill the + * `map` array. Each item in this array represent + * a path element from the SVG, with informations for + * the animation. + * + * ``` + * [ + * { + * el: the path element + * length: length of the path line + * startAt: time start of the path animation (in frames) + * duration: path animation duration (in frames) + * }, + * ... + * ] + * ``` + * + */ + Vivus.prototype.mapping = function() { + var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint; + timePoint = totalLength = lengthMeter = 0; + paths = this.el.querySelectorAll('path'); + + for (i = 0; i < paths.length; i++) { + path = paths[i]; + if (this.isInvisible(path)) { + continue; + } + pathObj = { + el: path, + length: Math.ceil(path.getTotalLength()) + }; + // Test if the path length is correct + if (isNaN(pathObj.length)) { + if (window.console && console.warn) { + console.warn( + 'Vivus [mapping]: cannot retrieve a path element length', + path + ); + } + continue; + } + this.map.push(pathObj); + path.style.strokeDasharray = + pathObj.length + ' ' + (pathObj.length + this.dashGap * 2); + path.style.strokeDashoffset = pathObj.length + this.dashGap; + pathObj.length += this.dashGap; + totalLength += pathObj.length; + + this.renderPath(i); + } + + totalLength = totalLength === 0 ? 1 : totalLength; + this.delay = this.delay === null ? this.duration / 3 : this.delay; + this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1); + + // Reverse stack if asked + if (this.reverseStack) { + this.map.reverse(); + } + + for (i = 0; i < this.map.length; i++) { + pathObj = this.map[i]; + + switch (this.type) { + case 'delayed': + pathObj.startAt = this.delayUnit * i; + pathObj.duration = this.duration - this.delay; + break; + + case 'oneByOne': + pathObj.startAt = (lengthMeter / totalLength) * this.duration; + pathObj.duration = (pathObj.length / totalLength) * this.duration; + break; + + case 'sync': + case 'async': + case 'nsync': + pathObj.startAt = 0; + pathObj.duration = this.duration; + break; + + case 'scenario-sync': + path = pathObj.el; + pAttrs = this.parseAttr(path); + pathObj.startAt = + timePoint + + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0); + pathObj.duration = parsePositiveInt( + pAttrs['data-duration'], + this.duration + ); + timePoint = + pAttrs['data-async'] !== undefined + ? pathObj.startAt + : pathObj.startAt + pathObj.duration; + this.frameLength = Math.max( + this.frameLength, + pathObj.startAt + pathObj.duration + ); + break; + + case 'scenario': + path = pathObj.el; + pAttrs = this.parseAttr(path); + pathObj.startAt = + parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0; + pathObj.duration = parsePositiveInt( + pAttrs['data-duration'], + this.duration + ); + this.frameLength = Math.max( + this.frameLength, + pathObj.startAt + pathObj.duration + ); + break; + } + lengthMeter += pathObj.length; + this.frameLength = this.frameLength || this.duration; + } + }; + + /** + * Interval method to draw the SVG from current + * position of the animation. It update the value of + * `currentFrame` and re-trace the SVG. + * + * It use this.handle to store the requestAnimationFrame + * and clear it one the animation is stopped. So this + * attribute can be used to know if the animation is + * playing. + * + * Once the animation at the end, this method will + * trigger the Vivus callback. + * + */ + Vivus.prototype.drawer = function() { + var self = this; + this.currentFrame += this.speed; + + if (this.currentFrame <= 0) { + this.stop(); + this.reset(); + } else if (this.currentFrame >= this.frameLength) { + this.stop(); + this.currentFrame = this.frameLength; + this.trace(); + if (this.selfDestroy) { + this.destroy(); + } + } else { + this.trace(); + this.handle = requestAnimFrame(function() { + self.drawer(); + }); + return; + } + + this.callback(this); + if (this.instanceCallback) { + this.instanceCallback(this); + this.instanceCallback = null; + } + }; + + /** + * Draw the SVG at the current instant from the + * `currentFrame` value. Here is where most of the magic is. + * The trick is to use the `strokeDashoffset` style property. + * + * For optimisation reasons, a new property called `progress` + * is added in each item of `map`. This one contain the current + * progress of the path element. Only if the new value is different + * the new value will be applied to the DOM element. This + * method save a lot of resources to re-render the SVG. And could + * be improved if the animation couldn't be played forward. + * + */ + Vivus.prototype.trace = function() { + var i, progress, path, currentFrame; + currentFrame = + this.animTimingFunction(this.currentFrame / this.frameLength) * + this.frameLength; + for (i = 0; i < this.map.length; i++) { + path = this.map[i]; + progress = (currentFrame - path.startAt) / path.duration; + progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress))); + if (path.progress !== progress) { + path.progress = progress; + path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress)); + this.renderPath(i); + } + } + }; + + /** + * Method forcing the browser to re-render a path element + * from it's index in the map. Depending on the `forceRender` + * value. + * The trick is to replace the path element by it's clone. + * This practice is not recommended because it's asking more + * ressources, too much DOM manupulation.. + * but it's the only way to let the magic happen on IE. + * By default, this fallback is only applied on IE. + * + * @param {Number} index Path index + */ + Vivus.prototype.renderPath = function(index) { + if (this.forceRender && this.map && this.map[index]) { + var pathObj = this.map[index], + newPath = pathObj.el.cloneNode(true); + pathObj.el.parentNode.replaceChild(newPath, pathObj.el); + pathObj.el = newPath; + } + }; + + /** + * When the SVG object is loaded and ready, + * this method will continue the initialisation. + * + * This this mainly due to the case of passing an + * object tag in the constructor. It will wait + * the end of the loading to initialise. + * + */ + Vivus.prototype.init = function() { + // Set object variables + this.frameLength = 0; + this.currentFrame = 0; + this.map = []; + + // Start + new Pathformer(this.el); + this.mapping(); + this.starter(); + + if (this.onReady) { + this.onReady(this); + } + }; + + /** + * Trigger to start of the animation. + * Depending on the `start` value, a different script + * will be applied. + * + * If the `start` value is not valid, an error will be thrown. + * Even if technically, this is impossible. + * + */ + Vivus.prototype.starter = function() { + switch (this.start) { + case 'manual': + return; + + case 'autostart': + this.play(); + break; + + case 'inViewport': + var self = this, + listener = function() { + if (self.isInViewport(self.parentEl, 1)) { + self.play(); + window.removeEventListener('scroll', listener); + } + }; + window.addEventListener('scroll', listener); + listener(); + break; + } + }; + + /** + * Controls + ************************************** + */ + + /** + * Get the current status of the animation between + * three different states: 'start', 'progress', 'end'. + * @return {string} Instance status + */ + Vivus.prototype.getStatus = function() { + return this.currentFrame === 0 + ? 'start' + : this.currentFrame === this.frameLength + ? 'end' + : 'progress'; + }; + + /** + * Reset the instance to the initial state : undraw + * Be careful, it just reset the animation, if you're + * playing the animation, this won't stop it. But just + * make it start from start. + * + */ + Vivus.prototype.reset = function() { + return this.setFrameProgress(0); + }; + + /** + * Set the instance to the final state : drawn + * Be careful, it just set the animation, if you're + * playing the animation on rewind, this won't stop it. + * But just make it start from the end. + * + */ + Vivus.prototype.finish = function() { + return this.setFrameProgress(1); + }; + + /** + * Set the level of progress of the drawing. + * + * @param {number} progress Level of progress to set + */ + Vivus.prototype.setFrameProgress = function(progress) { + progress = Math.min(1, Math.max(0, progress)); + this.currentFrame = Math.round(this.frameLength * progress); + this.trace(); + return this; + }; + + /** + * Play the animation at the desired speed. + * Speed must be a valid number (no zero). + * By default, the speed value is 1. + * But a negative value is accepted to go forward. + * + * And works with float too. + * But don't forget we are in JavaScript, se be nice + * with him and give him a 1/2^x value. + * + * @param {number} speed Animation speed [optional] + */ + Vivus.prototype.play = function(speed, callback) { + this.instanceCallback = null; + + if (speed && typeof speed === 'function') { + this.instanceCallback = speed; // first parameter is actually the callback function + speed = null; + } else if (speed && typeof speed !== 'number') { + throw new Error('Vivus [play]: invalid speed'); + } + // if the first parameter wasn't the callback, check if the seconds was + if (callback && typeof callback === 'function' && !this.instanceCallback) { + this.instanceCallback = callback; + } + + this.speed = speed || 1; + if (!this.handle) { + this.drawer(); + } + return this; + }; + + /** + * Stop the current animation, if on progress. + * Should not trigger any error. + * + */ + Vivus.prototype.stop = function() { + if (this.handle) { + cancelAnimFrame(this.handle); + this.handle = null; + } + return this; + }; + + /** + * Destroy the instance. + * Remove all bad styling attributes on all + * path tags + * + */ + Vivus.prototype.destroy = function() { + this.stop(); + var i, path; + for (i = 0; i < this.map.length; i++) { + path = this.map[i]; + path.el.style.strokeDashoffset = null; + path.el.style.strokeDasharray = null; + this.renderPath(i); + } + }; + + /** + * Utils methods + * include methods from Codrops + ************************************** + */ + + /** + * Method to best guess if a path should added into + * the animation or not. + * + * 1. Use the `data-vivus-ignore` attribute if set + * 2. Check if the instance must ignore invisible paths + * 3. Check if the path is visible + * + * For now the visibility checking is unstable. + * It will be used for a beta phase. + * + * Other improvments are planned. Like detecting + * is the path got a stroke or a valid opacity. + */ + Vivus.prototype.isInvisible = function(el) { + var rect, + ignoreAttr = el.getAttribute('data-ignore'); + + if (ignoreAttr !== null) { + return ignoreAttr !== 'false'; + } + + if (this.ignoreInvisible) { + rect = el.getBoundingClientRect(); + return !rect.width && !rect.height; + } else { + return false; + } + }; + + /** + * Parse attributes of a DOM element to + * get an object of {attributeName => attributeValue} + * + * @param {object} element DOM element to parse + * @return {object} Object of attributes + */ + Vivus.prototype.parseAttr = function(element) { + var attr, + output = {}; + if (element && element.attributes) { + for (var i = 0; i < element.attributes.length; i++) { + attr = element.attributes[i]; + output[attr.name] = attr.value; + } + } + return output; + }; + + /** + * Reply if an element is in the page viewport + * + * @param {object} el Element to observe + * @param {number} h Percentage of height + * @return {boolean} + */ + Vivus.prototype.isInViewport = function(el, h) { + var scrolled = this.scrollY(), + viewed = scrolled + this.getViewportH(), + elBCR = el.getBoundingClientRect(), + elHeight = elBCR.height, + elTop = scrolled + elBCR.top, + elBottom = elTop + elHeight; + + // if 0, the element is considered in the viewport as soon as it enters. + // if 1, the element is considered in the viewport only when it's fully inside + // value in percentage (1 >= h >= 0) + h = h || 0; + + return elTop + elHeight * h <= viewed && elBottom >= scrolled; + }; + + /** + * Get the viewport height in pixels + * + * @return {integer} Viewport height + */ + Vivus.prototype.getViewportH = function() { + var client = this.docElem.clientHeight, + inner = window.innerHeight; + + if (client < inner) { + return inner; + } else { + return client; + } + }; + + /** + * Get the page Y offset + * + * @return {integer} Page Y offset + */ + Vivus.prototype.scrollY = function() { + return window.pageYOffset || this.docElem.scrollTop; + }; + + setupEnv = function() { + if (Vivus.prototype.docElem) { + return; + } + + /** + * Alias for document element + * + * @type {DOMelement} + */ + Vivus.prototype.docElem = window.document.documentElement; + + /** + * Alias for `requestAnimationFrame` or + * `setTimeout` function for deprecated browsers. + * + */ + requestAnimFrame = (function() { + return ( + window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(/* function */ callback) { + return window.setTimeout(callback, 1000 / 60); + } + ); + })(); + + /** + * Alias for `cancelAnimationFrame` or + * `cancelTimeout` function for deprecated browsers. + * + */ + cancelAnimFrame = (function() { + return ( + window.cancelAnimationFrame || + window.webkitCancelAnimationFrame || + window.mozCancelAnimationFrame || + window.oCancelAnimationFrame || + window.msCancelAnimationFrame || + function(id) { + return window.clearTimeout(id); + } + ); + })(); + }; + + /** + * Parse string to integer. + * If the number is not positive or null + * the method will return the default value + * or 0 if undefined + * + * @param {string} value String to parse + * @param {*} defaultValue Value to return if the result parsed is invalid + * @return {number} + * + */ + parsePositiveInt = function(value, defaultValue) { + var output = parseInt(value, 10); + return output >= 0 ? output : defaultValue; + }; diff --git a/nodefrontend/node_modules/asap/CHANGES.md b/nodefrontend/node_modules/asap/CHANGES.md new file mode 100644 index 00000000..f105b919 --- /dev/null +++ b/nodefrontend/node_modules/asap/CHANGES.md @@ -0,0 +1,70 @@ + +## 2.0.6 + +Version 2.0.4 adds support for React Native by clarifying in package.json that +the browser environment does not support Node.js domains. +Why this is necessary, we leave as an exercise for the user. + +## 2.0.3 + +Version 2.0.3 fixes a bug when adjusting the capacity of the task queue. + +## 2.0.1-2.02 + +Version 2.0.1 fixes a bug in the way redirects were expressed that affected the +function of Browserify, but which Mr would tolerate. + +## 2.0.0 + +Version 2 of ASAP is a full rewrite with a few salient changes. +First, the ASAP source is CommonJS only and designed with [Browserify][] and +[Browserify-compatible][Mr] module loaders in mind. + +[Browserify]: https://github.com/substack/node-browserify +[Mr]: https://github.com/montagejs/mr + +The new version has been refactored in two dimensions. +Support for Node.js and browsers have been separated, using Browserify +redirects and ASAP has been divided into two modules. +The "raw" layer depends on the tasks to catch thrown exceptions and unravel +Node.js domains. + +The full implementation of ASAP is loadable as `require("asap")` in both Node.js +and browsers. + +The raw layer that lacks exception handling overhead is loadable as +`require("asap/raw")`. +The interface is the same for both layers. + +Tasks are no longer required to be functions, but can rather be any object that +implements `task.call()`. +With this feature you can recycle task objects to avoid garbage collector churn +and avoid closures in general. + +The implementation has been rigorously documented so that our successors can +understand the scope of the problem that this module solves and all of its +nuances, ensuring that the next generation of implementations know what details +are essential. + +- [asap.js](https://github.com/kriskowal/asap/blob/master/asap.js) +- [raw.js](https://github.com/kriskowal/asap/blob/master/raw.js) +- [browser-asap.js](https://github.com/kriskowal/asap/blob/master/browser-asap.js) +- [browser-raw.js](https://github.com/kriskowal/asap/blob/master/browser-raw.js) + +The new version has also been rigorously tested across a broad spectrum of +browsers, in both the window and worker context. +The following charts capture the browser test results for the most recent +release. +The first chart shows test results for ASAP running in the main window context. +The second chart shows test results for ASAP running in a web worker context. +Test results are inconclusive (grey) on browsers that do not support web +workers. +These data are captured automatically by [Continuous +Integration][]. + +![Browser Compatibility](http://kriskowal-asap.s3-website-us-west-2.amazonaws.com/train/integration-2/saucelabs-results-matrix.svg) + +![Compatibility in Web Workers](http://kriskowal-asap.s3-website-us-west-2.amazonaws.com/train/integration-2/saucelabs-worker-results-matrix.svg) + +[Continuous Integration]: https://github.com/kriskowal/asap/blob/master/CONTRIBUTING.md + diff --git a/nodefrontend/node_modules/asap/LICENSE.md b/nodefrontend/node_modules/asap/LICENSE.md new file mode 100644 index 00000000..ba18c613 --- /dev/null +++ b/nodefrontend/node_modules/asap/LICENSE.md @@ -0,0 +1,21 @@ + +Copyright 2009–2014 Contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + diff --git a/nodefrontend/node_modules/asap/README.md b/nodefrontend/node_modules/asap/README.md new file mode 100644 index 00000000..452fd8c2 --- /dev/null +++ b/nodefrontend/node_modules/asap/README.md @@ -0,0 +1,237 @@ +# ASAP + +[![Build Status](https://travis-ci.org/kriskowal/asap.png?branch=master)](https://travis-ci.org/kriskowal/asap) + +Promise and asynchronous observer libraries, as well as hand-rolled callback +programs and libraries, often need a mechanism to postpone the execution of a +callback until the next available event. +(See [Designing API’s for Asynchrony][Zalgo].) +The `asap` function executes a task **as soon as possible** but not before it +returns, waiting only for the completion of the current event and previously +scheduled tasks. + +```javascript +asap(function () { + // ... +}); +``` + +[Zalgo]: http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony + +This CommonJS package provides an `asap` module that exports a function that +executes a task function *as soon as possible*. + +ASAP strives to schedule events to occur before yielding for IO, reflow, +or redrawing. +Each event receives an independent stack, with only platform code in parent +frames and the events run in the order they are scheduled. + +ASAP provides a fast event queue that will execute tasks until it is +empty before yielding to the JavaScript engine's underlying event-loop. +When a task gets added to a previously empty event queue, ASAP schedules a flush +event, preferring for that event to occur before the JavaScript engine has an +opportunity to perform IO tasks or rendering, thus making the first task and +subsequent tasks semantically indistinguishable. +ASAP uses a variety of techniques to preserve this invariant on different +versions of browsers and Node.js. + +By design, ASAP prevents input events from being handled until the task +queue is empty. +If the process is busy enough, this may cause incoming connection requests to be +dropped, and may cause existing connections to inform the sender to reduce the +transmission rate or stall. +ASAP allows this on the theory that, if there is enough work to do, there is no +sense in looking for trouble. +As a consequence, ASAP can interfere with smooth animation. +If your task should be tied to the rendering loop, consider using +`requestAnimationFrame` instead. +A long sequence of tasks can also effect the long running script dialog. +If this is a problem, you may be able to use ASAP’s cousin `setImmediate` to +break long processes into shorter intervals and periodically allow the browser +to breathe. +`setImmediate` will yield for IO, reflow, and repaint events. +It also returns a handler and can be canceled. +For a `setImmediate` shim, consider [YuzuJS setImmediate][setImmediate]. + +[setImmediate]: https://github.com/YuzuJS/setImmediate + +Take care. +ASAP can sustain infinite recursive calls without warning. +It will not halt from a stack overflow, and it will not consume unbounded +memory. +This is behaviorally equivalent to an infinite loop. +Just as with infinite loops, you can monitor a Node.js process for this behavior +with a heart-beat signal. +As with infinite loops, a very small amount of caution goes a long way to +avoiding problems. + +```javascript +function loop() { + asap(loop); +} +loop(); +``` + +In browsers, if a task throws an exception, it will not interrupt the flushing +of high-priority tasks. +The exception will be postponed to a later, low-priority event to avoid +slow-downs. +In Node.js, if a task throws an exception, ASAP will resume flushing only if—and +only after—the error is handled by `domain.on("error")` or +`process.on("uncaughtException")`. + +## Raw ASAP + +Checking for exceptions comes at a cost. +The package also provides an `asap/raw` module that exports the underlying +implementation which is faster but stalls if a task throws an exception. +This internal version of the ASAP function does not check for errors. +If a task does throw an error, it will stall the event queue unless you manually +call `rawAsap.requestFlush()` before throwing the error, or any time after. + +In Node.js, `asap/raw` also runs all tasks outside any domain. +If you need a task to be bound to your domain, you will have to do it manually. + +```js +if (process.domain) { + task = process.domain.bind(task); +} +rawAsap(task); +``` + +## Tasks + +A task may be any object that implements `call()`. +A function will suffice, but closures tend not to be reusable and can cause +garbage collector churn. +Both `asap` and `rawAsap` accept task objects to give you the option of +recycling task objects or using higher callable object abstractions. +See the `asap` source for an illustration. + + +## Compatibility + +ASAP is tested on Node.js v0.10 and in a broad spectrum of web browsers. +The following charts capture the browser test results for the most recent +release. +The first chart shows test results for ASAP running in the main window context. +The second chart shows test results for ASAP running in a web worker context. +Test results are inconclusive (grey) on browsers that do not support web +workers. +These data are captured automatically by [Continuous +Integration][]. + +[Continuous Integration]: https://github.com/kriskowal/asap/blob/master/CONTRIBUTING.md + +![Browser Compatibility](http://kriskowal-asap.s3-website-us-west-2.amazonaws.com/train/integration-2/saucelabs-results-matrix.svg) + +![Compatibility in Web Workers](http://kriskowal-asap.s3-website-us-west-2.amazonaws.com/train/integration-2/saucelabs-worker-results-matrix.svg) + +## Caveats + +When a task is added to an empty event queue, it is not always possible to +guarantee that the task queue will begin flushing immediately after the current +event. +However, once the task queue begins flushing, it will not yield until the queue +is empty, even if the queue grows while executing tasks. + +The following browsers allow the use of [DOM mutation observers][] to access +the HTML [microtask queue][], and thus begin flushing ASAP's task queue +immediately at the end of the current event loop turn, before any rendering or +IO: + +[microtask queue]: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#microtask-queue +[DOM mutation observers]: http://dom.spec.whatwg.org/#mutation-observers + +- Android 4–4.3 +- Chrome 26–34 +- Firefox 14–29 +- Internet Explorer 11 +- iPad Safari 6–7.1 +- iPhone Safari 7–7.1 +- Safari 6–7 + +In the absense of mutation observers, there are a few browsers, and situations +like web workers in some of the above browsers, where [message channels][] +would be a useful way to avoid falling back to timers. +Message channels give direct access to the HTML [task queue][], so the ASAP +task queue would flush after any already queued rendering and IO tasks, but +without having the minimum delay imposed by timers. +However, among these browsers, Internet Explorer 10 and Safari do not reliably +dispatch messages, so they are not worth the trouble to implement. + +[message channels]: http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#message-channels +[task queue]: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#concept-task + +- Internet Explorer 10 +- Safair 5.0-1 +- Opera 11-12 + +In the absense of mutation observers, these browsers and the following browsers +all fall back to using `setTimeout` and `setInterval` to ensure that a `flush` +occurs. +The implementation uses both and cancels whatever handler loses the race, since +`setTimeout` tends to occasionally skip tasks in unisolated circumstances. +Timers generally delay the flushing of ASAP's task queue for four milliseconds. + +- Firefox 3–13 +- Internet Explorer 6–10 +- iPad Safari 4.3 +- Lynx 2.8.7 + + +## Heritage + +ASAP has been factored out of the [Q][] asynchronous promise library. +It originally had a naïve implementation in terms of `setTimeout`, but +[Malte Ubl][NonBlocking] provided an insight that `postMessage` might be +useful for creating a high-priority, no-delay event dispatch hack. +Since then, Internet Explorer proposed and implemented `setImmediate`. +Robert Katić began contributing to Q by measuring the performance of +the internal implementation of `asap`, paying particular attention to +error recovery. +Domenic, Robert, and Kris Kowal collectively settled on the current strategy of +unrolling the high-priority event queue internally regardless of what strategy +we used to dispatch the potentially lower-priority flush event. +Domenic went on to make ASAP cooperate with Node.js domains. + +[Q]: https://github.com/kriskowal/q +[NonBlocking]: http://www.nonblocking.io/2011/06/windownexttick.html + +For further reading, Nicholas Zakas provided a thorough article on [The +Case for setImmediate][NCZ]. + +[NCZ]: http://www.nczonline.net/blog/2013/07/09/the-case-for-setimmediate/ + +Ember’s RSVP promise implementation later [adopted][RSVP ASAP] the name ASAP but +further developed the implentation. +Particularly, The `MessagePort` implementation was abandoned due to interaction +[problems with Mobile Internet Explorer][IE Problems] in favor of an +implementation backed on the newer and more reliable DOM `MutationObserver` +interface. +These changes were back-ported into this library. + +[IE Problems]: https://github.com/cujojs/when/issues/197 +[RSVP ASAP]: https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js + +In addition, ASAP factored into `asap` and `asap/raw`, such that `asap` remained +exception-safe, but `asap/raw` provided a tight kernel that could be used for +tasks that guaranteed that they would not throw exceptions. +This core is useful for promise implementations that capture thrown errors in +rejected promises and do not need a second safety net. +At the same time, the exception handling in `asap` was factored into separate +implementations for Node.js and browsers, using the the [Browserify][Browser +Config] `browser` property in `package.json` to instruct browser module loaders +and bundlers, including [Browserify][], [Mr][], and [Mop][], to use the +browser-only implementation. + +[Browser Config]: https://gist.github.com/defunctzombie/4339901 +[Browserify]: https://github.com/substack/node-browserify +[Mr]: https://github.com/montagejs/mr +[Mop]: https://github.com/montagejs/mop + +## License + +Copyright 2009-2014 by Contributors +MIT License (enclosed) + diff --git a/nodefrontend/node_modules/asap/asap.js b/nodefrontend/node_modules/asap/asap.js new file mode 100644 index 00000000..f04fcd58 --- /dev/null +++ b/nodefrontend/node_modules/asap/asap.js @@ -0,0 +1,65 @@ +"use strict"; + +var rawAsap = require("./raw"); +var freeTasks = []; + +/** + * Calls a task as soon as possible after returning, in its own event, with + * priority over IO events. An exception thrown in a task can be handled by + * `process.on("uncaughtException") or `domain.on("error")`, but will otherwise + * crash the process. If the error is handled, all subsequent tasks will + * resume. + * + * @param {{call}} task A callable object, typically a function that takes no + * arguments. + */ +module.exports = asap; +function asap(task) { + var rawTask; + if (freeTasks.length) { + rawTask = freeTasks.pop(); + } else { + rawTask = new RawTask(); + } + rawTask.task = task; + rawTask.domain = process.domain; + rawAsap(rawTask); +} + +function RawTask() { + this.task = null; + this.domain = null; +} + +RawTask.prototype.call = function () { + if (this.domain) { + this.domain.enter(); + } + var threw = true; + try { + this.task.call(); + threw = false; + // If the task throws an exception (presumably) Node.js restores the + // domain stack for the next event. + if (this.domain) { + this.domain.exit(); + } + } finally { + // We use try/finally and a threw flag to avoid messing up stack traces + // when we catch and release errors. + if (threw) { + // In Node.js, uncaught exceptions are considered fatal errors. + // Re-throw them to interrupt flushing! + // Ensure that flushing continues if an uncaught exception is + // suppressed listening process.on("uncaughtException") or + // domain.on("error"). + rawAsap.requestFlush(); + } + // If the task threw an error, we do not want to exit the domain here. + // Exiting the domain would prevent the domain from catching the error. + this.task = null; + this.domain = null; + freeTasks.push(this); + } +}; + diff --git a/nodefrontend/node_modules/asap/browser-asap.js b/nodefrontend/node_modules/asap/browser-asap.js new file mode 100644 index 00000000..805c9824 --- /dev/null +++ b/nodefrontend/node_modules/asap/browser-asap.js @@ -0,0 +1,66 @@ +"use strict"; + +// rawAsap provides everything we need except exception management. +var rawAsap = require("./raw"); +// RawTasks are recycled to reduce GC churn. +var freeTasks = []; +// We queue errors to ensure they are thrown in right order (FIFO). +// Array-as-queue is good enough here, since we are just dealing with exceptions. +var pendingErrors = []; +var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError); + +function throwFirstError() { + if (pendingErrors.length) { + throw pendingErrors.shift(); + } +} + +/** + * Calls a task as soon as possible after returning, in its own event, with priority + * over other events like animation, reflow, and repaint. An error thrown from an + * event will not interrupt, nor even substantially slow down the processing of + * other events, but will be rather postponed to a lower priority event. + * @param {{call}} task A callable object, typically a function that takes no + * arguments. + */ +module.exports = asap; +function asap(task) { + var rawTask; + if (freeTasks.length) { + rawTask = freeTasks.pop(); + } else { + rawTask = new RawTask(); + } + rawTask.task = task; + rawAsap(rawTask); +} + +// We wrap tasks with recyclable task objects. A task object implements +// `call`, just like a function. +function RawTask() { + this.task = null; +} + +// The sole purpose of wrapping the task is to catch the exception and recycle +// the task object after its single use. +RawTask.prototype.call = function () { + try { + this.task.call(); + } catch (error) { + if (asap.onerror) { + // This hook exists purely for testing purposes. + // Its name will be periodically randomized to break any code that + // depends on its existence. + asap.onerror(error); + } else { + // In a web browser, exceptions are not fatal. However, to avoid + // slowing down the queue of pending tasks, we rethrow the error in a + // lower priority turn. + pendingErrors.push(error); + requestErrorThrow(); + } + } finally { + this.task = null; + freeTasks[freeTasks.length] = this; + } +}; diff --git a/nodefrontend/node_modules/asap/browser-raw.js b/nodefrontend/node_modules/asap/browser-raw.js new file mode 100644 index 00000000..9cee7e32 --- /dev/null +++ b/nodefrontend/node_modules/asap/browser-raw.js @@ -0,0 +1,223 @@ +"use strict"; + +// Use the fastest means possible to execute a task in its own turn, with +// priority over other events including IO, animation, reflow, and redraw +// events in browsers. +// +// An exception thrown by a task will permanently interrupt the processing of +// subsequent tasks. The higher level `asap` function ensures that if an +// exception is thrown by a task, that the task queue will continue flushing as +// soon as possible, but if you use `rawAsap` directly, you are responsible to +// either ensure that no exceptions are thrown from your task, or to manually +// call `rawAsap.requestFlush` if an exception is thrown. +module.exports = rawAsap; +function rawAsap(task) { + if (!queue.length) { + requestFlush(); + flushing = true; + } + // Equivalent to push, but avoids a function call. + queue[queue.length] = task; +} + +var queue = []; +// Once a flush has been requested, no further calls to `requestFlush` are +// necessary until the next `flush` completes. +var flushing = false; +// `requestFlush` is an implementation-specific method that attempts to kick +// off a `flush` event as quickly as possible. `flush` will attempt to exhaust +// the event queue before yielding to the browser's own event loop. +var requestFlush; +// The position of the next task to execute in the task queue. This is +// preserved between calls to `flush` so that it can be resumed if +// a task throws an exception. +var index = 0; +// If a task schedules additional tasks recursively, the task queue can grow +// unbounded. To prevent memory exhaustion, the task queue will periodically +// truncate already-completed tasks. +var capacity = 1024; + +// The flush function processes all tasks that have been scheduled with +// `rawAsap` unless and until one of those tasks throws an exception. +// If a task throws an exception, `flush` ensures that its state will remain +// consistent and will resume where it left off when called again. +// However, `flush` does not make any arrangements to be called again if an +// exception is thrown. +function flush() { + while (index < queue.length) { + var currentIndex = index; + // Advance the index before calling the task. This ensures that we will + // begin flushing on the next task the task throws an error. + index = index + 1; + queue[currentIndex].call(); + // Prevent leaking memory for long chains of recursive calls to `asap`. + // If we call `asap` within tasks scheduled by `asap`, the queue will + // grow, but to avoid an O(n) walk for every task we execute, we don't + // shift tasks off the queue after they have been executed. + // Instead, we periodically shift 1024 tasks off the queue. + if (index > capacity) { + // Manually shift all values starting at the index back to the + // beginning of the queue. + for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) { + queue[scan] = queue[scan + index]; + } + queue.length -= index; + index = 0; + } + } + queue.length = 0; + index = 0; + flushing = false; +} + +// `requestFlush` is implemented using a strategy based on data collected from +// every available SauceLabs Selenium web driver worker at time of writing. +// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593 + +// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that +// have WebKitMutationObserver but not un-prefixed MutationObserver. +// Must use `global` or `self` instead of `window` to work in both frames and web +// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop. + +/* globals self */ +var scope = typeof global !== "undefined" ? global : self; +var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver; + +// MutationObservers are desirable because they have high priority and work +// reliably everywhere they are implemented. +// They are implemented in all modern browsers. +// +// - Android 4-4.3 +// - Chrome 26-34 +// - Firefox 14-29 +// - Internet Explorer 11 +// - iPad Safari 6-7.1 +// - iPhone Safari 7-7.1 +// - Safari 6-7 +if (typeof BrowserMutationObserver === "function") { + requestFlush = makeRequestCallFromMutationObserver(flush); + +// MessageChannels are desirable because they give direct access to the HTML +// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera +// 11-12, and in web workers in many engines. +// Although message channels yield to any queued rendering and IO tasks, they +// would be better than imposing the 4ms delay of timers. +// However, they do not work reliably in Internet Explorer or Safari. + +// Internet Explorer 10 is the only browser that has setImmediate but does +// not have MutationObservers. +// Although setImmediate yields to the browser's renderer, it would be +// preferrable to falling back to setTimeout since it does not have +// the minimum 4ms penalty. +// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and +// Desktop to a lesser extent) that renders both setImmediate and +// MessageChannel useless for the purposes of ASAP. +// https://github.com/kriskowal/q/issues/396 + +// Timers are implemented universally. +// We fall back to timers in workers in most engines, and in foreground +// contexts in the following browsers. +// However, note that even this simple case requires nuances to operate in a +// broad spectrum of browsers. +// +// - Firefox 3-13 +// - Internet Explorer 6-9 +// - iPad Safari 4.3 +// - Lynx 2.8.7 +} else { + requestFlush = makeRequestCallFromTimer(flush); +} + +// `requestFlush` requests that the high priority event queue be flushed as +// soon as possible. +// This is useful to prevent an error thrown in a task from stalling the event +// queue if the exception handled by Node.js’s +// `process.on("uncaughtException")` or by a domain. +rawAsap.requestFlush = requestFlush; + +// To request a high priority event, we induce a mutation observer by toggling +// the text of a text node between "1" and "-1". +function makeRequestCallFromMutationObserver(callback) { + var toggle = 1; + var observer = new BrowserMutationObserver(callback); + var node = document.createTextNode(""); + observer.observe(node, {characterData: true}); + return function requestCall() { + toggle = -toggle; + node.data = toggle; + }; +} + +// The message channel technique was discovered by Malte Ubl and was the +// original foundation for this library. +// http://www.nonblocking.io/2011/06/windownexttick.html + +// Safari 6.0.5 (at least) intermittently fails to create message ports on a +// page's first load. Thankfully, this version of Safari supports +// MutationObservers, so we don't need to fall back in that case. + +// function makeRequestCallFromMessageChannel(callback) { +// var channel = new MessageChannel(); +// channel.port1.onmessage = callback; +// return function requestCall() { +// channel.port2.postMessage(0); +// }; +// } + +// For reasons explained above, we are also unable to use `setImmediate` +// under any circumstances. +// Even if we were, there is another bug in Internet Explorer 10. +// It is not sufficient to assign `setImmediate` to `requestFlush` because +// `setImmediate` must be called *by name* and therefore must be wrapped in a +// closure. +// Never forget. + +// function makeRequestCallFromSetImmediate(callback) { +// return function requestCall() { +// setImmediate(callback); +// }; +// } + +// Safari 6.0 has a problem where timers will get lost while the user is +// scrolling. This problem does not impact ASAP because Safari 6.0 supports +// mutation observers, so that implementation is used instead. +// However, if we ever elect to use timers in Safari, the prevalent work-around +// is to add a scroll event listener that calls for a flush. + +// `setTimeout` does not call the passed callback if the delay is less than +// approximately 7 in web workers in Firefox 8 through 18, and sometimes not +// even then. + +function makeRequestCallFromTimer(callback) { + return function requestCall() { + // We dispatch a timeout with a specified delay of 0 for engines that + // can reliably accommodate that request. This will usually be snapped + // to a 4 milisecond delay, but once we're flushing, there's no delay + // between events. + var timeoutHandle = setTimeout(handleTimer, 0); + // However, since this timer gets frequently dropped in Firefox + // workers, we enlist an interval handle that will try to fire + // an event 20 times per second until it succeeds. + var intervalHandle = setInterval(handleTimer, 50); + + function handleTimer() { + // Whichever timer succeeds will cancel both timers and + // execute the callback. + clearTimeout(timeoutHandle); + clearInterval(intervalHandle); + callback(); + } + }; +} + +// This is for `asap.js` only. +// Its name will be periodically randomized to break any code that depends on +// its existence. +rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer; + +// ASAP was originally a nextTick shim included in Q. This was factored out +// into this ASAP package. It was later adapted to RSVP which made further +// amendments. These decisions, particularly to marginalize MessageChannel and +// to capture the MutationObserver implementation in a closure, were integrated +// back into ASAP proper. +// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js diff --git a/nodefrontend/node_modules/asap/package.json b/nodefrontend/node_modules/asap/package.json new file mode 100644 index 00000000..41ba107b --- /dev/null +++ b/nodefrontend/node_modules/asap/package.json @@ -0,0 +1,87 @@ +{ + "_from": "asap@~2.0.6", + "_id": "asap@2.0.6", + "_inBundle": false, + "_integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "_location": "/asap", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "asap@~2.0.6", + "name": "asap", + "escapedName": "asap", + "rawSpec": "~2.0.6", + "saveSpec": null, + "fetchSpec": "~2.0.6" + }, + "_requiredBy": [ + "/promise" + ], + "_resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "_shasum": "e50347611d7e690943208bbdafebcbc2fb866d46", + "_spec": "asap@~2.0.6", + "_where": "/home/alpcentaur/ProjektA/PrototypeWebApp/nodefrontend/node_modules/promise", + "browser": { + "./asap": "./browser-asap.js", + "./asap.js": "./browser-asap.js", + "./raw": "./browser-raw.js", + "./raw.js": "./browser-raw.js", + "./test/domain.js": "./test/browser-domain.js" + }, + "bugs": { + "url": "https://github.com/kriskowal/asap/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "High-priority task queue for Node.js and browsers", + "devDependencies": { + "benchmark": "^1.0.0", + "events": "^1.0.1", + "jshint": "^2.5.1", + "knox": "^0.8.10", + "mr": "^2.0.5", + "opener": "^1.3.0", + "q": "^2.0.3", + "q-io": "^2.0.3", + "saucelabs": "^0.1.1", + "wd": "^0.2.21", + "weak-map": "^1.0.5" + }, + "files": [ + "raw.js", + "asap.js", + "browser-raw.js", + "browser-asap.js" + ], + "homepage": "https://github.com/kriskowal/asap#readme", + "keywords": [ + "event", + "task", + "queue" + ], + "license": "MIT", + "main": "./asap.js", + "name": "asap", + "react-native": { + "domain": false + }, + "repository": { + "type": "git", + "url": "git+https://github.com/kriskowal/asap.git" + }, + "scripts": { + "benchmarks": "node benchmarks", + "lint": "jshint raw.js asap.js browser-raw.js browser-asap.js $(find scripts -name '*.js' | grep -v gauntlet)", + "test": "npm run lint && npm run test-node", + "test-browser": "node scripts/publish-bundle.js test/asap-test.js | xargs opener", + "test-node": "node test/asap-test.js", + "test-publish": "node scripts/publish-bundle.js test/asap-test.js | pbcopy", + "test-saucelabs": "node scripts/saucelabs.js test/asap-test.js scripts/saucelabs-spot-configurations.json", + "test-saucelabs-all": "node scripts/saucelabs.js test/asap-test.js scripts/saucelabs-all-configurations.json", + "test-saucelabs-worker": "node scripts/saucelabs-worker-test.js scripts/saucelabs-spot-configurations.json", + "test-saucelabs-worker-all": "node scripts/saucelabs-worker-test.js scripts/saucelabs-all-configurations.json", + "test-travis": "npm run lint && npm run test-node && npm run test-saucelabs && npm run test-saucelabs-worker" + }, + "version": "2.0.6" +} diff --git a/nodefrontend/node_modules/asap/raw.js b/nodefrontend/node_modules/asap/raw.js new file mode 100644 index 00000000..ae3b8923 --- /dev/null +++ b/nodefrontend/node_modules/asap/raw.js @@ -0,0 +1,101 @@ +"use strict"; + +var domain; // The domain module is executed on demand +var hasSetImmediate = typeof setImmediate === "function"; + +// Use the fastest means possible to execute a task in its own turn, with +// priority over other events including network IO events in Node.js. +// +// An exception thrown by a task will permanently interrupt the processing of +// subsequent tasks. The higher level `asap` function ensures that if an +// exception is thrown by a task, that the task queue will continue flushing as +// soon as possible, but if you use `rawAsap` directly, you are responsible to +// either ensure that no exceptions are thrown from your task, or to manually +// call `rawAsap.requestFlush` if an exception is thrown. +module.exports = rawAsap; +function rawAsap(task) { + if (!queue.length) { + requestFlush(); + flushing = true; + } + // Avoids a function call + queue[queue.length] = task; +} + +var queue = []; +// Once a flush has been requested, no further calls to `requestFlush` are +// necessary until the next `flush` completes. +var flushing = false; +// The position of the next task to execute in the task queue. This is +// preserved between calls to `flush` so that it can be resumed if +// a task throws an exception. +var index = 0; +// If a task schedules additional tasks recursively, the task queue can grow +// unbounded. To prevent memory excaustion, the task queue will periodically +// truncate already-completed tasks. +var capacity = 1024; + +// The flush function processes all tasks that have been scheduled with +// `rawAsap` unless and until one of those tasks throws an exception. +// If a task throws an exception, `flush` ensures that its state will remain +// consistent and will resume where it left off when called again. +// However, `flush` does not make any arrangements to be called again if an +// exception is thrown. +function flush() { + while (index < queue.length) { + var currentIndex = index; + // Advance the index before calling the task. This ensures that we will + // begin flushing on the next task the task throws an error. + index = index + 1; + queue[currentIndex].call(); + // Prevent leaking memory for long chains of recursive calls to `asap`. + // If we call `asap` within tasks scheduled by `asap`, the queue will + // grow, but to avoid an O(n) walk for every task we execute, we don't + // shift tasks off the queue after they have been executed. + // Instead, we periodically shift 1024 tasks off the queue. + if (index > capacity) { + // Manually shift all values starting at the index back to the + // beginning of the queue. + for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) { + queue[scan] = queue[scan + index]; + } + queue.length -= index; + index = 0; + } + } + queue.length = 0; + index = 0; + flushing = false; +} + +rawAsap.requestFlush = requestFlush; +function requestFlush() { + // Ensure flushing is not bound to any domain. + // It is not sufficient to exit the domain, because domains exist on a stack. + // To execute code outside of any domain, the following dance is necessary. + var parentDomain = process.domain; + if (parentDomain) { + if (!domain) { + // Lazy execute the domain module. + // Only employed if the user elects to use domains. + domain = require("domain"); + } + domain.active = process.domain = null; + } + + // `setImmediate` is slower that `process.nextTick`, but `process.nextTick` + // cannot handle recursion. + // `requestFlush` will only be called recursively from `asap.js`, to resume + // flushing after an error is thrown into a domain. + // Conveniently, `setImmediate` was introduced in the same version + // `process.nextTick` started throwing recursion errors. + if (flushing && hasSetImmediate) { + setImmediate(flush); + } else { + process.nextTick(flush); + } + + if (parentDomain) { + domain.active = process.domain = parentDomain; + } +} diff --git a/nodefrontend/node_modules/promise/.github/FUNDING.yml b/nodefrontend/node_modules/promise/.github/FUNDING.yml new file mode 100644 index 00000000..dbe993db --- /dev/null +++ b/nodefrontend/node_modules/promise/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ForbesLindesay]# Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/promise # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/nodefrontend/node_modules/promise/.jshintrc b/nodefrontend/node_modules/promise/.jshintrc new file mode 100644 index 00000000..47c256f0 --- /dev/null +++ b/nodefrontend/node_modules/promise/.jshintrc @@ -0,0 +1,5 @@ +{ + "asi": true, + "node": true, + "strict": true +} diff --git a/nodefrontend/node_modules/promise/LICENSE b/nodefrontend/node_modules/promise/LICENSE new file mode 100644 index 00000000..7a1f7636 --- /dev/null +++ b/nodefrontend/node_modules/promise/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014 Forbes Lindesay + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/nodefrontend/node_modules/promise/Readme.md b/nodefrontend/node_modules/promise/Readme.md new file mode 100644 index 00000000..aa0b5f5b --- /dev/null +++ b/nodefrontend/node_modules/promise/Readme.md @@ -0,0 +1,256 @@ + +# promise + +This is a simple implementation of Promises. It is a super set of ES6 Promises designed to have readable, performant code and to provide just the extensions that are absolutely necessary for using promises today. + +For detailed tutorials on its use, see www.promisejs.org + +**N.B.** This promise exposes internals via underscore (`_`) prefixed properties. If you use these, your code will break with each new release. + +[![travis][travis-image]][travis-url] +[![dep][dep-image]][dep-url] +[![npm][npm-image]][npm-url] +[![downloads][downloads-image]][downloads-url] + +[travis-image]: https://img.shields.io/travis/then/promise.svg?style=flat +[travis-url]: https://travis-ci.org/then/promise +[dep-image]: https://img.shields.io/david/then/promise.svg?style=flat +[dep-url]: https://david-dm.org/then/promise +[npm-image]: https://img.shields.io/npm/v/promise.svg?style=flat +[npm-url]: https://npmjs.org/package/promise +[downloads-image]: https://img.shields.io/npm/dm/promise.svg?style=flat +[downloads-url]: https://npmjs.org/package/promise + +## Installation + +**Server:** + + $ npm install promise + +**Client:** + +You can use browserify on the client, or use the pre-compiled script that acts as a polyfill. + +```html + +``` + +Note that the [es5-shim](https://github.com/es-shims/es5-shim) must be loaded before this library to support browsers pre IE9. + +```html + +``` + +## Usage + +The example below shows how you can load the promise library (in a way that works on both client and server using node or browserify). It then demonstrates creating a promise from scratch. You simply call `new Promise(fn)`. There is a complete specification for what is returned by this method in [Promises/A+](http://promises-aplus.github.com/promises-spec/). + +```javascript +var Promise = require('promise'); + +var promise = new Promise(function (resolve, reject) { + get('http://www.google.com', function (err, res) { + if (err) reject(err); + else resolve(res); + }); +}); +``` + +If you need [domains](https://nodejs.org/api/domain.html) support, you should instead use: + +```js +var Promise = require('promise/domains'); +``` + +If you are in an environment that implements `setImmediate` and don't want the optimisations provided by asap, you can use: + +```js +var Promise = require('promise/setimmediate'); +``` + +If you only want part of the features, e.g. just a pure ES6 polyfill: + +```js +var Promise = require('promise/lib/es6-extensions'); +// or require('promise/domains/es6-extensions'); +// or require('promise/setimmediate/es6-extensions'); +``` + +## Unhandled Rejections + +By default, promises silence any unhandled rejections. + +You can enable logging of unhandled ReferenceErrors and TypeErrors via: + +```js +require('promise/lib/rejection-tracking').enable(); +``` + +Due to the performance cost, you should only do this during development. + +You can enable logging of all unhandled rejections if you need to debug an exception you think is being swallowed by promises: + +```js +require('promise/lib/rejection-tracking').enable( + {allRejections: true} +); +``` + +Due to the high probability of false positives, I only recommend using this when debugging specific issues that you think may be being swallowed. For the preferred debugging method, see `Promise#done(onFulfilled, onRejected)`. + +`rejection-tracking.enable(options)` takes the following options: + + - allRejections (`boolean`) - track all exceptions, not just reference errors and type errors. Note that this has a high probability of resulting in false positives if your code loads data optimistically + - whitelist (`Array`) - this defaults to `[ReferenceError, TypeError]` but you can override it with your own list of error constructors to track. + - `onUnhandled(id, error)` and `onHandled(id, error)` - you can use these to provide your own customised display for errors. Note that if possible you should indicate that the error was a false positive if `onHandled` is called. `onHandled` is only called if `onUnhandled` has already been called. + +To reduce the chance of false-positives there is a delay of up to 2 seconds before errors are logged. This means that if you attach an error handler within 2 seconds, it won't be logged as a false positive. ReferenceErrors and TypeErrors are only subject to a 100ms delay due to the higher likelihood that the error is due to programmer error. + +## API + +Detailed API reference docs are available at https://www.promisejs.org/api/. + +Before all examples, you will need: + +```js +var Promise = require('promise'); +``` + +### new Promise(resolver) + +This creates and returns a new promise. `resolver` must be a function. The `resolver` function is passed two arguments: + + 1. `resolve` should be called with a single argument. If it is called with a non-promise value then the promise is fulfilled with that value. If it is called with a promise (A) then the returned promise takes on the state of that new promise (A). + 2. `reject` should be called with a single argument. The returned promise will be rejected with that argument. + +### Static Functions + + These methods are invoked by calling `Promise.methodName`. + +#### Promise.resolve(value) + +(deprecated aliases: `Promise.from(value)`, `Promise.cast(value)`) + +Converts values and foreign promises into Promises/A+ promises. If you pass it a value then it returns a Promise for that value. If you pass it something that is close to a promise (such as a jQuery attempt at a promise) it returns a Promise that takes on the state of `value` (rejected or fulfilled). + +#### Promise.reject(value) + +Returns a rejected promise with the given value. + +#### Promise.all(array) + +Returns a promise for an array. If it is called with a single argument that `Array.isArray` then this returns a promise for a copy of that array with any promises replaced by their fulfilled values. e.g. + +```js +Promise.all([Promise.resolve('a'), 'b', Promise.resolve('c')]) + .then(function (res) { + assert(res[0] === 'a') + assert(res[1] === 'b') + assert(res[2] === 'c') + }) +``` + +#### Promise.race(array) + +Returns a promise that resolves or rejects with the result of the first promise to resolve/reject, e.g. +```js +var rejected = Promise.reject(new Error('Whatever')); +var fulfilled = new Promise(function (resolve) { + setTimeout(() => resolve('success'), 500); +}); + +var race = Promise.race([rejected, fulfilled]); +// => immediately rejected with `new Error('Whatever')` + +var success = Promise.resolve('immediate success'); +var first = Promise.race([success, fulfilled]); +// => immediately succeeds with `immediate success` +``` + +#### Promise.denodeify(fn) + +_Non Standard_ + +Takes a function which accepts a node style callback and returns a new function that returns a promise instead. + +e.g. + +```javascript +var fs = require('fs') + +var read = Promise.denodeify(fs.readFile) +var write = Promise.denodeify(fs.writeFile) + +var p = read('foo.json', 'utf8') + .then(function (str) { + return write('foo.json', JSON.stringify(JSON.parse(str), null, ' '), 'utf8') + }) +``` + +#### Promise.nodeify(fn) + +_Non Standard_ + +The twin to `denodeify` is useful when you want to export an API that can be used by people who haven't learnt about the brilliance of promises yet. + +```javascript +module.exports = Promise.nodeify(awesomeAPI) +function awesomeAPI(a, b) { + return download(a, b) +} +``` + +If the last argument passed to `module.exports` is a function, then it will be treated like a node.js callback and not parsed on to the child function, otherwise the API will just return a promise. + +### Prototype Methods + +These methods are invoked on a promise instance by calling `myPromise.methodName` + +### Promise#then(onFulfilled, onRejected) + +This method follows the [Promises/A+ spec](http://promises-aplus.github.io/promises-spec/). It explains things very clearly so I recommend you read it. + +Either `onFulfilled` or `onRejected` will be called and they will not be called more than once. They will be passed a single argument and will always be called asynchronously (in the next turn of the event loop). + +If the promise is fulfilled then `onFulfilled` is called. If the promise is rejected then `onRejected` is called. + +The call to `.then` also returns a promise. If the handler that is called returns a promise, the promise returned by `.then` takes on the state of that returned promise. If the handler that is called returns a value that is not a promise, the promise returned by `.then` will be fulfilled with that value. If the handler that is called throws an exception then the promise returned by `.then` is rejected with that exception. + +#### Promise#catch(onRejected) + +Sugar for `Promise#then(null, onRejected)`, to mirror `catch` in synchronous code. + +#### Promise#done(onFulfilled, onRejected) + +_Non Standard_ + +The same semantics as `.then` except that it does not return a promise and any exceptions are re-thrown so that they can be logged (crashing the application in non-browser environments) + +#### Promise#nodeify(callback) + +_Non Standard_ + +If `callback` is `null` or `undefined` it just returns `this`. If `callback` is a function it is called with rejection reason as the first argument and result as the second argument (as per the node.js convention). + +This lets you write API functions that look like: + +```javascript +function awesomeAPI(foo, bar, callback) { + return internalAPI(foo, bar) + .then(parseResult) + .then(null, retryErrors) + .nodeify(callback) +} +``` + +People who use typical node.js style callbacks will be able to just pass a callback and get the expected behavior. The enlightened people can not pass a callback and will get awesome promises. + +## Enterprise Support + +Available as part of the Tidelift Subscription + +The maintainers of promise and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-promise?utm_source=npm-promise&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) + +## License + + MIT diff --git a/nodefrontend/node_modules/promise/build.js b/nodefrontend/node_modules/promise/build.js new file mode 100644 index 00000000..99947d1f --- /dev/null +++ b/nodefrontend/node_modules/promise/build.js @@ -0,0 +1,66 @@ +'use strict'; + +var fs = require('fs'); +var rimraf = require('rimraf'); +var acorn = require('acorn'); +var walk = require('acorn/dist/walk'); +var crypto = require('crypto'); + +var shasum = crypto.createHash('sha512'); +fs.readdirSync(__dirname + '/src').sort().forEach(function (filename) { + shasum.update(fs.readFileSync(__dirname + '/src/' + filename, 'utf8')); +}); + +const names = {}; +const characterSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; +let i = characterSet.indexOf(shasum.digest('base64').replace(/[^0-9a-zA-Z]/g, '')[0]); +function getIdFor(name) { + if (names[name]) return names[name]; + return names[name] = '_' + characterSet[i++ % characterSet.length] +} + +function fixup(src) { + var ast = acorn.parse(src); + src = src.split(''); + walk.simple(ast, { + MemberExpression: function (node) { + if (node.computed) return; + if (node.property.type !== 'Identifier') return; + if (node.property.name[0] !== '_') return; + replace(node.property, getIdFor(node.property.name)); + } + }); + function replace(node, str) { + for (var i = node.start; i < node.end; i++) { + src[i] = ''; + } + src[node.start] = str; + } + return src.join(''); +} +rimraf.sync(__dirname + '/lib/'); +fs.mkdirSync(__dirname + '/lib/'); +fs.readdirSync(__dirname + '/src').forEach(function (filename) { + var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8'); + var out = fixup(src); + fs.writeFileSync(__dirname + '/lib/' + filename, out); +}); + +rimraf.sync(__dirname + '/domains/'); +fs.mkdirSync(__dirname + '/domains/'); +fs.readdirSync(__dirname + '/src').forEach(function (filename) { + var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8'); + var out = fixup(src); + out = out.replace(/require\(\'asap\/raw\'\)/g, "require('asap')"); + fs.writeFileSync(__dirname + '/domains/' + filename, out); +}); + +rimraf.sync(__dirname + '/setimmediate/'); +fs.mkdirSync(__dirname + '/setimmediate/'); +fs.readdirSync(__dirname + '/src').forEach(function (filename) { + var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8'); + var out = fixup(src); + out = out.replace(/var asap \= require\(\'([a-z\/]+)\'\);/g, ''); + out = out.replace(/asap/g, "setImmediate"); + fs.writeFileSync(__dirname + '/setimmediate/' + filename, out); +}); diff --git a/nodefrontend/node_modules/promise/core.js b/nodefrontend/node_modules/promise/core.js new file mode 100644 index 00000000..5f332a20 --- /dev/null +++ b/nodefrontend/node_modules/promise/core.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./lib/core.js'); + +console.error('require("promise/core") is deprecated, use require("promise/lib/core") instead.'); diff --git a/nodefrontend/node_modules/promise/domains/core.js b/nodefrontend/node_modules/promise/domains/core.js new file mode 100644 index 00000000..73ae257a --- /dev/null +++ b/nodefrontend/node_modules/promise/domains/core.js @@ -0,0 +1,213 @@ +'use strict'; + +var asap = require('asap'); + +function noop() {} + +// States: +// +// 0 - pending +// 1 - fulfilled with _value +// 2 - rejected with _value +// 3 - adopted the state of another promise, _value +// +// once the state is no longer pending (0) it is immutable + +// All `_` prefixed properties will be reduced to `_{random number}` +// at build time to obfuscate them and discourage their use. +// We don't use symbols or Object.defineProperty to fully hide them +// because the performance isn't good enough. + + +// to avoid using try/catch inside critical functions, we +// extract them to here. +var LAST_ERROR = null; +var IS_ERROR = {}; +function getThen(obj) { + try { + return obj.then; + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} + +function tryCallOne(fn, a) { + try { + return fn(a); + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} +function tryCallTwo(fn, a, b) { + try { + fn(a, b); + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} + +module.exports = Promise; + +function Promise(fn) { + if (typeof this !== 'object') { + throw new TypeError('Promises must be constructed via new'); + } + if (typeof fn !== 'function') { + throw new TypeError('Promise constructor\'s argument is not a function'); + } + this._U = 0; + this._V = 0; + this._W = null; + this._X = null; + if (fn === noop) return; + doResolve(fn, this); +} +Promise._Y = null; +Promise._Z = null; +Promise._0 = noop; + +Promise.prototype.then = function(onFulfilled, onRejected) { + if (this.constructor !== Promise) { + return safeThen(this, onFulfilled, onRejected); + } + var res = new Promise(noop); + handle(this, new Handler(onFulfilled, onRejected, res)); + return res; +}; + +function safeThen(self, onFulfilled, onRejected) { + return new self.constructor(function (resolve, reject) { + var res = new Promise(noop); + res.then(resolve, reject); + handle(self, new Handler(onFulfilled, onRejected, res)); + }); +} +function handle(self, deferred) { + while (self._V === 3) { + self = self._W; + } + if (Promise._Y) { + Promise._Y(self); + } + if (self._V === 0) { + if (self._U === 0) { + self._U = 1; + self._X = deferred; + return; + } + if (self._U === 1) { + self._U = 2; + self._X = [self._X, deferred]; + return; + } + self._X.push(deferred); + return; + } + handleResolved(self, deferred); +} + +function handleResolved(self, deferred) { + asap(function() { + var cb = self._V === 1 ? deferred.onFulfilled : deferred.onRejected; + if (cb === null) { + if (self._V === 1) { + resolve(deferred.promise, self._W); + } else { + reject(deferred.promise, self._W); + } + return; + } + var ret = tryCallOne(cb, self._W); + if (ret === IS_ERROR) { + reject(deferred.promise, LAST_ERROR); + } else { + resolve(deferred.promise, ret); + } + }); +} +function resolve(self, newValue) { + // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === self) { + return reject( + self, + new TypeError('A promise cannot be resolved with itself.') + ); + } + if ( + newValue && + (typeof newValue === 'object' || typeof newValue === 'function') + ) { + var then = getThen(newValue); + if (then === IS_ERROR) { + return reject(self, LAST_ERROR); + } + if ( + then === self.then && + newValue instanceof Promise + ) { + self._V = 3; + self._W = newValue; + finale(self); + return; + } else if (typeof then === 'function') { + doResolve(then.bind(newValue), self); + return; + } + } + self._V = 1; + self._W = newValue; + finale(self); +} + +function reject(self, newValue) { + self._V = 2; + self._W = newValue; + if (Promise._Z) { + Promise._Z(self, newValue); + } + finale(self); +} +function finale(self) { + if (self._U === 1) { + handle(self, self._X); + self._X = null; + } + if (self._U === 2) { + for (var i = 0; i < self._X.length; i++) { + handle(self, self._X[i]); + } + self._X = null; + } +} + +function Handler(onFulfilled, onRejected, promise){ + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; + this.onRejected = typeof onRejected === 'function' ? onRejected : null; + this.promise = promise; +} + +/** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ +function doResolve(fn, promise) { + var done = false; + var res = tryCallTwo(fn, function (value) { + if (done) return; + done = true; + resolve(promise, value); + }, function (reason) { + if (done) return; + done = true; + reject(promise, reason); + }); + if (!done && res === IS_ERROR) { + done = true; + reject(promise, LAST_ERROR); + } +} diff --git a/nodefrontend/node_modules/promise/domains/done.js b/nodefrontend/node_modules/promise/domains/done.js new file mode 100644 index 00000000..f879317d --- /dev/null +++ b/nodefrontend/node_modules/promise/domains/done.js @@ -0,0 +1,13 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.prototype.done = function (onFulfilled, onRejected) { + var self = arguments.length ? this.then.apply(this, arguments) : this; + self.then(null, function (err) { + setTimeout(function () { + throw err; + }, 0); + }); +}; diff --git a/nodefrontend/node_modules/promise/domains/es6-extensions.js b/nodefrontend/node_modules/promise/domains/es6-extensions.js new file mode 100644 index 00000000..24665f58 --- /dev/null +++ b/nodefrontend/node_modules/promise/domains/es6-extensions.js @@ -0,0 +1,119 @@ +'use strict'; + +//This file contains the ES6 extensions to the core Promises/A+ API + +var Promise = require('./core.js'); + +module.exports = Promise; + +/* Static Functions */ + +var TRUE = valuePromise(true); +var FALSE = valuePromise(false); +var NULL = valuePromise(null); +var UNDEFINED = valuePromise(undefined); +var ZERO = valuePromise(0); +var EMPTYSTRING = valuePromise(''); + +function valuePromise(value) { + var p = new Promise(Promise._0); + p._V = 1; + p._W = value; + return p; +} +Promise.resolve = function (value) { + if (value instanceof Promise) return value; + + if (value === null) return NULL; + if (value === undefined) return UNDEFINED; + if (value === true) return TRUE; + if (value === false) return FALSE; + if (value === 0) return ZERO; + if (value === '') return EMPTYSTRING; + + if (typeof value === 'object' || typeof value === 'function') { + try { + var then = value.then; + if (typeof then === 'function') { + return new Promise(then.bind(value)); + } + } catch (ex) { + return new Promise(function (resolve, reject) { + reject(ex); + }); + } + } + return valuePromise(value); +}; + +var iterableToArray = function (iterable) { + if (typeof Array.from === 'function') { + // ES2015+, iterables exist + iterableToArray = Array.from; + return Array.from(iterable); + } + + // ES5, only arrays and array-likes exist + iterableToArray = function (x) { return Array.prototype.slice.call(x); }; + return Array.prototype.slice.call(iterable); +} + +Promise.all = function (arr) { + var args = iterableToArray(arr); + + return new Promise(function (resolve, reject) { + if (args.length === 0) return resolve([]); + var remaining = args.length; + function res(i, val) { + if (val && (typeof val === 'object' || typeof val === 'function')) { + if (val instanceof Promise && val.then === Promise.prototype.then) { + while (val._V === 3) { + val = val._W; + } + if (val._V === 1) return res(i, val._W); + if (val._V === 2) reject(val._W); + val.then(function (val) { + res(i, val); + }, reject); + return; + } else { + var then = val.then; + if (typeof then === 'function') { + var p = new Promise(then.bind(val)); + p.then(function (val) { + res(i, val); + }, reject); + return; + } + } + } + args[i] = val; + if (--remaining === 0) { + resolve(args); + } + } + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); +}; + +Promise.reject = function (value) { + return new Promise(function (resolve, reject) { + reject(value); + }); +}; + +Promise.race = function (values) { + return new Promise(function (resolve, reject) { + iterableToArray(values).forEach(function(value){ + Promise.resolve(value).then(resolve, reject); + }); + }); +}; + +/* Prototype Methods */ + +Promise.prototype['catch'] = function (onRejected) { + return this.then(null, onRejected); +}; diff --git a/nodefrontend/node_modules/promise/domains/finally.js b/nodefrontend/node_modules/promise/domains/finally.js new file mode 100644 index 00000000..3f8a6b7a --- /dev/null +++ b/nodefrontend/node_modules/promise/domains/finally.js @@ -0,0 +1,16 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.prototype.finally = function (f) { + return this.then(function (value) { + return Promise.resolve(f()).then(function () { + return value; + }); + }, function (err) { + return Promise.resolve(f()).then(function () { + throw err; + }); + }); +}; diff --git a/nodefrontend/node_modules/promise/domains/index.js b/nodefrontend/node_modules/promise/domains/index.js new file mode 100644 index 00000000..6e674f38 --- /dev/null +++ b/nodefrontend/node_modules/promise/domains/index.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = require('./core.js'); +require('./done.js'); +require('./finally.js'); +require('./es6-extensions.js'); +require('./node-extensions.js'); +require('./synchronous.js'); diff --git a/nodefrontend/node_modules/promise/domains/node-extensions.js b/nodefrontend/node_modules/promise/domains/node-extensions.js new file mode 100644 index 00000000..157cddc2 --- /dev/null +++ b/nodefrontend/node_modules/promise/domains/node-extensions.js @@ -0,0 +1,130 @@ +'use strict'; + +// This file contains then/promise specific extensions that are only useful +// for node.js interop + +var Promise = require('./core.js'); +var asap = require('asap'); + +module.exports = Promise; + +/* Static Functions */ + +Promise.denodeify = function (fn, argumentCount) { + if ( + typeof argumentCount === 'number' && argumentCount !== Infinity + ) { + return denodeifyWithCount(fn, argumentCount); + } else { + return denodeifyWithoutCount(fn); + } +}; + +var callbackFn = ( + 'function (err, res) {' + + 'if (err) { rj(err); } else { rs(res); }' + + '}' +); +function denodeifyWithCount(fn, argumentCount) { + var args = []; + for (var i = 0; i < argumentCount; i++) { + args.push('a' + i); + } + var body = [ + 'return function (' + args.join(',') + ') {', + 'var self = this;', + 'return new Promise(function (rs, rj) {', + 'var res = fn.call(', + ['self'].concat(args).concat([callbackFn]).join(','), + ');', + 'if (res &&', + '(typeof res === "object" || typeof res === "function") &&', + 'typeof res.then === "function"', + ') {rs(res);}', + '});', + '};' + ].join(''); + return Function(['Promise', 'fn'], body)(Promise, fn); +} +function denodeifyWithoutCount(fn) { + var fnLength = Math.max(fn.length - 1, 3); + var args = []; + for (var i = 0; i < fnLength; i++) { + args.push('a' + i); + } + var body = [ + 'return function (' + args.join(',') + ') {', + 'var self = this;', + 'var args;', + 'var argLength = arguments.length;', + 'if (arguments.length > ' + fnLength + ') {', + 'args = new Array(arguments.length + 1);', + 'for (var i = 0; i < arguments.length; i++) {', + 'args[i] = arguments[i];', + '}', + '}', + 'return new Promise(function (rs, rj) {', + 'var cb = ' + callbackFn + ';', + 'var res;', + 'switch (argLength) {', + args.concat(['extra']).map(function (_, index) { + return ( + 'case ' + (index) + ':' + + 'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' + + 'break;' + ); + }).join(''), + 'default:', + 'args[argLength] = cb;', + 'res = fn.apply(self, args);', + '}', + + 'if (res &&', + '(typeof res === "object" || typeof res === "function") &&', + 'typeof res.then === "function"', + ') {rs(res);}', + '});', + '};' + ].join(''); + + return Function( + ['Promise', 'fn'], + body + )(Promise, fn); +} + +Promise.nodeify = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + var callback = + typeof args[args.length - 1] === 'function' ? args.pop() : null; + var ctx = this; + try { + return fn.apply(this, arguments).nodeify(callback, ctx); + } catch (ex) { + if (callback === null || typeof callback == 'undefined') { + return new Promise(function (resolve, reject) { + reject(ex); + }); + } else { + asap(function () { + callback.call(ctx, ex); + }) + } + } + } +}; + +Promise.prototype.nodeify = function (callback, ctx) { + if (typeof callback != 'function') return this; + + this.then(function (value) { + asap(function () { + callback.call(ctx, null, value); + }); + }, function (err) { + asap(function () { + callback.call(ctx, err); + }); + }); +}; diff --git a/nodefrontend/node_modules/promise/domains/rejection-tracking.js b/nodefrontend/node_modules/promise/domains/rejection-tracking.js new file mode 100644 index 00000000..a4be2690 --- /dev/null +++ b/nodefrontend/node_modules/promise/domains/rejection-tracking.js @@ -0,0 +1,113 @@ +'use strict'; + +var Promise = require('./core'); + +var DEFAULT_WHITELIST = [ + ReferenceError, + TypeError, + RangeError +]; + +var enabled = false; +exports.disable = disable; +function disable() { + enabled = false; + Promise._Y = null; + Promise._Z = null; +} + +exports.enable = enable; +function enable(options) { + options = options || {}; + if (enabled) disable(); + enabled = true; + var id = 0; + var displayId = 0; + var rejections = {}; + Promise._Y = function (promise) { + if ( + promise._V === 2 && // IS REJECTED + rejections[promise._1] + ) { + if (rejections[promise._1].logged) { + onHandled(promise._1); + } else { + clearTimeout(rejections[promise._1].timeout); + } + delete rejections[promise._1]; + } + }; + Promise._Z = function (promise, err) { + if (promise._U === 0) { // not yet handled + promise._1 = id++; + rejections[promise._1] = { + displayId: null, + error: err, + timeout: setTimeout( + onUnhandled.bind(null, promise._1), + // For reference errors and type errors, this almost always + // means the programmer made a mistake, so log them after just + // 100ms + // otherwise, wait 2 seconds to see if they get handled + matchWhitelist(err, DEFAULT_WHITELIST) + ? 100 + : 2000 + ), + logged: false + }; + } + }; + function onUnhandled(id) { + if ( + options.allRejections || + matchWhitelist( + rejections[id].error, + options.whitelist || DEFAULT_WHITELIST + ) + ) { + rejections[id].displayId = displayId++; + if (options.onUnhandled) { + rejections[id].logged = true; + options.onUnhandled( + rejections[id].displayId, + rejections[id].error + ); + } else { + rejections[id].logged = true; + logError( + rejections[id].displayId, + rejections[id].error + ); + } + } + } + function onHandled(id) { + if (rejections[id].logged) { + if (options.onHandled) { + options.onHandled(rejections[id].displayId, rejections[id].error); + } else if (!rejections[id].onUnhandled) { + console.warn( + 'Promise Rejection Handled (id: ' + rejections[id].displayId + '):' + ); + console.warn( + ' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id ' + + rejections[id].displayId + '.' + ); + } + } + } +} + +function logError(id, error) { + console.warn('Possible Unhandled Promise Rejection (id: ' + id + '):'); + var errStr = (error && (error.stack || error)) + ''; + errStr.split('\n').forEach(function (line) { + console.warn(' ' + line); + }); +} + +function matchWhitelist(error, list) { + return list.some(function (cls) { + return error instanceof cls; + }); +} \ No newline at end of file diff --git a/nodefrontend/node_modules/promise/domains/synchronous.js b/nodefrontend/node_modules/promise/domains/synchronous.js new file mode 100644 index 00000000..96e3705a --- /dev/null +++ b/nodefrontend/node_modules/promise/domains/synchronous.js @@ -0,0 +1,62 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.enableSynchronous = function () { + Promise.prototype.isPending = function() { + return this.getState() == 0; + }; + + Promise.prototype.isFulfilled = function() { + return this.getState() == 1; + }; + + Promise.prototype.isRejected = function() { + return this.getState() == 2; + }; + + Promise.prototype.getValue = function () { + if (this._V === 3) { + return this._W.getValue(); + } + + if (!this.isFulfilled()) { + throw new Error('Cannot get a value of an unfulfilled promise.'); + } + + return this._W; + }; + + Promise.prototype.getReason = function () { + if (this._V === 3) { + return this._W.getReason(); + } + + if (!this.isRejected()) { + throw new Error('Cannot get a rejection reason of a non-rejected promise.'); + } + + return this._W; + }; + + Promise.prototype.getState = function () { + if (this._V === 3) { + return this._W.getState(); + } + if (this._V === -1 || this._V === -2) { + return 0; + } + + return this._V; + }; +}; + +Promise.disableSynchronous = function() { + Promise.prototype.isPending = undefined; + Promise.prototype.isFulfilled = undefined; + Promise.prototype.isRejected = undefined; + Promise.prototype.getValue = undefined; + Promise.prototype.getReason = undefined; + Promise.prototype.getState = undefined; +}; diff --git a/nodefrontend/node_modules/promise/index.d.ts b/nodefrontend/node_modules/promise/index.d.ts new file mode 100644 index 00000000..e83d65f3 --- /dev/null +++ b/nodefrontend/node_modules/promise/index.d.ts @@ -0,0 +1,246 @@ +/** + * Represents the completion of an asynchronous operation + */ +interface ThenPromise extends Promise { + /** + * Attaches callbacks for the resolution and/or rejection of the ThenPromise. + * @param onfulfilled The callback to execute when the ThenPromise is resolved. + * @param onrejected The callback to execute when the ThenPromise is rejected. + * @returns A ThenPromise for the completion of which ever callback is executed. + */ + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): ThenPromise; + + /** + * Attaches a callback for only the rejection of the ThenPromise. + * @param onrejected The callback to execute when the ThenPromise is rejected. + * @returns A ThenPromise for the completion of the callback. + */ + catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): ThenPromise; + + // Extensions specific to then/promise + + /** + * Attaches callbacks for the resolution and/or rejection of the ThenPromise, without returning a new promise. + * @param onfulfilled The callback to execute when the ThenPromise is resolved. + * @param onrejected The callback to execute when the ThenPromise is rejected. + */ + done(onfulfilled?: ((value: T) => any) | undefined | null, onrejected?: ((reason: any) => any) | undefined | null): void; + + + /** + * Calls a node.js style callback. If none is provided, the promise is returned. + */ + nodeify(callback: void | null): ThenPromise; + nodeify(callback: (err: Error, value: T) => void): void; +} + +interface ThenPromiseConstructor { + /** + * A reference to the prototype. + */ + readonly prototype: ThenPromise; + + /** + * Creates a new ThenPromise. + * @param executor A callback used to initialize the promise. This callback is passed two arguments: + * a resolve callback used resolve the promise with a value or the result of another promise, + * and a reject callback used to reject the promise with a provided reason or error. + */ + new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => any): ThenPromise; + + /** + * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises + * resolve, or rejected when any ThenPromise is rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; + + /** + * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises + * resolve, or rejected when any ThenPromise is rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; + + /** + * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises + * resolve, or rejected when any ThenPromise is rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8]>; + + /** + * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises + * resolve, or rejected when any ThenPromise is rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7]>; + + /** + * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises + * resolve, or rejected when any ThenPromise is rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6]>; + + /** + * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises + * resolve, or rejected when any ThenPromise is rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5]>; + + /** + * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises + * resolve, or rejected when any ThenPromise is rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike ]): ThenPromise<[T1, T2, T3, T4]>; + + /** + * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises + * resolve, or rejected when any ThenPromise is rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): ThenPromise<[T1, T2, T3]>; + + /** + * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises + * resolve, or rejected when any ThenPromise is rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + all(values: [T1 | PromiseLike, T2 | PromiseLike]): ThenPromise<[T1, T2]>; + + /** + * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises + * resolve, or rejected when any ThenPromise is rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + all(values: (T | PromiseLike)[]): ThenPromise; + + /** + * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved + * or rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): ThenPromise; + + /** + * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved + * or rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): ThenPromise; + + /** + * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved + * or rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): ThenPromise; + + /** + * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved + * or rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): ThenPromise; + + /** + * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved + * or rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): ThenPromise; + + /** + * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved + * or rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): ThenPromise; + + /** + * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved + * or rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): ThenPromise; + + /** + * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved + * or rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): ThenPromise; + + /** + * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved + * or rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + race(values: [T1 | PromiseLike, T2 | PromiseLike]): ThenPromise; + + /** + * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved + * or rejected. + * @param values An array of Promises. + * @returns A new ThenPromise. + */ + race(values: (T | PromiseLike)[]): ThenPromise; + + /** + * Creates a new rejected promise for the provided reason. + * @param reason The reason the promise was rejected. + * @returns A new rejected ThenPromise. + */ + reject(reason: any): ThenPromise; + + /** + * Creates a new rejected promise for the provided reason. + * @param reason The reason the promise was rejected. + * @returns A new rejected ThenPromise. + */ + reject(reason: any): ThenPromise; + + /** + * Creates a new resolved promise for the provided value. + * @param value A promise. + * @returns A promise whose internal state matches the provided promise. + */ + resolve(value: T | PromiseLike): ThenPromise; + + /** + * Creates a new resolved promise . + * @returns A resolved promise. + */ + resolve(): ThenPromise; + + // Extensions specific to then/promise + + denodeify: (fn: Function) => (...args: any[]) => ThenPromise; + nodeify: (fn: Function) => Function; +} + +declare var ThenPromise: ThenPromiseConstructor; + +export = ThenPromise; \ No newline at end of file diff --git a/nodefrontend/node_modules/promise/index.js b/nodefrontend/node_modules/promise/index.js new file mode 100644 index 00000000..1c38e467 --- /dev/null +++ b/nodefrontend/node_modules/promise/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./lib') diff --git a/nodefrontend/node_modules/promise/index.js.flow b/nodefrontend/node_modules/promise/index.js.flow new file mode 100644 index 00000000..9c390d47 --- /dev/null +++ b/nodefrontend/node_modules/promise/index.js.flow @@ -0,0 +1,52 @@ +// @flow + +declare class ThenPromise<+R> extends Promise { + constructor(callback: ( + resolve: (result: Promise | R) => void, + reject: (error: any) => void + ) => mixed): void; + + + then(onFulfill: null | void, onReject: null | void): ThenPromise; + then( + onFulfill: null | void, + onReject: (error: any) => Promise | U + ): ThenPromise; + then( + onFulfill: (value: R) => Promise | U, + onReject: null | void | ((error: any) => Promise | U) + ): ThenPromise; + + + catch(onReject: null | void): ThenPromise; + catch( + onReject: (error: any) => Promise | U + ): ThenPromise; + + // Extensions specific to then/promise + + /** + * Attaches callbacks for the resolution and/or rejection of the ThenPromise, without returning a new promise. + * @param onfulfilled The callback to execute when the ThenPromise is resolved. + * @param onrejected The callback to execute when the ThenPromise is rejected. + */ + done(onfulfilled?: (value: R) => any, onrejected?: (reason: any) => any): void; + + + /** + * Calls a node.js style callback. If none is provided, the promise is returned. + */ + nodeify(callback: void | null): ThenPromise; + nodeify(callback: (err: Error, value: R) => void): void; + + static resolve(object: Promise | T): ThenPromise; + static reject(error?: any): ThenPromise; + static all>(promises: T): ThenPromise<$TupleMap>; + static race | T>(promises: Iterable): ThenPromise; + + // Extensions specific to then/promise + + static denodeify(fn: Function): (...args: any[]) => ThenPromise; + static nodeify(fn: Function): Function; +} +module.exports = ThenPromise; diff --git a/nodefrontend/node_modules/promise/lib/core.js b/nodefrontend/node_modules/promise/lib/core.js new file mode 100644 index 00000000..2cc02263 --- /dev/null +++ b/nodefrontend/node_modules/promise/lib/core.js @@ -0,0 +1,213 @@ +'use strict'; + +var asap = require('asap/raw'); + +function noop() {} + +// States: +// +// 0 - pending +// 1 - fulfilled with _value +// 2 - rejected with _value +// 3 - adopted the state of another promise, _value +// +// once the state is no longer pending (0) it is immutable + +// All `_` prefixed properties will be reduced to `_{random number}` +// at build time to obfuscate them and discourage their use. +// We don't use symbols or Object.defineProperty to fully hide them +// because the performance isn't good enough. + + +// to avoid using try/catch inside critical functions, we +// extract them to here. +var LAST_ERROR = null; +var IS_ERROR = {}; +function getThen(obj) { + try { + return obj.then; + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} + +function tryCallOne(fn, a) { + try { + return fn(a); + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} +function tryCallTwo(fn, a, b) { + try { + fn(a, b); + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} + +module.exports = Promise; + +function Promise(fn) { + if (typeof this !== 'object') { + throw new TypeError('Promises must be constructed via new'); + } + if (typeof fn !== 'function') { + throw new TypeError('Promise constructor\'s argument is not a function'); + } + this._U = 0; + this._V = 0; + this._W = null; + this._X = null; + if (fn === noop) return; + doResolve(fn, this); +} +Promise._Y = null; +Promise._Z = null; +Promise._0 = noop; + +Promise.prototype.then = function(onFulfilled, onRejected) { + if (this.constructor !== Promise) { + return safeThen(this, onFulfilled, onRejected); + } + var res = new Promise(noop); + handle(this, new Handler(onFulfilled, onRejected, res)); + return res; +}; + +function safeThen(self, onFulfilled, onRejected) { + return new self.constructor(function (resolve, reject) { + var res = new Promise(noop); + res.then(resolve, reject); + handle(self, new Handler(onFulfilled, onRejected, res)); + }); +} +function handle(self, deferred) { + while (self._V === 3) { + self = self._W; + } + if (Promise._Y) { + Promise._Y(self); + } + if (self._V === 0) { + if (self._U === 0) { + self._U = 1; + self._X = deferred; + return; + } + if (self._U === 1) { + self._U = 2; + self._X = [self._X, deferred]; + return; + } + self._X.push(deferred); + return; + } + handleResolved(self, deferred); +} + +function handleResolved(self, deferred) { + asap(function() { + var cb = self._V === 1 ? deferred.onFulfilled : deferred.onRejected; + if (cb === null) { + if (self._V === 1) { + resolve(deferred.promise, self._W); + } else { + reject(deferred.promise, self._W); + } + return; + } + var ret = tryCallOne(cb, self._W); + if (ret === IS_ERROR) { + reject(deferred.promise, LAST_ERROR); + } else { + resolve(deferred.promise, ret); + } + }); +} +function resolve(self, newValue) { + // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === self) { + return reject( + self, + new TypeError('A promise cannot be resolved with itself.') + ); + } + if ( + newValue && + (typeof newValue === 'object' || typeof newValue === 'function') + ) { + var then = getThen(newValue); + if (then === IS_ERROR) { + return reject(self, LAST_ERROR); + } + if ( + then === self.then && + newValue instanceof Promise + ) { + self._V = 3; + self._W = newValue; + finale(self); + return; + } else if (typeof then === 'function') { + doResolve(then.bind(newValue), self); + return; + } + } + self._V = 1; + self._W = newValue; + finale(self); +} + +function reject(self, newValue) { + self._V = 2; + self._W = newValue; + if (Promise._Z) { + Promise._Z(self, newValue); + } + finale(self); +} +function finale(self) { + if (self._U === 1) { + handle(self, self._X); + self._X = null; + } + if (self._U === 2) { + for (var i = 0; i < self._X.length; i++) { + handle(self, self._X[i]); + } + self._X = null; + } +} + +function Handler(onFulfilled, onRejected, promise){ + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; + this.onRejected = typeof onRejected === 'function' ? onRejected : null; + this.promise = promise; +} + +/** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ +function doResolve(fn, promise) { + var done = false; + var res = tryCallTwo(fn, function (value) { + if (done) return; + done = true; + resolve(promise, value); + }, function (reason) { + if (done) return; + done = true; + reject(promise, reason); + }); + if (!done && res === IS_ERROR) { + done = true; + reject(promise, LAST_ERROR); + } +} diff --git a/nodefrontend/node_modules/promise/lib/done.js b/nodefrontend/node_modules/promise/lib/done.js new file mode 100644 index 00000000..f879317d --- /dev/null +++ b/nodefrontend/node_modules/promise/lib/done.js @@ -0,0 +1,13 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.prototype.done = function (onFulfilled, onRejected) { + var self = arguments.length ? this.then.apply(this, arguments) : this; + self.then(null, function (err) { + setTimeout(function () { + throw err; + }, 0); + }); +}; diff --git a/nodefrontend/node_modules/promise/lib/es6-extensions.js b/nodefrontend/node_modules/promise/lib/es6-extensions.js new file mode 100644 index 00000000..24665f58 --- /dev/null +++ b/nodefrontend/node_modules/promise/lib/es6-extensions.js @@ -0,0 +1,119 @@ +'use strict'; + +//This file contains the ES6 extensions to the core Promises/A+ API + +var Promise = require('./core.js'); + +module.exports = Promise; + +/* Static Functions */ + +var TRUE = valuePromise(true); +var FALSE = valuePromise(false); +var NULL = valuePromise(null); +var UNDEFINED = valuePromise(undefined); +var ZERO = valuePromise(0); +var EMPTYSTRING = valuePromise(''); + +function valuePromise(value) { + var p = new Promise(Promise._0); + p._V = 1; + p._W = value; + return p; +} +Promise.resolve = function (value) { + if (value instanceof Promise) return value; + + if (value === null) return NULL; + if (value === undefined) return UNDEFINED; + if (value === true) return TRUE; + if (value === false) return FALSE; + if (value === 0) return ZERO; + if (value === '') return EMPTYSTRING; + + if (typeof value === 'object' || typeof value === 'function') { + try { + var then = value.then; + if (typeof then === 'function') { + return new Promise(then.bind(value)); + } + } catch (ex) { + return new Promise(function (resolve, reject) { + reject(ex); + }); + } + } + return valuePromise(value); +}; + +var iterableToArray = function (iterable) { + if (typeof Array.from === 'function') { + // ES2015+, iterables exist + iterableToArray = Array.from; + return Array.from(iterable); + } + + // ES5, only arrays and array-likes exist + iterableToArray = function (x) { return Array.prototype.slice.call(x); }; + return Array.prototype.slice.call(iterable); +} + +Promise.all = function (arr) { + var args = iterableToArray(arr); + + return new Promise(function (resolve, reject) { + if (args.length === 0) return resolve([]); + var remaining = args.length; + function res(i, val) { + if (val && (typeof val === 'object' || typeof val === 'function')) { + if (val instanceof Promise && val.then === Promise.prototype.then) { + while (val._V === 3) { + val = val._W; + } + if (val._V === 1) return res(i, val._W); + if (val._V === 2) reject(val._W); + val.then(function (val) { + res(i, val); + }, reject); + return; + } else { + var then = val.then; + if (typeof then === 'function') { + var p = new Promise(then.bind(val)); + p.then(function (val) { + res(i, val); + }, reject); + return; + } + } + } + args[i] = val; + if (--remaining === 0) { + resolve(args); + } + } + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); +}; + +Promise.reject = function (value) { + return new Promise(function (resolve, reject) { + reject(value); + }); +}; + +Promise.race = function (values) { + return new Promise(function (resolve, reject) { + iterableToArray(values).forEach(function(value){ + Promise.resolve(value).then(resolve, reject); + }); + }); +}; + +/* Prototype Methods */ + +Promise.prototype['catch'] = function (onRejected) { + return this.then(null, onRejected); +}; diff --git a/nodefrontend/node_modules/promise/lib/finally.js b/nodefrontend/node_modules/promise/lib/finally.js new file mode 100644 index 00000000..3f8a6b7a --- /dev/null +++ b/nodefrontend/node_modules/promise/lib/finally.js @@ -0,0 +1,16 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.prototype.finally = function (f) { + return this.then(function (value) { + return Promise.resolve(f()).then(function () { + return value; + }); + }, function (err) { + return Promise.resolve(f()).then(function () { + throw err; + }); + }); +}; diff --git a/nodefrontend/node_modules/promise/lib/index.js b/nodefrontend/node_modules/promise/lib/index.js new file mode 100644 index 00000000..6e674f38 --- /dev/null +++ b/nodefrontend/node_modules/promise/lib/index.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = require('./core.js'); +require('./done.js'); +require('./finally.js'); +require('./es6-extensions.js'); +require('./node-extensions.js'); +require('./synchronous.js'); diff --git a/nodefrontend/node_modules/promise/lib/node-extensions.js b/nodefrontend/node_modules/promise/lib/node-extensions.js new file mode 100644 index 00000000..157cddc2 --- /dev/null +++ b/nodefrontend/node_modules/promise/lib/node-extensions.js @@ -0,0 +1,130 @@ +'use strict'; + +// This file contains then/promise specific extensions that are only useful +// for node.js interop + +var Promise = require('./core.js'); +var asap = require('asap'); + +module.exports = Promise; + +/* Static Functions */ + +Promise.denodeify = function (fn, argumentCount) { + if ( + typeof argumentCount === 'number' && argumentCount !== Infinity + ) { + return denodeifyWithCount(fn, argumentCount); + } else { + return denodeifyWithoutCount(fn); + } +}; + +var callbackFn = ( + 'function (err, res) {' + + 'if (err) { rj(err); } else { rs(res); }' + + '}' +); +function denodeifyWithCount(fn, argumentCount) { + var args = []; + for (var i = 0; i < argumentCount; i++) { + args.push('a' + i); + } + var body = [ + 'return function (' + args.join(',') + ') {', + 'var self = this;', + 'return new Promise(function (rs, rj) {', + 'var res = fn.call(', + ['self'].concat(args).concat([callbackFn]).join(','), + ');', + 'if (res &&', + '(typeof res === "object" || typeof res === "function") &&', + 'typeof res.then === "function"', + ') {rs(res);}', + '});', + '};' + ].join(''); + return Function(['Promise', 'fn'], body)(Promise, fn); +} +function denodeifyWithoutCount(fn) { + var fnLength = Math.max(fn.length - 1, 3); + var args = []; + for (var i = 0; i < fnLength; i++) { + args.push('a' + i); + } + var body = [ + 'return function (' + args.join(',') + ') {', + 'var self = this;', + 'var args;', + 'var argLength = arguments.length;', + 'if (arguments.length > ' + fnLength + ') {', + 'args = new Array(arguments.length + 1);', + 'for (var i = 0; i < arguments.length; i++) {', + 'args[i] = arguments[i];', + '}', + '}', + 'return new Promise(function (rs, rj) {', + 'var cb = ' + callbackFn + ';', + 'var res;', + 'switch (argLength) {', + args.concat(['extra']).map(function (_, index) { + return ( + 'case ' + (index) + ':' + + 'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' + + 'break;' + ); + }).join(''), + 'default:', + 'args[argLength] = cb;', + 'res = fn.apply(self, args);', + '}', + + 'if (res &&', + '(typeof res === "object" || typeof res === "function") &&', + 'typeof res.then === "function"', + ') {rs(res);}', + '});', + '};' + ].join(''); + + return Function( + ['Promise', 'fn'], + body + )(Promise, fn); +} + +Promise.nodeify = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + var callback = + typeof args[args.length - 1] === 'function' ? args.pop() : null; + var ctx = this; + try { + return fn.apply(this, arguments).nodeify(callback, ctx); + } catch (ex) { + if (callback === null || typeof callback == 'undefined') { + return new Promise(function (resolve, reject) { + reject(ex); + }); + } else { + asap(function () { + callback.call(ctx, ex); + }) + } + } + } +}; + +Promise.prototype.nodeify = function (callback, ctx) { + if (typeof callback != 'function') return this; + + this.then(function (value) { + asap(function () { + callback.call(ctx, null, value); + }); + }, function (err) { + asap(function () { + callback.call(ctx, err); + }); + }); +}; diff --git a/nodefrontend/node_modules/promise/lib/rejection-tracking.js b/nodefrontend/node_modules/promise/lib/rejection-tracking.js new file mode 100644 index 00000000..a4be2690 --- /dev/null +++ b/nodefrontend/node_modules/promise/lib/rejection-tracking.js @@ -0,0 +1,113 @@ +'use strict'; + +var Promise = require('./core'); + +var DEFAULT_WHITELIST = [ + ReferenceError, + TypeError, + RangeError +]; + +var enabled = false; +exports.disable = disable; +function disable() { + enabled = false; + Promise._Y = null; + Promise._Z = null; +} + +exports.enable = enable; +function enable(options) { + options = options || {}; + if (enabled) disable(); + enabled = true; + var id = 0; + var displayId = 0; + var rejections = {}; + Promise._Y = function (promise) { + if ( + promise._V === 2 && // IS REJECTED + rejections[promise._1] + ) { + if (rejections[promise._1].logged) { + onHandled(promise._1); + } else { + clearTimeout(rejections[promise._1].timeout); + } + delete rejections[promise._1]; + } + }; + Promise._Z = function (promise, err) { + if (promise._U === 0) { // not yet handled + promise._1 = id++; + rejections[promise._1] = { + displayId: null, + error: err, + timeout: setTimeout( + onUnhandled.bind(null, promise._1), + // For reference errors and type errors, this almost always + // means the programmer made a mistake, so log them after just + // 100ms + // otherwise, wait 2 seconds to see if they get handled + matchWhitelist(err, DEFAULT_WHITELIST) + ? 100 + : 2000 + ), + logged: false + }; + } + }; + function onUnhandled(id) { + if ( + options.allRejections || + matchWhitelist( + rejections[id].error, + options.whitelist || DEFAULT_WHITELIST + ) + ) { + rejections[id].displayId = displayId++; + if (options.onUnhandled) { + rejections[id].logged = true; + options.onUnhandled( + rejections[id].displayId, + rejections[id].error + ); + } else { + rejections[id].logged = true; + logError( + rejections[id].displayId, + rejections[id].error + ); + } + } + } + function onHandled(id) { + if (rejections[id].logged) { + if (options.onHandled) { + options.onHandled(rejections[id].displayId, rejections[id].error); + } else if (!rejections[id].onUnhandled) { + console.warn( + 'Promise Rejection Handled (id: ' + rejections[id].displayId + '):' + ); + console.warn( + ' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id ' + + rejections[id].displayId + '.' + ); + } + } + } +} + +function logError(id, error) { + console.warn('Possible Unhandled Promise Rejection (id: ' + id + '):'); + var errStr = (error && (error.stack || error)) + ''; + errStr.split('\n').forEach(function (line) { + console.warn(' ' + line); + }); +} + +function matchWhitelist(error, list) { + return list.some(function (cls) { + return error instanceof cls; + }); +} \ No newline at end of file diff --git a/nodefrontend/node_modules/promise/lib/synchronous.js b/nodefrontend/node_modules/promise/lib/synchronous.js new file mode 100644 index 00000000..96e3705a --- /dev/null +++ b/nodefrontend/node_modules/promise/lib/synchronous.js @@ -0,0 +1,62 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.enableSynchronous = function () { + Promise.prototype.isPending = function() { + return this.getState() == 0; + }; + + Promise.prototype.isFulfilled = function() { + return this.getState() == 1; + }; + + Promise.prototype.isRejected = function() { + return this.getState() == 2; + }; + + Promise.prototype.getValue = function () { + if (this._V === 3) { + return this._W.getValue(); + } + + if (!this.isFulfilled()) { + throw new Error('Cannot get a value of an unfulfilled promise.'); + } + + return this._W; + }; + + Promise.prototype.getReason = function () { + if (this._V === 3) { + return this._W.getReason(); + } + + if (!this.isRejected()) { + throw new Error('Cannot get a rejection reason of a non-rejected promise.'); + } + + return this._W; + }; + + Promise.prototype.getState = function () { + if (this._V === 3) { + return this._W.getState(); + } + if (this._V === -1 || this._V === -2) { + return 0; + } + + return this._V; + }; +}; + +Promise.disableSynchronous = function() { + Promise.prototype.isPending = undefined; + Promise.prototype.isFulfilled = undefined; + Promise.prototype.isRejected = undefined; + Promise.prototype.getValue = undefined; + Promise.prototype.getReason = undefined; + Promise.prototype.getState = undefined; +}; diff --git a/nodefrontend/node_modules/promise/package.json b/nodefrontend/node_modules/promise/package.json new file mode 100644 index 00000000..c2ebdd3a --- /dev/null +++ b/nodefrontend/node_modules/promise/package.json @@ -0,0 +1,67 @@ +{ + "_from": "promise", + "_id": "promise@8.1.0", + "_inBundle": false, + "_integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "_location": "/promise", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "promise", + "name": "promise", + "escapedName": "promise", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "_shasum": "697c25c3dfe7435dd79fcd58c38a135888eaf05e", + "_spec": "promise", + "_where": "/home/alpcentaur/ProjektA/PrototypeWebApp/nodefrontend", + "author": { + "name": "ForbesLindesay" + }, + "bugs": { + "url": "https://github.com/then/promise/issues" + }, + "bundleDependencies": false, + "dependencies": { + "asap": "~2.0.6" + }, + "deprecated": false, + "description": "Bare bones Promises/A+ implementation", + "devDependencies": { + "acorn": "^1.0.1", + "better-assert": "*", + "istanbul": "^0.3.13", + "mocha": "*", + "promises-aplus-tests": "*", + "rimraf": "^2.3.2" + }, + "homepage": "https://github.com/then/promise#readme", + "license": "MIT", + "main": "index.js", + "name": "promise", + "repository": { + "type": "git", + "url": "git+https://github.com/then/promise.git" + }, + "scripts": { + "coverage": "istanbul cover node_modules/mocha/bin/_mocha -- --bail --timeout 200 --slow 99999 -R dot", + "prepublish": "node build", + "pretest": "node build", + "pretest-extensions": "node build", + "pretest-memory-leak": "node build", + "pretest-resolve": "node build", + "test": "mocha --bail --timeout 200 --slow 99999 -R dot && npm run test-memory-leak", + "test-extensions": "mocha test/extensions-tests.js --timeout 200 --slow 999999", + "test-memory-leak": "node --expose-gc test/memory-leak.js", + "test-resolve": "mocha test/resolver-tests.js --timeout 200 --slow 999999" + }, + "version": "8.1.0" +} diff --git a/nodefrontend/node_modules/promise/polyfill-done.js b/nodefrontend/node_modules/promise/polyfill-done.js new file mode 100644 index 00000000..e50b4c0e --- /dev/null +++ b/nodefrontend/node_modules/promise/polyfill-done.js @@ -0,0 +1,12 @@ +// should work in any browser without browserify + +if (typeof Promise.prototype.done !== 'function') { + Promise.prototype.done = function (onFulfilled, onRejected) { + var self = arguments.length ? this.then.apply(this, arguments) : this + self.then(null, function (err) { + setTimeout(function () { + throw err + }, 0) + }) + } +} \ No newline at end of file diff --git a/nodefrontend/node_modules/promise/polyfill.js b/nodefrontend/node_modules/promise/polyfill.js new file mode 100644 index 00000000..db099f8e --- /dev/null +++ b/nodefrontend/node_modules/promise/polyfill.js @@ -0,0 +1,10 @@ +// not "use strict" so we can declare global "Promise" + +var asap = require('asap'); + +if (typeof Promise === 'undefined') { + Promise = require('./lib/core.js') + require('./lib/es6-extensions.js') +} + +require('./polyfill-done.js'); diff --git a/nodefrontend/node_modules/promise/setimmediate/core.js b/nodefrontend/node_modules/promise/setimmediate/core.js new file mode 100644 index 00000000..7a261921 --- /dev/null +++ b/nodefrontend/node_modules/promise/setimmediate/core.js @@ -0,0 +1,213 @@ +'use strict'; + + + +function noop() {} + +// States: +// +// 0 - pending +// 1 - fulfilled with _value +// 2 - rejected with _value +// 3 - adopted the state of another promise, _value +// +// once the state is no longer pending (0) it is immutable + +// All `_` prefixed properties will be reduced to `_{random number}` +// at build time to obfuscate them and discourage their use. +// We don't use symbols or Object.defineProperty to fully hide them +// because the performance isn't good enough. + + +// to avoid using try/catch inside critical functions, we +// extract them to here. +var LAST_ERROR = null; +var IS_ERROR = {}; +function getThen(obj) { + try { + return obj.then; + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} + +function tryCallOne(fn, a) { + try { + return fn(a); + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} +function tryCallTwo(fn, a, b) { + try { + fn(a, b); + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} + +module.exports = Promise; + +function Promise(fn) { + if (typeof this !== 'object') { + throw new TypeError('Promises must be constructed via new'); + } + if (typeof fn !== 'function') { + throw new TypeError('Promise constructor\'s argument is not a function'); + } + this._U = 0; + this._V = 0; + this._W = null; + this._X = null; + if (fn === noop) return; + doResolve(fn, this); +} +Promise._Y = null; +Promise._Z = null; +Promise._0 = noop; + +Promise.prototype.then = function(onFulfilled, onRejected) { + if (this.constructor !== Promise) { + return safeThen(this, onFulfilled, onRejected); + } + var res = new Promise(noop); + handle(this, new Handler(onFulfilled, onRejected, res)); + return res; +}; + +function safeThen(self, onFulfilled, onRejected) { + return new self.constructor(function (resolve, reject) { + var res = new Promise(noop); + res.then(resolve, reject); + handle(self, new Handler(onFulfilled, onRejected, res)); + }); +} +function handle(self, deferred) { + while (self._V === 3) { + self = self._W; + } + if (Promise._Y) { + Promise._Y(self); + } + if (self._V === 0) { + if (self._U === 0) { + self._U = 1; + self._X = deferred; + return; + } + if (self._U === 1) { + self._U = 2; + self._X = [self._X, deferred]; + return; + } + self._X.push(deferred); + return; + } + handleResolved(self, deferred); +} + +function handleResolved(self, deferred) { + setImmediate(function() { + var cb = self._V === 1 ? deferred.onFulfilled : deferred.onRejected; + if (cb === null) { + if (self._V === 1) { + resolve(deferred.promise, self._W); + } else { + reject(deferred.promise, self._W); + } + return; + } + var ret = tryCallOne(cb, self._W); + if (ret === IS_ERROR) { + reject(deferred.promise, LAST_ERROR); + } else { + resolve(deferred.promise, ret); + } + }); +} +function resolve(self, newValue) { + // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === self) { + return reject( + self, + new TypeError('A promise cannot be resolved with itself.') + ); + } + if ( + newValue && + (typeof newValue === 'object' || typeof newValue === 'function') + ) { + var then = getThen(newValue); + if (then === IS_ERROR) { + return reject(self, LAST_ERROR); + } + if ( + then === self.then && + newValue instanceof Promise + ) { + self._V = 3; + self._W = newValue; + finale(self); + return; + } else if (typeof then === 'function') { + doResolve(then.bind(newValue), self); + return; + } + } + self._V = 1; + self._W = newValue; + finale(self); +} + +function reject(self, newValue) { + self._V = 2; + self._W = newValue; + if (Promise._Z) { + Promise._Z(self, newValue); + } + finale(self); +} +function finale(self) { + if (self._U === 1) { + handle(self, self._X); + self._X = null; + } + if (self._U === 2) { + for (var i = 0; i < self._X.length; i++) { + handle(self, self._X[i]); + } + self._X = null; + } +} + +function Handler(onFulfilled, onRejected, promise){ + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; + this.onRejected = typeof onRejected === 'function' ? onRejected : null; + this.promise = promise; +} + +/** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ +function doResolve(fn, promise) { + var done = false; + var res = tryCallTwo(fn, function (value) { + if (done) return; + done = true; + resolve(promise, value); + }, function (reason) { + if (done) return; + done = true; + reject(promise, reason); + }); + if (!done && res === IS_ERROR) { + done = true; + reject(promise, LAST_ERROR); + } +} diff --git a/nodefrontend/node_modules/promise/setimmediate/done.js b/nodefrontend/node_modules/promise/setimmediate/done.js new file mode 100644 index 00000000..f879317d --- /dev/null +++ b/nodefrontend/node_modules/promise/setimmediate/done.js @@ -0,0 +1,13 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.prototype.done = function (onFulfilled, onRejected) { + var self = arguments.length ? this.then.apply(this, arguments) : this; + self.then(null, function (err) { + setTimeout(function () { + throw err; + }, 0); + }); +}; diff --git a/nodefrontend/node_modules/promise/setimmediate/es6-extensions.js b/nodefrontend/node_modules/promise/setimmediate/es6-extensions.js new file mode 100644 index 00000000..24665f58 --- /dev/null +++ b/nodefrontend/node_modules/promise/setimmediate/es6-extensions.js @@ -0,0 +1,119 @@ +'use strict'; + +//This file contains the ES6 extensions to the core Promises/A+ API + +var Promise = require('./core.js'); + +module.exports = Promise; + +/* Static Functions */ + +var TRUE = valuePromise(true); +var FALSE = valuePromise(false); +var NULL = valuePromise(null); +var UNDEFINED = valuePromise(undefined); +var ZERO = valuePromise(0); +var EMPTYSTRING = valuePromise(''); + +function valuePromise(value) { + var p = new Promise(Promise._0); + p._V = 1; + p._W = value; + return p; +} +Promise.resolve = function (value) { + if (value instanceof Promise) return value; + + if (value === null) return NULL; + if (value === undefined) return UNDEFINED; + if (value === true) return TRUE; + if (value === false) return FALSE; + if (value === 0) return ZERO; + if (value === '') return EMPTYSTRING; + + if (typeof value === 'object' || typeof value === 'function') { + try { + var then = value.then; + if (typeof then === 'function') { + return new Promise(then.bind(value)); + } + } catch (ex) { + return new Promise(function (resolve, reject) { + reject(ex); + }); + } + } + return valuePromise(value); +}; + +var iterableToArray = function (iterable) { + if (typeof Array.from === 'function') { + // ES2015+, iterables exist + iterableToArray = Array.from; + return Array.from(iterable); + } + + // ES5, only arrays and array-likes exist + iterableToArray = function (x) { return Array.prototype.slice.call(x); }; + return Array.prototype.slice.call(iterable); +} + +Promise.all = function (arr) { + var args = iterableToArray(arr); + + return new Promise(function (resolve, reject) { + if (args.length === 0) return resolve([]); + var remaining = args.length; + function res(i, val) { + if (val && (typeof val === 'object' || typeof val === 'function')) { + if (val instanceof Promise && val.then === Promise.prototype.then) { + while (val._V === 3) { + val = val._W; + } + if (val._V === 1) return res(i, val._W); + if (val._V === 2) reject(val._W); + val.then(function (val) { + res(i, val); + }, reject); + return; + } else { + var then = val.then; + if (typeof then === 'function') { + var p = new Promise(then.bind(val)); + p.then(function (val) { + res(i, val); + }, reject); + return; + } + } + } + args[i] = val; + if (--remaining === 0) { + resolve(args); + } + } + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); +}; + +Promise.reject = function (value) { + return new Promise(function (resolve, reject) { + reject(value); + }); +}; + +Promise.race = function (values) { + return new Promise(function (resolve, reject) { + iterableToArray(values).forEach(function(value){ + Promise.resolve(value).then(resolve, reject); + }); + }); +}; + +/* Prototype Methods */ + +Promise.prototype['catch'] = function (onRejected) { + return this.then(null, onRejected); +}; diff --git a/nodefrontend/node_modules/promise/setimmediate/finally.js b/nodefrontend/node_modules/promise/setimmediate/finally.js new file mode 100644 index 00000000..3f8a6b7a --- /dev/null +++ b/nodefrontend/node_modules/promise/setimmediate/finally.js @@ -0,0 +1,16 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.prototype.finally = function (f) { + return this.then(function (value) { + return Promise.resolve(f()).then(function () { + return value; + }); + }, function (err) { + return Promise.resolve(f()).then(function () { + throw err; + }); + }); +}; diff --git a/nodefrontend/node_modules/promise/setimmediate/index.js b/nodefrontend/node_modules/promise/setimmediate/index.js new file mode 100644 index 00000000..6e674f38 --- /dev/null +++ b/nodefrontend/node_modules/promise/setimmediate/index.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = require('./core.js'); +require('./done.js'); +require('./finally.js'); +require('./es6-extensions.js'); +require('./node-extensions.js'); +require('./synchronous.js'); diff --git a/nodefrontend/node_modules/promise/setimmediate/node-extensions.js b/nodefrontend/node_modules/promise/setimmediate/node-extensions.js new file mode 100644 index 00000000..f03e861d --- /dev/null +++ b/nodefrontend/node_modules/promise/setimmediate/node-extensions.js @@ -0,0 +1,130 @@ +'use strict'; + +// This file contains then/promise specific extensions that are only useful +// for node.js interop + +var Promise = require('./core.js'); + + +module.exports = Promise; + +/* Static Functions */ + +Promise.denodeify = function (fn, argumentCount) { + if ( + typeof argumentCount === 'number' && argumentCount !== Infinity + ) { + return denodeifyWithCount(fn, argumentCount); + } else { + return denodeifyWithoutCount(fn); + } +}; + +var callbackFn = ( + 'function (err, res) {' + + 'if (err) { rj(err); } else { rs(res); }' + + '}' +); +function denodeifyWithCount(fn, argumentCount) { + var args = []; + for (var i = 0; i < argumentCount; i++) { + args.push('a' + i); + } + var body = [ + 'return function (' + args.join(',') + ') {', + 'var self = this;', + 'return new Promise(function (rs, rj) {', + 'var res = fn.call(', + ['self'].concat(args).concat([callbackFn]).join(','), + ');', + 'if (res &&', + '(typeof res === "object" || typeof res === "function") &&', + 'typeof res.then === "function"', + ') {rs(res);}', + '});', + '};' + ].join(''); + return Function(['Promise', 'fn'], body)(Promise, fn); +} +function denodeifyWithoutCount(fn) { + var fnLength = Math.max(fn.length - 1, 3); + var args = []; + for (var i = 0; i < fnLength; i++) { + args.push('a' + i); + } + var body = [ + 'return function (' + args.join(',') + ') {', + 'var self = this;', + 'var args;', + 'var argLength = arguments.length;', + 'if (arguments.length > ' + fnLength + ') {', + 'args = new Array(arguments.length + 1);', + 'for (var i = 0; i < arguments.length; i++) {', + 'args[i] = arguments[i];', + '}', + '}', + 'return new Promise(function (rs, rj) {', + 'var cb = ' + callbackFn + ';', + 'var res;', + 'switch (argLength) {', + args.concat(['extra']).map(function (_, index) { + return ( + 'case ' + (index) + ':' + + 'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' + + 'break;' + ); + }).join(''), + 'default:', + 'args[argLength] = cb;', + 'res = fn.apply(self, args);', + '}', + + 'if (res &&', + '(typeof res === "object" || typeof res === "function") &&', + 'typeof res.then === "function"', + ') {rs(res);}', + '});', + '};' + ].join(''); + + return Function( + ['Promise', 'fn'], + body + )(Promise, fn); +} + +Promise.nodeify = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + var callback = + typeof args[args.length - 1] === 'function' ? args.pop() : null; + var ctx = this; + try { + return fn.apply(this, arguments).nodeify(callback, ctx); + } catch (ex) { + if (callback === null || typeof callback == 'undefined') { + return new Promise(function (resolve, reject) { + reject(ex); + }); + } else { + setImmediate(function () { + callback.call(ctx, ex); + }) + } + } + } +}; + +Promise.prototype.nodeify = function (callback, ctx) { + if (typeof callback != 'function') return this; + + this.then(function (value) { + setImmediate(function () { + callback.call(ctx, null, value); + }); + }, function (err) { + setImmediate(function () { + callback.call(ctx, err); + }); + }); +}; diff --git a/nodefrontend/node_modules/promise/setimmediate/rejection-tracking.js b/nodefrontend/node_modules/promise/setimmediate/rejection-tracking.js new file mode 100644 index 00000000..a4be2690 --- /dev/null +++ b/nodefrontend/node_modules/promise/setimmediate/rejection-tracking.js @@ -0,0 +1,113 @@ +'use strict'; + +var Promise = require('./core'); + +var DEFAULT_WHITELIST = [ + ReferenceError, + TypeError, + RangeError +]; + +var enabled = false; +exports.disable = disable; +function disable() { + enabled = false; + Promise._Y = null; + Promise._Z = null; +} + +exports.enable = enable; +function enable(options) { + options = options || {}; + if (enabled) disable(); + enabled = true; + var id = 0; + var displayId = 0; + var rejections = {}; + Promise._Y = function (promise) { + if ( + promise._V === 2 && // IS REJECTED + rejections[promise._1] + ) { + if (rejections[promise._1].logged) { + onHandled(promise._1); + } else { + clearTimeout(rejections[promise._1].timeout); + } + delete rejections[promise._1]; + } + }; + Promise._Z = function (promise, err) { + if (promise._U === 0) { // not yet handled + promise._1 = id++; + rejections[promise._1] = { + displayId: null, + error: err, + timeout: setTimeout( + onUnhandled.bind(null, promise._1), + // For reference errors and type errors, this almost always + // means the programmer made a mistake, so log them after just + // 100ms + // otherwise, wait 2 seconds to see if they get handled + matchWhitelist(err, DEFAULT_WHITELIST) + ? 100 + : 2000 + ), + logged: false + }; + } + }; + function onUnhandled(id) { + if ( + options.allRejections || + matchWhitelist( + rejections[id].error, + options.whitelist || DEFAULT_WHITELIST + ) + ) { + rejections[id].displayId = displayId++; + if (options.onUnhandled) { + rejections[id].logged = true; + options.onUnhandled( + rejections[id].displayId, + rejections[id].error + ); + } else { + rejections[id].logged = true; + logError( + rejections[id].displayId, + rejections[id].error + ); + } + } + } + function onHandled(id) { + if (rejections[id].logged) { + if (options.onHandled) { + options.onHandled(rejections[id].displayId, rejections[id].error); + } else if (!rejections[id].onUnhandled) { + console.warn( + 'Promise Rejection Handled (id: ' + rejections[id].displayId + '):' + ); + console.warn( + ' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id ' + + rejections[id].displayId + '.' + ); + } + } + } +} + +function logError(id, error) { + console.warn('Possible Unhandled Promise Rejection (id: ' + id + '):'); + var errStr = (error && (error.stack || error)) + ''; + errStr.split('\n').forEach(function (line) { + console.warn(' ' + line); + }); +} + +function matchWhitelist(error, list) { + return list.some(function (cls) { + return error instanceof cls; + }); +} \ No newline at end of file diff --git a/nodefrontend/node_modules/promise/setimmediate/synchronous.js b/nodefrontend/node_modules/promise/setimmediate/synchronous.js new file mode 100644 index 00000000..96e3705a --- /dev/null +++ b/nodefrontend/node_modules/promise/setimmediate/synchronous.js @@ -0,0 +1,62 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.enableSynchronous = function () { + Promise.prototype.isPending = function() { + return this.getState() == 0; + }; + + Promise.prototype.isFulfilled = function() { + return this.getState() == 1; + }; + + Promise.prototype.isRejected = function() { + return this.getState() == 2; + }; + + Promise.prototype.getValue = function () { + if (this._V === 3) { + return this._W.getValue(); + } + + if (!this.isFulfilled()) { + throw new Error('Cannot get a value of an unfulfilled promise.'); + } + + return this._W; + }; + + Promise.prototype.getReason = function () { + if (this._V === 3) { + return this._W.getReason(); + } + + if (!this.isRejected()) { + throw new Error('Cannot get a rejection reason of a non-rejected promise.'); + } + + return this._W; + }; + + Promise.prototype.getState = function () { + if (this._V === 3) { + return this._W.getState(); + } + if (this._V === -1 || this._V === -2) { + return 0; + } + + return this._V; + }; +}; + +Promise.disableSynchronous = function() { + Promise.prototype.isPending = undefined; + Promise.prototype.isFulfilled = undefined; + Promise.prototype.isRejected = undefined; + Promise.prototype.getValue = undefined; + Promise.prototype.getReason = undefined; + Promise.prototype.getState = undefined; +}; diff --git a/nodefrontend/node_modules/promise/src/core.js b/nodefrontend/node_modules/promise/src/core.js new file mode 100644 index 00000000..312010d9 --- /dev/null +++ b/nodefrontend/node_modules/promise/src/core.js @@ -0,0 +1,213 @@ +'use strict'; + +var asap = require('asap/raw'); + +function noop() {} + +// States: +// +// 0 - pending +// 1 - fulfilled with _value +// 2 - rejected with _value +// 3 - adopted the state of another promise, _value +// +// once the state is no longer pending (0) it is immutable + +// All `_` prefixed properties will be reduced to `_{random number}` +// at build time to obfuscate them and discourage their use. +// We don't use symbols or Object.defineProperty to fully hide them +// because the performance isn't good enough. + + +// to avoid using try/catch inside critical functions, we +// extract them to here. +var LAST_ERROR = null; +var IS_ERROR = {}; +function getThen(obj) { + try { + return obj.then; + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} + +function tryCallOne(fn, a) { + try { + return fn(a); + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} +function tryCallTwo(fn, a, b) { + try { + fn(a, b); + } catch (ex) { + LAST_ERROR = ex; + return IS_ERROR; + } +} + +module.exports = Promise; + +function Promise(fn) { + if (typeof this !== 'object') { + throw new TypeError('Promises must be constructed via new'); + } + if (typeof fn !== 'function') { + throw new TypeError('Promise constructor\'s argument is not a function'); + } + this._deferredState = 0; + this._state = 0; + this._value = null; + this._deferreds = null; + if (fn === noop) return; + doResolve(fn, this); +} +Promise._onHandle = null; +Promise._onReject = null; +Promise._noop = noop; + +Promise.prototype.then = function(onFulfilled, onRejected) { + if (this.constructor !== Promise) { + return safeThen(this, onFulfilled, onRejected); + } + var res = new Promise(noop); + handle(this, new Handler(onFulfilled, onRejected, res)); + return res; +}; + +function safeThen(self, onFulfilled, onRejected) { + return new self.constructor(function (resolve, reject) { + var res = new Promise(noop); + res.then(resolve, reject); + handle(self, new Handler(onFulfilled, onRejected, res)); + }); +} +function handle(self, deferred) { + while (self._state === 3) { + self = self._value; + } + if (Promise._onHandle) { + Promise._onHandle(self); + } + if (self._state === 0) { + if (self._deferredState === 0) { + self._deferredState = 1; + self._deferreds = deferred; + return; + } + if (self._deferredState === 1) { + self._deferredState = 2; + self._deferreds = [self._deferreds, deferred]; + return; + } + self._deferreds.push(deferred); + return; + } + handleResolved(self, deferred); +} + +function handleResolved(self, deferred) { + asap(function() { + var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; + if (cb === null) { + if (self._state === 1) { + resolve(deferred.promise, self._value); + } else { + reject(deferred.promise, self._value); + } + return; + } + var ret = tryCallOne(cb, self._value); + if (ret === IS_ERROR) { + reject(deferred.promise, LAST_ERROR); + } else { + resolve(deferred.promise, ret); + } + }); +} +function resolve(self, newValue) { + // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === self) { + return reject( + self, + new TypeError('A promise cannot be resolved with itself.') + ); + } + if ( + newValue && + (typeof newValue === 'object' || typeof newValue === 'function') + ) { + var then = getThen(newValue); + if (then === IS_ERROR) { + return reject(self, LAST_ERROR); + } + if ( + then === self.then && + newValue instanceof Promise + ) { + self._state = 3; + self._value = newValue; + finale(self); + return; + } else if (typeof then === 'function') { + doResolve(then.bind(newValue), self); + return; + } + } + self._state = 1; + self._value = newValue; + finale(self); +} + +function reject(self, newValue) { + self._state = 2; + self._value = newValue; + if (Promise._onReject) { + Promise._onReject(self, newValue); + } + finale(self); +} +function finale(self) { + if (self._deferredState === 1) { + handle(self, self._deferreds); + self._deferreds = null; + } + if (self._deferredState === 2) { + for (var i = 0; i < self._deferreds.length; i++) { + handle(self, self._deferreds[i]); + } + self._deferreds = null; + } +} + +function Handler(onFulfilled, onRejected, promise){ + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; + this.onRejected = typeof onRejected === 'function' ? onRejected : null; + this.promise = promise; +} + +/** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ +function doResolve(fn, promise) { + var done = false; + var res = tryCallTwo(fn, function (value) { + if (done) return; + done = true; + resolve(promise, value); + }, function (reason) { + if (done) return; + done = true; + reject(promise, reason); + }); + if (!done && res === IS_ERROR) { + done = true; + reject(promise, LAST_ERROR); + } +} diff --git a/nodefrontend/node_modules/promise/src/done.js b/nodefrontend/node_modules/promise/src/done.js new file mode 100644 index 00000000..f879317d --- /dev/null +++ b/nodefrontend/node_modules/promise/src/done.js @@ -0,0 +1,13 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.prototype.done = function (onFulfilled, onRejected) { + var self = arguments.length ? this.then.apply(this, arguments) : this; + self.then(null, function (err) { + setTimeout(function () { + throw err; + }, 0); + }); +}; diff --git a/nodefrontend/node_modules/promise/src/es6-extensions.js b/nodefrontend/node_modules/promise/src/es6-extensions.js new file mode 100644 index 00000000..1161b57d --- /dev/null +++ b/nodefrontend/node_modules/promise/src/es6-extensions.js @@ -0,0 +1,119 @@ +'use strict'; + +//This file contains the ES6 extensions to the core Promises/A+ API + +var Promise = require('./core.js'); + +module.exports = Promise; + +/* Static Functions */ + +var TRUE = valuePromise(true); +var FALSE = valuePromise(false); +var NULL = valuePromise(null); +var UNDEFINED = valuePromise(undefined); +var ZERO = valuePromise(0); +var EMPTYSTRING = valuePromise(''); + +function valuePromise(value) { + var p = new Promise(Promise._noop); + p._state = 1; + p._value = value; + return p; +} +Promise.resolve = function (value) { + if (value instanceof Promise) return value; + + if (value === null) return NULL; + if (value === undefined) return UNDEFINED; + if (value === true) return TRUE; + if (value === false) return FALSE; + if (value === 0) return ZERO; + if (value === '') return EMPTYSTRING; + + if (typeof value === 'object' || typeof value === 'function') { + try { + var then = value.then; + if (typeof then === 'function') { + return new Promise(then.bind(value)); + } + } catch (ex) { + return new Promise(function (resolve, reject) { + reject(ex); + }); + } + } + return valuePromise(value); +}; + +var iterableToArray = function (iterable) { + if (typeof Array.from === 'function') { + // ES2015+, iterables exist + iterableToArray = Array.from; + return Array.from(iterable); + } + + // ES5, only arrays and array-likes exist + iterableToArray = function (x) { return Array.prototype.slice.call(x); }; + return Array.prototype.slice.call(iterable); +} + +Promise.all = function (arr) { + var args = iterableToArray(arr); + + return new Promise(function (resolve, reject) { + if (args.length === 0) return resolve([]); + var remaining = args.length; + function res(i, val) { + if (val && (typeof val === 'object' || typeof val === 'function')) { + if (val instanceof Promise && val.then === Promise.prototype.then) { + while (val._state === 3) { + val = val._value; + } + if (val._state === 1) return res(i, val._value); + if (val._state === 2) reject(val._value); + val.then(function (val) { + res(i, val); + }, reject); + return; + } else { + var then = val.then; + if (typeof then === 'function') { + var p = new Promise(then.bind(val)); + p.then(function (val) { + res(i, val); + }, reject); + return; + } + } + } + args[i] = val; + if (--remaining === 0) { + resolve(args); + } + } + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); +}; + +Promise.reject = function (value) { + return new Promise(function (resolve, reject) { + reject(value); + }); +}; + +Promise.race = function (values) { + return new Promise(function (resolve, reject) { + iterableToArray(values).forEach(function(value){ + Promise.resolve(value).then(resolve, reject); + }); + }); +}; + +/* Prototype Methods */ + +Promise.prototype['catch'] = function (onRejected) { + return this.then(null, onRejected); +}; diff --git a/nodefrontend/node_modules/promise/src/finally.js b/nodefrontend/node_modules/promise/src/finally.js new file mode 100644 index 00000000..3f8a6b7a --- /dev/null +++ b/nodefrontend/node_modules/promise/src/finally.js @@ -0,0 +1,16 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.prototype.finally = function (f) { + return this.then(function (value) { + return Promise.resolve(f()).then(function () { + return value; + }); + }, function (err) { + return Promise.resolve(f()).then(function () { + throw err; + }); + }); +}; diff --git a/nodefrontend/node_modules/promise/src/index.js b/nodefrontend/node_modules/promise/src/index.js new file mode 100644 index 00000000..6e674f38 --- /dev/null +++ b/nodefrontend/node_modules/promise/src/index.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = require('./core.js'); +require('./done.js'); +require('./finally.js'); +require('./es6-extensions.js'); +require('./node-extensions.js'); +require('./synchronous.js'); diff --git a/nodefrontend/node_modules/promise/src/node-extensions.js b/nodefrontend/node_modules/promise/src/node-extensions.js new file mode 100644 index 00000000..157cddc2 --- /dev/null +++ b/nodefrontend/node_modules/promise/src/node-extensions.js @@ -0,0 +1,130 @@ +'use strict'; + +// This file contains then/promise specific extensions that are only useful +// for node.js interop + +var Promise = require('./core.js'); +var asap = require('asap'); + +module.exports = Promise; + +/* Static Functions */ + +Promise.denodeify = function (fn, argumentCount) { + if ( + typeof argumentCount === 'number' && argumentCount !== Infinity + ) { + return denodeifyWithCount(fn, argumentCount); + } else { + return denodeifyWithoutCount(fn); + } +}; + +var callbackFn = ( + 'function (err, res) {' + + 'if (err) { rj(err); } else { rs(res); }' + + '}' +); +function denodeifyWithCount(fn, argumentCount) { + var args = []; + for (var i = 0; i < argumentCount; i++) { + args.push('a' + i); + } + var body = [ + 'return function (' + args.join(',') + ') {', + 'var self = this;', + 'return new Promise(function (rs, rj) {', + 'var res = fn.call(', + ['self'].concat(args).concat([callbackFn]).join(','), + ');', + 'if (res &&', + '(typeof res === "object" || typeof res === "function") &&', + 'typeof res.then === "function"', + ') {rs(res);}', + '});', + '};' + ].join(''); + return Function(['Promise', 'fn'], body)(Promise, fn); +} +function denodeifyWithoutCount(fn) { + var fnLength = Math.max(fn.length - 1, 3); + var args = []; + for (var i = 0; i < fnLength; i++) { + args.push('a' + i); + } + var body = [ + 'return function (' + args.join(',') + ') {', + 'var self = this;', + 'var args;', + 'var argLength = arguments.length;', + 'if (arguments.length > ' + fnLength + ') {', + 'args = new Array(arguments.length + 1);', + 'for (var i = 0; i < arguments.length; i++) {', + 'args[i] = arguments[i];', + '}', + '}', + 'return new Promise(function (rs, rj) {', + 'var cb = ' + callbackFn + ';', + 'var res;', + 'switch (argLength) {', + args.concat(['extra']).map(function (_, index) { + return ( + 'case ' + (index) + ':' + + 'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' + + 'break;' + ); + }).join(''), + 'default:', + 'args[argLength] = cb;', + 'res = fn.apply(self, args);', + '}', + + 'if (res &&', + '(typeof res === "object" || typeof res === "function") &&', + 'typeof res.then === "function"', + ') {rs(res);}', + '});', + '};' + ].join(''); + + return Function( + ['Promise', 'fn'], + body + )(Promise, fn); +} + +Promise.nodeify = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + var callback = + typeof args[args.length - 1] === 'function' ? args.pop() : null; + var ctx = this; + try { + return fn.apply(this, arguments).nodeify(callback, ctx); + } catch (ex) { + if (callback === null || typeof callback == 'undefined') { + return new Promise(function (resolve, reject) { + reject(ex); + }); + } else { + asap(function () { + callback.call(ctx, ex); + }) + } + } + } +}; + +Promise.prototype.nodeify = function (callback, ctx) { + if (typeof callback != 'function') return this; + + this.then(function (value) { + asap(function () { + callback.call(ctx, null, value); + }); + }, function (err) { + asap(function () { + callback.call(ctx, err); + }); + }); +}; diff --git a/nodefrontend/node_modules/promise/src/rejection-tracking.js b/nodefrontend/node_modules/promise/src/rejection-tracking.js new file mode 100644 index 00000000..33a59a19 --- /dev/null +++ b/nodefrontend/node_modules/promise/src/rejection-tracking.js @@ -0,0 +1,113 @@ +'use strict'; + +var Promise = require('./core'); + +var DEFAULT_WHITELIST = [ + ReferenceError, + TypeError, + RangeError +]; + +var enabled = false; +exports.disable = disable; +function disable() { + enabled = false; + Promise._onHandle = null; + Promise._onReject = null; +} + +exports.enable = enable; +function enable(options) { + options = options || {}; + if (enabled) disable(); + enabled = true; + var id = 0; + var displayId = 0; + var rejections = {}; + Promise._onHandle = function (promise) { + if ( + promise._state === 2 && // IS REJECTED + rejections[promise._rejectionId] + ) { + if (rejections[promise._rejectionId].logged) { + onHandled(promise._rejectionId); + } else { + clearTimeout(rejections[promise._rejectionId].timeout); + } + delete rejections[promise._rejectionId]; + } + }; + Promise._onReject = function (promise, err) { + if (promise._deferredState === 0) { // not yet handled + promise._rejectionId = id++; + rejections[promise._rejectionId] = { + displayId: null, + error: err, + timeout: setTimeout( + onUnhandled.bind(null, promise._rejectionId), + // For reference errors and type errors, this almost always + // means the programmer made a mistake, so log them after just + // 100ms + // otherwise, wait 2 seconds to see if they get handled + matchWhitelist(err, DEFAULT_WHITELIST) + ? 100 + : 2000 + ), + logged: false + }; + } + }; + function onUnhandled(id) { + if ( + options.allRejections || + matchWhitelist( + rejections[id].error, + options.whitelist || DEFAULT_WHITELIST + ) + ) { + rejections[id].displayId = displayId++; + if (options.onUnhandled) { + rejections[id].logged = true; + options.onUnhandled( + rejections[id].displayId, + rejections[id].error + ); + } else { + rejections[id].logged = true; + logError( + rejections[id].displayId, + rejections[id].error + ); + } + } + } + function onHandled(id) { + if (rejections[id].logged) { + if (options.onHandled) { + options.onHandled(rejections[id].displayId, rejections[id].error); + } else if (!rejections[id].onUnhandled) { + console.warn( + 'Promise Rejection Handled (id: ' + rejections[id].displayId + '):' + ); + console.warn( + ' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id ' + + rejections[id].displayId + '.' + ); + } + } + } +} + +function logError(id, error) { + console.warn('Possible Unhandled Promise Rejection (id: ' + id + '):'); + var errStr = (error && (error.stack || error)) + ''; + errStr.split('\n').forEach(function (line) { + console.warn(' ' + line); + }); +} + +function matchWhitelist(error, list) { + return list.some(function (cls) { + return error instanceof cls; + }); +} \ No newline at end of file diff --git a/nodefrontend/node_modules/promise/src/synchronous.js b/nodefrontend/node_modules/promise/src/synchronous.js new file mode 100644 index 00000000..38b228f5 --- /dev/null +++ b/nodefrontend/node_modules/promise/src/synchronous.js @@ -0,0 +1,62 @@ +'use strict'; + +var Promise = require('./core.js'); + +module.exports = Promise; +Promise.enableSynchronous = function () { + Promise.prototype.isPending = function() { + return this.getState() == 0; + }; + + Promise.prototype.isFulfilled = function() { + return this.getState() == 1; + }; + + Promise.prototype.isRejected = function() { + return this.getState() == 2; + }; + + Promise.prototype.getValue = function () { + if (this._state === 3) { + return this._value.getValue(); + } + + if (!this.isFulfilled()) { + throw new Error('Cannot get a value of an unfulfilled promise.'); + } + + return this._value; + }; + + Promise.prototype.getReason = function () { + if (this._state === 3) { + return this._value.getReason(); + } + + if (!this.isRejected()) { + throw new Error('Cannot get a rejection reason of a non-rejected promise.'); + } + + return this._value; + }; + + Promise.prototype.getState = function () { + if (this._state === 3) { + return this._value.getState(); + } + if (this._state === -1 || this._state === -2) { + return 0; + } + + return this._state; + }; +}; + +Promise.disableSynchronous = function() { + Promise.prototype.isPending = undefined; + Promise.prototype.isFulfilled = undefined; + Promise.prototype.isRejected = undefined; + Promise.prototype.getValue = undefined; + Promise.prototype.getReason = undefined; + Promise.prototype.getState = undefined; +}; diff --git a/nodefrontend/node_modules/python-shell/CHANGELOG.md b/nodefrontend/node_modules/python-shell/CHANGELOG.md new file mode 100644 index 00000000..064ad271 --- /dev/null +++ b/nodefrontend/node_modules/python-shell/CHANGELOG.md @@ -0,0 +1,20 @@ +## 1.0.8 +* @joaoe fixed a bug with pythonshell not working with unset std streams +* https://github.com/extrabacon/python-shell/milestone/9 + +## 1.0.7 +* default python path updated to py on windows + +## 1.0.4 +* added getVersionSync + +## 0.0.3 +* fixed buffering in `PythonShell.receive`, fixing [#1](https://github.com/extrabacon/python-shell/issues/1) + +## 0.0.2 +* improved documentation + +## 0.0.1 +* initial version +* independent module moved from [extrabacon/pyspreadsheet](https://github.com/extrabacon/pyspreadsheet) + diff --git a/nodefrontend/node_modules/python-shell/README.md b/nodefrontend/node_modules/python-shell/README.md new file mode 100644 index 00000000..2af5c7ec --- /dev/null +++ b/nodefrontend/node_modules/python-shell/README.md @@ -0,0 +1,358 @@ +# [python-shell](https://www.npmjs.com/package/python-shell) [![Build status](https://ci.appveyor.com/api/projects/status/m8e3h53vvxg5wb2q/branch/master?svg=true)](https://ci.appveyor.com/project/Almenon/python-shell/branch/master) [![codecov](https://codecov.io/gh/extrabacon/python-shell/branch/master/graph/badge.svg)](https://codecov.io/gh/extrabacon/python-shell) + + +A simple way to run Python scripts from Node.js with basic but efficient inter-process communication and better error handling. + +## Features + ++ Reliably spawn Python scripts in a child process ++ Built-in text, JSON and binary modes ++ Custom parsers and formatters ++ Simple and efficient data transfers through stdin and stdout streams ++ Extended stack traces when an error is thrown + +## Installation + +```bash +npm install python-shell +``` + +To run the tests: +```bash +npm test +``` + +## Documentation + +### Running python code: + +```typescript +import {PythonShell} from 'python-shell'; + +PythonShell.runString('x=1+1;print(x)', null, function (err) { + if (err) throw err; + console.log('finished'); +}); +``` + +If the script exits with a non-zero code, an error will be thrown. + +Note the use of imports! If you're not using typescript ಠ_ಠ you can [still get imports to work with this guide](https://github.com/extrabacon/python-shell/issues/148#issuecomment-419120209). + +Or you can use require like so: +```javascript +let {PythonShell} = require('python-shell') +``` + +### Running a Python script: + +```typescript +import {PythonShell} from 'python-shell'; + +PythonShell.run('my_script.py', null, function (err) { + if (err) throw err; + console.log('finished'); +}); +``` + +If the script exits with a non-zero code, an error will be thrown. + +### Running a Python script with arguments and options: + +```typescript +import {PythonShell} from 'python-shell'; + +let options = { + mode: 'text', + pythonPath: 'path/to/python', + pythonOptions: ['-u'], // get print results in real-time + scriptPath: 'path/to/my/scripts', + args: ['value1', 'value2', 'value3'] +}; + +PythonShell.run('my_script.py', options, function (err, results) { + if (err) throw err; + // results is an array consisting of messages collected during execution + console.log('results: %j', results); +}); +``` + +### Exchanging data between Node and Python: + +```typescript +import {PythonShell} from 'python-shell'; +let pyshell = new PythonShell('my_script.py'); + +// sends a message to the Python script via stdin +pyshell.send('hello'); + +pyshell.on('message', function (message) { + // received a message sent from the Python script (a simple "print" statement) + console.log(message); +}); + +// end the input stream and allow the process to exit +pyshell.end(function (err,code,signal) { + if (err) throw err; + console.log('The exit code was: ' + code); + console.log('The exit signal was: ' + signal); + console.log('finished'); +}); +``` + +Use `.send(message)` to send a message to the Python script. Attach the `message` event to listen to messages emitted from the Python script. + +Use `options.mode` to quickly setup how data is sent and received between your Node and Python applications. + + * use `text` mode for exchanging lines of text ending with a [newline character](http://hayne.net/MacDev/Notes/unixFAQ.html#endOfLine). + * use `json` mode for exchanging JSON fragments + * use `binary` mode for anything else (data is sent and received as-is) + +Stderr always uses text mode. + +For more details and examples including Python source code, take a look at the tests. + +### Error Handling and extended stack traces + +An error will be thrown if the process exits with a non-zero exit code. Additionally, if "stderr" contains a formatted Python traceback, the error is augmented with Python exception details including a concatenated stack trace. + +Sample error with traceback (from test/python/error.py): + +``` +Traceback (most recent call last): + File "test/python/error.py", line 6, in + divide_by_zero() + File "test/python/error.py", line 4, in divide_by_zero + print 1/0 +ZeroDivisionError: integer division or modulo by zero +``` + +would result into the following error: + +```typescript +{ [Error: ZeroDivisionError: integer division or modulo by zero] + traceback: 'Traceback (most recent call last):\n File "test/python/error.py", line 6, in \n divide_by_zero()\n File "test/python/error.py", line 4, in divide_by_zero\n print 1/0\nZeroDivisionError: integer division or modulo by zero\n', + executable: 'python', + options: null, + script: 'test/python/error.py', + args: null, + exitCode: 1 } +``` + +and `err.stack` would look like this: + +``` +Error: ZeroDivisionError: integer division or modulo by zero + at PythonShell.parseError (python-shell/index.js:131:17) + at ChildProcess. (python-shell/index.js:67:28) + at ChildProcess.EventEmitter.emit (events.js:98:17) + at Process.ChildProcess._handle.onexit (child_process.js:797:12) + ----- Python Traceback ----- + File "test/python/error.py", line 6, in + divide_by_zero() + File "test/python/error.py", line 4, in divide_by_zero + print 1/0 +``` + +## API Reference + +#### `PythonShell(script, options)` constructor + +Creates an instance of `PythonShell` and starts the Python process + +* `script`: the path of the script to execute +* `options`: the execution options, consisting of: + * `mode`: Configures how data is exchanged when data flows through stdin and stdout. The possible values are: + * `text`: each line of data (ending with "\n") is emitted as a message (default) + * `json`: each line of data (ending with "\n") is parsed as JSON and emitted as a message + * `binary`: data is streamed as-is through `stdout` and `stdin` + * `formatter`: each message to send is transformed using this method, then appended with "\n" + * `parser`: each line of data (ending with "\n") is parsed with this function and its result is emitted as a message + * `stderrParser`: each line of logs (ending with "\n") is parsed with this function and its result is emitted as a message + * `encoding`: the text encoding to apply on the child process streams (default: "utf8") + * `pythonPath`: The path where to locate the "python" executable. Default: "python" + * `pythonOptions`: Array of option switches to pass to "python" + * `scriptPath`: The default path where to look for scripts. Default is the current working directory. + * `args`: Array of arguments to pass to the script + +Other options are forwarded to `child_process.spawn`. + +PythonShell instances have the following properties: +* `script`: the path of the script to execute +* `command`: the full command arguments passed to the Python executable +* `stdin`: the Python stdin stream, used to send data to the child process +* `stdout`: the Python stdout stream, used for receiving data from the child process +* `stderr`: the Python stderr stream, used for communicating logs & errors +* `childProcess`: the process instance created via `child_process.spawn` +* `terminated`: boolean indicating whether the process has exited +* `exitCode`: the process exit code, available after the process has ended + +Example: + +```typescript +// create a new instance +let shell = new PythonShell('script.py', options); +``` + +#### `#defaultOptions` + +Configures default options for all new instances of PythonShell. + +Example: + +```typescript +// setup a default "scriptPath" +PythonShell.defaultOptions = { scriptPath: '../scripts' }; +``` + +#### `#run(script, options, callback)` + +Runs the Python script and invokes `callback` with the results. The callback contains the execution error (if any) as well as an array of messages emitted from the Python script. + +This method is also returning the `PythonShell` instance. + +Example: + +```typescript +// run a simple script +PythonShell.run('script.py', null, function (err, results) { + // script finished +}); +``` + +#### `#runString(code, options, callback)` + +Runs the Python code and invokes `callback` with the results. The callback contains the execution error (if any) as well as an array of messages emitted from the Python script. + +This method is also returning the `PythonShell` instance. + +Example: + +```typescript +// run a simple script +PythonShell.runString('x=1;print(x)', null, function (err, results) { + // script finished +}); +``` + +#### `#checkSyntax(code:string)` + +Checks the syntax of the code and returns a promise. +Promise is rejected if there is a syntax error. + +#### `#checkSyntaxFile(filePath:string)` + +Checks the syntax of the file and returns a promise. +Promise is rejected if there is a syntax error. + +#### `#getVersion(pythonPath?:string)` + +Returns the python version. Optional pythonPath param to get the version +of a specific python interpreter. + +#### `#getVersionSync(pythonPath?:string)` + +Returns the python version. Optional pythonPath param to get the version +of a specific python interpreter. + +#### `.send(message)` + +Sends a message to the Python script via stdin. The data is formatted according to the selected mode (text or JSON), or through a custom function when `formatter` is specified. + +Example: + +```typescript +// send a message in text mode +let shell = new PythonShell('script.py', { mode: 'text'}); +shell.send('hello world!'); + +// send a message in JSON mode +let shell = new PythonShell('script.py', { mode: 'json'}); +shell.send({ command: "do_stuff", args: [1, 2, 3] }); +``` + +#### `.receive(data)` + +Parses incoming data from the Python script written via stdout and emits `message` events. This method is called automatically as data is being received from stdout. + +#### `.receiveStderr(data)` + +Parses incoming logs from the Python script written via stderr and emits `stderr` events. This method is called automatically as data is being received from stderr. + +#### `.end(callback)` + +Closes the stdin stream, allowing the Python script to finish and exit. The optional callback is invoked when the process is terminated. + +#### `.kill(signal)` + +Terminates the python script. A kill signal may be provided by `signal`, if `signal` is not specified SIGTERM is sent. + +#### event: `message` + +Fires when a chunk of data is parsed from the stdout stream via the `receive` method. If a `parser` method is specified, the result of this function will be the message value. This event is not emitted in binary mode. + +Example: + +```typescript +// receive a message in text mode +let shell = new PythonShell('script.py', { mode: 'text'}); +shell.on('message', function (message) { + // handle message (a line of text from stdout) +}); + +// receive a message in JSON mode +let shell = new PythonShell('script.py', { mode: 'json'}); +shell.on('message', function (message) { + // handle message (a line of text from stdout, parsed as JSON) +}); +``` + +#### event: `stderr` + +Fires when a chunk of logs is parsed from the stderr stream via the `receiveStderr` method. If a `stderrParser` method is specified, the result of this function will be the message value. This event is not emitted in binary mode. + +Example: + +```typescript +// receive a message in text mode +let shell = new PythonShell('script.py', { mode: 'text'}); +shell.on('stderr', function (stderr) { + // handle stderr (a line of text from stderr) +}); +``` + +#### event: `close` + +Fires when the process has been terminated, with an error or not. + +#### event: `error` + +Fires when the process terminates with a non-zero exit code. + +## Used By: + +Python-Shell is used by [arepl-vscode](https://github.com/almenon/arepl-vscode), [gitinspector](https://github.com/ejwa/gitinspector), [pyspreadsheet](https://github.com/extrabacon/pyspreadsheet), [AtlantOS Ocean Data QC](https://github.com/ocean-data-qc/ocean-data-qc) and more! + +## License + +The MIT License (MIT) + +Copyright (c) 2014 Nicolas Mercier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/nodefrontend/node_modules/python-shell/index.d.ts b/nodefrontend/node_modules/python-shell/index.d.ts new file mode 100644 index 00000000..33edb5ac --- /dev/null +++ b/nodefrontend/node_modules/python-shell/index.d.ts @@ -0,0 +1,179 @@ +/// +import { EventEmitter } from 'events'; +import { ChildProcess, SpawnOptions } from 'child_process'; +import { Readable, Writable } from 'stream'; +export interface Options extends SpawnOptions { + /** + * if binary is enabled message and stderr events will not be emitted + */ + mode?: 'text' | 'json' | 'binary'; + formatter?: (param: string) => any; + parser?: (param: string) => any; + stderrParser?: (param: string) => any; + encoding?: string; + pythonPath?: string; + /** + * see https://docs.python.org/3.7/using/cmdline.html + */ + pythonOptions?: string[]; + /** + * overrides scriptPath passed into PythonShell constructor + */ + scriptPath?: string; + /** + * arguments to your program + */ + args?: string[]; +} +export declare class PythonShellError extends Error { + traceback: string | Buffer; + exitCode?: number; +} +/** + * An interactive Python shell exchanging data through stdio + * @param {string} script The python script to execute + * @param {object} [options] The launch options (also passed to child_process.spawn) + * @constructor + */ +export declare class PythonShell extends EventEmitter { + scriptPath: string; + command: string[]; + mode: string; + formatter: (param: string | Object) => any; + parser: (param: string) => any; + stderrParser: (param: string) => any; + terminated: boolean; + childProcess: ChildProcess; + stdin: Writable; + stdout: Readable; + stderr: Readable; + exitSignal: string; + exitCode: number; + private stderrHasEnded; + private stdoutHasEnded; + private _remaining; + private _endCallback; + static defaultPythonPath: string; + static defaultOptions: Options; + /** + * spawns a python process + * @param scriptPath path to script. Relative to current directory or options.scriptFolder if specified + * @param options + */ + constructor(scriptPath: string, options?: Options); + static format: { + text: (data: any) => string; + json: (data: any) => string; + }; + static parse: { + text: (data: any) => string; + json: (data: string) => any; + }; + /** + * checks syntax without executing code + * @returns {Promise} rejects w/ stderr if syntax failure + */ + static checkSyntax(code: string): Promise; + static getPythonPath(): string; + /** + * checks syntax without executing code + * @returns {Promise} rejects w/ stderr if syntax failure + */ + static checkSyntaxFile(filePath: string): Promise; + /** + * Runs a Python script and returns collected messages + * @param {string} scriptPath The path to the script to execute + * @param {Options} options The execution options + * @param {Function} callback The callback function to invoke with the script results + * @return {PythonShell} The PythonShell instance + */ + static run(scriptPath: string, options?: Options, callback?: (err?: PythonShellError, output?: any[]) => any): PythonShell; + /** + * Runs the inputted string of python code and returns collected messages. DO NOT ALLOW UNTRUSTED USER INPUT HERE! + * @param {string} code The python code to execute + * @param {Options} options The execution options + * @param {Function} callback The callback function to invoke with the script results + * @return {PythonShell} The PythonShell instance + */ + static runString(code: string, options?: Options, callback?: (err: PythonShellError, output?: any[]) => any): PythonShell; + static getVersion(pythonPath?: string): Promise<{ + stdout: string; + stderr: string; + }>; + static getVersionSync(pythonPath?: string): string; + /** + * Parses an error thrown from the Python process through stderr + * @param {string|Buffer} data The stderr contents to parse + * @return {Error} The parsed error with extended stack trace when traceback is available + */ + private parseError; + /** + * Sends a message to the Python shell through stdin + * Override this method to format data to be sent to the Python process + * @returns {PythonShell} The same instance for chaining calls + */ + send(message: string | Object): this; + /** + * Parses data received from the Python shell stdout stream and emits "message" events + * This method is not used in binary mode + * Override this method to parse incoming data from the Python process into messages + * @param {string|Buffer} data The data to parse into messages + */ + receive(data: string | Buffer): this; + /** + * Parses data received from the Python shell stderr stream and emits "stderr" events + * This method is not used in binary mode + * Override this method to parse incoming logs from the Python process into messages + * @param {string|Buffer} data The data to parse into messages + */ + receiveStderr(data: string | Buffer): this; + private receiveInternal; + /** + * Closes the stdin stream. Unless python is listening for stdin in a loop + * this should cause the process to finish its work and close. + * @returns {PythonShell} The same instance for chaining calls + */ + end(callback: (err: PythonShellError, exitCode: number, exitSignal: string) => any): this; + /** + * Sends a kill signal to the process + * @returns {PythonShell} The same instance for chaining calls + */ + kill(signal?: NodeJS.Signals): this; + /** + * Alias for kill. + * @deprecated + */ + terminate(signal?: NodeJS.Signals): this; +} +export interface PythonShell { + addListener(event: string, listener: (...args: any[]) => void): this; + emit(event: string | symbol, ...args: any[]): boolean; + on(event: string, listener: (...args: any[]) => void): this; + once(event: string, listener: (...args: any[]) => void): this; + prependListener(event: string, listener: (...args: any[]) => void): this; + prependOnceListener(event: string, listener: (...args: any[]) => void): this; + addListener(event: "message", listener: (parsedChunk: any) => void): this; + emit(event: "message", parsedChunk: any): boolean; + on(event: "message", listener: (parsedChunk: any) => void): this; + once(event: "message", listener: (parsedChunk: any) => void): this; + prependListener(event: "message", listener: (parsedChunk: any) => void): this; + prependOnceListener(event: "message", listener: (parsedChunk: any) => void): this; + addListener(event: "stderr", listener: (parsedChunk: any) => void): this; + emit(event: "stderr", parsedChunk: any): boolean; + on(event: "stderr", listener: (parsedChunk: any) => void): this; + once(event: "stderr", listener: (parsedChunk: any) => void): this; + prependListener(event: "stderr", listener: (parsedChunk: any) => void): this; + prependOnceListener(event: "stderr", listener: (parsedChunk: any) => void): this; + addListener(event: "close", listener: () => void): this; + emit(event: "close"): boolean; + on(event: "close", listener: () => void): this; + once(event: "close", listener: () => void): this; + prependListener(event: "close", listener: () => void): this; + prependOnceListener(event: "close", listener: () => void): this; + addListener(event: "error", listener: (error: PythonShellError) => void): this; + emit(event: "error", error: PythonShellError): boolean; + on(event: "error", listener: (error: PythonShellError) => void): this; + once(event: "error", listener: (error: PythonShellError) => void): this; + prependListener(event: "error", listener: (error: PythonShellError) => void): this; + prependOnceListener(event: "error", listener: (error: PythonShellError) => void): this; +} diff --git a/nodefrontend/node_modules/python-shell/index.js b/nodefrontend/node_modules/python-shell/index.js new file mode 100644 index 00000000..d51ef882 --- /dev/null +++ b/nodefrontend/node_modules/python-shell/index.js @@ -0,0 +1,389 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PythonShell = exports.PythonShellError = void 0; +const events_1 = require("events"); +const child_process_1 = require("child_process"); +const os_1 = require("os"); +const path_1 = require("path"); +const fs_1 = require("fs"); +const util_1 = require("util"); +function toArray(source) { + if (typeof source === 'undefined' || source === null) { + return []; + } + else if (!Array.isArray(source)) { + return [source]; + } + return source; +} +/** + * adds arguments as properties to obj + */ +function extend(obj, ...args) { + Array.prototype.slice.call(arguments, 1).forEach(function (source) { + if (source) { + for (let key in source) { + obj[key] = source[key]; + } + } + }); + return obj; +} +/** + * gets a random int from 0-10000000000 + */ +function getRandomInt() { + return Math.floor(Math.random() * 10000000000); +} +class PythonShellError extends Error { +} +exports.PythonShellError = PythonShellError; +/** + * An interactive Python shell exchanging data through stdio + * @param {string} script The python script to execute + * @param {object} [options] The launch options (also passed to child_process.spawn) + * @constructor + */ +class PythonShell extends events_1.EventEmitter { + /** + * spawns a python process + * @param scriptPath path to script. Relative to current directory or options.scriptFolder if specified + * @param options + */ + constructor(scriptPath, options) { + super(); + /** + * returns either pythonshell func (if val string) or custom func (if val Function) + */ + function resolve(type, val) { + if (typeof val === 'string') { + // use a built-in function using its name + return PythonShell[type][val]; + } + else if (typeof val === 'function') { + // use a custom function + return val; + } + } + if (scriptPath.trim().length == 0) + throw Error("scriptPath cannot be empty! You must give a script for python to run"); + let self = this; + let errorData = ''; + events_1.EventEmitter.call(this); + options = extend({}, PythonShell.defaultOptions, options); + let pythonPath; + if (!options.pythonPath) { + pythonPath = PythonShell.defaultPythonPath; + } + else + pythonPath = options.pythonPath; + let pythonOptions = toArray(options.pythonOptions); + let scriptArgs = toArray(options.args); + this.scriptPath = path_1.join(options.scriptPath || '', scriptPath); + this.command = pythonOptions.concat(this.scriptPath, scriptArgs); + this.mode = options.mode || 'text'; + this.formatter = resolve('format', options.formatter || this.mode); + this.parser = resolve('parse', options.parser || this.mode); + // We don't expect users to ever format stderr as JSON so we default to text mode + this.stderrParser = resolve('parse', options.stderrParser || 'text'); + this.terminated = false; + this.childProcess = child_process_1.spawn(pythonPath, this.command, options); + ['stdout', 'stdin', 'stderr'].forEach(function (name) { + self[name] = self.childProcess[name]; + self.parser && self[name] && self[name].setEncoding(options.encoding || 'utf8'); + }); + // parse incoming data on stdout + if (this.parser && this.stdout) { + this.stdout.on('data', this.receive.bind(this)); + } + // listen to stderr and emit errors for incoming data + if (this.stderrParser && this.stderr) { + this.stderr.on('data', this.receiveStderr.bind(this)); + } + if (this.stderr) { + this.stderr.on('data', function (data) { + errorData += '' + data; + }); + this.stderr.on('end', function () { + self.stderrHasEnded = true; + terminateIfNeeded(); + }); + } + else { + self.stderrHasEnded = true; + } + if (this.stdout) { + this.stdout.on('end', function () { + self.stdoutHasEnded = true; + terminateIfNeeded(); + }); + } + else { + self.stdoutHasEnded = true; + } + this.childProcess.on('exit', function (code, signal) { + self.exitCode = code; + self.exitSignal = signal; + terminateIfNeeded(); + }); + function terminateIfNeeded() { + if (!self.stderrHasEnded || !self.stdoutHasEnded || (self.exitCode == null && self.exitSignal == null)) + return; + let err; + if (self.exitCode && self.exitCode !== 0) { + if (errorData) { + err = self.parseError(errorData); + } + else { + err = new PythonShellError('process exited with code ' + self.exitCode); + } + err = extend(err, { + executable: pythonPath, + options: pythonOptions.length ? pythonOptions : null, + script: self.scriptPath, + args: scriptArgs.length ? scriptArgs : null, + exitCode: self.exitCode + }); + // do not emit error if only a callback is used + if (self.listeners('error').length || !self._endCallback) { + self.emit('error', err); + } + } + self.terminated = true; + self.emit('close'); + self._endCallback && self._endCallback(err, self.exitCode, self.exitSignal); + } + ; + } + /** + * checks syntax without executing code + * @returns {Promise} rejects w/ stderr if syntax failure + */ + static checkSyntax(code) { + return __awaiter(this, void 0, void 0, function* () { + const randomInt = getRandomInt(); + const filePath = os_1.tmpdir() + path_1.sep + `pythonShellSyntaxCheck${randomInt}.py`; + // todo: replace this with util.promisify (once we no longer support node v7) + return new Promise((resolve, reject) => { + fs_1.writeFile(filePath, code, (err) => { + if (err) + reject(err); + resolve(this.checkSyntaxFile(filePath)); + }); + }); + }); + } + static getPythonPath() { + return this.defaultOptions.pythonPath ? this.defaultOptions.pythonPath : this.defaultPythonPath; + } + /** + * checks syntax without executing code + * @returns {Promise} rejects w/ stderr if syntax failure + */ + static checkSyntaxFile(filePath) { + return __awaiter(this, void 0, void 0, function* () { + const pythonPath = this.getPythonPath(); + const compileCommand = `${pythonPath} -m py_compile ${filePath}`; + return new Promise((resolve, reject) => { + child_process_1.exec(compileCommand, (error, stdout, stderr) => { + if (error == null) + resolve(); + else + reject(stderr); + }); + }); + }); + } + /** + * Runs a Python script and returns collected messages + * @param {string} scriptPath The path to the script to execute + * @param {Options} options The execution options + * @param {Function} callback The callback function to invoke with the script results + * @return {PythonShell} The PythonShell instance + */ + static run(scriptPath, options, callback) { + let pyshell = new PythonShell(scriptPath, options); + let output = []; + return pyshell.on('message', function (message) { + output.push(message); + }).end(function (err) { + return callback(err ? err : null, output.length ? output : null); + }); + } + ; + /** + * Runs the inputted string of python code and returns collected messages. DO NOT ALLOW UNTRUSTED USER INPUT HERE! + * @param {string} code The python code to execute + * @param {Options} options The execution options + * @param {Function} callback The callback function to invoke with the script results + * @return {PythonShell} The PythonShell instance + */ + static runString(code, options, callback) { + // put code in temp file + const randomInt = getRandomInt(); + const filePath = os_1.tmpdir + path_1.sep + `pythonShellFile${randomInt}.py`; + fs_1.writeFileSync(filePath, code); + return PythonShell.run(filePath, options, callback); + } + ; + static getVersion(pythonPath) { + if (!pythonPath) + pythonPath = this.getPythonPath(); + const execPromise = util_1.promisify(child_process_1.exec); + return execPromise(pythonPath + " --version"); + } + static getVersionSync(pythonPath) { + if (!pythonPath) + pythonPath = this.getPythonPath(); + return child_process_1.execSync(pythonPath + " --version").toString(); + } + /** + * Parses an error thrown from the Python process through stderr + * @param {string|Buffer} data The stderr contents to parse + * @return {Error} The parsed error with extended stack trace when traceback is available + */ + parseError(data) { + let text = '' + data; + let error; + if (/^Traceback/.test(text)) { + // traceback data is available + let lines = text.trim().split(os_1.EOL); + let exception = lines.pop(); + error = new PythonShellError(exception); + error.traceback = data; + // extend stack trace + error.stack += os_1.EOL + ' ----- Python Traceback -----' + os_1.EOL + ' '; + error.stack += lines.slice(1).join(os_1.EOL + ' '); + } + else { + // otherwise, create a simpler error with stderr contents + error = new PythonShellError(text); + } + return error; + } + ; + /** + * Sends a message to the Python shell through stdin + * Override this method to format data to be sent to the Python process + * @returns {PythonShell} The same instance for chaining calls + */ + send(message) { + if (!this.stdin) + throw new Error("stdin not open for writing"); + let data = this.formatter ? this.formatter(message) : message; + if (this.mode !== 'binary') + data += os_1.EOL; + this.stdin.write(data); + return this; + } + ; + /** + * Parses data received from the Python shell stdout stream and emits "message" events + * This method is not used in binary mode + * Override this method to parse incoming data from the Python process into messages + * @param {string|Buffer} data The data to parse into messages + */ + receive(data) { + return this.receiveInternal(data, 'message'); + } + ; + /** + * Parses data received from the Python shell stderr stream and emits "stderr" events + * This method is not used in binary mode + * Override this method to parse incoming logs from the Python process into messages + * @param {string|Buffer} data The data to parse into messages + */ + receiveStderr(data) { + return this.receiveInternal(data, 'stderr'); + } + ; + receiveInternal(data, emitType) { + let self = this; + let parts = ('' + data).split(os_1.EOL); + if (parts.length === 1) { + // an incomplete record, keep buffering + this._remaining = (this._remaining || '') + parts[0]; + return this; + } + let lastLine = parts.pop(); + // fix the first line with the remaining from the previous iteration of 'receive' + parts[0] = (this._remaining || '') + parts[0]; + // keep the remaining for the next iteration of 'receive' + this._remaining = lastLine; + parts.forEach(function (part) { + if (emitType == 'message') + self.emit(emitType, self.parser(part)); + else if (emitType == 'stderr') + self.emit(emitType, self.stderrParser(part)); + }); + return this; + } + /** + * Closes the stdin stream. Unless python is listening for stdin in a loop + * this should cause the process to finish its work and close. + * @returns {PythonShell} The same instance for chaining calls + */ + end(callback) { + if (this.childProcess.stdin) { + this.childProcess.stdin.end(); + } + this._endCallback = callback; + return this; + } + ; + /** + * Sends a kill signal to the process + * @returns {PythonShell} The same instance for chaining calls + */ + kill(signal) { + this.childProcess.kill(signal); + this.terminated = true; + return this; + } + ; + /** + * Alias for kill. + * @deprecated + */ + terminate(signal) { + // todo: remove this next breaking release + return this.kill(signal); + } +} +exports.PythonShell = PythonShell; +// starting 2020 python2 is deprecated so we choose 3 as default +PythonShell.defaultPythonPath = process.platform != "win32" ? "python3" : "py"; +PythonShell.defaultOptions = {}; //allow global overrides for options +// built-in formatters +PythonShell.format = { + text: function toText(data) { + if (!data) + return ''; + else if (typeof data !== 'string') + return data.toString(); + return data; + }, + json: function toJson(data) { + return JSON.stringify(data); + } +}; +//built-in parsers +PythonShell.parse = { + text: function asText(data) { + return data; + }, + json: function asJson(data) { + return JSON.parse(data); + } +}; +; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/nodefrontend/node_modules/python-shell/index.js.map b/nodefrontend/node_modules/python-shell/index.js.map new file mode 100644 index 00000000..aa06f908 --- /dev/null +++ b/nodefrontend/node_modules/python-shell/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mCAAsC;AACtC,iDAAkF;AAClF,2BAA2C;AAC3C,+BAAgC;AAEhC,2BAA8C;AAC9C,+BAAiC;AAEjC,SAAS,OAAO,CAAI,MAAa;IAC7B,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,IAAI,EAAE;QAClD,OAAO,EAAE,CAAC;KACb;SAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QAC/B,OAAO,CAAC,MAAM,CAAC,CAAC;KACnB;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,MAAM,CAAC,GAAM,EAAE,GAAG,IAAI;IAC3B,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,MAAM;QAC7D,IAAI,MAAM,EAAE;YACR,KAAK,IAAI,GAAG,IAAI,MAAM,EAAE;gBACpB,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;aAC1B;SACJ;IACL,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,YAAY;IACjB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAC,WAAW,CAAC,CAAC;AACjD,CAAC;AA0BD,MAAa,gBAAiB,SAAQ,KAAK;CAG1C;AAHD,4CAGC;AAED;;;;;GAKG;AACH,MAAa,WAAY,SAAQ,qBAAY;IAwBzC;;;;OAIG;IACH,YAAY,UAAiB,EAAE,OAAgB;QAC3C,KAAK,EAAE,CAAC;QAER;;WAEG;QACH,SAAS,OAAO,CAAC,IAAI,EAAE,GAAmB;YACtC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;gBACzB,yCAAyC;gBACzC,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;aACjC;iBAAM,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE;gBAClC,wBAAwB;gBACxB,OAAO,GAAG,CAAC;aACd;QACL,CAAC;QAED,IAAG,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC;YAAE,MAAM,KAAK,CAAC,sEAAsE,CAAC,CAAA;QAErH,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,IAAI,SAAS,GAAG,EAAE,CAAC;QACnB,qBAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAExB,OAAO,GAAY,MAAM,CAAC,EAAE,EAAE,WAAW,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACnE,IAAI,UAAiB,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;YACrB,UAAU,GAAG,WAAW,CAAC,iBAAiB,CAAC;SAC9C;;YAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACvC,IAAI,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACnD,IAAI,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEvC,IAAI,CAAC,UAAU,GAAG,WAAI,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACjE,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,iFAAiF;QACjF,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,IAAI,MAAM,CAAC,CAAC;QACrE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,YAAY,GAAG,qBAAK,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE7D,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,UAAU,IAAI;YAChD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC;QACpF,CAAC,CAAC,CAAC;QAEH,gCAAgC;QAChC,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE;YAC5B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;SACnD;QAED,qDAAqD;QACrD,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,EAAE;YAClC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;SACzD;QAED,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,IAAI;gBACjC,SAAS,IAAI,EAAE,GAAG,IAAI,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE;gBAClB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC3B,iBAAiB,EAAE,CAAC;YACxB,CAAC,CAAC,CAAC;SACN;aAAM;YACH,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;SAC9B;QAED,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE;gBAClB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC3B,iBAAiB,EAAE,CAAC;YACxB,CAAC,CAAC,CAAC;SACN;aAAM;YACH,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;SAC9B;QAED,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,IAAI,EAAC,MAAM;YAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;YACzB,iBAAiB,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,SAAS,iBAAiB;YACtB,IAAG,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC;gBAAE,OAAO;YAE9G,IAAI,GAAoB,CAAC;YACzB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC,EAAE;gBACtC,IAAI,SAAS,EAAE;oBACX,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;iBACpC;qBAAM;oBACH,GAAG,GAAG,IAAI,gBAAgB,CAAC,2BAA2B,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;iBAC3E;gBACD,GAAG,GAAqB,MAAM,CAAC,GAAG,EAAE;oBAChC,UAAU,EAAE,UAAU;oBACtB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI;oBACpD,MAAM,EAAE,IAAI,CAAC,UAAU;oBACvB,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;oBAC3C,QAAQ,EAAE,IAAI,CAAC,QAAQ;iBAC1B,CAAC,CAAC;gBACH,+CAA+C;gBAC/C,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;oBACtD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;iBAC3B;aACJ;YAED,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACnB,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,EAAC,IAAI,CAAC,QAAQ,EAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9E,CAAC;QAAA,CAAC;IACN,CAAC;IAwBD;;;OAGA;IACH,MAAM,CAAO,WAAW,CAAC,IAAW;;YAC7B,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,WAAM,EAAE,GAAG,UAAG,GAAG,yBAAyB,SAAS,KAAK,CAAA;YAEzE,6EAA6E;YAChF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAChC,cAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,EAAC,EAAE;oBAC7B,IAAI,GAAG;wBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;oBACrB,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC5C,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC;KAAA;IAED,MAAM,CAAC,aAAa;QAChB,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC;IACpG,CAAC;IAEJ;;;OAGG;IACH,MAAM,CAAO,eAAe,CAAC,QAAe;;YAErC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;YAC1C,MAAM,cAAc,GAAG,GAAG,UAAU,kBAAkB,QAAQ,EAAE,CAAA;YAE7D,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,oBAAI,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;oBAC3C,IAAG,KAAK,IAAI,IAAI;wBAAE,OAAO,EAAE,CAAA;;wBACtB,MAAM,CAAC,MAAM,CAAC,CAAA;gBACvB,CAAC,CAAC,CAAA;YACN,CAAC,CAAC,CAAA;QACT,CAAC;KAAA;IAEE;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,CAAC,UAAiB,EAAE,OAAgB,EAAE,QAAqD;QACjG,IAAI,OAAO,GAAG,IAAI,WAAW,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,OAAO,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,OAAO;YAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,GAAG;YAChB,OAAO,QAAQ,CAAC,GAAG,CAAA,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;IACP,CAAC;IAAA,CAAC;IAEF;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,CAAC,IAAW,EAAE,OAAgB,EAAE,QAAoD;QAEhG,wBAAwB;QACxB,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,WAAM,GAAG,UAAG,GAAG,kBAAkB,SAAS,KAAK,CAAA;QAChE,kBAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAE9B,OAAO,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IACxD,CAAC;IAAA,CAAC;IAEF,MAAM,CAAC,UAAU,CAAC,UAAkB;QAChC,IAAG,CAAC,UAAU;YAAE,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;QACjD,MAAM,WAAW,GAAG,gBAAS,CAAC,oBAAI,CAAC,CAAA;QACnC,OAAO,WAAW,CAAC,UAAU,GAAG,YAAY,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,UAAkB;QACpC,IAAG,CAAC,UAAU;YAAE,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;QACjD,OAAO,wBAAQ,CAAC,UAAU,GAAG,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAA;IACzD,CAAC;IAED;;;;OAIG;IACK,UAAU,CAAC,IAAkB;QACjC,IAAI,IAAI,GAAG,EAAE,GAAC,IAAI,CAAC;QACnB,IAAI,KAAsB,CAAC;QAE3B,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACzB,8BAA8B;YAC9B,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,QAAO,CAAC,CAAC;YACvC,IAAI,SAAS,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;YAC5B,KAAK,GAAG,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;YACxC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;YACvB,qBAAqB;YACrB,KAAK,CAAC,KAAK,IAAI,QAAO,GAAC,kCAAkC,GAAC,QAAO,GAAC,IAAI,CAAC;YACvE,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAO,GAAC,IAAI,CAAC,CAAC;SACpD;aAAM;YACH,yDAAyD;YACzD,KAAK,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;SACtC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;IAAA,CAAC;IAEF;;;;OAIG;IACH,IAAI,CAAC,OAAqB;QACtB,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC/D,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QAC9D,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;YAAE,IAAI,IAAI,QAAO,CAAC;QAC5C,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IAChB,CAAC;IAAA,CAAC;IAEF;;;;;OAKG;IACH,OAAO,CAAC,IAAkB;QACtB,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;IAAA,CAAC;IAEF;;;;;OAKG;IACH,aAAa,CAAC,IAAkB;QAC5B,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IAAA,CAAC;IAEM,eAAe,CAAC,IAAkB,EAAE,QAA2B;QACnE,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,IAAI,KAAK,GAAG,CAAC,EAAE,GAAC,IAAI,CAAC,CAAC,KAAK,CAAC,QAAO,CAAC,CAAC;QAErC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;YACpB,uCAAuC;YACvC,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC;SACf;QAED,IAAI,QAAQ,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;QAC3B,iFAAiF;QACjF,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9C,yDAAyD;QACzD,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;QAE3B,KAAK,CAAC,OAAO,CAAC,UAAU,IAAI;YACxB,IAAG,QAAQ,IAAI,SAAS;gBAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;iBAC5D,IAAG,QAAQ,IAAI,QAAQ;gBAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,GAAG,CAAC,QAAuE;QACvE,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE;YACzB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;SACjC;QACD,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;QAC7B,OAAO,IAAI,CAAC;IAChB,CAAC;IAAA,CAAC;IAEF;;;OAGG;IACH,IAAI,CAAC,MAAuB;QACxB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC;IAChB,CAAC;IAAA,CAAC;IAEF;;;OAGG;IACH,SAAS,CAAC,MAAuB;QAC7B,0CAA0C;QAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC5B,CAAC;;AAvWL,kCAwWC;AArVG,gEAAgE;AACzD,6BAAiB,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAEnE,0BAAc,GAAW,EAAE,CAAC,CAAC,oCAAoC;AAsHxE,sBAAsB;AACf,kBAAM,GAAG;IACZ,IAAI,EAAE,SAAS,MAAM,CAAC,IAAI;QACtB,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;aAChB,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC1D,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,EAAE,SAAS,MAAM,CAAC,IAAI;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;CACJ,CAAC;AAEF,kBAAkB;AACX,iBAAK,GAAG;IACX,IAAI,EAAE,SAAS,MAAM,CAAC,IAAI;QACtB,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,EAAE,SAAS,MAAM,CAAC,IAAW;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;CACJ,CAAC;AAwML,CAAC"} \ No newline at end of file diff --git a/nodefrontend/node_modules/python-shell/package.json b/nodefrontend/node_modules/python-shell/package.json new file mode 100644 index 00000000..d61d3cad --- /dev/null +++ b/nodefrontend/node_modules/python-shell/package.json @@ -0,0 +1,73 @@ +{ + "_from": "python-shell", + "_id": "python-shell@2.0.3", + "_inBundle": false, + "_integrity": "sha512-SBYQzXjexcxmmgzpjdIVxum9tj4Zaov1jNuSGMLssPxRhZ7lxqlpuEtLT0TEed0RAqhGfx2YFVC+imCJOmkVHg==", + "_location": "/python-shell", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "python-shell", + "name": "python-shell", + "escapedName": "python-shell", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/python-shell/-/python-shell-2.0.3.tgz", + "_shasum": "03040cae27934d88e1226fd34316b39dfb2fddf0", + "_spec": "python-shell", + "_where": "/home/alpcentaur/ProjektA/PrototypeWebApp/nodefrontend", + "author": { + "name": "Nicolas Mercier", + "email": "nicolas@extrabacon.net" + }, + "bugs": { + "url": "http://github.com/extrabacon/python-shell/issues" + }, + "bundleDependencies": false, + "dependencies": {}, + "deprecated": false, + "description": "Run Python scripts from Node.js with simple (but efficient) inter-process communication through stdio", + "devDependencies": { + "@types/mocha": "^5.2.5", + "@types/node": "^10.5.2", + "mocha": "^5.2.0", + "mocha-appveyor-reporter": "^0.4.0", + "should": "^13.2.1", + "ts-node": "^9.0.0", + "typescript": "^3.8.3" + }, + "engines": { + "node": ">=0.10" + }, + "files": [ + "*.d.ts", + "*.js", + "*.js.map", + "CHANGELOG.md", + "README.md" + ], + "homepage": "http://github.com/extrabacon/python-shell", + "keywords": [ + "python" + ], + "license": "MIT", + "name": "python-shell", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/extrabacon/python-shell.git" + }, + "scripts": { + "appveyorTest": "tsc -p ./ && nyc mocha --reporter mocha-appveyor-reporter test/*.js", + "compile": "tsc -watch -p ./", + "test": "tsc -p ./ && mocha -r ts-node/register" + }, + "version": "2.0.3" +} + diff --git a/nodefrontend/package-lock.json b/nodefrontend/package-lock.json new file mode 100644 index 00000000..2b735ad2 --- /dev/null +++ b/nodefrontend/package-lock.json @@ -0,0 +1,24 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "promise": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "requires": { + "asap": "~2.0.6" + } + }, + "python-shell": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/python-shell/-/python-shell-2.0.3.tgz", + "integrity": "sha512-SBYQzXjexcxmmgzpjdIVxum9tj4Zaov1jNuSGMLssPxRhZ7lxqlpuEtLT0TEed0RAqhGfx2YFVC+imCJOmkVHg==" + } + } +} diff --git a/nodefrontend/public/data.json b/nodefrontend/public/data.json new file mode 100644 index 00000000..fffbe679 --- /dev/null +++ b/nodefrontend/public/data.json @@ -0,0 +1 @@ +It worked diff --git a/nodefrontend/script.py b/nodefrontend/script.py new file mode 100644 index 00000000..30ee1a93 --- /dev/null +++ b/nodefrontend/script.py @@ -0,0 +1,5 @@ +import time + +time.sleep(5) + +print('It worked') diff --git a/nodefrontend/server.js b/nodefrontend/server.js new file mode 100644 index 00000000..91d0049b --- /dev/null +++ b/nodefrontend/server.js @@ -0,0 +1,232 @@ + +var http = require('http'); +const fs = require('fs'); +var url = require('url'); +var path = require('path'); +var StringDecoder = require('string_decoder').StringDecoder; +var exec = require("child_process").exec; +var Promise= require('promise'); + +var mimeTypes = { + "html": "text/html", + "jpeg": "image/jpeg", + "jpg": "image/jpeg", + "png": "image/png", + "js": "text/javascript", + "css": "text/css", + "json": "text/plain"}; + + + +function writenodes(nodes) { + + fs.writeFile('public/Verbesserungen.txt', nodes, { flag: 'w' }, (err) => { + if (err) + console.log(err); + else { + console.log("File written successfully\n"); + console.log("The written has the following contents:"); + console.log(fs.readFileSync("public/nodes.txt", "utf8")); + } +})}; +// function writeedges(edges) { +// +// fs.writeFile('public/edges.txt', edges, { flag: 'w' }, (err) => { +// if (err) +// console.log(err); +// else { +// console.log("File written successfully\n"); +// console.log("The written has the following contents:"); +// console.log(fs.readFileSync("public/edges.txt", "utf8")); +// } +// })}; +// the following read funcitons are not asyncronous, that means they will block the process.. +// for scalability this has to be changed in future +// function readnodes() { +// var input = fs.readFileSync('public/nodes.txt', 'utf8') +// // console.log('input ooohyeah',input) +// // // var danodes = JSON.parse(input); +// // +// // const lines = input.split(/\r?\n/); +// // console.log('line numbaaa 1', lines, lines[1], lines[1].length) +// // var string = ''; +// // var i; +// // +// // for (i = 0; i < (lines.length - 2); i++) { +// // string += '"data' + i.toString() + '":' + lines[i] + ' ,' ; +// // }; +// // string += '"data' + lines.length.toString() + '":' + lines[lines.length - 2] ; +// // string = '{' + string + '}' ; +// // const jsonlines = JSON.parse(string) +// // +// // +// // let sortedlines = []; +// // sortedlines = [].slice.call(jsonlines).sort(function(a,b) { +// // var x = a.length; +// // var y = b.length; +// // if (x < y) { +// // return -1; +// // } +// // if (x > y) { +// // return 1; +// // } +// // return 0; +// // +// // }); +// // console.log('daline1 in nodes', sortedlines) +// return input +// }; +// function readedges() { +// +// var daedges = fs.readFileSync('public/edges.txt', 'utf8'); +// // const lines = daedges.split(/\r?\n/); +// // // console.log(lines) +// // sortedlines = lines.sort(function(a,b) { +// // var x = a.length; +// // var y = b.length; +// // if (x < y) { +// // return -1; +// // } +// // if (x > y) { +// // return 1; +// // } +// // return 0; +// // +// // }); +// // console.log('daline1 in edges', sortedlines[0]) +// return daedges +// }; +// + + + + + +http.createServer((request, response)=>{ + var pathname = url.parse(request.url).pathname; + var filename; + if(pathname === "/"){ + filename = "Prototyp.html"; + } + else{ + filename = path.join(process.cwd(), pathname); + } + + + + + + + try{ + fs.accessSync(filename, fs.F_OK); + var fileStream = fs.createReadStream(filename); + var mimeType = mimeTypes[path.extname(filename).split(".")[1]]; + response.writeHead(200, {'Content-Type':mimeType}); + fileStream.pipe(response); + + + if (mimeType === "text/plain"){ + // Get the payload,if any + var decoder = new StringDecoder('utf-8'); + var buffer = ''; + var theanswer = ''; + request.on('data', function(data) { + buffer += decoder.write(data); + }); + var theanswer = ''; + console.log('i am at least come til here') + request.on('end', function() { + buffer += decoder.end(); + if (buffer[3] === 'i'){ + + + + + + + console.log(buffer); + + + } + if (buffer[3] === 'f'){ + + + console.log(buffer); + theanswer = 'your changes were taken into the\n\nM A T R I X' + + + + } + + console.log(buffer[3]) + if (buffer[3] === 'e'){ + + + + +// console.log('oleola',nodes) + + + + + } + + const execpython = new Promise((resolve, reject) => { + exec("python script.py > public/data.json", (error, stdout, stderr) => { + if (error) { + console.log(`error: ${error.message}`); + reject(error) + } else { + console.log(`stdout: ${stdout}`); + resolve(stdout) + } + }); + +}) + + + + const checkIfItsDone = () => { + execpython + .then(ok => { + console.log(ok) + }) + .catch(err => { + console.log(err) + }) + } + + + + checkIfItsDone() + + +// var string = 'oi'; +// // var string = execpython('oi'); +// // console.log('output of execpython', string); +// Promise.resolve(string) +// .then(execpython(string)) +// .then(s => response.end(s)) + + + // Log the request/response + console.log('Payload received: ',buffer); + }); + + + } + + } + catch(e) { + console.log('File not exists: ' + filename); + + response.writeHead(404, {'Content-Type': 'text/plain'}); + response.write('404 Not Found\n'); + response.end(); + return; + } + + return; + } + +).listen(5000); diff --git a/nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb b/nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb new file mode 100644 index 00000000..c77c067d Binary files /dev/null and b/nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb differ diff --git a/requirements.txt b/requirements.txt index 2312be3e..7089ebfd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,13 +7,14 @@ appmode==0.7.0 argh==0.26.2 asn1crypto==0.24.0 astor==0.7.1 +astunparse==1.6.3 async-generator==1.10 async-timeout==3.0.1 attrs==18.2.0 Automat==0.7.0 backcall==0.1.0 beautifulsoup4==4.6.3 -bleach==3.0.2 +bleach==1.5.0 blis==0.4.1 boto==2.49.0 boto3==1.9.71 @@ -21,6 +22,7 @@ botocore==1.12.71 bqplot==0.12.6 bz2file==0.98 CacheControl==0.12.5 +cachetools==4.1.1 catalogue==1.0.0 certifi==2019.6.16 cffi==1.11.5 @@ -52,7 +54,7 @@ grpcio==1.17.0 gunicorn==19.9.0 h5py==2.8.0 hickle==3.3.2 -html5lib==1.0.1 +html5lib==0.9999999 hyperlink==18.0.0 idna==2.7 idna-ssl==1.1.0 @@ -90,6 +92,7 @@ Markdown==2.6.11 MarkupSafe==1.1.0 matplotlib==3.0.2 mistune==0.8.4 +mock==3.0.5 more-itertools==8.1.0 msgpack==0.5.6 msgpack-numpy==0.4.3.2 @@ -101,7 +104,9 @@ ngrok==0.0.1 nltk==3.4.1 notebook==5.7.2 numpy==1.15.4 +oauthlib==3.1.0 olefile==0.46 +opt-einsum==3.3.0 packaging==18.0 pandas==0.23.4 pandocfilters==1.4.2 @@ -150,7 +155,9 @@ QtPy==1.5.1 queuelib==1.5.0 regex==2018.1.10 requests==2.20.1 +requests-oauthlib==1.3.0 retrying==1.3.3 +rsa==4.6 s3transfer==0.1.13 scikit-learn==0.20.0 scipy==1.1.0 @@ -163,8 +170,11 @@ smart-open==1.7.1 spacy==2.0.18 srsly==1.0.1 tensorboard==1.12.0 +tensorboard-plugin-wit==1.7.0 tensorflow==1.12.0 +tensorflow-gpu==1.12.0 tensorflow-serving-api==1.12.0 +tensorflow-tensorboard==1.5.1 termcolor==1.1.0 terminado==0.8.1 testpath==0.4.2 diff --git a/venv/bin/pyrsa-decrypt b/venv/bin/pyrsa-decrypt new file mode 100755 index 00000000..011e7a49 --- /dev/null +++ b/venv/bin/pyrsa-decrypt @@ -0,0 +1,8 @@ +#!/home/alpcentaur/ProjektA/PrototypeWebApp/venv/bin/python3.5 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import decrypt +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(decrypt()) diff --git a/venv/bin/pyrsa-encrypt b/venv/bin/pyrsa-encrypt new file mode 100755 index 00000000..94cfb57c --- /dev/null +++ b/venv/bin/pyrsa-encrypt @@ -0,0 +1,8 @@ +#!/home/alpcentaur/ProjektA/PrototypeWebApp/venv/bin/python3.5 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import encrypt +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(encrypt()) diff --git a/venv/bin/pyrsa-keygen b/venv/bin/pyrsa-keygen new file mode 100755 index 00000000..99b3b191 --- /dev/null +++ b/venv/bin/pyrsa-keygen @@ -0,0 +1,8 @@ +#!/home/alpcentaur/ProjektA/PrototypeWebApp/venv/bin/python3.5 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import keygen +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(keygen()) diff --git a/venv/bin/pyrsa-priv2pub b/venv/bin/pyrsa-priv2pub new file mode 100755 index 00000000..41a3deee --- /dev/null +++ b/venv/bin/pyrsa-priv2pub @@ -0,0 +1,8 @@ +#!/home/alpcentaur/ProjektA/PrototypeWebApp/venv/bin/python3.5 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.util import private_to_public +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(private_to_public()) diff --git a/venv/bin/pyrsa-sign b/venv/bin/pyrsa-sign new file mode 100755 index 00000000..c1179034 --- /dev/null +++ b/venv/bin/pyrsa-sign @@ -0,0 +1,8 @@ +#!/home/alpcentaur/ProjektA/PrototypeWebApp/venv/bin/python3.5 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import sign +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(sign()) diff --git a/venv/bin/pyrsa-verify b/venv/bin/pyrsa-verify new file mode 100755 index 00000000..7ae20e17 --- /dev/null +++ b/venv/bin/pyrsa-verify @@ -0,0 +1,8 @@ +#!/home/alpcentaur/ProjektA/PrototypeWebApp/venv/bin/python3.5 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import verify +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(verify()) diff --git a/venv/etc/jupyter/jupyter_notebook_config.json b/venv/etc/jupyter/jupyter_notebook_config.json new file mode 100644 index 00000000..c8d00d09 --- /dev/null +++ b/venv/etc/jupyter/jupyter_notebook_config.json @@ -0,0 +1,7 @@ +{ + "NotebookApp": { + "nbserver_extensions": { + "appmode.server_extension": true + } + } +} \ No newline at end of file diff --git a/venv/etc/jupyter/nbconfig/notebook.json b/venv/etc/jupyter/nbconfig/notebook.json new file mode 100644 index 00000000..9305135b --- /dev/null +++ b/venv/etc/jupyter/nbconfig/notebook.json @@ -0,0 +1,5 @@ +{ + "load_extensions": { + "appmode/main": true + } +} \ No newline at end of file diff --git a/venv/lib/python3.5/site-packages/absl/__pycache__/__init__.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/__pycache__/__init__.cpython-35.pyc index 04211811..67dc1873 100644 Binary files a/venv/lib/python3.5/site-packages/absl/__pycache__/__init__.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/__pycache__/__init__.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/__pycache__/_enum_module.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/__pycache__/_enum_module.cpython-35.pyc index 57194418..7233a374 100644 Binary files a/venv/lib/python3.5/site-packages/absl/__pycache__/_enum_module.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/__pycache__/_enum_module.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/__pycache__/app.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/__pycache__/app.cpython-35.pyc index 29a1b0f8..c1184bdc 100644 Binary files a/venv/lib/python3.5/site-packages/absl/__pycache__/app.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/__pycache__/app.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/__pycache__/command_name.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/__pycache__/command_name.cpython-35.pyc index 7d17ea13..9bd05a8d 100644 Binary files a/venv/lib/python3.5/site-packages/absl/__pycache__/command_name.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/__pycache__/command_name.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/__init__.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/__init__.cpython-35.pyc index 87ac7085..33072009 100644 Binary files a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/__init__.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/__init__.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_argument_parser.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_argument_parser.cpython-35.pyc index 831d6c4c..66ce2376 100644 Binary files a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_argument_parser.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_argument_parser.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_defines.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_defines.cpython-35.pyc index c279db51..d2755fc6 100644 Binary files a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_defines.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_defines.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_exceptions.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_exceptions.cpython-35.pyc index 216b605e..e57b8e6c 100644 Binary files a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_exceptions.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_exceptions.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_flag.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_flag.cpython-35.pyc index a8508b38..123ed726 100644 Binary files a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_flag.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_flag.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_flagvalues.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_flagvalues.cpython-35.pyc index 647a3c5c..8a56325e 100644 Binary files a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_flagvalues.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_flagvalues.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_helpers.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_helpers.cpython-35.pyc index 8427cb41..c40a2239 100644 Binary files a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_helpers.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_helpers.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_validators.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_validators.cpython-35.pyc index 092b99b3..464e9ff9 100644 Binary files a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_validators.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/_validators.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/argparse_flags.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/argparse_flags.cpython-35.pyc index 872a7f48..4436de7b 100644 Binary files a/venv/lib/python3.5/site-packages/absl/flags/__pycache__/argparse_flags.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/flags/__pycache__/argparse_flags.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/logging/__pycache__/__init__.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/logging/__pycache__/__init__.cpython-35.pyc index 3e90923c..c6a15935 100644 Binary files a/venv/lib/python3.5/site-packages/absl/logging/__pycache__/__init__.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/logging/__pycache__/__init__.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/logging/__pycache__/converter.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/logging/__pycache__/converter.cpython-35.pyc index 2c6e3e8a..87abac12 100644 Binary files a/venv/lib/python3.5/site-packages/absl/logging/__pycache__/converter.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/logging/__pycache__/converter.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/__init__.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/__init__.cpython-35.pyc index 20c43410..d287e250 100644 Binary files a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/__init__.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/__init__.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/_bazelize_command.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/_bazelize_command.cpython-35.pyc index 38da0eea..38290b4d 100644 Binary files a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/_bazelize_command.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/_bazelize_command.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/_pretty_print_reporter.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/_pretty_print_reporter.cpython-35.pyc index a01b399c..215e5d48 100644 Binary files a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/_pretty_print_reporter.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/_pretty_print_reporter.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/absltest.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/absltest.cpython-35.pyc index ac8eaaa6..a1d217eb 100644 Binary files a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/absltest.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/absltest.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/flagsaver.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/flagsaver.cpython-35.pyc index aba9f51c..a791cd31 100644 Binary files a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/flagsaver.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/flagsaver.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/parameterized.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/parameterized.cpython-35.pyc index bb79bb1b..8701e7e0 100644 Binary files a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/parameterized.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/parameterized.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/xml_reporter.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/xml_reporter.cpython-35.pyc index d9ed40ea..483c6acc 100644 Binary files a/venv/lib/python3.5/site-packages/absl/testing/__pycache__/xml_reporter.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/testing/__pycache__/xml_reporter.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/third_party/__pycache__/__init__.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/third_party/__pycache__/__init__.cpython-35.pyc index f0929462..ed17d30b 100644 Binary files a/venv/lib/python3.5/site-packages/absl/third_party/__pycache__/__init__.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/third_party/__pycache__/__init__.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/__init__.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/__init__.cpython-35.pyc index ae7ca560..6e42472d 100644 Binary files a/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/__init__.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/__init__.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/case.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/case.cpython-35.pyc index 0c7663ca..ef3bc1ff 100644 Binary files a/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/case.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/case.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/result.cpython-35.pyc b/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/result.cpython-35.pyc index a4b2e1d9..383ea889 100644 Binary files a/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/result.cpython-35.pyc and b/venv/lib/python3.5/site-packages/absl/third_party/unittest3_backport/__pycache__/result.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/AUTHORS.rst b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/AUTHORS.rst new file mode 100644 index 00000000..f0683ed9 --- /dev/null +++ b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/AUTHORS.rst @@ -0,0 +1,20 @@ +======= +Credits +======= + +Maintainer +---------- + +* Simon Percivall + +Authors +------- + +* The Python Software Foundation +* Bogdan Opanchuk +* Vladimir Iakovlev +* Thomas Grainger +* Amund Hov +* Jakub Wilk +* Mateusz Bysiek +* Serge Sans Paille diff --git a/venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/INSTALLER b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/INSTALLER similarity index 100% rename from venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/INSTALLER rename to venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/INSTALLER diff --git a/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/LICENSE b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/LICENSE new file mode 100644 index 00000000..099193e4 --- /dev/null +++ b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/LICENSE @@ -0,0 +1,64 @@ +LICENSE +======= + +Copyright (c) 2014, Simon Percivall +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of AST Unparser nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011, 2012, 2013, 2014 Python Software Foundation; All Rights Reserved" are retained +in Python alone or in any derivative version prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. diff --git a/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/METADATA b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/METADATA new file mode 100644 index 00000000..c8f3d61e --- /dev/null +++ b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/METADATA @@ -0,0 +1,165 @@ +Metadata-Version: 2.1 +Name: astunparse +Version: 1.6.3 +Summary: An AST unparser for Python +Home-page: https://github.com/simonpercivall/astunparse +Maintainer: Simon Percivall +Maintainer-email: percivall@gmail.com +License: BSD +Keywords: astunparse +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Natural Language :: English +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Topic :: Software Development :: Code Generators +Requires-Dist: wheel (<1.0,>=0.23.0) +Requires-Dist: six (<2.0,>=1.6.1) + +============ +AST Unparser +============ + +.. image:: https://badge.fury.io/py/astunparse.png + :target: http://badge.fury.io/py/astunparse + +.. image:: https://travis-ci.org/simonpercivall/astunparse.png?branch=master + :target: https://travis-ci.org/simonpercivall/astunparse + +.. image:: https://readthedocs.org/projects/astunparse/badge/ + :target: https://astunparse.readthedocs.org/ + +An AST unparser for Python. + +This is a factored out version of ``unparse`` found in the Python +source distribution; under Demo/parser in Python 2 and under Tools/parser +in Python 3. + +Basic example:: + + import inspect + import ast + import astunparse + + # get back the source code + astunparse.unparse(ast.parse(inspect.getsource(ast))) + + # get a pretty-printed dump of the AST + astunparse.dump(ast.parse(inspect.getsource(ast))) + + +This library is single-source compatible with Python 2.6 through Python 3.5. It +is authored by the Python core developers; I have simply merged the Python 2.7 +and the Python 3.5 source and test suites, and added a wrapper. This factoring +out is to provide a library implementation that supports both versions. + +Added to this is a pretty-printing ``dump`` utility function. + +The test suite both runs specific tests and also roundtrips much of the +standard library. + +Extensions and Alternatives +--------------------------- + +Similar projects include: + + * codegen_ + * astor_ + * astmonkey_ + * astprint_ + +None of these roundtrip much of the standard library and fail several of the basic +tests in the ``test_unparse`` test suite. + +This library uses mature and core maintained code instead of trying to patch +existing libraries. The ``unparse`` and the ``test_unparse`` modules +are under the PSF license. + +Extensions include: + + * typed-astunparse: extends astunparse to support type annotations. + +* Documentation: http://astunparse.rtfd.org. + +Features +-------- + +* unparses Python AST. +* pretty-prints AST. + + +.. _codegen: https://github.com/andreif/codegen +.. _astor: https://github.com/berkerpeksag/astor +.. _astmonkey: https://github.com/konradhalas/astmonkey +.. _astprint: https://github.com/Manticore/astprint + + +Changelog +========= + +Here's the recent changes to AST Unparser. + +1.6.3 - 2019-12-22 +~~~~~~~~~~~~~~~~~~ + +* Add full support for Python 3.8 + +1.6.2 - 2019-01-19 +~~~~~~~~~~~~~~~~~~ + +* Add support for the Constant node in Python 3.8 +* Add tests to the sdist + +1.6.1 - 2018-10-03 +~~~~~~~~~~~~~~~~~~ + +* Fix the roundtripping of very complex f-strings. + +1.6.0 - 2018-09-30 +~~~~~~~~~~~~~~~~~~ + +* Python 3.7 compatibility + +1.5.0 - 2017-02-05 +~~~~~~~~~~~~~~~~~~ + +* Python 3.6 compatibility +* bugfix: correct argparser option type + +1.4.0 - 2016-06-24 +~~~~~~~~~~~~~~~~~~ + +* Support for the ``async`` keyword +* Support for unparsing "Interactive" and "Expression" nodes + +1.3.0 - 2016-01-17 +~~~~~~~~~~~~~~~~~~ + +* Python 3.5 compatibility + +1.2.0 - 2014-04-03 +~~~~~~~~~~~~~~~~~~ + +* Python 2.6 through 3.4 compatibility +* A new function ``dump`` is added to return a pretty-printed version + of the AST. It's also available when running ``python -m astunparse`` + as the ``--dump`` argument. + +1.1.0 - 2014-04-01 +~~~~~~~~~~~~~~~~~~ + +* ``unparse`` will return the source code for an AST. It is pretty + feature-complete, and round-trips the stdlib, and is compatible with + Python 2.7 and Python 3.4. + + Running ``python -m astunparse`` will print the round-tripped source + for any python files given as argument. + + diff --git a/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/RECORD b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/RECORD new file mode 100644 index 00000000..73876b21 --- /dev/null +++ b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/RECORD @@ -0,0 +1,15 @@ +astunparse-1.6.3.dist-info/AUTHORS.rst,sha256=_VxW6Jgbo7Qu1u8z3O3uS0_AoCwuagAPoHwsc5TwxVw,257 +astunparse-1.6.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +astunparse-1.6.3.dist-info/LICENSE,sha256=kvwOT0-pRgVY7t80ErmI1DOi3Ls6nEVAKhRaT6uKasY,3936 +astunparse-1.6.3.dist-info/METADATA,sha256=vQ5__mA9vvjnREIJ61SolBrPCW52OugdLCScjVsL_Ec,4391 +astunparse-1.6.3.dist-info/RECORD,, +astunparse-1.6.3.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110 +astunparse-1.6.3.dist-info/top_level.txt,sha256=D97cApMaOtwZJ6KEsu7GakV5Kt7YpcRkL0dD010ftIo,11 +astunparse/__init__.py,sha256=Vi1Ni9JeZyX7kUX7YEgvaj1S6ky6RyUy8qL_CON1Ugw,357 +astunparse/__main__.py,sha256=OeZij_FXCdGilJ1G5H7H0ChEOuDJUqY_hFCLe8GZpc8,1222 +astunparse/__pycache__/__init__.cpython-35.pyc,, +astunparse/__pycache__/__main__.cpython-35.pyc,, +astunparse/__pycache__/printer.cpython-35.pyc,, +astunparse/__pycache__/unparser.cpython-35.pyc,, +astunparse/printer.py,sha256=8K09sbxtItuH9qE7jphZfN4vudsn3KpIWssudeBAXGo,1408 +astunparse/unparser.py,sha256=RnI-3goUb3N72KIDHDRiFApOJZfIcAtQ5vEIUY7jB5M,27426 diff --git a/venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/WHEEL b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/WHEEL similarity index 70% rename from venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/WHEEL rename to venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/WHEEL index 1316c41d..8b701e93 100644 --- a/venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/WHEEL +++ b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/WHEEL @@ -1,5 +1,5 @@ Wheel-Version: 1.0 -Generator: bdist_wheel (0.31.1) +Generator: bdist_wheel (0.33.6) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any diff --git a/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/top_level.txt b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/top_level.txt new file mode 100644 index 00000000..119f6789 --- /dev/null +++ b/venv/lib/python3.5/site-packages/astunparse-1.6.3.dist-info/top_level.txt @@ -0,0 +1 @@ +astunparse diff --git a/venv/lib/python3.5/site-packages/astunparse/__init__.py b/venv/lib/python3.5/site-packages/astunparse/__init__.py new file mode 100644 index 00000000..e2eeddc8 --- /dev/null +++ b/venv/lib/python3.5/site-packages/astunparse/__init__.py @@ -0,0 +1,20 @@ +# coding: utf-8 +from __future__ import absolute_import +from six.moves import cStringIO +from .unparser import Unparser +from .printer import Printer + + +__version__ = '1.6.3' + + +def unparse(tree): + v = cStringIO() + Unparser(tree, file=v) + return v.getvalue() + + +def dump(tree): + v = cStringIO() + Printer(file=v).visit(tree) + return v.getvalue() diff --git a/venv/lib/python3.5/site-packages/astunparse/__main__.py b/venv/lib/python3.5/site-packages/astunparse/__main__.py new file mode 100644 index 00000000..1729cd7c --- /dev/null +++ b/venv/lib/python3.5/site-packages/astunparse/__main__.py @@ -0,0 +1,48 @@ +from __future__ import print_function +import sys +import os +import argparse +from .unparser import roundtrip +from . import dump + + +def roundtrip_recursive(target, dump_tree=False): + if os.path.isfile(target): + print(target) + print("=" * len(target)) + if dump_tree: + dump(target) + else: + roundtrip(target) + print() + elif os.path.isdir(target): + for item in os.listdir(target): + if item.endswith(".py"): + roundtrip_recursive(os.path.join(target, item), dump_tree) + else: + print( + "WARNING: skipping '%s', not a file or directory" % target, + file=sys.stderr + ) + + +def main(args): + parser = argparse.ArgumentParser(prog="astunparse") + parser.add_argument( + 'target', + nargs='+', + help="Files or directories to show roundtripped source for" + ) + parser.add_argument( + '--dump', + type=bool, + help="Show a pretty-printed AST instead of the source" + ) + + arguments = parser.parse_args(args) + for target in arguments.target: + roundtrip_recursive(target, dump_tree=arguments.dump) + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/venv/lib/python3.5/site-packages/astunparse/__pycache__/__init__.cpython-35.pyc b/venv/lib/python3.5/site-packages/astunparse/__pycache__/__init__.cpython-35.pyc new file mode 100644 index 00000000..34e1a511 Binary files /dev/null and b/venv/lib/python3.5/site-packages/astunparse/__pycache__/__init__.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/astunparse/__pycache__/__main__.cpython-35.pyc b/venv/lib/python3.5/site-packages/astunparse/__pycache__/__main__.cpython-35.pyc new file mode 100644 index 00000000..44ab6ad6 Binary files /dev/null and b/venv/lib/python3.5/site-packages/astunparse/__pycache__/__main__.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/astunparse/__pycache__/printer.cpython-35.pyc b/venv/lib/python3.5/site-packages/astunparse/__pycache__/printer.cpython-35.pyc new file mode 100644 index 00000000..13875155 Binary files /dev/null and b/venv/lib/python3.5/site-packages/astunparse/__pycache__/printer.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/astunparse/__pycache__/unparser.cpython-35.pyc b/venv/lib/python3.5/site-packages/astunparse/__pycache__/unparser.cpython-35.pyc new file mode 100644 index 00000000..814f4070 Binary files /dev/null and b/venv/lib/python3.5/site-packages/astunparse/__pycache__/unparser.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/astunparse/printer.py b/venv/lib/python3.5/site-packages/astunparse/printer.py new file mode 100644 index 00000000..92d64f77 --- /dev/null +++ b/venv/lib/python3.5/site-packages/astunparse/printer.py @@ -0,0 +1,51 @@ +from __future__ import unicode_literals +import sys +import ast +import six + + +class Printer(ast.NodeVisitor): + + def __init__(self, file=sys.stdout, indent=" "): + self.indentation = 0 + self.indent_with = indent + self.f = file + + # overridden to make the API obvious + def visit(self, node): + super(Printer, self).visit(node) + + def write(self, text): + self.f.write(six.text_type(text)) + + def generic_visit(self, node): + + if isinstance(node, list): + nodestart = "[" + nodeend = "]" + children = [("", child) for child in node] + else: + nodestart = type(node).__name__ + "(" + nodeend = ")" + children = [(name + "=", value) for name, value in ast.iter_fields(node)] + + if len(children) > 1: + self.indentation += 1 + + self.write(nodestart) + for i, pair in enumerate(children): + attr, child = pair + if len(children) > 1: + self.write("\n" + self.indent_with * self.indentation) + if isinstance(child, (ast.AST, list)): + self.write(attr) + self.visit(child) + else: + self.write(attr + repr(child)) + + if i != len(children) - 1: + self.write(",") + self.write(nodeend) + + if len(children) > 1: + self.indentation -= 1 diff --git a/venv/lib/python3.5/site-packages/astunparse/unparser.py b/venv/lib/python3.5/site-packages/astunparse/unparser.py new file mode 100644 index 00000000..0ef6fd8b --- /dev/null +++ b/venv/lib/python3.5/site-packages/astunparse/unparser.py @@ -0,0 +1,906 @@ +"Usage: unparse.py " +from __future__ import print_function, unicode_literals +import six +import sys +import ast +import os +import tokenize +from six import StringIO + +# Large float and imaginary literals get turned into infinities in the AST. +# We unparse those infinities to INFSTR. +INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1) + +def interleave(inter, f, seq): + """Call f on each item in seq, calling inter() in between. + """ + seq = iter(seq) + try: + f(next(seq)) + except StopIteration: + pass + else: + for x in seq: + inter() + f(x) + +class Unparser: + """Methods in this class recursively traverse an AST and + output source code for the abstract syntax; original formatting + is disregarded. """ + + def __init__(self, tree, file = sys.stdout): + """Unparser(tree, file=sys.stdout) -> None. + Print the source for tree to file.""" + self.f = file + self.future_imports = [] + self._indent = 0 + self.dispatch(tree) + print("", file=self.f) + self.f.flush() + + def fill(self, text = ""): + "Indent a piece of text, according to the current indentation level" + self.f.write("\n"+" "*self._indent + text) + + def write(self, text): + "Append a piece of text to the current line." + self.f.write(six.text_type(text)) + + def enter(self): + "Print ':', and increase the indentation." + self.write(":") + self._indent += 1 + + def leave(self): + "Decrease the indentation level." + self._indent -= 1 + + def dispatch(self, tree): + "Dispatcher function, dispatching tree type T to method _T." + if isinstance(tree, list): + for t in tree: + self.dispatch(t) + return + meth = getattr(self, "_"+tree.__class__.__name__) + meth(tree) + + + ############### Unparsing methods ###################### + # There should be one method per concrete grammar type # + # Constructors should be grouped by sum type. Ideally, # + # this would follow the order in the grammar, but # + # currently doesn't. # + ######################################################## + + def _Module(self, tree): + for stmt in tree.body: + self.dispatch(stmt) + + def _Interactive(self, tree): + for stmt in tree.body: + self.dispatch(stmt) + + def _Expression(self, tree): + self.dispatch(tree.body) + + # stmt + def _Expr(self, tree): + self.fill() + self.dispatch(tree.value) + + def _NamedExpr(self, tree): + self.write("(") + self.dispatch(tree.target) + self.write(" := ") + self.dispatch(tree.value) + self.write(")") + + def _Import(self, t): + self.fill("import ") + interleave(lambda: self.write(", "), self.dispatch, t.names) + + def _ImportFrom(self, t): + # A from __future__ import may affect unparsing, so record it. + if t.module and t.module == '__future__': + self.future_imports.extend(n.name for n in t.names) + + self.fill("from ") + self.write("." * t.level) + if t.module: + self.write(t.module) + self.write(" import ") + interleave(lambda: self.write(", "), self.dispatch, t.names) + + def _Assign(self, t): + self.fill() + for target in t.targets: + self.dispatch(target) + self.write(" = ") + self.dispatch(t.value) + + def _AugAssign(self, t): + self.fill() + self.dispatch(t.target) + self.write(" "+self.binop[t.op.__class__.__name__]+"= ") + self.dispatch(t.value) + + def _AnnAssign(self, t): + self.fill() + if not t.simple and isinstance(t.target, ast.Name): + self.write('(') + self.dispatch(t.target) + if not t.simple and isinstance(t.target, ast.Name): + self.write(')') + self.write(": ") + self.dispatch(t.annotation) + if t.value: + self.write(" = ") + self.dispatch(t.value) + + def _Return(self, t): + self.fill("return") + if t.value: + self.write(" ") + self.dispatch(t.value) + + def _Pass(self, t): + self.fill("pass") + + def _Break(self, t): + self.fill("break") + + def _Continue(self, t): + self.fill("continue") + + def _Delete(self, t): + self.fill("del ") + interleave(lambda: self.write(", "), self.dispatch, t.targets) + + def _Assert(self, t): + self.fill("assert ") + self.dispatch(t.test) + if t.msg: + self.write(", ") + self.dispatch(t.msg) + + def _Exec(self, t): + self.fill("exec ") + self.dispatch(t.body) + if t.globals: + self.write(" in ") + self.dispatch(t.globals) + if t.locals: + self.write(", ") + self.dispatch(t.locals) + + def _Print(self, t): + self.fill("print ") + do_comma = False + if t.dest: + self.write(">>") + self.dispatch(t.dest) + do_comma = True + for e in t.values: + if do_comma:self.write(", ") + else:do_comma=True + self.dispatch(e) + if not t.nl: + self.write(",") + + def _Global(self, t): + self.fill("global ") + interleave(lambda: self.write(", "), self.write, t.names) + + def _Nonlocal(self, t): + self.fill("nonlocal ") + interleave(lambda: self.write(", "), self.write, t.names) + + def _Await(self, t): + self.write("(") + self.write("await") + if t.value: + self.write(" ") + self.dispatch(t.value) + self.write(")") + + def _Yield(self, t): + self.write("(") + self.write("yield") + if t.value: + self.write(" ") + self.dispatch(t.value) + self.write(")") + + def _YieldFrom(self, t): + self.write("(") + self.write("yield from") + if t.value: + self.write(" ") + self.dispatch(t.value) + self.write(")") + + def _Raise(self, t): + self.fill("raise") + if six.PY3: + if not t.exc: + assert not t.cause + return + self.write(" ") + self.dispatch(t.exc) + if t.cause: + self.write(" from ") + self.dispatch(t.cause) + else: + self.write(" ") + if t.type: + self.dispatch(t.type) + if t.inst: + self.write(", ") + self.dispatch(t.inst) + if t.tback: + self.write(", ") + self.dispatch(t.tback) + + def _Try(self, t): + self.fill("try") + self.enter() + self.dispatch(t.body) + self.leave() + for ex in t.handlers: + self.dispatch(ex) + if t.orelse: + self.fill("else") + self.enter() + self.dispatch(t.orelse) + self.leave() + if t.finalbody: + self.fill("finally") + self.enter() + self.dispatch(t.finalbody) + self.leave() + + def _TryExcept(self, t): + self.fill("try") + self.enter() + self.dispatch(t.body) + self.leave() + + for ex in t.handlers: + self.dispatch(ex) + if t.orelse: + self.fill("else") + self.enter() + self.dispatch(t.orelse) + self.leave() + + def _TryFinally(self, t): + if len(t.body) == 1 and isinstance(t.body[0], ast.TryExcept): + # try-except-finally + self.dispatch(t.body) + else: + self.fill("try") + self.enter() + self.dispatch(t.body) + self.leave() + + self.fill("finally") + self.enter() + self.dispatch(t.finalbody) + self.leave() + + def _ExceptHandler(self, t): + self.fill("except") + if t.type: + self.write(" ") + self.dispatch(t.type) + if t.name: + self.write(" as ") + if six.PY3: + self.write(t.name) + else: + self.dispatch(t.name) + self.enter() + self.dispatch(t.body) + self.leave() + + def _ClassDef(self, t): + self.write("\n") + for deco in t.decorator_list: + self.fill("@") + self.dispatch(deco) + self.fill("class "+t.name) + if six.PY3: + self.write("(") + comma = False + for e in t.bases: + if comma: self.write(", ") + else: comma = True + self.dispatch(e) + for e in t.keywords: + if comma: self.write(", ") + else: comma = True + self.dispatch(e) + if sys.version_info[:2] < (3, 5): + if t.starargs: + if comma: self.write(", ") + else: comma = True + self.write("*") + self.dispatch(t.starargs) + if t.kwargs: + if comma: self.write(", ") + else: comma = True + self.write("**") + self.dispatch(t.kwargs) + self.write(")") + elif t.bases: + self.write("(") + for a in t.bases: + self.dispatch(a) + self.write(", ") + self.write(")") + self.enter() + self.dispatch(t.body) + self.leave() + + def _FunctionDef(self, t): + self.__FunctionDef_helper(t, "def") + + def _AsyncFunctionDef(self, t): + self.__FunctionDef_helper(t, "async def") + + def __FunctionDef_helper(self, t, fill_suffix): + self.write("\n") + for deco in t.decorator_list: + self.fill("@") + self.dispatch(deco) + def_str = fill_suffix+" "+t.name + "(" + self.fill(def_str) + self.dispatch(t.args) + self.write(")") + if getattr(t, "returns", False): + self.write(" -> ") + self.dispatch(t.returns) + self.enter() + self.dispatch(t.body) + self.leave() + + def _For(self, t): + self.__For_helper("for ", t) + + def _AsyncFor(self, t): + self.__For_helper("async for ", t) + + def __For_helper(self, fill, t): + self.fill(fill) + self.dispatch(t.target) + self.write(" in ") + self.dispatch(t.iter) + self.enter() + self.dispatch(t.body) + self.leave() + if t.orelse: + self.fill("else") + self.enter() + self.dispatch(t.orelse) + self.leave() + + def _If(self, t): + self.fill("if ") + self.dispatch(t.test) + self.enter() + self.dispatch(t.body) + self.leave() + # collapse nested ifs into equivalent elifs. + while (t.orelse and len(t.orelse) == 1 and + isinstance(t.orelse[0], ast.If)): + t = t.orelse[0] + self.fill("elif ") + self.dispatch(t.test) + self.enter() + self.dispatch(t.body) + self.leave() + # final else + if t.orelse: + self.fill("else") + self.enter() + self.dispatch(t.orelse) + self.leave() + + def _While(self, t): + self.fill("while ") + self.dispatch(t.test) + self.enter() + self.dispatch(t.body) + self.leave() + if t.orelse: + self.fill("else") + self.enter() + self.dispatch(t.orelse) + self.leave() + + def _generic_With(self, t, async_=False): + self.fill("async with " if async_ else "with ") + if hasattr(t, 'items'): + interleave(lambda: self.write(", "), self.dispatch, t.items) + else: + self.dispatch(t.context_expr) + if t.optional_vars: + self.write(" as ") + self.dispatch(t.optional_vars) + self.enter() + self.dispatch(t.body) + self.leave() + + def _With(self, t): + self._generic_With(t) + + def _AsyncWith(self, t): + self._generic_With(t, async_=True) + + # expr + def _Bytes(self, t): + self.write(repr(t.s)) + + def _Str(self, tree): + if six.PY3: + self.write(repr(tree.s)) + else: + # if from __future__ import unicode_literals is in effect, + # then we want to output string literals using a 'b' prefix + # and unicode literals with no prefix. + if "unicode_literals" not in self.future_imports: + self.write(repr(tree.s)) + elif isinstance(tree.s, str): + self.write("b" + repr(tree.s)) + elif isinstance(tree.s, unicode): + self.write(repr(tree.s).lstrip("u")) + else: + assert False, "shouldn't get here" + + def _JoinedStr(self, t): + # JoinedStr(expr* values) + self.write("f") + string = StringIO() + self._fstring_JoinedStr(t, string.write) + # Deviation from `unparse.py`: Try to find an unused quote. + # This change is made to handle _very_ complex f-strings. + v = string.getvalue() + if '\n' in v or '\r' in v: + quote_types = ["'''", '"""'] + else: + quote_types = ["'", '"', '"""', "'''"] + for quote_type in quote_types: + if quote_type not in v: + v = "{quote_type}{v}{quote_type}".format(quote_type=quote_type, v=v) + break + else: + v = repr(v) + self.write(v) + + def _FormattedValue(self, t): + # FormattedValue(expr value, int? conversion, expr? format_spec) + self.write("f") + string = StringIO() + self._fstring_JoinedStr(t, string.write) + self.write(repr(string.getvalue())) + + def _fstring_JoinedStr(self, t, write): + for value in t.values: + meth = getattr(self, "_fstring_" + type(value).__name__) + meth(value, write) + + def _fstring_Str(self, t, write): + value = t.s.replace("{", "{{").replace("}", "}}") + write(value) + + def _fstring_Constant(self, t, write): + assert isinstance(t.value, str) + value = t.value.replace("{", "{{").replace("}", "}}") + write(value) + + def _fstring_FormattedValue(self, t, write): + write("{") + expr = StringIO() + Unparser(t.value, expr) + expr = expr.getvalue().rstrip("\n") + if expr.startswith("{"): + write(" ") # Separate pair of opening brackets as "{ {" + write(expr) + if t.conversion != -1: + conversion = chr(t.conversion) + assert conversion in "sra" + write("!{conversion}".format(conversion=conversion)) + if t.format_spec: + write(":") + meth = getattr(self, "_fstring_" + type(t.format_spec).__name__) + meth(t.format_spec, write) + write("}") + + def _Name(self, t): + self.write(t.id) + + def _NameConstant(self, t): + self.write(repr(t.value)) + + def _Repr(self, t): + self.write("`") + self.dispatch(t.value) + self.write("`") + + def _write_constant(self, value): + if isinstance(value, (float, complex)): + # Substitute overflowing decimal literal for AST infinities. + self.write(repr(value).replace("inf", INFSTR)) + else: + self.write(repr(value)) + + def _Constant(self, t): + value = t.value + if isinstance(value, tuple): + self.write("(") + if len(value) == 1: + self._write_constant(value[0]) + self.write(",") + else: + interleave(lambda: self.write(", "), self._write_constant, value) + self.write(")") + elif value is Ellipsis: # instead of `...` for Py2 compatibility + self.write("...") + else: + if t.kind == "u": + self.write("u") + self._write_constant(t.value) + + def _Num(self, t): + repr_n = repr(t.n) + if six.PY3: + self.write(repr_n.replace("inf", INFSTR)) + else: + # Parenthesize negative numbers, to avoid turning (-1)**2 into -1**2. + if repr_n.startswith("-"): + self.write("(") + if "inf" in repr_n and repr_n.endswith("*j"): + repr_n = repr_n.replace("*j", "j") + # Substitute overflowing decimal literal for AST infinities. + self.write(repr_n.replace("inf", INFSTR)) + if repr_n.startswith("-"): + self.write(")") + + def _List(self, t): + self.write("[") + interleave(lambda: self.write(", "), self.dispatch, t.elts) + self.write("]") + + def _ListComp(self, t): + self.write("[") + self.dispatch(t.elt) + for gen in t.generators: + self.dispatch(gen) + self.write("]") + + def _GeneratorExp(self, t): + self.write("(") + self.dispatch(t.elt) + for gen in t.generators: + self.dispatch(gen) + self.write(")") + + def _SetComp(self, t): + self.write("{") + self.dispatch(t.elt) + for gen in t.generators: + self.dispatch(gen) + self.write("}") + + def _DictComp(self, t): + self.write("{") + self.dispatch(t.key) + self.write(": ") + self.dispatch(t.value) + for gen in t.generators: + self.dispatch(gen) + self.write("}") + + def _comprehension(self, t): + if getattr(t, 'is_async', False): + self.write(" async for ") + else: + self.write(" for ") + self.dispatch(t.target) + self.write(" in ") + self.dispatch(t.iter) + for if_clause in t.ifs: + self.write(" if ") + self.dispatch(if_clause) + + def _IfExp(self, t): + self.write("(") + self.dispatch(t.body) + self.write(" if ") + self.dispatch(t.test) + self.write(" else ") + self.dispatch(t.orelse) + self.write(")") + + def _Set(self, t): + assert(t.elts) # should be at least one element + self.write("{") + interleave(lambda: self.write(", "), self.dispatch, t.elts) + self.write("}") + + def _Dict(self, t): + self.write("{") + def write_key_value_pair(k, v): + self.dispatch(k) + self.write(": ") + self.dispatch(v) + + def write_item(item): + k, v = item + if k is None: + # for dictionary unpacking operator in dicts {**{'y': 2}} + # see PEP 448 for details + self.write("**") + self.dispatch(v) + else: + write_key_value_pair(k, v) + interleave(lambda: self.write(", "), write_item, zip(t.keys, t.values)) + self.write("}") + + def _Tuple(self, t): + self.write("(") + if len(t.elts) == 1: + elt = t.elts[0] + self.dispatch(elt) + self.write(",") + else: + interleave(lambda: self.write(", "), self.dispatch, t.elts) + self.write(")") + + unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"} + def _UnaryOp(self, t): + self.write("(") + self.write(self.unop[t.op.__class__.__name__]) + self.write(" ") + if six.PY2 and isinstance(t.op, ast.USub) and isinstance(t.operand, ast.Num): + # If we're applying unary minus to a number, parenthesize the number. + # This is necessary: -2147483648 is different from -(2147483648) on + # a 32-bit machine (the first is an int, the second a long), and + # -7j is different from -(7j). (The first has real part 0.0, the second + # has real part -0.0.) + self.write("(") + self.dispatch(t.operand) + self.write(")") + else: + self.dispatch(t.operand) + self.write(")") + + binop = { "Add":"+", "Sub":"-", "Mult":"*", "MatMult":"@", "Div":"/", "Mod":"%", + "LShift":"<<", "RShift":">>", "BitOr":"|", "BitXor":"^", "BitAnd":"&", + "FloorDiv":"//", "Pow": "**"} + def _BinOp(self, t): + self.write("(") + self.dispatch(t.left) + self.write(" " + self.binop[t.op.__class__.__name__] + " ") + self.dispatch(t.right) + self.write(")") + + cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=", + "Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"} + def _Compare(self, t): + self.write("(") + self.dispatch(t.left) + for o, e in zip(t.ops, t.comparators): + self.write(" " + self.cmpops[o.__class__.__name__] + " ") + self.dispatch(e) + self.write(")") + + boolops = {ast.And: 'and', ast.Or: 'or'} + def _BoolOp(self, t): + self.write("(") + s = " %s " % self.boolops[t.op.__class__] + interleave(lambda: self.write(s), self.dispatch, t.values) + self.write(")") + + def _Attribute(self,t): + self.dispatch(t.value) + # Special case: 3.__abs__() is a syntax error, so if t.value + # is an integer literal then we need to either parenthesize + # it or add an extra space to get 3 .__abs__(). + if isinstance(t.value, getattr(ast, 'Constant', getattr(ast, 'Num', None))) and isinstance(t.value.n, int): + self.write(" ") + self.write(".") + self.write(t.attr) + + def _Call(self, t): + self.dispatch(t.func) + self.write("(") + comma = False + for e in t.args: + if comma: self.write(", ") + else: comma = True + self.dispatch(e) + for e in t.keywords: + if comma: self.write(", ") + else: comma = True + self.dispatch(e) + if sys.version_info[:2] < (3, 5): + if t.starargs: + if comma: self.write(", ") + else: comma = True + self.write("*") + self.dispatch(t.starargs) + if t.kwargs: + if comma: self.write(", ") + else: comma = True + self.write("**") + self.dispatch(t.kwargs) + self.write(")") + + def _Subscript(self, t): + self.dispatch(t.value) + self.write("[") + self.dispatch(t.slice) + self.write("]") + + def _Starred(self, t): + self.write("*") + self.dispatch(t.value) + + # slice + def _Ellipsis(self, t): + self.write("...") + + def _Index(self, t): + self.dispatch(t.value) + + def _Slice(self, t): + if t.lower: + self.dispatch(t.lower) + self.write(":") + if t.upper: + self.dispatch(t.upper) + if t.step: + self.write(":") + self.dispatch(t.step) + + def _ExtSlice(self, t): + interleave(lambda: self.write(', '), self.dispatch, t.dims) + + # argument + def _arg(self, t): + self.write(t.arg) + if t.annotation: + self.write(": ") + self.dispatch(t.annotation) + + # others + def _arguments(self, t): + first = True + # normal arguments + all_args = getattr(t, 'posonlyargs', []) + t.args + defaults = [None] * (len(all_args) - len(t.defaults)) + t.defaults + for index, elements in enumerate(zip(all_args, defaults), 1): + a, d = elements + if first:first = False + else: self.write(", ") + self.dispatch(a) + if d: + self.write("=") + self.dispatch(d) + if index == len(getattr(t, 'posonlyargs', ())): + self.write(", /") + + # varargs, or bare '*' if no varargs but keyword-only arguments present + if t.vararg or getattr(t, "kwonlyargs", False): + if first:first = False + else: self.write(", ") + self.write("*") + if t.vararg: + if hasattr(t.vararg, 'arg'): + self.write(t.vararg.arg) + if t.vararg.annotation: + self.write(": ") + self.dispatch(t.vararg.annotation) + else: + self.write(t.vararg) + if getattr(t, 'varargannotation', None): + self.write(": ") + self.dispatch(t.varargannotation) + + # keyword-only arguments + if getattr(t, "kwonlyargs", False): + for a, d in zip(t.kwonlyargs, t.kw_defaults): + if first:first = False + else: self.write(", ") + self.dispatch(a), + if d: + self.write("=") + self.dispatch(d) + + # kwargs + if t.kwarg: + if first:first = False + else: self.write(", ") + if hasattr(t.kwarg, 'arg'): + self.write("**"+t.kwarg.arg) + if t.kwarg.annotation: + self.write(": ") + self.dispatch(t.kwarg.annotation) + else: + self.write("**"+t.kwarg) + if getattr(t, 'kwargannotation', None): + self.write(": ") + self.dispatch(t.kwargannotation) + + def _keyword(self, t): + if t.arg is None: + # starting from Python 3.5 this denotes a kwargs part of the invocation + self.write("**") + else: + self.write(t.arg) + self.write("=") + self.dispatch(t.value) + + def _Lambda(self, t): + self.write("(") + self.write("lambda ") + self.dispatch(t.args) + self.write(": ") + self.dispatch(t.body) + self.write(")") + + def _alias(self, t): + self.write(t.name) + if t.asname: + self.write(" as "+t.asname) + + def _withitem(self, t): + self.dispatch(t.context_expr) + if t.optional_vars: + self.write(" as ") + self.dispatch(t.optional_vars) + +def roundtrip(filename, output=sys.stdout): + if six.PY3: + with open(filename, "rb") as pyfile: + encoding = tokenize.detect_encoding(pyfile.readline)[0] + with open(filename, "r", encoding=encoding) as pyfile: + source = pyfile.read() + else: + with open(filename, "r") as pyfile: + source = pyfile.read() + tree = compile(source, filename, "exec", ast.PyCF_ONLY_AST, dont_inherit=True) + Unparser(tree, output) + + + +def testdir(a): + try: + names = [n for n in os.listdir(a) if n.endswith('.py')] + except OSError: + print("Directory not readable: %s" % a, file=sys.stderr) + else: + for n in names: + fullname = os.path.join(a, n) + if os.path.isfile(fullname): + output = StringIO() + print('Testing %s' % fullname) + try: + roundtrip(fullname, output) + except Exception as e: + print(' Failed to compile, exception is %s' % repr(e)) + elif os.path.isdir(fullname): + testdir(fullname) + +def main(args): + if args[0] == '--testdir': + for a in args[1:]: + testdir(a) + else: + for a in args: + roundtrip(a) + +if __name__=='__main__': + main(sys.argv[1:]) diff --git a/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/DESCRIPTION.rst b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/DESCRIPTION.rst new file mode 100644 index 00000000..b4ab87a5 --- /dev/null +++ b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/DESCRIPTION.rst @@ -0,0 +1,281 @@ +====== +Bleach +====== + +.. image:: https://travis-ci.org/mozilla/bleach.png?branch=master + :target: https://travis-ci.org/mozilla/bleach + +.. image:: https://badge.fury.io/py/Bleach.svg + :target: http://badge.fury.io/py/Bleach + +Bleach is a whitelist-based HTML sanitizing library that escapes or strips +markup and attributes. + +Bleach can also linkify text safely, applying filters that Django's ``urlize`` +filter cannot, and optionally setting ``rel`` attributes, even on links already +in the text. + +Bleach is intended for sanitizing text from *untrusted* sources. If you find +yourself jumping through hoops to allow your site administrators to do lots of +things, you're probably outside the use cases. Either trust those users, or +don't. + +Because it relies on html5lib_, Bleach is as good as modern browsers at dealing +with weird, quirky HTML fragments. And *any* of Bleach's methods will fix +unbalanced or mis-nested tags. + +The version on GitHub_ is the most up-to-date and contains the latest bug +fixes. You can find full documentation on `ReadTheDocs`_. + +:Code: https://github.com/mozilla/bleach +:Documentation: https://bleach.readthedocs.io/ +:Issue tracker: https://github.com/mozilla/bleach/issues +:IRC: ``#bleach`` on irc.mozilla.org +:License: Apache License v2; see LICENSE file + + +Reporting Bugs +============== + +For regular bugs, please report them `in our issue tracker +`_. + +If you believe that you've found a security vulnerability, please `file a secure +bug report in our bug tracker +`_ +or send an email to *security AT mozilla DOT org*. + +For more information on security-related bug disclosure and the PGP key to use +for sending encrypted mail or to verify responses received from that address, +please read our wiki page at +``_. + + +Installing Bleach +================= + +Bleach is available on PyPI_, so you can install it with ``pip``:: + + $ pip install bleach + +Or with ``easy_install``:: + + $ easy_install bleach + +Or by cloning the repo from GitHub_:: + + $ git clone git://github.com/mozilla/bleach.git + +Then install it by running:: + + $ python setup.py install + + +Upgrading Bleach +================ + +.. warning:: + + Before doing any upgrades, read through `Bleach Changes + `_ for backwards + incompatible changes, newer versions, etc. + + +Basic use +========= + +The simplest way to use Bleach is: + +.. code-block:: python + + >>> import bleach + + >>> bleach.clean('an example') + u'an <script>evil()</script> example' + + >>> bleach.linkify('an http://example.com url') + u'an http://example.com url + + +.. _html5lib: https://github.com/html5lib/html5lib-python +.. _GitHub: https://github.com/mozilla/bleach +.. _ReadTheDocs: https://bleach.readthedocs.io/ +.. _PyPI: http://pypi.python.org/pypi/bleach + + +Bleach Changes +============== + +Version 1.5 (November 4th, 2016) +-------------------------------- + +**Backwards incompatible changes** + +- clean: The list of ``ALLOWED_PROTOCOLS`` now defaults to http, https and + mailto. Previously it was a long list of protocols something like ed2k, ftp, + http, https, irc, mailto, news, gopher, nntp, telnet, webcal, xmpp, callto, + feed, urn, aim, rsync, tag, ssh, sftp, rtsp, afs, data. #149 + +**Changes** + +- clean: Added ``protocols`` to arguments list to let you override the list of + allowed protocols. Thank you, Andreas Malecki! #149 +- linkify: Fix a bug involving periods at the end of an email address. Thank you, + Lorenz Schori! #219 +- linkify: Fix linkification of non-ascii ports. Thank you Alexandre, Macabies! + #207 +- linkify: Fix linkify inappropriately removing node tails when dropping nodes. + #132 +- Fixed a test that failed periodically. #161 +- Switched from nose to py.test. #204 +- Add test matrix for all supported Python and html5lib versions. #230 +- Limit to html5lib ``>=0.999,!=0.9999,!=0.99999,<0.99999999`` because 0.9999 + and 0.99999 are busted. +- Add support for ``python setup.py test``. #97 + + +Version 1.4.3 (May 23rd, 2016) +------------------------------ + +**Changes** + +- Limit to html5lib ``>=0.999,<0.99999999`` because of impending change to + sanitizer api. #195 + + +Version 1.4.2 (September 11, 2015) +---------------------------------- + +**Changes** + +- linkify: Fix hang in linkify with ``parse_email=True``. #124 +- linkify: Fix crash in linkify when removing a link that is a first-child. #136 +- Updated TLDs. +- linkify: Don't remove exterior brackets when linkifying. #146 + + +Version 1.4.1 (December 15, 2014) +--------------------------------- + +**Changes** + +- Consistent order of attributes in output. +- Python 3.4 support. + + +Version 1.4 (January 12, 2014) +------------------------------ + +**Changes** + +- linkify: Update linkify to use etree type Treewalker instead of simpletree. +- Updated html5lib to version ``>=0.999``. +- Update all code to be compatible with Python 3 and 2 using six. +- Switch to Apache License. + + +Version 1.3 +----------- + +- Used by Python 3-only fork. + + +Version 1.2.2 (May 18, 2013) +---------------------------- + +- Pin html5lib to version 0.95 for now due to major API break. + +Version 1.2.1 (February 19, 2013) +--------------------------------- + +- clean() no longer considers ``feed:`` an acceptable protocol due to + inconsistencies in browser behavior. + + +Version 1.2 (January 28, 2013) +------------------------------ + +- linkify() has changed considerably. Many keyword arguments have been + replaced with a single callbacks list. Please see the documentation + for more information. +- Bleach will no longer consider unacceptable protocols when linkifying. +- linkify() now takes a tokenizer argument that allows it to skip + sanitization. +- delinkify() is gone. +- Removed exception handling from _render. clean() and linkify() may now + throw. +- linkify() correctly ignores case for protocols and domain names. +- linkify() correctly handles markup within an tag. + + +Version 1.1.5 +------------- + + +Version 1.1.4 +------------- + + +Version 1.1.3 (July 10, 2012) +----------------------------- + +- Fix parsing bare URLs when parse_email=True. + + +Version 1.1.2 (June 1, 2012) +---------------------------- + +- Fix hang in style attribute sanitizer. (#61) +- Allow '/' in style attribute values. + + +Version 1.1.1 (February 17, 2012) +--------------------------------- + +- Fix tokenizer for html5lib 0.9.5. + + +Version 1.1.0 (October 24, 2011) +-------------------------------- + +- linkify() now understands port numbers. (#38) +- Documented character encoding behavior. (#41) +- Add an optional target argument to linkify(). +- Add delinkify() method. (#45) +- Support subdomain whitelist for delinkify(). (#47, #48) + + +Version 1.0.4 (September 2, 2011) +--------------------------------- + +- Switch to SemVer git tags. +- Make linkify() smarter about trailing punctuation. (#30) +- Pass exc_info to logger during rendering issues. +- Add wildcard key for attributes. (#19) +- Make linkify() use the HTMLSanitizer tokenizer. (#36) +- Fix URLs wrapped in parentheses. (#23) +- Make linkify() UTF-8 safe. (#33) + + +Version 1.0.3 (June 14, 2011) +----------------------------- + +- linkify() works with 3rd level domains. (#24) +- clean() supports vendor prefixes in style values. (#31, #32) +- Fix linkify() email escaping. + + +Version 1.0.2 (June 6, 2011) +---------------------------- + +- linkify() supports email addresses. +- clean() supports callables in attributes filter. + + +Version 1.0.1 (April 12, 2011) +------------------------------ + +- linkify() doesn't drop trailing slashes. (#21) +- linkify() won't linkify 'libgl.so.1'. (#22) + + diff --git a/venv/lib/python3.5/site-packages/bleach/_vendor/html5lib-1.0.1.dist-info/INSTALLER b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/INSTALLER similarity index 100% rename from venv/lib/python3.5/site-packages/bleach/_vendor/html5lib-1.0.1.dist-info/INSTALLER rename to venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/INSTALLER diff --git a/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/METADATA b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/METADATA new file mode 100644 index 00000000..5175341a --- /dev/null +++ b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/METADATA @@ -0,0 +1,308 @@ +Metadata-Version: 2.0 +Name: bleach +Version: 1.5.0 +Summary: An easy whitelist-based HTML-sanitizing tool. +Home-page: http://github.com/mozilla/bleach +Author: Will Kahn-Greene +Author-email: UNKNOWN +License: Apache Software License +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Dist: six +Requires-Dist: html5lib (>=0.999,!=0.9999,!=0.99999,<0.99999999) + +====== +Bleach +====== + +.. image:: https://travis-ci.org/mozilla/bleach.png?branch=master + :target: https://travis-ci.org/mozilla/bleach + +.. image:: https://badge.fury.io/py/Bleach.svg + :target: http://badge.fury.io/py/Bleach + +Bleach is a whitelist-based HTML sanitizing library that escapes or strips +markup and attributes. + +Bleach can also linkify text safely, applying filters that Django's ``urlize`` +filter cannot, and optionally setting ``rel`` attributes, even on links already +in the text. + +Bleach is intended for sanitizing text from *untrusted* sources. If you find +yourself jumping through hoops to allow your site administrators to do lots of +things, you're probably outside the use cases. Either trust those users, or +don't. + +Because it relies on html5lib_, Bleach is as good as modern browsers at dealing +with weird, quirky HTML fragments. And *any* of Bleach's methods will fix +unbalanced or mis-nested tags. + +The version on GitHub_ is the most up-to-date and contains the latest bug +fixes. You can find full documentation on `ReadTheDocs`_. + +:Code: https://github.com/mozilla/bleach +:Documentation: https://bleach.readthedocs.io/ +:Issue tracker: https://github.com/mozilla/bleach/issues +:IRC: ``#bleach`` on irc.mozilla.org +:License: Apache License v2; see LICENSE file + + +Reporting Bugs +============== + +For regular bugs, please report them `in our issue tracker +`_. + +If you believe that you've found a security vulnerability, please `file a secure +bug report in our bug tracker +`_ +or send an email to *security AT mozilla DOT org*. + +For more information on security-related bug disclosure and the PGP key to use +for sending encrypted mail or to verify responses received from that address, +please read our wiki page at +``_. + + +Installing Bleach +================= + +Bleach is available on PyPI_, so you can install it with ``pip``:: + + $ pip install bleach + +Or with ``easy_install``:: + + $ easy_install bleach + +Or by cloning the repo from GitHub_:: + + $ git clone git://github.com/mozilla/bleach.git + +Then install it by running:: + + $ python setup.py install + + +Upgrading Bleach +================ + +.. warning:: + + Before doing any upgrades, read through `Bleach Changes + `_ for backwards + incompatible changes, newer versions, etc. + + +Basic use +========= + +The simplest way to use Bleach is: + +.. code-block:: python + + >>> import bleach + + >>> bleach.clean('an example') + u'an <script>evil()</script> example' + + >>> bleach.linkify('an http://example.com url') + u'an http://example.com url + + +.. _html5lib: https://github.com/html5lib/html5lib-python +.. _GitHub: https://github.com/mozilla/bleach +.. _ReadTheDocs: https://bleach.readthedocs.io/ +.. _PyPI: http://pypi.python.org/pypi/bleach + + +Bleach Changes +============== + +Version 1.5 (November 4th, 2016) +-------------------------------- + +**Backwards incompatible changes** + +- clean: The list of ``ALLOWED_PROTOCOLS`` now defaults to http, https and + mailto. Previously it was a long list of protocols something like ed2k, ftp, + http, https, irc, mailto, news, gopher, nntp, telnet, webcal, xmpp, callto, + feed, urn, aim, rsync, tag, ssh, sftp, rtsp, afs, data. #149 + +**Changes** + +- clean: Added ``protocols`` to arguments list to let you override the list of + allowed protocols. Thank you, Andreas Malecki! #149 +- linkify: Fix a bug involving periods at the end of an email address. Thank you, + Lorenz Schori! #219 +- linkify: Fix linkification of non-ascii ports. Thank you Alexandre, Macabies! + #207 +- linkify: Fix linkify inappropriately removing node tails when dropping nodes. + #132 +- Fixed a test that failed periodically. #161 +- Switched from nose to py.test. #204 +- Add test matrix for all supported Python and html5lib versions. #230 +- Limit to html5lib ``>=0.999,!=0.9999,!=0.99999,<0.99999999`` because 0.9999 + and 0.99999 are busted. +- Add support for ``python setup.py test``. #97 + + +Version 1.4.3 (May 23rd, 2016) +------------------------------ + +**Changes** + +- Limit to html5lib ``>=0.999,<0.99999999`` because of impending change to + sanitizer api. #195 + + +Version 1.4.2 (September 11, 2015) +---------------------------------- + +**Changes** + +- linkify: Fix hang in linkify with ``parse_email=True``. #124 +- linkify: Fix crash in linkify when removing a link that is a first-child. #136 +- Updated TLDs. +- linkify: Don't remove exterior brackets when linkifying. #146 + + +Version 1.4.1 (December 15, 2014) +--------------------------------- + +**Changes** + +- Consistent order of attributes in output. +- Python 3.4 support. + + +Version 1.4 (January 12, 2014) +------------------------------ + +**Changes** + +- linkify: Update linkify to use etree type Treewalker instead of simpletree. +- Updated html5lib to version ``>=0.999``. +- Update all code to be compatible with Python 3 and 2 using six. +- Switch to Apache License. + + +Version 1.3 +----------- + +- Used by Python 3-only fork. + + +Version 1.2.2 (May 18, 2013) +---------------------------- + +- Pin html5lib to version 0.95 for now due to major API break. + +Version 1.2.1 (February 19, 2013) +--------------------------------- + +- clean() no longer considers ``feed:`` an acceptable protocol due to + inconsistencies in browser behavior. + + +Version 1.2 (January 28, 2013) +------------------------------ + +- linkify() has changed considerably. Many keyword arguments have been + replaced with a single callbacks list. Please see the documentation + for more information. +- Bleach will no longer consider unacceptable protocols when linkifying. +- linkify() now takes a tokenizer argument that allows it to skip + sanitization. +- delinkify() is gone. +- Removed exception handling from _render. clean() and linkify() may now + throw. +- linkify() correctly ignores case for protocols and domain names. +- linkify() correctly handles markup within an tag. + + +Version 1.1.5 +------------- + + +Version 1.1.4 +------------- + + +Version 1.1.3 (July 10, 2012) +----------------------------- + +- Fix parsing bare URLs when parse_email=True. + + +Version 1.1.2 (June 1, 2012) +---------------------------- + +- Fix hang in style attribute sanitizer. (#61) +- Allow '/' in style attribute values. + + +Version 1.1.1 (February 17, 2012) +--------------------------------- + +- Fix tokenizer for html5lib 0.9.5. + + +Version 1.1.0 (October 24, 2011) +-------------------------------- + +- linkify() now understands port numbers. (#38) +- Documented character encoding behavior. (#41) +- Add an optional target argument to linkify(). +- Add delinkify() method. (#45) +- Support subdomain whitelist for delinkify(). (#47, #48) + + +Version 1.0.4 (September 2, 2011) +--------------------------------- + +- Switch to SemVer git tags. +- Make linkify() smarter about trailing punctuation. (#30) +- Pass exc_info to logger during rendering issues. +- Add wildcard key for attributes. (#19) +- Make linkify() use the HTMLSanitizer tokenizer. (#36) +- Fix URLs wrapped in parentheses. (#23) +- Make linkify() UTF-8 safe. (#33) + + +Version 1.0.3 (June 14, 2011) +----------------------------- + +- linkify() works with 3rd level domains. (#24) +- clean() supports vendor prefixes in style values. (#31, #32) +- Fix linkify() email escaping. + + +Version 1.0.2 (June 6, 2011) +---------------------------- + +- linkify() supports email addresses. +- clean() supports callables in attributes filter. + + +Version 1.0.1 (April 12, 2011) +------------------------------ + +- linkify() doesn't drop trailing slashes. (#21) +- linkify() won't linkify 'libgl.so.1'. (#22) + + diff --git a/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/RECORD b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/RECORD new file mode 100644 index 00000000..b0ac2c1b --- /dev/null +++ b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/RECORD @@ -0,0 +1,17 @@ +bleach-1.5.0.dist-info/DESCRIPTION.rst,sha256=jJ9jn1_mkWMbFlaBtIf7dPMwzoGmA4H-fRB8b3ER0Dg,7828 +bleach-1.5.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +bleach-1.5.0.dist-info/METADATA,sha256=JSll0wzttNFf3wvAnzfwcuYH9UPcfpjL-N55RVyKJQw,8925 +bleach-1.5.0.dist-info/RECORD,, +bleach-1.5.0.dist-info/WHEEL,sha256=AvR0WeTpDaxT645bl5FQxUK6NPsTls2ttpcGJg3j1Xg,110 +bleach-1.5.0.dist-info/metadata.json,sha256=bT8WVZh6PG2fcHLhV6woBY84EPwqSFnwwKegq3jXUW0,1224 +bleach-1.5.0.dist-info/top_level.txt,sha256=dcv0wKIySB0zMjAEXLwY4V0-3IN9UZQGAT1wDmfQICY,7 +bleach/__init__.py,sha256=GS2ORCpzVrM6y_mkmnbaZZZ9D2gf9siX-Z4zDUofW4U,15427 +bleach/__pycache__/__init__.cpython-35.pyc,, +bleach/__pycache__/callbacks.cpython-35.pyc,, +bleach/__pycache__/encoding.cpython-35.pyc,, +bleach/__pycache__/sanitizer.cpython-35.pyc,, +bleach/__pycache__/version.cpython-35.pyc,, +bleach/callbacks.py,sha256=UTrc4JiioTwGxAKnZjpcFUPLxOcUSZt1KnmDqvdeYM4,534 +bleach/encoding.py,sha256=aq062I1yXRPPjZjYzY4FoMYkCjBA-0QCU-xBhgq4JMQ,2277 +bleach/sanitizer.py,sha256=t5IcbT36QOqZjG_h8bO2SOIn_OF_mUzYyRmRzDzyM-k,6483 +bleach/version.py,sha256=oskxHPFV-2W-vHpduEGWyRW8wyOa70mj_3qtLxPyRBM,136 diff --git a/venv/lib/python3.5/site-packages/bleach/_vendor/html5lib-1.0.1.dist-info/WHEEL b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/WHEEL similarity index 69% rename from venv/lib/python3.5/site-packages/bleach/_vendor/html5lib-1.0.1.dist-info/WHEEL rename to venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/WHEEL index 7bf9daa1..9dff69d8 100644 --- a/venv/lib/python3.5/site-packages/bleach/_vendor/html5lib-1.0.1.dist-info/WHEEL +++ b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/WHEEL @@ -1,5 +1,5 @@ Wheel-Version: 1.0 -Generator: bdist_wheel (0.30.0.a0) +Generator: bdist_wheel (0.24.0) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any diff --git a/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/metadata.json b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/metadata.json new file mode 100644 index 00000000..5125c302 --- /dev/null +++ b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/metadata.json @@ -0,0 +1 @@ +{"license": "Apache Software License", "name": "bleach", "metadata_version": "2.0", "generator": "bdist_wheel (0.24.0)", "test_requires": [{"requires": ["pytest (==3.0.3)"]}], "summary": "An easy whitelist-based HTML-sanitizing tool.", "run_requires": [{"requires": ["six", "html5lib (>=0.999,!=0.9999,!=0.99999,<0.99999999)"]}], "version": "1.5.0", "extensions": {"python.details": {"project_urls": {"Home": "http://github.com/mozilla/bleach"}, "document_names": {"description": "DESCRIPTION.rst"}, "contacts": [{"role": "author", "name": "Will Kahn-Greene"}]}}, "classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Software Development :: Libraries :: Python Modules"], "extras": []} \ No newline at end of file diff --git a/venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/top_level.txt b/venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/top_level.txt similarity index 100% rename from venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/top_level.txt rename to venv/lib/python3.5/site-packages/bleach-1.5.0.dist-info/top_level.txt diff --git a/venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/METADATA b/venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/METADATA deleted file mode 100644 index 30681103..00000000 --- a/venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/METADATA +++ /dev/null @@ -1,713 +0,0 @@ -Metadata-Version: 2.1 -Name: bleach -Version: 3.0.2 -Summary: An easy safelist-based HTML-sanitizing tool. -Home-page: https://github.com/mozilla/bleach -Maintainer: Will Kahn-Greene -Maintainer-email: willkg@mozilla.com -License: Apache Software License -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* -Requires-Dist: six -Requires-Dist: webencodings - -====== -Bleach -====== - -.. image:: https://travis-ci.org/mozilla/bleach.svg?branch=master - :target: https://travis-ci.org/mozilla/bleach - -.. image:: https://badge.fury.io/py/bleach.svg - :target: http://badge.fury.io/py/bleach - -Bleach is an allowed-list-based HTML sanitizing library that escapes or strips -markup and attributes. - -Bleach can also linkify text safely, applying filters that Django's ``urlize`` -filter cannot, and optionally setting ``rel`` attributes, even on links already -in the text. - -Bleach is intended for sanitizing text from *untrusted* sources. If you find -yourself jumping through hoops to allow your site administrators to do lots of -things, you're probably outside the use cases. Either trust those users, or -don't. - -Because it relies on html5lib_, Bleach is as good as modern browsers at dealing -with weird, quirky HTML fragments. And *any* of Bleach's methods will fix -unbalanced or mis-nested tags. - -The version on GitHub_ is the most up-to-date and contains the latest bug -fixes. You can find full documentation on `ReadTheDocs`_. - -:Code: https://github.com/mozilla/bleach -:Documentation: https://bleach.readthedocs.io/ -:Issue tracker: https://github.com/mozilla/bleach/issues -:IRC: ``#bleach`` on irc.mozilla.org -:License: Apache License v2; see LICENSE file - - -Reporting Bugs -============== - -For regular bugs, please report them `in our issue tracker -`_. - -If you believe that you've found a security vulnerability, please `file a secure -bug report in our bug tracker -`_ -or send an email to *security AT mozilla DOT org*. - -For more information on security-related bug disclosure and the PGP key to use -for sending encrypted mail or to verify responses received from that address, -please read our wiki page at -``_. - - -Security -======== - -Bleach is a security-focused library. - -We have a responsible security vulnerability reporting process. Please use -that if you're reporting a security issue. - -Security issues are fixed in private. After we land such a fix, we'll do a -release. - -For every release, we mark security issues we've fixed in the ``CHANGES`` in -the **Security issues** section. We include any relevant CVE links. - - -Installing Bleach -================= - -Bleach is available on PyPI_, so you can install it with ``pip``:: - - $ pip install bleach - - -Upgrading Bleach -================ - -.. warning:: - - Before doing any upgrades, read through `Bleach Changes - `_ for backwards - incompatible changes, newer versions, etc. - - -Basic use -========= - -The simplest way to use Bleach is: - -.. code-block:: python - - >>> import bleach - - >>> bleach.clean('an example') - u'an <script>evil()</script> example' - - >>> bleach.linkify('an http://example.com url') - u'an http://example.com url - - -Code of conduct -=============== - -This project and repository is governed by Mozilla's code of conduct and -etiquette guidelines. For more details please see the `Mozilla Community -Participation Guidelines -`_ and -`Developer Etiquette Guidelines -`_. - - -.. _html5lib: https://github.com/html5lib/html5lib-python -.. _GitHub: https://github.com/mozilla/bleach -.. _ReadTheDocs: https://bleach.readthedocs.io/ -.. _PyPI: http://pypi.python.org/pypi/bleach - - -Bleach changes -============== - -Version 3.0.2 (October 11th, 2018) ----------------------------------- - -**Security fixes** - -None - -**Backwards incompatible changes** - -None - -**Features** - -None - -**Bug fixes** - -* Merge ``Characters`` tokens after sanitizing them. This fixes issues in the - ``LinkifyFilter`` where it was only linkifying parts of urls. (#374) - - -Version 3.0.1 (October 9th, 2018) ---------------------------------- - -**Security fixes** - -None - -**Backwards incompatible changes** - -None - -**Features** - -* Support Python 3.7. It supported Python 3.7 just fine, but we added 3.7 to - the list of Python environments we test so this is now officially supported. - (#377) - -**Bug fixes** - -* Fix ``list`` object has no attribute ``lower`` in ``clean``. (#398) -* Fix ``abbr`` getting escaped in ``linkify``. (#400) - - -Version 3.0.0 (October 3rd, 2018) ---------------------------------- - -**Security fixes** - -None - -**Backwards incompatible changes** - -* A bunch of functions were moved from one module to another. - - These were moved from ``bleach.sanitizer`` to ``bleach.html5lib_shim``: - - * ``convert_entity`` - * ``convert_entities`` - * ``match_entity`` - * ``next_possible_entity`` - * ``BleachHTMLSerializer`` - * ``BleachHTMLTokenizer`` - * ``BleachHTMLParser`` - - These functions and classes weren't documented and aren't part of the - public API, but people read code and might be using them so we're - considering it an incompatible API change. - - If you're using them, you'll need to update your code. - -**Features** - -* Bleach no longer depends on html5lib. html5lib==1.0.1 is now vendored into - Bleach. You can remove it from your requirements file if none of your other - requirements require html5lib. - - This means Bleach will now work fine with other libraries that depend on - html5lib regardless of what version of html5lib they require. (#386) - -**Bug fixes** - -* Fixed tags getting added when using clean or linkify. This was a - long-standing regression from the Bleach 2.0 rewrite. (#280, #392) - -* Fixed ```` getting replaced with a string. Now it gets escaped or - stripped depending on whether it's in the allowed tags or not. (#279) - - -Version 2.1.4 (August 16th, 2018) ---------------------------------- - -**Security fixes** - -None - -**Backwards incompatible changes** - -* Dropped support for Python 3.3. (#328) - -**Features** - -None - -**Bug fixes** - -* Handle ambiguous ampersands in correctly. (#359) - - -Version 2.1.3 (March 5th, 2018) -------------------------------- - -**Security fixes** - -* Attributes that have URI values weren't properly sanitized if the - values contained character entities. Using character entities, it - was possible to construct a URI value with a scheme that was not - allowed that would slide through unsanitized. - - This security issue was introduced in Bleach 2.1. Anyone using - Bleach 2.1 is highly encouraged to upgrade. - - https://bugzilla.mozilla.org/show_bug.cgi?id=1442745 - -**Backwards incompatible changes** - -None - -**Features** - -None - -**Bug fixes** - -* Fixed some other edge cases for attribute URI value sanitizing and - improved testing of this code. - - -Version 2.1.2 (December 7th, 2017) ----------------------------------- - -**Security fixes** - -None - -**Backwards incompatible changes** - -None - -**Features** - -None - -**Bug fixes** - -* Support html5lib-python 1.0.1. (#337) - -* Add deprecation warning for supporting html5lib-python < 1.0. - -* Switch to semver. - - -Version 2.1.1 (October 2nd, 2017) ---------------------------------- - -**Security fixes** - -None - -**Backwards incompatible changes** - -None - -**Features** - -None - -**Bug fixes** - -* Fix ``setup.py`` opening files when ``LANG=``. (#324) - - -Version 2.1 (September 28th, 2017) ----------------------------------- - -**Security fixes** - -* Convert control characters (backspace particularly) to "?" preventing - malicious copy-and-paste situations. (#298) - - See ``_ for more details. - - This affects all previous versions of Bleach. Check the comments on that - issue for ways to alleviate the issue if you can't upgrade to Bleach 2.1. - - -**Backwards incompatible changes** - -* Redid versioning. ``bleach.VERSION`` is no longer available. Use the string - version at ``bleach.__version__`` and parse it with - ``pkg_resources.parse_version``. (#307) - -* clean, linkify: linkify and clean should only accept text types; thank you, - Janusz! (#292) - -* clean, linkify: accept only unicode or utf-8-encoded str (#176) - - -**Features** - - -**Bug fixes** - -* ``bleach.clean()`` no longer unescapes entities including ones that are missing - a ``;`` at the end which can happen in urls and other places. (#143) - -* linkify: fix http links inside of mailto links; thank you, sedrubal! (#300) - -* clarify security policy in docs (#303) - -* fix dependency specification for html5lib 1.0b8, 1.0b9, and 1.0b10; thank you, - Zoltán! (#268) - -* add Bleach vs. html5lib comparison to README; thank you, Stu Cox! (#278) - -* fix KeyError exceptions on tags without href attr; thank you, Alex Defsen! - (#273) - -* add test website and scripts to test ``bleach.clean()`` output in browser; - thank you, Greg Guthe! - - -Version 2.0 (March 8th, 2017) ------------------------------ - -**Security fixes** - -* None - - -**Backwards incompatible changes** - -* Removed support for Python 2.6. #206 - -* Removed support for Python 3.2. #224 - -* Bleach no longer supports html5lib < 0.99999999 (8 9s). - - This version is a rewrite to use the new sanitizing API since the old - one was dropped in html5lib 0.99999999 (8 9s). - - If you're using 0.9999999 (7 9s) upgrade to 0.99999999 (8 9s) or higher. - - If you're using 1.0b8 (equivalent to 0.9999999 (7 9s)), upgrade to 1.0b9 - (equivalent to 0.99999999 (8 9s)) or higher. - -* ``bleach.clean`` and friends were rewritten - - ``clean`` was reimplemented as an html5lib filter and happens at a different - step in the HTML parsing -> traversing -> serializing process. Because of - that, there are some differences in clean's output as compared with previous - versions. - - Amongst other things, this version will add end tags even if the tag in - question is to be escaped. - -* ``bleach.clean`` and friends attribute callables now take three arguments: - tag, attribute name and attribute value. Previously they only took attribute - name and attribute value. - - All attribute callables will need to be updated. - -* ``bleach.linkify`` was rewritten - - ``linkify`` was reimplemented as an html5lib Filter. As such, it no longer - accepts a ``tokenizer`` argument. - - The callback functions for adjusting link attributes now takes a namespaced - attribute. - - Previously you'd do something like this:: - - def check_protocol(attrs, is_new): - if not attrs.get('href', '').startswith('http:', 'https:')): - return None - return attrs - - Now it's more like this:: - - def check_protocol(attrs, is_new): - if not attrs.get((None, u'href'), u'').startswith(('http:', 'https:')): - # ^^^^^^^^^^^^^^^ - return None - return attrs - - Further, you need to make sure you're always using unicode values. If you - don't then html5lib will raise an assertion error that the value is not - unicode. - - All linkify filters will need to be updated. - -* ``bleach.linkify`` and friends had a ``skip_pre`` argument--that's been - replaced with a more general ``skip_tags`` argument. - - Before, you might do:: - - bleach.linkify(some_text, skip_pre=True) - - The equivalent with Bleach 2.0 is:: - - bleach.linkify(some_text, skip_tags=['pre']) - - You can skip other tags, too, like ``style`` or ``script`` or other places - where you don't want linkification happening. - - All uses of linkify that use ``skip_pre`` will need to be updated. - - -**Changes** - -* Supports Python 3.6. - -* Supports html5lib >= 0.99999999 (8 9s). - -* There's a ``bleach.sanitizer.Cleaner`` class that you can instantiate with your - favorite clean settings for easy reuse. - -* There's a ``bleach.linkifier.Linker`` class that you can instantiate with your - favorite linkify settings for easy reuse. - -* There's a ``bleach.linkifier.LinkifyFilter`` which is an htm5lib filter that - you can pass as a filter to ``bleach.sanitizer.Cleaner`` allowing you to clean - and linkify in one pass. - -* ``bleach.clean`` and friends can now take a callable as an attributes arg value. - -* Tons of bug fixes. - -* Cleaned up tests. - -* Documentation fixes. - - -Version 1.5 (November 4th, 2016) --------------------------------- - -**Security fixes** - -* None - -**Backwards incompatible changes** - -* clean: The list of ``ALLOWED_PROTOCOLS`` now defaults to http, https and - mailto. - - Previously it was a long list of protocols something like ed2k, ftp, http, - https, irc, mailto, news, gopher, nntp, telnet, webcal, xmpp, callto, feed, - urn, aim, rsync, tag, ssh, sftp, rtsp, afs, data. #149 - -**Changes** - -* clean: Added ``protocols`` to arguments list to let you override the list of - allowed protocols. Thank you, Andreas Malecki! #149 - -* linkify: Fix a bug involving periods at the end of an email address. Thank you, - Lorenz Schori! #219 - -* linkify: Fix linkification of non-ascii ports. Thank you Alexandre, Macabies! - #207 - -* linkify: Fix linkify inappropriately removing node tails when dropping nodes. - #132 - -* Fixed a test that failed periodically. #161 - -* Switched from nose to py.test. #204 - -* Add test matrix for all supported Python and html5lib versions. #230 - -* Limit to html5lib ``>=0.999,!=0.9999,!=0.99999,<0.99999999`` because 0.9999 - and 0.99999 are busted. - -* Add support for ``python setup.py test``. #97 - - -Version 1.4.3 (May 23rd, 2016) ------------------------------- - -**Security fixes** - -* None - -**Changes** - -* Limit to html5lib ``>=0.999,<0.99999999`` because of impending change to - sanitizer api. #195 - - -Version 1.4.2 (September 11, 2015) ----------------------------------- - -**Changes** - -* linkify: Fix hang in linkify with ``parse_email=True``. #124 - -* linkify: Fix crash in linkify when removing a link that is a first-child. #136 - -* Updated TLDs. - -* linkify: Don't remove exterior brackets when linkifying. #146 - - -Version 1.4.1 (December 15, 2014) ---------------------------------- - -**Changes** - -* Consistent order of attributes in output. - -* Python 3.4 support. - - -Version 1.4 (January 12, 2014) ------------------------------- - -**Changes** - -* linkify: Update linkify to use etree type Treewalker instead of simpletree. - -* Updated html5lib to version ``>=0.999``. - -* Update all code to be compatible with Python 3 and 2 using six. - -* Switch to Apache License. - - -Version 1.3 ------------ - -* Used by Python 3-only fork. - - -Version 1.2.2 (May 18, 2013) ----------------------------- - -* Pin html5lib to version 0.95 for now due to major API break. - - -Version 1.2.1 (February 19, 2013) ---------------------------------- - -* ``clean()`` no longer considers ``feed:`` an acceptable protocol due to - inconsistencies in browser behavior. - - -Version 1.2 (January 28, 2013) ------------------------------- - -* ``linkify()`` has changed considerably. Many keyword arguments have been - replaced with a single callbacks list. Please see the documentation for more - information. - -* Bleach will no longer consider unacceptable protocols when linkifying. - -* ``linkify()`` now takes a tokenizer argument that allows it to skip - sanitization. - -* ``delinkify()`` is gone. - -* Removed exception handling from ``_render``. ``clean()`` and ``linkify()`` may - now throw. - -* ``linkify()`` correctly ignores case for protocols and domain names. - -* ``linkify()`` correctly handles markup within an tag. - - -Version 1.1.5 -------------- - - -Version 1.1.4 -------------- - - -Version 1.1.3 (July 10, 2012) ------------------------------ - -* Fix parsing bare URLs when parse_email=True. - - -Version 1.1.2 (June 1, 2012) ----------------------------- - -* Fix hang in style attribute sanitizer. (#61) - -* Allow ``/`` in style attribute values. - - -Version 1.1.1 (February 17, 2012) ---------------------------------- - -* Fix tokenizer for html5lib 0.9.5. - - -Version 1.1.0 (October 24, 2011) --------------------------------- - -* ``linkify()`` now understands port numbers. (#38) - -* Documented character encoding behavior. (#41) - -* Add an optional target argument to ``linkify()``. - -* Add ``delinkify()`` method. (#45) - -* Support subdomain whitelist for ``delinkify()``. (#47, #48) - - -Version 1.0.4 (September 2, 2011) ---------------------------------- - -* Switch to SemVer git tags. - -* Make ``linkify()`` smarter about trailing punctuation. (#30) - -* Pass ``exc_info`` to logger during rendering issues. - -* Add wildcard key for attributes. (#19) - -* Make ``linkify()`` use the ``HTMLSanitizer`` tokenizer. (#36) - -* Fix URLs wrapped in parentheses. (#23) - -* Make ``linkify()`` UTF-8 safe. (#33) - - -Version 1.0.3 (June 14, 2011) ------------------------------ - -* ``linkify()`` works with 3rd level domains. (#24) - -* ``clean()`` supports vendor prefixes in style values. (#31, #32) - -* Fix ``linkify()`` email escaping. - - -Version 1.0.2 (June 6, 2011) ----------------------------- - -* ``linkify()`` supports email addresses. - -* ``clean()`` supports callables in attributes filter. - - -Version 1.0.1 (April 12, 2011) ------------------------------- - -* ``linkify()`` doesn't drop trailing slashes. (#21) -* ``linkify()`` won't linkify 'libgl.so.1'. (#22) - - diff --git a/venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/RECORD b/venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/RECORD deleted file mode 100644 index e9b569f2..00000000 --- a/venv/lib/python3.5/site-packages/bleach-3.0.2.dist-info/RECORD +++ /dev/null @@ -1,98 +0,0 @@ -bleach-3.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -bleach-3.0.2.dist-info/METADATA,sha256=GcznRjuWkR0OzcUFsJTSl2B0BgA11h_pj7bSOkZV5no,18213 -bleach-3.0.2.dist-info/RECORD,, -bleach-3.0.2.dist-info/WHEEL,sha256=gduuPyBvFJQSQ0zdyxF7k0zynDXbIbvg5ZBHoXum5uk,110 -bleach-3.0.2.dist-info/top_level.txt,sha256=dcv0wKIySB0zMjAEXLwY4V0-3IN9UZQGAT1wDmfQICY,7 -bleach/__init__.py,sha256=v3RcHvH3ELASWs50ehoEAQI0cHa84AmZakCQZ4fhTNM,3775 -bleach/__pycache__/__init__.cpython-35.pyc,, -bleach/__pycache__/callbacks.cpython-35.pyc,, -bleach/__pycache__/html5lib_shim.cpython-35.pyc,, -bleach/__pycache__/linkifier.cpython-35.pyc,, -bleach/__pycache__/sanitizer.cpython-35.pyc,, -bleach/__pycache__/utils.cpython-35.pyc,, -bleach/_vendor/README.rst,sha256=bQJ4-KbxFcntTIrbmbmJSkTwNoLv2HqkWK_OE8WArHs,1257 -bleach/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -bleach/_vendor/__pycache__/__init__.cpython-35.pyc,, -bleach/_vendor/html5lib-1.0.1.dist-info/DESCRIPTION.rst,sha256=1QkiA38mSikkzyQO1kAQXkBUtQSTl-MR63Zd2TMe06s,13763 -bleach/_vendor/html5lib-1.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -bleach/_vendor/html5lib-1.0.1.dist-info/LICENSE.txt,sha256=FqOZkWGekvGGgJMtoqkZn999ld8-yu3FLqBiGKq6_W8,1084 -bleach/_vendor/html5lib-1.0.1.dist-info/METADATA,sha256=ViKKPHTrTam-_oHIB2cxmtg4gKgqdfl4ahDnIWBdyUE,15484 -bleach/_vendor/html5lib-1.0.1.dist-info/RECORD,sha256=YAZeNEUF4uty-pGA7qGcPOGH-OAYnHPQYwzw701RsDk,3600 -bleach/_vendor/html5lib-1.0.1.dist-info/WHEEL,sha256=5wvfB7GvgZAbKBSE9uX9Zbi6LCL-_KgezgHblXhCRnM,113 -bleach/_vendor/html5lib-1.0.1.dist-info/metadata.json,sha256=bbLAvG6pYvgK2EdWNVi1mNa5pu9bI4qLwGm0IvuesFA,1731 -bleach/_vendor/html5lib-1.0.1.dist-info/top_level.txt,sha256=XEX6CHpskSmvjJB4tP6m4Q5NYXhIf_0ceMc0PNbzJPQ,9 -bleach/_vendor/html5lib/__init__.py,sha256=q1D20NqqzRVgmTHW2xiVtaQT2eKna-iit3tL62Yn5OI,1145 -bleach/_vendor/html5lib/__pycache__/__init__.cpython-35.pyc,, -bleach/_vendor/html5lib/__pycache__/_ihatexml.cpython-35.pyc,, -bleach/_vendor/html5lib/__pycache__/_inputstream.cpython-35.pyc,, -bleach/_vendor/html5lib/__pycache__/_tokenizer.cpython-35.pyc,, -bleach/_vendor/html5lib/__pycache__/_utils.cpython-35.pyc,, -bleach/_vendor/html5lib/__pycache__/constants.cpython-35.pyc,, -bleach/_vendor/html5lib/__pycache__/html5parser.cpython-35.pyc,, -bleach/_vendor/html5lib/__pycache__/serializer.cpython-35.pyc,, -bleach/_vendor/html5lib/_ihatexml.py,sha256=3LBtJMlzgwM8vpQiU1TvGmEEmNH72sV0yD8yS53y07A,16705 -bleach/_vendor/html5lib/_inputstream.py,sha256=WtC-hb3nS7Du6XvdL9JACOQgD5ydPKb7f9z0q4OIvRM,32499 -bleach/_vendor/html5lib/_tokenizer.py,sha256=JFZ4kiYfas1f62q2bdXH8Ch5DtXAWEZg0KYkRF4boRQ,76568 -bleach/_vendor/html5lib/_trie/__init__.py,sha256=8VR1bcgD2OpeS2XExpu5yBhP_Q1K-lwKbBKICBPf1kU,289 -bleach/_vendor/html5lib/_trie/__pycache__/__init__.cpython-35.pyc,, -bleach/_vendor/html5lib/_trie/__pycache__/_base.cpython-35.pyc,, -bleach/_vendor/html5lib/_trie/__pycache__/datrie.cpython-35.pyc,, -bleach/_vendor/html5lib/_trie/__pycache__/py.cpython-35.pyc,, -bleach/_vendor/html5lib/_trie/_base.py,sha256=uJHVhzif9S0MJXgy9F98iEev5evi_rgUk5BmEbUSp8c,930 -bleach/_vendor/html5lib/_trie/datrie.py,sha256=rGMj61020CBiR97e4kyMyqn_FSIJzgDcYT2uj7PZkoo,1166 -bleach/_vendor/html5lib/_trie/py.py,sha256=zg7RZSHxJ8mLmuI_7VEIV8AomISrgkvqCP477AgXaG0,1763 -bleach/_vendor/html5lib/_utils.py,sha256=UHC4fXEZRJ0YM44Z4DeLem66auCjb08vSPcN6Y714Iw,4003 -bleach/_vendor/html5lib/constants.py,sha256=4lmZWLtEPRLnl8NzftOoYTJdo6jpeMtP6dqQC0g_bWQ,83518 -bleach/_vendor/html5lib/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -bleach/_vendor/html5lib/filters/__pycache__/__init__.cpython-35.pyc,, -bleach/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-35.pyc,, -bleach/_vendor/html5lib/filters/__pycache__/base.cpython-35.pyc,, -bleach/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-35.pyc,, -bleach/_vendor/html5lib/filters/__pycache__/lint.cpython-35.pyc,, -bleach/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-35.pyc,, -bleach/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-35.pyc,, -bleach/_vendor/html5lib/filters/__pycache__/whitespace.cpython-35.pyc,, -bleach/_vendor/html5lib/filters/alphabeticalattributes.py,sha256=lViZc2JMCclXi_5gduvmdzrRxtO5Xo9ONnbHBVCsykU,919 -bleach/_vendor/html5lib/filters/base.py,sha256=z-IU9ZAYjpsVsqmVt7kuWC63jR11hDMr6CVrvuao8W0,286 -bleach/_vendor/html5lib/filters/inject_meta_charset.py,sha256=egDXUEHXmAG9504xz0K6ALDgYkvUrC2q15YUVeNlVQg,2945 -bleach/_vendor/html5lib/filters/lint.py,sha256=upXATs6By7cot7o0bnNqR15sPq2Fn6Vnjvoy3gyO_rY,3631 -bleach/_vendor/html5lib/filters/optionaltags.py,sha256=8lWT75J0aBOHmPgfmqTHSfPpPMp01T84NKu0CRedxcE,10588 -bleach/_vendor/html5lib/filters/sanitizer.py,sha256=V6_cpCq9EXgXkL1CblWEUxSgHy466Hy8k0453x8PSs8,26236 -bleach/_vendor/html5lib/filters/whitespace.py,sha256=8eWqZxd4UC4zlFGW6iyY6f-2uuT8pOCSALc3IZt7_t4,1214 -bleach/_vendor/html5lib/html5parser.py,sha256=eeMsctZUonbJZPegB_CElFye2lGufMcMsxQxsJtf7Mg,118951 -bleach/_vendor/html5lib/serializer.py,sha256=cmZQjjaXThEe2_6yzDqeb3yXS_hUggv0cCa2VBD9e2Y,15746 -bleach/_vendor/html5lib/treeadapters/__init__.py,sha256=18hyI-at2aBsdKzpwRwa5lGF1ipgctaTYXoU9En2ZQg,650 -bleach/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-35.pyc,, -bleach/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-35.pyc,, -bleach/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-35.pyc,, -bleach/_vendor/html5lib/treeadapters/genshi.py,sha256=CH27pAsDKmu4ZGkAUrwty7u0KauGLCZRLPMzaO3M5vo,1715 -bleach/_vendor/html5lib/treeadapters/sax.py,sha256=BKS8woQTnKiqeffHsxChUqL4q2ZR_wb5fc9MJ3zQC8s,1776 -bleach/_vendor/html5lib/treebuilders/__init__.py,sha256=AysSJyvPfikCMMsTVvaxwkgDieELD5dfR8FJIAuq7hY,3592 -bleach/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-35.pyc,, -bleach/_vendor/html5lib/treebuilders/__pycache__/base.cpython-35.pyc,, -bleach/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-35.pyc,, -bleach/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-35.pyc,, -bleach/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-35.pyc,, -bleach/_vendor/html5lib/treebuilders/base.py,sha256=JEFLxUEsluRl7vY-6cnAk44HxgCAkaj4GpEOBpg8tao,14567 -bleach/_vendor/html5lib/treebuilders/dom.py,sha256=SY3MsijXyzdNPc8aK5IQsupBoM8J67y56DgNtGvsb9g,8835 -bleach/_vendor/html5lib/treebuilders/etree.py,sha256=R0zaNrdtPel3XHV8PUVcQzVnMuiOm_8fpZof7tU7ips,12752 -bleach/_vendor/html5lib/treebuilders/etree_lxml.py,sha256=9V0dXxbJYYq-Skgb5-_OL2NkVYpjioEb4CHajo0e9yI,14122 -bleach/_vendor/html5lib/treewalkers/__init__.py,sha256=yhXxHpjlSqfQyUag3v8-vWjMPriFBU8YRAPNpDgBTn8,5714 -bleach/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-35.pyc,, -bleach/_vendor/html5lib/treewalkers/__pycache__/base.cpython-35.pyc,, -bleach/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-35.pyc,, -bleach/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-35.pyc,, -bleach/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-35.pyc,, -bleach/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-35.pyc,, -bleach/_vendor/html5lib/treewalkers/base.py,sha256=ouiOsuSzvI0KgzdWP8PlxIaSNs9falhbiinAEc_UIJY,7476 -bleach/_vendor/html5lib/treewalkers/dom.py,sha256=EHyFR8D8lYNnyDU9lx_IKigVJRyecUGua0mOi7HBukc,1413 -bleach/_vendor/html5lib/treewalkers/etree.py,sha256=gRzfuNnWg6r-fvtXRp4xPVTC1CHPowcn8Dc4-WcDoOg,4538 -bleach/_vendor/html5lib/treewalkers/etree_lxml.py,sha256=AR07dDrdkDqrQT4yNK_5WeGiZMHfOrM3ZmmII6YrSgs,6297 -bleach/_vendor/html5lib/treewalkers/genshi.py,sha256=4D2PECZ5n3ZN3qu3jMl9yY7B81jnQApBQSVlfaIuYbA,2309 -bleach/_vendor/pip_install_vendor.sh,sha256=ZrS4exm9McHoXsmpgOFHP9li6KVCN5aBeEq7G64CODY,90 -bleach/_vendor/vendor.txt,sha256=jvInrceXXdsUKKFJg9qSQTjsJOK_X3s10AVKA_hlplk,186 -bleach/callbacks.py,sha256=SRPRKUioBvShXqHUi1zE2Qdvm60wciab5i5lnu3cnng,804 -bleach/html5lib_shim.py,sha256=Bz5MaQBBdKRXidB9sP5x55pZ960ARIadXEjhBqieqq8,15516 -bleach/linkifier.py,sha256=SRM04i6N2d_BLuP4C8FaJoMJ02DHXPbwZYgV2yCVhMs,19432 -bleach/sanitizer.py,sha256=x-NO6iRi9KcdCNrtbCi2FFSxvkI0rx1UKvNSEVsbmeQ,20211 -bleach/utils.py,sha256=xehkBK0bogKXZ26LFFT6zeAJo0sZ4TZKQGZq7SBAFUI,1115 diff --git a/venv/lib/python3.5/site-packages/bleach/__init__.py b/venv/lib/python3.5/site-packages/bleach/__init__.py index 8ed01763..13b5e2e7 100644 --- a/venv/lib/python3.5/site-packages/bleach/__init__.py +++ b/venv/lib/python3.5/site-packages/bleach/__init__.py @@ -1,31 +1,105 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals - -from pkg_resources import parse_version - -from bleach.linkifier import ( - DEFAULT_CALLBACKS, - Linker, -) -from bleach.sanitizer import ( - ALLOWED_ATTRIBUTES, - ALLOWED_PROTOCOLS, - ALLOWED_STYLES, - ALLOWED_TAGS, - Cleaner, -) - - -# yyyymmdd -__releasedate__ = '20181011' -# x.y.z or x.y.z.dev0 -- semver -__version__ = '3.0.2' -VERSION = parse_version(__version__) - +import logging +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass +import re + +import html5lib +from html5lib.sanitizer import HTMLSanitizer +from html5lib.serializer.htmlserializer import HTMLSerializer + +from . import callbacks as linkify_callbacks +from .encoding import force_unicode +from .sanitizer import BleachSanitizer +from .version import __version__, VERSION # flake8: noqa __all__ = ['clean', 'linkify'] +log = logging.getLogger(__name__) +log.addHandler(NullHandler()) + +ALLOWED_TAGS = [ + 'a', + 'abbr', + 'acronym', + 'b', + 'blockquote', + 'code', + 'em', + 'i', + 'li', + 'ol', + 'strong', + 'ul', +] + +ALLOWED_ATTRIBUTES = { + 'a': ['href', 'title'], + 'abbr': ['title'], + 'acronym': ['title'], +} + +ALLOWED_STYLES = [] + +ALLOWED_PROTOCOLS = ['http', 'https', 'mailto'] + +TLDS = """ac ad ae aero af ag ai al am an ao aq ar arpa as asia at au aw ax az + ba bb bd be bf bg bh bi biz bj bm bn bo br bs bt bv bw by bz ca cat + cc cd cf cg ch ci ck cl cm cn co com coop cr cu cv cx cy cz de dj dk + dm do dz ec edu ee eg er es et eu fi fj fk fm fo fr ga gb gd ge gf gg + gh gi gl gm gn gov gp gq gr gs gt gu gw gy hk hm hn hr ht hu id ie il + im in info int io iq ir is it je jm jo jobs jp ke kg kh ki km kn kp + kr kw ky kz la lb lc li lk lr ls lt lu lv ly ma mc md me mg mh mil mk + ml mm mn mo mobi mp mq mr ms mt mu museum mv mw mx my mz na name nc ne + net nf ng ni nl no np nr nu nz om org pa pe pf pg ph pk pl pm pn post + pr pro ps pt pw py qa re ro rs ru rw sa sb sc sd se sg sh si sj sk sl + sm sn so sr ss st su sv sx sy sz tc td tel tf tg th tj tk tl tm tn to + tp tr travel tt tv tw tz ua ug uk us uy uz va vc ve vg vi vn vu wf ws + xn xxx ye yt yu za zm zw""".split() + +# Make sure that .com doesn't get matched by .co first +TLDS.reverse() + +PROTOCOLS = HTMLSanitizer.acceptable_protocols + +url_re = re.compile( + r"""\(* # Match any opening parentheses. + \b(?"]*)? + # /path/zz (excluding "unsafe" chars from RFC 1738, + # except for # and ~, which happen in practice) + """.format('|'.join(PROTOCOLS), '|'.join(TLDS)), + re.IGNORECASE | re.VERBOSE | re.UNICODE) + +proto_re = re.compile(r'^[\w-]+:/{0,3}', re.IGNORECASE) + +punct_re = re.compile(r'([\.,]+)$') + +email_re = re.compile( + r"""(? tag replaced by the text within it + adj = replace_nodes(tree, _text, node, current_child) + # pull back current_child by 1 to scan the new nodes + # again. + current_child -= 1 + else: + text = force_unicode(attrs.pop('_text')) + for attr_key, attr_val in attrs.items(): + node.set(attr_key, attr_val) + + for n in reversed(list(node)): + node.remove(n) + text = parser.parseFragment(text) + node.text = text.text + for n in text: + node.append(n) + _seen.add(node) + + elif current_child >= 0: + if node.tag == ETREE_TAG('pre') and skip_pre: + linkify_nodes(node, False) + elif not (node in _seen): + linkify_nodes(node, parse_text) + + current_child += 1 + + def email_repl(match): + addr = match.group(0).replace('"', '"') + link = { + '_text': addr, + 'href': 'mailto:{0!s}'.format(addr), + } + link = apply_callbacks(link, True) + + if link is None: + return addr + + _href = link.pop('href') + _text = link.pop('_text') + + repl = '{2!s}' + attr = '{0!s}="{1!s}"' + attribs = ' '.join(attr.format(k, v) for k, v in link.items()) + return repl.format(_href, attribs, _text) + + def link_repl(match): + url = match.group(0) + open_brackets = close_brackets = 0 + if url.startswith('('): + _wrapping = strip_wrapping_parentheses(url) + url, open_brackets, close_brackets = _wrapping + if url.endswith(')') and '(' not in url: + # This is a clumsy handling for the case where we have something + # like (foo http://example.com) and the ) gets picked up by the + # url_re but we don't want it part of the link. + new_url = url.rstrip(')') + close_brackets += len(url) - len(new_url) + url = new_url + + end = '' + m = re.search(punct_re, url) + if m: + end = m.group(0) + url = url[0:m.start()] + if re.search(proto_re, url): + href = url + else: + href = ''.join(['http://', url]) + + link = { + '_text': url, + 'href': href, + } + + link = apply_callbacks(link, True) + + if link is None: + return '(' * open_brackets + url + ')' * close_brackets + + _text = link.pop('_text') + _href = link.pop('href') + + repl = '{0!s}{3!s}{4!s}{5!s}' + attr = '{0!s}="{1!s}"' + attribs = ' '.join(attr.format(k, v) for k, v in link.items()) + + return repl.format('(' * open_brackets, + _href, attribs, _text, end, + ')' * close_brackets) + + try: + linkify_nodes(forest) + except RuntimeError as e: + # If we hit the max recursion depth, just return what we've got. + log.exception('Probable recursion error: {0!r}'.format(e)) + + return _render(forest) + + +def _render(tree): + """Try rendering as HTML, then XML, then give up.""" + return force_unicode(_serialize(tree)) + + +def _serialize(domtree): + walker = html5lib.treewalkers.getTreeWalker('etree') + stream = walker(domtree) + serializer = HTMLSerializer(quote_attr_values=True, + alphabetical_attributes=True, + omit_optional_tags=False) + return serializer.render(stream) diff --git a/venv/lib/python3.5/site-packages/bleach/__pycache__/__init__.cpython-35.pyc b/venv/lib/python3.5/site-packages/bleach/__pycache__/__init__.cpython-35.pyc index 13c1fea3..744aa2d4 100644 Binary files a/venv/lib/python3.5/site-packages/bleach/__pycache__/__init__.cpython-35.pyc and b/venv/lib/python3.5/site-packages/bleach/__pycache__/__init__.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/bleach/__pycache__/callbacks.cpython-35.pyc b/venv/lib/python3.5/site-packages/bleach/__pycache__/callbacks.cpython-35.pyc index e14f3dfa..38d1fb8e 100644 Binary files a/venv/lib/python3.5/site-packages/bleach/__pycache__/callbacks.cpython-35.pyc and b/venv/lib/python3.5/site-packages/bleach/__pycache__/callbacks.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/bleach/__pycache__/encoding.cpython-35.pyc b/venv/lib/python3.5/site-packages/bleach/__pycache__/encoding.cpython-35.pyc new file mode 100644 index 00000000..3bf628c9 Binary files /dev/null and b/venv/lib/python3.5/site-packages/bleach/__pycache__/encoding.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/bleach/__pycache__/html5lib_shim.cpython-35.pyc b/venv/lib/python3.5/site-packages/bleach/__pycache__/html5lib_shim.cpython-35.pyc deleted file mode 100644 index 0ec277fe..00000000 Binary files a/venv/lib/python3.5/site-packages/bleach/__pycache__/html5lib_shim.cpython-35.pyc and /dev/null differ diff --git a/venv/lib/python3.5/site-packages/bleach/__pycache__/linkifier.cpython-35.pyc b/venv/lib/python3.5/site-packages/bleach/__pycache__/linkifier.cpython-35.pyc deleted file mode 100644 index 101e4a0f..00000000 Binary files a/venv/lib/python3.5/site-packages/bleach/__pycache__/linkifier.cpython-35.pyc and /dev/null differ diff --git a/venv/lib/python3.5/site-packages/bleach/__pycache__/sanitizer.cpython-35.pyc b/venv/lib/python3.5/site-packages/bleach/__pycache__/sanitizer.cpython-35.pyc index d859874c..20e3f091 100644 Binary files a/venv/lib/python3.5/site-packages/bleach/__pycache__/sanitizer.cpython-35.pyc and b/venv/lib/python3.5/site-packages/bleach/__pycache__/sanitizer.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/bleach/__pycache__/utils.cpython-35.pyc b/venv/lib/python3.5/site-packages/bleach/__pycache__/utils.cpython-35.pyc deleted file mode 100644 index 5fe6c08e..00000000 Binary files a/venv/lib/python3.5/site-packages/bleach/__pycache__/utils.cpython-35.pyc and /dev/null differ diff --git a/venv/lib/python3.5/site-packages/bleach/__pycache__/version.cpython-35.pyc b/venv/lib/python3.5/site-packages/bleach/__pycache__/version.cpython-35.pyc new file mode 100644 index 00000000..667c72a8 Binary files /dev/null and b/venv/lib/python3.5/site-packages/bleach/__pycache__/version.cpython-35.pyc differ diff --git a/venv/lib/python3.5/site-packages/bleach/_vendor/README.rst b/venv/lib/python3.5/site-packages/bleach/_vendor/README.rst deleted file mode 100644 index a8a42d68..00000000 --- a/venv/lib/python3.5/site-packages/bleach/_vendor/README.rst +++ /dev/null @@ -1,37 +0,0 @@ -======================= -Vendored library policy -======================= - -To simplify Bleach development, we're now vendoring certain libraries that -we use. - -Vendored libraries must follow these rules: - -1. Vendored libraries must be pure Python--no compiling. -2. Source code for the libary is included in this directory. -3. License must be included in this repo and in the Bleach distribution. -4. Requirements of the library become requirements of Bleach. -5. No modifications to the library may be made. - - -Adding/Updating a vendored library -================================== - -Way to vendor a library or update a version: - -1. Update ``vendor.txt`` with the library, version, and hash. You can use - `hashin `_. -2. Remove all old files and directories of the old version. -3. Run ``pip_install_vendor.sh`` and check everything it produced in including - the ``.dist-info`` directory and contents. - - -Reviewing a change involving a vendored library -=============================================== - -Way to verify a vendored library addition/update: - -1. Pull down the branch. -2. Delete all the old files and directories of the old version. -3. Run ``pip_install_vendor.sh``. -4. Run ``git diff`` and verify there are no changes. diff --git a/venv/lib/python3.5/site-packages/bleach/_vendor/__pycache__/__init__.cpython-35.pyc b/venv/lib/python3.5/site-packages/bleach/_vendor/__pycache__/__init__.cpython-35.pyc deleted file mode 100644 index 7dba15a0..00000000 Binary files a/venv/lib/python3.5/site-packages/bleach/_vendor/__pycache__/__init__.cpython-35.pyc and /dev/null differ diff --git a/venv/lib/python3.5/site-packages/bleach/_vendor/html5lib-1.0.1.dist-info/METADATA b/venv/lib/python3.5/site-packages/bleach/_vendor/html5lib-1.0.1.dist-info/METADATA deleted file mode 100644 index f8131d7b..00000000 --- a/venv/lib/python3.5/site-packages/bleach/_vendor/html5lib-1.0.1.dist-info/METADATA +++ /dev/null @@ -1,530 +0,0 @@ -Metadata-Version: 2.0 -Name: html5lib -Version: 1.0.1 -Summary: HTML parser based on the WHATWG HTML specification -Home-page: https://github.com/html5lib/html5lib-python -Author: James Graham -Author-email: james@hoppipolla.co.uk -License: MIT License -Description-Content-Type: UNKNOWN -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Text Processing :: Markup :: HTML -Requires-Dist: six (>=1.9) -Requires-Dist: webencodings -Provides-Extra: all -Requires-Dist: genshi; extra == 'all' -Requires-Dist: chardet (>=2.2); extra == 'all' -Provides-Extra: all -Requires-Dist: datrie; platform_python_implementation == 'CPython' and extra == 'all' -Requires-Dist: lxml; platform_python_implementation == 'CPython' and extra == 'all' -Provides-Extra: chardet -Requires-Dist: chardet (>=2.2); extra == 'chardet' -Provides-Extra: datrie -Requires-Dist: datrie; platform_python_implementation == 'CPython' and extra == 'datrie' -Provides-Extra: genshi -Requires-Dist: genshi; extra == 'genshi' -Provides-Extra: lxml -Requires-Dist: lxml; platform_python_implementation == 'CPython' and extra == 'lxml' - -html5lib -======== - -.. image:: https://travis-ci.org/html5lib/html5lib-python.png?branch=master - :target: https://travis-ci.org/html5lib/html5lib-python - -html5lib is a pure-python library for parsing HTML. It is designed to -conform to the WHATWG HTML specification, as is implemented by all major -web browsers. - - -Usage ------ - -Simple usage follows this pattern: - -.. code-block:: python - - import html5lib - with open("mydocument.html", "rb") as f: - document = html5lib.parse(f) - -or: - -.. code-block:: python - - import html5lib - document = html5lib.parse("

Hello World!") - -By default, the ``document`` will be an ``xml.etree`` element instance. -Whenever possible, html5lib chooses the accelerated ``ElementTree`` -implementation (i.e. ``xml.etree.cElementTree`` on Python 2.x). - -Two other tree types are supported: ``xml.dom.minidom`` and -``lxml.etree``. To use an alternative format, specify the name of -a treebuilder: - -.. code-block:: python - - import html5lib - with open("mydocument.html", "rb") as f: - lxml_etree_document = html5lib.parse(f, treebuilder="lxml") - -When using with ``urllib2`` (Python 2), the charset from HTTP should be -pass into html5lib as follows: - -.. code-block:: python - - from contextlib import closing - from urllib2 import urlopen - import html5lib - - with closing(urlopen("http://example.com/")) as f: - document = html5lib.parse(f, transport_encoding=f.info().getparam("charset")) - -When using with ``urllib.request`` (Python 3), the charset from HTTP -should be pass into html5lib as follows: - -.. code-block:: python - - from urllib.request import urlopen - import html5lib - - with urlopen("http://example.com/") as f: - document = html5lib.parse(f, transport_encoding=f.info().get_content_charset()) - -To have more control over the parser, create a parser object explicitly. -For instance, to make the parser raise exceptions on parse errors, use: - -.. code-block:: python - - import html5lib - with open("mydocument.html", "rb") as f: - parser = html5lib.HTMLParser(strict=True) - document = parser.parse(f) - -When you're instantiating parser objects explicitly, pass a treebuilder -class as the ``tree`` keyword argument to use an alternative document -format: - -.. code-block:: python - - import html5lib - parser = html5lib.HTMLParser(tree=html5lib.getTreeBuilder("dom")) - minidom_document = parser.parse("

Hello World!") - -More documentation is available at https://html5lib.readthedocs.io/. - - -Installation ------------- - -html5lib works on CPython 2.7+, CPython 3.3+ and PyPy. To install it, -use: - -.. code-block:: bash - - $ pip install html5lib - - -Optional Dependencies ---------------------- - -The following third-party libraries may be used for additional -functionality: - -- ``datrie`` can be used under CPython to improve parsing performance - (though in almost all cases the improvement is marginal); - -- ``lxml`` is supported as a tree format (for both building and - walking) under CPython (but *not* PyPy where it is known to cause - segfaults); - -- ``genshi`` has a treewalker (but not builder); and - -- ``chardet`` can be used as a fallback when character encoding cannot - be determined. - - -Bugs ----- - -Please report any bugs on the `issue tracker -`_. - - -Tests ------ - -Unit tests require the ``pytest`` and ``mock`` libraries and can be -run using the ``py.test`` command in the root directory. - -Test data are contained in a separate `html5lib-tests -`_ repository and included -as a submodule, thus for git checkouts they must be initialized:: - - $ git submodule init - $ git submodule update - -If you have all compatible Python implementations available on your -system, you can run tests on all of them using the ``tox`` utility, -which can be found on PyPI. - - -Questions? ----------- - -There's a mailing list available for support on Google Groups, -`html5lib-discuss `_, -though you may get a quicker response asking on IRC in `#whatwg on -irc.freenode.net `_. - -Change Log ----------- - -1.0.1 -~~~~~ - -Released on December 7, 2017 - -Breaking changes: - -* Drop support for Python 2.6. (#330) (Thank you, Hugo, Will Kahn-Greene!) -* Remove ``utils/spider.py`` (#353) (Thank you, Jon Dufresne!) - -Features: - -* Improve documentation. (#300, #307) (Thank you, Jon Dufresne, Tom Most, - Will Kahn-Greene!) -* Add iframe seamless boolean attribute. (Thank you, Ritwik Gupta!) -* Add itemscope as a boolean attribute. (#194) (Thank you, Jonathan Vanasco!) -* Support Python 3.6. (#333) (Thank you, Jon Dufresne!) -* Add CI support for Windows using AppVeyor. (Thank you, John Vandenberg!) -* Improve testing and CI and add code coverage (#323, #334), (Thank you, Jon - Dufresne, John Vandenberg, Geoffrey Sneddon, Will Kahn-Greene!) -* Semver-compliant version number. - -Bug fixes: - -* Add support for setuptools < 18.5 to support environment markers. (Thank you, - John Vandenberg!) -* Add explicit dependency for six >= 1.9. (Thank you, Eric Amorde!) -* Fix regexes to work with Python 3.7 regex adjustments. (#318, #379) (Thank - you, Benedikt Morbach, Ville Skyttä, Mark Vasilkov!) -* Fix alphabeticalattributes filter namespace bug. (#324) (Thank you, Will - Kahn-Greene!) -* Include license file in generated wheel package. (#350) (Thank you, Jon - Dufresne!) -* Fix annotation-xml typo. (#339) (Thank you, Will Kahn-Greene!) -* Allow uppercase hex chararcters in CSS colour check. (#377) (Thank you, - Komal Dembla, Hugo!) - - -1.0 -~~~ - -Released and unreleased on December 7, 2017. Badly packaged release. - - -0.999999999/1.0b10 -~~~~~~~~~~~~~~~~~~ - -Released on July 15, 2016 - -* Fix attribute order going to the tree builder to be document order - instead of reverse document order(!). - - -0.99999999/1.0b9 -~~~~~~~~~~~~~~~~ - -Released on July 14, 2016 - -* **Added ordereddict as a mandatory dependency on Python 2.6.** - -* Added ``lxml``, ``genshi``, ``datrie``, ``charade``, and ``all`` - extras that will do the right thing based on the specific - interpreter implementation. - -* Now requires the ``mock`` package for the testsuite. - -* Cease supporting DATrie under PyPy. - -* **Remove PullDOM support, as this hasn't ever been properly - tested, doesn't entirely work, and as far as I can tell is - completely unused by anyone.** - -* Move testsuite to ``py.test``. - -* **Fix #124: move to webencodings for decoding the input byte stream; - this makes html5lib compliant with the Encoding Standard, and - introduces a required dependency on webencodings.** - -* **Cease supporting Python 3.2 (in both CPython and PyPy forms).** - -* **Fix comments containing double-dash with lxml 3.5 and above.** - -* **Use scripting disabled by default (as we don't implement - scripting).** - -* **Fix #11, avoiding the XSS bug potentially caused by serializer - allowing attribute values to be escaped out of in old browser versions, - changing the quote_attr_values option on serializer to take one of - three values, "always" (the old True value), "legacy" (the new option, - and the new default), and "spec" (the old False value, and the old - default).** - -* **Fix #72 by rewriting the sanitizer to apply only to treewalkers - (instead of the tokenizer); as such, this will require amending all - callers of it to use it via the treewalker API.** - -* **Drop support of charade, now that chardet is supported once more.** - -* **Replace the charset keyword argument on parse and related methods - with a set of keyword arguments: override_encoding, transport_encoding, - same_origin_parent_encoding, likely_encoding, and default_encoding.** - -* **Move filters._base, treebuilder._base, and treewalkers._base to .base - to clarify their status as public.** - -* **Get rid of the sanitizer package. Merge sanitizer.sanitize into the - sanitizer.htmlsanitizer module and move that to sanitizer. This means - anyone who used sanitizer.sanitize or sanitizer.HTMLSanitizer needs no - code changes.** - -* **Rename treewalkers.lxmletree to .etree_lxml and - treewalkers.genshistream to .genshi to have a consistent API.** - -* Move a whole load of stuff (inputstream, ihatexml, trie, tokenizer, - utils) to be underscore prefixed to clarify their status as private. - - -0.9999999/1.0b8 -~~~~~~~~~~~~~~~ - -Released on September 10, 2015 - -* Fix #195: fix the sanitizer to drop broken URLs (it threw an - exception between 0.9999 and 0.999999). - - -0.999999/1.0b7 -~~~~~~~~~~~~~~ - -Released on July 7, 2015 - -* Fix #189: fix the sanitizer to allow relative URLs again (as it did - prior to 0.9999/1.0b5). - - -0.99999/1.0b6 -~~~~~~~~~~~~~ - -Released on April 30, 2015 - -* Fix #188: fix the sanitizer to not throw an exception when sanitizing - bogus data URLs. - - -0.9999/1.0b5 -~~~~~~~~~~~~ - -Released on April 29, 2015 - -* Fix #153: Sanitizer fails to treat some attributes as URLs. Despite how - this sounds, this has no known security implications. No known version - of IE (5.5 to current), Firefox (3 to current), Safari (6 to current), - Chrome (1 to current), or Opera (12 to current) will run any script - provided in these attributes. - -* Pass error message to the ParseError exception in strict parsing mode. - -* Allow data URIs in the sanitizer, with a whitelist of content-types. - -* Add support for Python implementations that don't support lone - surrogates (read: Jython). Fixes #2. - -* Remove localization of error messages. This functionality was totally - unused (and untested that everything was localizable), so we may as - well follow numerous browsers in not supporting translating technical - strings. - -* Expose treewalkers.pprint as a public API. - -* Add a documentEncoding property to HTML5Parser, fix #121. - - -0.999 -~~~~~ - -Released on December 23, 2013 - -* Fix #127: add work-around for CPython issue #20007: .read(0) on - http.client.HTTPResponse drops the rest of the content. - -* Fix #115: lxml treewalker can now deal with fragments containing, at - their root level, text nodes with non-ASCII characters on Python 2. - - -0.99 -~~~~ - -Released on September 10, 2013 - -* No library changes from 1.0b3; released as 0.99 as pip has changed - behaviour from 1.4 to avoid installing pre-release versions per - PEP 440. - - -1.0b3 -~~~~~ - -Released on July 24, 2013 - -* Removed ``RecursiveTreeWalker`` from ``treewalkers._base``. Any - implementation using it should be moved to - ``NonRecursiveTreeWalker``, as everything bundled with html5lib has - for years. - -* Fix #67 so that ``BufferedStream`` to correctly returns a bytes - object, thereby fixing any case where html5lib is passed a - non-seekable RawIOBase-like object. - - -1.0b2 -~~~~~ - -Released on June 27, 2013 - -* Removed reordering of attributes within the serializer. There is now - an ``alphabetical_attributes`` option which preserves the previous - behaviour through a new filter. This allows attribute order to be - preserved through html5lib if the tree builder preserves order. - -* Removed ``dom2sax`` from DOM treebuilders. It has been replaced by - ``treeadapters.sax.to_sax`` which is generic and supports any - treewalker; it also resolves all known bugs with ``dom2sax``. - -* Fix treewalker assertions on hitting bytes strings on - Python 2. Previous to 1.0b1, treewalkers coped with mixed - bytes/unicode data on Python 2; this reintroduces this prior - behaviour on Python 2. Behaviour is unchanged on Python 3. - - -1.0b1 -~~~~~ - -Released on May 17, 2013 - -* Implementation updated to implement the `HTML specification - `_ as of 5th May - 2013 (`SVN `_ revision r7867). - -* Python 3.2+ supported in a single codebase using the ``six`` library. - -* Removed support for Python 2.5 and older. - -* Removed the deprecated Beautiful Soup 3 treebuilder. - ``beautifulsoup4`` can use ``html5lib`` as a parser instead. Note that - since it doesn't support namespaces, foreign content like SVG and - MathML is parsed incorrectly. - -* Removed ``simpletree`` from the package. The default tree builder is - now ``etree`` (using the ``xml.etree.cElementTree`` implementation if - available, and ``xml.etree.ElementTree`` otherwise). - -* Removed the ``XHTMLSerializer`` as it never actually guaranteed its - output was well-formed XML, and hence provided little of use. - -* Removed default DOM treebuilder, so ``html5lib.treebuilders.dom`` is no - longer supported. ``html5lib.treebuilders.getTreeBuilder("dom")`` will - return the default DOM treebuilder, which uses ``xml.dom.minidom``. - -* Optional heuristic character encoding detection now based on - ``charade`` for Python 2.6 - 3.3 compatibility. - -* Optional ``Genshi`` treewalker support fixed. - -* Many bugfixes, including: - - * #33: null in attribute value breaks XML AttValue; - - * #4: nested, indirect descendant,