<commit_before>define(
// Dependencies
[ 'underscore', 'leaflet', 'mosaic-commons', 'rbush',
        './Leaflet.InteractionLayer', './IndexedCanvas' ],
// Module
function(_, L, Mosaic, Rbush, InteractionLayer, IndexedCanvas) {

    /** This mixin provides methods used to index data points. */
    var MarkersLayer = InteractionLayer.extend({

        /**
         */
        initialize : function(options) {
            options = _.extend({
                async : true
            }, options);
            options.fillOpacity = options.opacity;
            delete options.opacity;
            InteractionLayer.prototype.initialize.call(this, options);
            this._canvasLayer = new L.TileLayer.Canvas(this.options);
            this._canvasLayer._redrawTile = _.bind(this._redrawTile, this);
            this._objectForEvent = _.bind(this._objectForEvent, this);
            this._clearTile = _.bind(this._onTileUnload, this);
            this._canvasLayer.on('tileunload', this._onTileUnload);
            this.setData(this.options.data);
        },

        // --------------------------------------------------------------------
        // Leaflet.InteractionLayer method

        /**
         * Returns an object from UTF grid corresponding to the coordinates of
         * the mouse event.
         */
        _objectForEvent : function(e) {
            var latlng = e.latlng;
            var map = this._map;
            var point = map.latLngToLayerPoint(latlng);
            point = point.add(map.getPixelOrigin());
            var tileSize = this._getTileSize();
            var tilePoint = point.divideBy(tileSize).floor();
            var key = tilePoint.x + ':' + tilePoint.y;
            var canvas = this._canvasLayer._tiles[key];
            var data;
            if (canvas && canvas._index) {
                var id = canvas._index._id;
                var canvasX = point.x % tileSize;
                var canvasY = point.y % tileSize;
                data = canvas._index.getData(canvasX, canvasY);
            }
            return {
                latlng : latlng,
                data : data
            };
        },

        // --------------------------------------------------------------------
        // Leaflet.ILayer methods

        /**
         * This method is called when this layer is added to the map.
         */
        onAdd : function(map) {
            InteractionLayer.prototype.onAdd.call(this, map);
            map.addLayer(this._canvasLayer);
        },

        /**
         * This method is called when this layer is removed from the map.
         */
        onRemove : function(map) {
            map.removeLayer(this._canvasLayer);
            InteractionLayer.prototype.onRemove.call(this, map);
        },

        // --------------------------------------------------------------------

        setData : function(data) {
            this._indexData(data);
            this._canvasLayer.redraw();
        },
        // --------------------------------------------------------------------

        /** Indexes the specified data array using a quad tree. */
        _indexData : function(data) {
            // Data indexing
            this._index = Rbush(9);
            data = data || [];
            data = _.map(data, function(d) {
                var coordinates = this._getBoundingBoxArray(d);
                if (coordinates) {
                    coordinates.data = d;
                }
                return coordinates;
            }, this);
            data = _.filter(data, function(array) {
                return !!array;
            });
            this._index.load(data);
        },

        /** Searches resources inside of the specified bounding box. */
        _searchInBbox : function(bbox, point) {
            var sw = bbox.getSouthWest();
            var ne = bbox.getNorthEast();
            point = point || ne;
            var coords = [ sw.lat, sw.lng, ne.lat, ne.lng ];
            var p = [ point.lat, point.lng ];
            var array = this._index.search(coords);
            // Sort points by Manhattan distance to the origin point
            array.sort(function(a, b) {
                var d1 = Math.abs(a[0] - p[0]) + Math.abs(a[1] - p[1]);
                var d2 = Math.abs(b[0] - p[0]) + Math.abs(b[1] - p[1]);
                return d1 - d2;
            });
            var result = _.map(array, function(arr) {
                return arr.data;
            });
            return result;
        },

        /** Returns size of canvas tiles. */
        _getTileSize : function() {
            return this._canvasLayer._getTileSize();
        },

        /** Returns a buffer zone size around each tile. */
        _getBufferZoneSize : function() {
            var r = this._getRadius() * 2.5;
            return L.point(r, r);
        },

        /**
         * This method is called when a tile is removed from the map. It cleans
         * up data associated with this tile.
         */
        _onTileUnload : function(evt) {
            var canvas = evt.tile;
            if (canvas._index) {
                canvas._index.reset();
                delete canvas._index;
            }
        },

        /**
         * This method is used by the underlying L.TileLayer.Canvas to draw
         * information on the canvas tile.
         */
        _redrawTile : function(canvas) {
            var that = this;
            var tileSize = that._getTileSize();
            var tilePoint = canvas._tilePoint;
            var nwPoint = tilePoint.multiplyBy(tileSize);
            var sePoint = nwPoint.add(new L.Point(tileSize, tileSize));
            var bufferSize = that._getBufferZoneSize();
            nwPoint = nwPoint.subtract(bufferSize);
            sePoint = sePoint.add(bufferSize);
            var bbox = new L.LatLngBounds(that._map.unproject(sePoint),
                    that._map.unproject(nwPoint));
            var index = that._getCanvasIndex(canvas);
            var data = that._searchInBbox(bbox);
            _.each(data, function(d) {
                var ctx = that._drawFeature(tilePoint, bbox, d);
                if (ctx) {
                    index.draw(ctx.image, ctx.anchor.x, ctx.anchor.y, d);
                }
            });
            that._canvasLayer.tileDrawn(canvas);
        },

        // -----------------------------------------------------------------

        /**
         * Returns an IndexedCanvas instance associated with the specified
         * canvas.
         */
        _getCanvasIndex : function(canvas) {
            var that = this;
            var index = canvas._index;
            if (index) {
                index.reset();
            } else {
                that._maskIndex = that._maskIndex || {};
                index = canvas._index = new IndexedCanvas({
                    canvas : canvas,
                    maskIndex : that._maskIndex
                });
            }
            return index;
        },

        /**
         * Returns an array with a bounding box ([south, west, north, east]) for
         * the specified object.
         */
        _getBoundingBoxArray : function(d) {
            if (!d.geometry || !d.geometry.coordinates)
                return null;
            var coords = d.geometry.coordinates;
            var array = [ coords[1], coords[0], coords[1], coords[0] ];
            return array;
        },

        /**
         * Draws the specified resource and returns an image with x/y
         * coordinates of this image on the canvas.
         *
         * @return an object containing the following fields: a) 'image' - an
         *         Image or Canvas instance with the drawn result b) 'anchor' a
         *         L.Point instance defining the point on the returned image
         *         corresponding to resource coordinates
         */
        _drawFeature : function(tilePoint, bbox, resource) {
            var geom = resource.geometry;
            if (!geom)
                return;
            var coords = geom.coordinates;
            if (!coords)
                return;
            var latlng = new L.LatLng(coords[1], coords[0]);
            var p = this._map.project(latlng);
            var tileSize = this._getTileSize();
            var s = tilePoint.multiplyBy(tileSize);

            var x = Math.round(p.x - s.x);
            var y = Math.round(p.y - s.y);
            var icon = this._getIconInfo(resource);
            var anchor = L.point(x, y);
            if (icon.anchor) {
                anchor._subtract(icon.anchor);
            }
            return {
                image : icon.image,
                anchor : anchor
            };
        },

        /**
         * Loads and returns icon information corresponding to the specified
         * resource.
         */
        _getIconInfo : function(resource) {
            var type = this._getResourceType(resource);
            var map = this._map;
            var zoom = map.getZoom();
            var iconIndex = this._iconIndex = this._iconIndex || {};
            var indexKey = zoom + ':' + type;
            var icon = iconIndex[indexKey];
            if (!icon) {
                icon = this._drawIcon(type);
                iconIndex[indexKey] = icon;
            }
            return icon;
        },

        /** Returns the type (as a string) of the specified resource. */
        _getResourceType : function(resource) {
            return 'resource';
        },

        _getOptionValue : function(key) {
            var val = this.options[key];
            if (_.isFunction(val)) {
                var args = _.toArray(arguments);
                args.splice(0, 1);
                val = val.apply(this.options, args);
            }
            return val;
        },

        _getVal : function(key, defaultValue) {
            return this._getOptionValue(key, this._map.getZoom()) || //
            defaultValue;
        },

        _getRadius : function(defaultValue) {
            return this._getVal('radius', 16);
        },

        /**
         * Draws an icon and returns information about it as an object with the
         * following fields: a) 'image' - an Image or a Canvas instance b)
         * 'anchor' a L.Point instance defining the position on the icon
         * corresponding to the resource coordinates
         */
        _drawIcon : function(type) {
            var radius = this._getRadius();
            var canvas = document.createElement('canvas');
            var lineWidth = this._getVal('lineWidth', 1);
            var width = radius * 2;
            var height = radius * 2;
            canvas.height = height;
            canvas.width = width;
            radius -= lineWidth;
            var g = canvas.getContext('2d');
            g.fillStyle = this._getVal('fillColor', 'white');
            g.globalAlpha = this._getVal('fillOpacity', 1);
            g.strokeStyle = this._getVal('lineColor', 'gray');
            g.lineWidth = lineWidth;
            g.lineCap = 'round';
            this._drawMarker(g, lineWidth, lineWidth, width - lineWidth * 2,
                    height - lineWidth * 2, radius * 0.6);
            g.fill();
            g.stroke();
            return {
                image : canvas,
                anchor : L.point(width / 2, height)
            };
        },

        _drawMarker : function(g, x, y, width, height, radius) {
            g.beginPath();
            // a
            g.moveTo(x + width / 2, y);
            // b
            g.bezierCurveTo(//
            x + width / 2 + radius / 2, y, //
            x + width / 2 + radius, y + radius / 2, //
            x + width / 2 + radius, y + radius);
            // c
            g.bezierCurveTo( //
            x + width / 2 + radius, y + radius * 2, //
            x + width / 2, y + height / 2 + radius, //
            x + width / 2, y + height);
            // d
            g.bezierCurveTo(//
            x + width / 2, y + height / 2 + radius, //
            x + width / 2 - radius, y + radius * 2, //
            x + width / 2 - radius, y + radius);
            // e (a)
            g.bezierCurveTo(//
            x + width / 2 - radius, y + radius / 2, //
            x + width / 2 - radius / 2, y + 0, //
            x + width / 2, y + 0);
            g.closePath();
        },

    });

    return MarkersLayer;

});
<commit_msg>Resource coordinates are loaded in a separate method<commit_after>define(
// Dependencies
[ 'underscore', 'leaflet', 'mosaic-commons', 'rbush',
        './Leaflet.InteractionLayer', './IndexedCanvas' ],
// Module
function(_, L, Mosaic, Rbush, InteractionLayer, IndexedCanvas) {

    /** This mixin provides methods used to index data points. */
    var MarkersLayer = InteractionLayer.extend({

        /**
         */
        initialize : function(options) {
            options = _.extend({
                async : true
            }, options);
            options.fillOpacity = options.opacity;
            delete options.opacity;
            InteractionLayer.prototype.initialize.call(this, options);
            this._canvasLayer = new L.TileLayer.Canvas(this.options);
            this._canvasLayer._redrawTile = _.bind(this._redrawTile, this);
            this._objectForEvent = _.bind(this._objectForEvent, this);
            this._clearTile = _.bind(this._onTileUnload, this);
            this._canvasLayer.on('tileunload', this._onTileUnload);
            this.setData(this.options.data);
        },

        // --------------------------------------------------------------------
        // Leaflet.InteractionLayer method

        /**
         * Returns an object from UTF grid corresponding to the coordinates of
         * the mouse event.
         */
        _objectForEvent : function(e) {
            var latlng = e.latlng;
            var map = this._map;
            var point = map.latLngToLayerPoint(latlng);
            point = point.add(map.getPixelOrigin());
            var tileSize = this._getTileSize();
            var tilePoint = point.divideBy(tileSize).floor();
            var key = tilePoint.x + ':' + tilePoint.y;
            var canvas = this._canvasLayer._tiles[key];
            var data;
            if (canvas && canvas._index) {
                var id = canvas._index._id;
                var canvasX = point.x % tileSize;
                var canvasY = point.y % tileSize;
                data = canvas._index.getData(canvasX, canvasY);
            }
            return {
                latlng : latlng,
                data : data
            };
        },

        // --------------------------------------------------------------------
        // Leaflet.ILayer methods

        /**
         * This method is called when this layer is added to the map.
         */
        onAdd : function(map) {
            InteractionLayer.prototype.onAdd.call(this, map);
            map.addLayer(this._canvasLayer);
        },

        /**
         * This method is called when this layer is removed from the map.
         */
        onRemove : function(map) {
            map.removeLayer(this._canvasLayer);
            InteractionLayer.prototype.onRemove.call(this, map);
        },

        // --------------------------------------------------------------------

        setData : function(data) {
            this._indexData(data);
            this._canvasLayer.redraw();
        },
        // --------------------------------------------------------------------

        /** Indexes the specified data array using a quad tree. */
        _indexData : function(data) {
            // Data indexing
            this._index = Rbush(9);
            data = data || [];
            data = _.map(data, function(d) {
                var coordinates = this._getBoundingBoxArray(d);
                if (coordinates) {
                    coordinates.data = d;
                }
                return coordinates;
            }, this);
            data = _.filter(data, function(array) {
                return !!array;
            });
            this._index.load(data);
        },

        /** Searches resources inside of the specified bounding box. */
        _searchInBbox : function(bbox, point) {
            var sw = bbox.getSouthWest();
            var ne = bbox.getNorthEast();
            point = point || ne;
            var coords = [ sw.lat, sw.lng, ne.lat, ne.lng ];
            var p = [ point.lat, point.lng ];
            var array = this._index.search(coords);
            // Sort points by Manhattan distance to the origin point
            array.sort(function(a, b) {
                var d1 = Math.abs(a[0] - p[0]) + Math.abs(a[1] - p[1]);
                var d2 = Math.abs(b[0] - p[0]) + Math.abs(b[1] - p[1]);
                return d1 - d2;
            });
            var result = _.map(array, function(arr) {
                return arr.data;
            });
            return result;
        },

        /** Returns size of canvas tiles. */
        _getTileSize : function() {
            return this._canvasLayer._getTileSize();
        },

        /** Returns a buffer zone size around each tile. */
        _getBufferZoneSize : function() {
            var r = this._getRadius() * 2.5;
            return L.point(r, r);
        },

        /**
         * This method is called when a tile is removed from the map. It cleans
         * up data associated with this tile.
         */
        _onTileUnload : function(evt) {
            var canvas = evt.tile;
            if (canvas._index) {
                canvas._index.reset();
                delete canvas._index;
            }
        },

        /**
         * This method is used by the underlying L.TileLayer.Canvas to draw
         * information on the canvas tile.
         */
        _redrawTile : function(canvas) {
            var that = this;
            var tileSize = that._getTileSize();
            var tilePoint = canvas._tilePoint;
            var nwPoint = tilePoint.multiplyBy(tileSize);
            var sePoint = nwPoint.add(new L.Point(tileSize, tileSize));
            var bufferSize = that._getBufferZoneSize();
            nwPoint = nwPoint.subtract(bufferSize);
            sePoint = sePoint.add(bufferSize);
            var bbox = new L.LatLngBounds(that._map.unproject(sePoint),
                    that._map.unproject(nwPoint));
            var index = that._getCanvasIndex(canvas);
            var data = that._searchInBbox(bbox);
            _.each(data, function(d) {
                var ctx = that._drawFeature(tilePoint, bbox, d);
                if (ctx) {
                    index.draw(ctx.image, ctx.anchor.x, ctx.anchor.y, d);
                }
            });
            that._canvasLayer.tileDrawn(canvas);
        },

        // -----------------------------------------------------------------

        /**
         * Returns an IndexedCanvas instance associated with the specified
         * canvas.
         */
        _getCanvasIndex : function(canvas) {
            var that = this;
            var index = canvas._index;
            if (index) {
                index.reset();
            } else {
                that._maskIndex = that._maskIndex || {};
                index = canvas._index = new IndexedCanvas({
                    canvas : canvas,
                    maskIndex : that._maskIndex
                });
            }
            return index;
        },

        /** Returns point coordinates for the specified resource. */
        _getCoordinates : function(d) {
            var geom = d.geometry;
            if (!geom || !geom.coordinates)
                return null;
            var coords;
            if (geom.type == 'Point') {
                coords = geom.coordinates;
            } else {
                var layer = L.GeoJSON.geometryToLayer(geom);
                var bbox = layer.getBounds();
                var center = bbox.getCenter();
                coords = [ center.lng, center.lat ];
            }
            return coords;
        },

        /**
         * Returns an array with a bounding box ([south, west, north, east]) for
         * the specified object.
         */
        _getBoundingBoxArray : function(d) {
            var coords = this._getCoordinates(d);
            if (!coords)
                return;
            var array = [ coords[1], coords[0], coords[1], coords[0] ];
            return array;
        },

        /**
         * Draws the specified resource and returns an image with x/y
         * coordinates of this image on the canvas.
         *
         * @return an object containing the following fields: a) 'image' - an
         *         Image or Canvas instance with the drawn result b) 'anchor' a
         *         L.Point instance defining the point on the returned image
         *         corresponding to resource coordinates
         */
        _drawFeature : function(tilePoint, bbox, resource) {
            var coords = this._getCoordinates(resource);
            if (!coords)
                return;

            var latlng = new L.LatLng(coords[1], coords[0]);
            var p = this._map.project(latlng);
            var tileSize = this._getTileSize();
            var s = tilePoint.multiplyBy(tileSize);

            var x = Math.round(p.x - s.x);
            var y = Math.round(p.y - s.y);
            var icon = this._getIconInfo(resource);
            var anchor = L.point(x, y);
            if (icon.anchor) {
                anchor._subtract(icon.anchor);
            }
            return {
                image : icon.image,
                anchor : anchor
            };
        },

        /**
         * Loads and returns icon information corresponding to the specified
         * resource.
         */
        _getIconInfo : function(resource) {
            var type = this._getResourceType(resource);
            var map = this._map;
            var zoom = map.getZoom();
            var iconIndex = this._iconIndex = this._iconIndex || {};
            var indexKey = zoom + ':' + type;
            var icon = iconIndex[indexKey];
            if (!icon) {
                icon = this._drawIcon(type);
                iconIndex[indexKey] = icon;
            }
            return icon;
        },

        /** Returns the type (as a string) of the specified resource. */
        _getResourceType : function(resource) {
            return 'resource';
        },

        _getOptionValue : function(key) {
            var val = this.options[key];
            if (_.isFunction(val)) {
                var args = _.toArray(arguments);
                args.splice(0, 1);
                val = val.apply(this.options, args);
            }
            return val;
        },

        _getVal : function(key, defaultValue) {
            return this._getOptionValue(key, this._map.getZoom()) || //
            defaultValue;
        },

        _getRadius : function(defaultValue) {
            return this._getVal('radius', 16);
        },

        /**
         * Draws an icon and returns information about it as an object with the
         * following fields: a) 'image' - an Image or a Canvas instance b)
         * 'anchor' a L.Point instance defining the position on the icon
         * corresponding to the resource coordinates
         */
        _drawIcon : function(type) {
            var radius = this._getRadius();
            var canvas = document.createElement('canvas');
            var lineWidth = this._getVal('lineWidth', 1);
            var width = radius * 2;
            var height = radius * 2;
            canvas.height = height;
            canvas.width = width;
            radius -= lineWidth;
            var g = canvas.getContext('2d');
            g.fillStyle = this._getVal('fillColor', 'white');
            g.globalAlpha = this._getVal('fillOpacity', 1);
            g.strokeStyle = this._getVal('lineColor', 'gray');
            g.lineWidth = lineWidth;
            g.lineCap = 'round';
            this._drawMarker(g, lineWidth, lineWidth, width - lineWidth * 2,
                    height - lineWidth * 2, radius * 0.6);
            g.fill();
            g.stroke();
            return {
                image : canvas,
                anchor : L.point(width / 2, height)
            };
        },

        _drawMarker : function(g, x, y, width, height, radius) {
            g.beginPath();
            // a
            g.moveTo(x + width / 2, y);
            // b
            g.bezierCurveTo(//
            x + width / 2 + radius / 2, y, //
            x + width / 2 + radius, y + radius / 2, //
            x + width / 2 + radius, y + radius);
            // c
            g.bezierCurveTo( //
            x + width / 2 + radius, y + radius * 2, //
            x + width / 2, y + height / 2 + radius, //
            x + width / 2, y + height);
            // d
            g.bezierCurveTo(//
            x + width / 2, y + height / 2 + radius, //
            x + width / 2 - radius, y + radius * 2, //
            x + width / 2 - radius, y + radius);
            // e (a)
            g.bezierCurveTo(//
            x + width / 2 - radius, y + radius / 2, //
            x + width / 2 - radius / 2, y + 0, //
            x + width / 2, y + 0);
            g.closePath();
        },

    });

    return MarkersLayer;

});
<|endoftext|>


<commit_before>import CommandAction from "../List/CommandAction.js";
import WordAction from "../List/WordAction.js";
import sleep from "../Util/sleep.js";

async function message({
	slackBot,
	botList,
	pluginList,
	getMessageFormatter,
	postMessageFormatter,
},data){
	// 通常のメッセージ以外は弾く
	if(data.subtype) return;

	// 全てのBotがつぶやくオブジェクトを溜めておく
	const outMsgObjList = [];

	// ユーザー名とチャンネルタグを抽出しながらテキストの処理をする
	const {messageObject:inMsgObj,symbols} = await getMessageFormatter.format(data);

	for(const bot of [...botList]){
		// 無効のbotはスルーする
		if(bot.disabled) continue;

		// commandやwordのActionについてさばいていく
		for(const botAction of [...bot.commandActionList,...bot.wordActionList]){
			// commandActionの時には、replyシンボルに引っかかるワードがあるかを見る
			if((botAction instanceof CommandAction) && (symbols.reply.indexOf(bot.id) === -1)){
				continue;
			}

			// actionsオブジェクトを生成する
			const actions = {};
			for(const name of ["check","message"]){
				actions[name] = botAction[name];
				actions[name] = actions[name].bind(bot,{
					actions,
					param: inMsgObj,
					msgObjList: outMsgObjList,
					symbols,
					botList,
					pluginList,
				});
			}

			// 実行関数にひっかけて、実行する場合はメッセージを登録する
			if(actions.check()){
				// メッセージオブジェクトを取得する
				let outMsgObj = actions.message();
				if(typeof(outMsgObj) !== "object") continue;
				if(typeof(outMsgObj) === null) continue;

				// Promiseの可能性を考慮してIDを付与する
				outMsgObj[bot.messageId] = bot.id;

				outMsgObj = await outMsgObj;

				// 追加する
				outMsgObjList.push(outMsgObj);
			}

			// プラグインへの処理を適用する
			for(const plugin of [...pluginList]){
				for(const pluginAction of [...plugin.commandActionList,...plugin.wordActionList]){
					// botおよびpluginが両方共同じ種類のアクションの時だけ適用する
					if((botAction instanceof CommandAction) && !(pluginAction instanceof CommandAction)) continue;
					if((botAction instanceof WordAction) && !(pluginAction instanceof WordAction)) continue;

					// actionsオブジェクトを生成する
					const actions = {};
					for(const name of ["check","message"]){
						actions[name] = pluginAction[name];
						actions[name] = actions[name].bind(plugin,{
							actions,
							param: inMsgObj,
							msgObjList: outMsgObjList,
							symbols,
							botList,
							pluginList,
							targetBot: bot,
						});
					}

					// 実行関数にひっかけて、実行する場合はメッセージを登録する
					if(actions.check()){
						// メッセージオブジェクトを取得する
						let outMsgObj = actions.message();
						if(typeof(outMsgObj) !== "object") continue;
						if(typeof(outMsgObj) === null) continue;

						// Promiseの可能性を考慮してIDを付与する
						outMsgObj[plugin.messageId] = plugin.id;

						outMsgObj = await outMsgObj;

						// 追加する
						outMsgObjList.push(outMsgObj);
					}
				}
			}
		}
	}

	// 引っかかったメッセージを全て投稿する
	for(let messageObject of outMsgObjList){
		// メッセージオブジェクトはPromiseの可能性もあるので待機する
		let outMsgObj = messageObject;
		outMsgObj = await postMessageFormatter.format(outMsgObj);

		//投稿を行う
		let {channelId,username} = outMsgObj;
		const data = await slackBot.postMessage(channelId,username,outMsgObj);

		console.log("commandActionもしくはwordActionを投稿しました。");
		console.log(data);
	}
}

export default message;<commit_msg>冗長な処理が含まれていたのを修正<commit_after>import CommandAction from "../List/CommandAction.js";
import WordAction from "../List/WordAction.js";
import sleep from "../Util/sleep.js";

async function message({
	slackBot,
	botList,
	pluginList,
	getMessageFormatter,
	postMessageFormatter,
},data){
	// 全てのBotがつぶやくオブジェクトを溜めておく
	const outMsgObjList = [];

	// ユーザー名とチャンネルタグを抽出しながらテキストの処理をする
	const {messageObject:inMsgObj,symbols} = await getMessageFormatter.format(data);

	for(const bot of [...botList]){
		// 無効のbotはスルーする
		if(bot.disabled) continue;

		// commandやwordのActionについてさばいていく
		for(const botAction of [...bot.commandActionList,...bot.wordActionList]){
			// commandActionの時には、replyシンボルに引っかかるワードがあるかを見る
			if((botAction instanceof CommandAction) && (symbols.reply.indexOf(bot.id) === -1)){
				continue;
			}

			// actionsオブジェクトを生成する
			const actions = {};
			for(const name of ["check","message"]){
				actions[name] = botAction[name];
				actions[name] = actions[name].bind(bot,{
					actions,
					param: inMsgObj,
					msgObjList: outMsgObjList,
					symbols,
					botList,
					pluginList,
				});
			}

			// 実行関数にひっかけて、実行する場合はメッセージを登録する
			if(actions.check()){
				// メッセージオブジェクトを取得する
				let outMsgObj = actions.message();
				if(typeof(outMsgObj) !== "object") continue;
				if(typeof(outMsgObj) === null) continue;

				// Promiseの可能性を考慮してIDを付与する
				outMsgObj[bot.messageId] = bot.id;

				outMsgObj = await outMsgObj;

				// 追加する
				outMsgObjList.push(outMsgObj);
			}

			// プラグインへの処理を適用する
			for(const plugin of [...pluginList]){
				for(const pluginAction of [...plugin.commandActionList,...plugin.wordActionList]){
					// botおよびpluginが両方共同じ種類のアクションの時だけ適用する
					if((botAction instanceof CommandAction) && !(pluginAction instanceof CommandAction)) continue;
					if((botAction instanceof WordAction) && !(pluginAction instanceof WordAction)) continue;

					// actionsオブジェクトを生成する
					const actions = {};
					for(const name of ["check","message"]){
						actions[name] = pluginAction[name];
						actions[name] = actions[name].bind(plugin,{
							actions,
							param: inMsgObj,
							msgObjList: outMsgObjList,
							symbols,
							botList,
							pluginList,
							targetBot: bot,
						});
					}

					// 実行関数にひっかけて、実行する場合はメッセージを登録する
					if(actions.check()){
						// メッセージオブジェクトを取得する
						let outMsgObj = actions.message();
						if(typeof(outMsgObj) !== "object") continue;
						if(typeof(outMsgObj) === null) continue;

						// Promiseの可能性を考慮してIDを付与する
						outMsgObj[plugin.messageId] = plugin.id;

						outMsgObj = await outMsgObj;

						// 追加する
						outMsgObjList.push(outMsgObj);
					}
				}
			}
		}
	}

	// 引っかかったメッセージを全て投稿する
	for(let messageObject of outMsgObjList){
		// メッセージオブジェクトはPromiseの可能性もあるので待機する
		let outMsgObj = messageObject;
		outMsgObj = await postMessageFormatter.format(outMsgObj);

		//投稿を行う
		let {channelId,username} = outMsgObj;
		const data = await slackBot.postMessage(channelId,username,outMsgObj);

		console.log("commandActionもしくはwordActionを投稿しました。");
		console.log(data);
	}
}

export default message;<|endoftext|>


<commit_before>module.exports.schema = [
  "float32",
  "boolean",
  "int8",
  "int16",
  [ "bool", [ "int8", ["varint"], "varuint" ], "string" ],
  {
    points: [ "varuint" ],
    name: "string"
  },
  "uint32",
  {
    otherDataTypes: {
      a: "uint8",
      b: "float64",
      c: "int16",
      d: "uint16",
      e: "int32"
    }
  },
  ["uint16", "int8"],
  "int8"
];

module.exports.items = [[
  1225.2347,
  false,
  23,
  5555,
  [ true, [7, [-866, 4453, 5234234, 4543434, 4544666], 1, 100, 10000 ], "hi" ],
  {
    points: [ 3434, 546, 1212, 66 ],
    name: "lilIlilIlilIlilIlilIlil"
  },
  500000000,
  {
    otherDataTypes: {
      a: 55,
      b: -53845.43242342342,
      c: -5300,
      d: 15000,
      e: 2000000
    }
  },
  [ 22, 5, 5, 5 ],
  1,
  2,
  3
]];
<commit_msg>In lieu of using a delta value for float testing<commit_after>module.exports.schema = [
  "float64",
  "boolean",
  "int8",
  "int16",
  [ "bool", [ "int8", ["varint"], "varuint" ], "string" ],
  {
    points: [ "varuint" ],
    name: "string"
  },
  "uint32",
  {
    otherDataTypes: {
      a: "uint8",
      b: "float64",
      c: "int16",
      d: "uint16",
      e: "int32"
    }
  },
  ["uint16", "int8"],
  "int8"
];

module.exports.items = [[
  1225.2347,
  false,
  23,
  5555,
  [ true, [7, [-866, 4453, 5234234, 4543434, 4544666], 1, 100, 10000 ], "hi" ],
  {
    points: [ 3434, 546, 1212, 66 ],
    name: "lilIlilIlilIlilIlilIlil"
  },
  500000000,
  {
    otherDataTypes: {
      a: 55,
      b: -53845.43242342342,
      c: -5300,
      d: 15000,
      e: 2000000
    }
  },
  [ 22, 5, 5, 5 ],
  1,
  2,
  3
]];
<|endoftext|>


<commit_before>goog.provide('xmpptk.muc.Occupant');
goog.provide('xmpptk.muc.Occupant.Affiliation');
goog.provide('xmpptk.muc.Occupant.Role');

goog.require('xmpptk.Model');

/**
 * @constructor
 * @inherits {xmpptk.Model}
 */
xmpptk.muc.Occupant = function(jid) {
    xmpptk.Model.call(this);

};
goog.inherit(xmpptk.muc.Occupant, xmpptk.Model);

/** @enum {string} */
xmpptk.muc.Occupant.Affiliation = {
    OUTCAST: 'outcast',
    NONE: 'none',
    MEMBER: 'member',
    ADMIN: 'admin',
    OWNER: 'owner'
};

/** @enum {string} */
xmpptk.muc.Occupant.Role = {
    NONE: 'none',
    PARTICIPANT: 'participant',
    VISITOR: 'visitor',
    MODERATOR: 'moderator'
};<commit_msg>added properties 'role' and 'affiliation'<commit_after>goog.provide('xmpptk.muc.Occupant');
goog.provide('xmpptk.muc.Occupant.Affiliation');
goog.provide('xmpptk.muc.Occupant.Role');

goog.require('xmpptk.Model');

/**
 * @constructor
 * @inherits {xmpptk.Model}
 */
xmpptk.muc.Occupant = function(jid) {
    xmpptk.Model.call(this);

};
goog.inherit(xmpptk.muc.Occupant, xmpptk.Model);

/** @enum {string} */
xmpptk.muc.Occupant.Affiliation = {
    OUTCAST: 'outcast',
    NONE: 'none',
    MEMBER: 'member',
    ADMIN: 'admin',
    OWNER: 'owner'
};

/** @enum {string} */
xmpptk.muc.Occupant.Role = {
    NONE: 'none',
    PARTICIPANT: 'participant',
    VISITOR: 'visitor',
    MODERATOR: 'moderator'
};

/** @type {xmpptk.muc.Occupant.Affiliation} */
xmpptk.muc.Occupant.prototype.affiliation;

/** @type {xmpptk.muc.Occupant.Role} */
xmpptk.muc.Occupant.prototype.role;<|endoftext|>


<commit_before>/**
 * Created by leoliu1209 on 18/12/11.
 * Contact: cubemail88@gmail.com
 */
import { advanceBy, advanceTo, clear } from 'jest-date-mock';
import Timeago from '../../src';
import zh_TW from '../../src/lang/zh_TW';

Timeago.register('zh_TW', zh_TW);

const timeago = Timeago();
let date = new Date();

beforeEach(() => {
  advanceTo(0);
  date = new Date();
});
afterEach(() => {
  clear();
});
describe('zh_TW', () => {
  test('time ago', () => {
    advanceTo(9 * 1000);
    expect(timeago.format(date, 'zh_TW')).toEqual('剛剛');

    advanceTo(30 * 1000);
    expect(timeago.format(date, 'zh_TW')).toEqual('30 秒前');

    advanceTo(1000 * 60);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 分鐘前');

    advanceTo(1000 * 60 * 30);
    expect(timeago.format(date, 'zh_TW')).toEqual('30 分鐘前');

    advanceTo(1000 * 60 * 60);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 小時前');

    advanceTo(1000 * 60 * 60 * 8);
    expect(timeago.format(date, 'zh_TW')).toEqual('8 小時前');

    advanceTo(1000 * 60 * 60 * 24);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 天前');

    advanceTo(1000 * 60 * 60 * 24 * 3);
    expect(timeago.format(date, 'zh_TW')).toEqual('3 天前');

    advanceTo(1000 * 60 * 60 * 24 * 7);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 週前');

    advanceTo(1000 * 60 * 60 * 24 * 7 * 3);
    expect(timeago.format(date, 'zh_TW')).toEqual('3 週前');

    advanceTo(1000 * 60 * 60 * 24 * 31);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 月前');

    advanceTo(1000 * 60 * 60 * 24 * 31 * 4);
    expect(timeago.format(date, 'zh_TW')).toEqual('4 月前');

    advanceTo(1000 * 60 * 60 * 24 * 366);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 年前');

    advanceTo(1000 * 60 * 60 * 24 * 366 * 10);
    expect(timeago.format(date, 'zh_TW')).toEqual('10 年前');
  });
  test('time in', () => {
    advanceTo(-9 * 1000);
    expect(timeago.format(date, 'zh_TW')).toEqual('片刻後');

    advanceTo(-30 * 1000);
    expect(timeago.format(date, 'zh_TW')).toEqual('30 秒後');

    advanceTo(-1000 * 60);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 分鐘後');

    advanceTo(-1000 * 60 * 30);
    expect(timeago.format(date, 'zh_TW')).toEqual('30 分鐘後');

    advanceTo(-1000 * 60 * 60);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 小時後');

    advanceTo(-1000 * 60 * 60 * 8);
    expect(timeago.format(date, 'zh_TW')).toEqual('8 小時後');

    advanceTo(-1000 * 60 * 60 * 24);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 天後');

    advanceTo(-1000 * 60 * 60 * 24 * 3);
    expect(timeago.format(date, 'zh_TW')).toEqual('3 天後');

    advanceTo(-1000 * 60 * 60 * 24 * 7);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 週後');

    advanceTo(-1000 * 60 * 60 * 24 * 7 * 3);
    expect(timeago.format(date, 'zh_TW')).toEqual('3 週後');

    advanceTo(-1000 * 60 * 60 * 24 * 31);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 月後');

    advanceTo(-1000 * 60 * 60 * 24 * 31 * 4);
    expect(timeago.format(date, 'zh_TW')).toEqual('4 月後');

    advanceTo(-1000 * 60 * 60 * 24 * 366);
    expect(timeago.format(date, 'zh_TW')).toEqual('1 年後');

    advanceTo(-1000 * 60 * 60 * 24 * 366 * 10);
    expect(timeago.format(date, 'zh_TW')).toEqual('10 年後');
  });
});
<commit_msg>update zh_TW.spec<commit_after>/**
 * Created by leoliu1209 on 18/12/11.
 * Contact: cubemail88@gmail.com
 */
import { advanceBy, advanceTo, clear } from 'jest-date-mock';
import { register, format } from '../../src';
import zh_TW from '../../src/lang/zh_TW';

register('zh_TW', zh_TW);

let date = new Date();

beforeEach(() => {
  advanceTo(0);
  date = new Date();
});
afterEach(() => {
  clear();
});
describe('zh_TW', () => {
  test('time ago', () => {
    advanceTo(9 * 1000);
    expect(format(date, 'zh_TW')).toEqual('剛剛');

    advanceTo(30 * 1000);
    expect(format(date, 'zh_TW')).toEqual('30 秒前');

    advanceTo(1000 * 60);
    expect(format(date, 'zh_TW')).toEqual('1 分鐘前');

    advanceTo(1000 * 60 * 30);
    expect(format(date, 'zh_TW')).toEqual('30 分鐘前');

    advanceTo(1000 * 60 * 60);
    expect(format(date, 'zh_TW')).toEqual('1 小時前');

    advanceTo(1000 * 60 * 60 * 8);
    expect(format(date, 'zh_TW')).toEqual('8 小時前');

    advanceTo(1000 * 60 * 60 * 24);
    expect(format(date, 'zh_TW')).toEqual('1 天前');

    advanceTo(1000 * 60 * 60 * 24 * 3);
    expect(format(date, 'zh_TW')).toEqual('3 天前');

    advanceTo(1000 * 60 * 60 * 24 * 7);
    expect(format(date, 'zh_TW')).toEqual('1 週前');

    advanceTo(1000 * 60 * 60 * 24 * 7 * 3);
    expect(format(date, 'zh_TW')).toEqual('3 週前');

    advanceTo(1000 * 60 * 60 * 24 * 31);
    expect(format(date, 'zh_TW')).toEqual('1 月前');

    advanceTo(1000 * 60 * 60 * 24 * 31 * 4);
    expect(format(date, 'zh_TW')).toEqual('4 月前');

    advanceTo(1000 * 60 * 60 * 24 * 366);
    expect(format(date, 'zh_TW')).toEqual('1 年前');

    advanceTo(1000 * 60 * 60 * 24 * 366 * 10);
    expect(format(date, 'zh_TW')).toEqual('10 年前');
  });
  test('time in', () => {
    advanceTo(-9 * 1000);
    expect(format(date, 'zh_TW')).toEqual('片刻後');

    advanceTo(-30 * 1000);
    expect(format(date, 'zh_TW')).toEqual('30 秒後');

    advanceTo(-1000 * 60);
    expect(format(date, 'zh_TW')).toEqual('1 分鐘後');

    advanceTo(-1000 * 60 * 30);
    expect(format(date, 'zh_TW')).toEqual('30 分鐘後');

    advanceTo(-1000 * 60 * 60);
    expect(format(date, 'zh_TW')).toEqual('1 小時後');

    advanceTo(-1000 * 60 * 60 * 8);
    expect(format(date, 'zh_TW')).toEqual('8 小時後');

    advanceTo(-1000 * 60 * 60 * 24);
    expect(format(date, 'zh_TW')).toEqual('1 天後');

    advanceTo(-1000 * 60 * 60 * 24 * 3);
    expect(format(date, 'zh_TW')).toEqual('3 天後');

    advanceTo(-1000 * 60 * 60 * 24 * 7);
    expect(format(date, 'zh_TW')).toEqual('1 週後');

    advanceTo(-1000 * 60 * 60 * 24 * 7 * 3);
    expect(format(date, 'zh_TW')).toEqual('3 週後');

    advanceTo(-1000 * 60 * 60 * 24 * 31);
    expect(format(date, 'zh_TW')).toEqual('1 月後');

    advanceTo(-1000 * 60 * 60 * 24 * 31 * 4);
    expect(format(date, 'zh_TW')).toEqual('4 月後');

    advanceTo(-1000 * 60 * 60 * 24 * 366);
    expect(format(date, 'zh_TW')).toEqual('1 年後');

    advanceTo(-1000 * 60 * 60 * 24 * 366 * 10);
    expect(format(date, 'zh_TW')).toEqual('10 年後');
  });
});
<|endoftext|>


<commit_before>function getBaseName(fileName)
{
	if(fileName == null) return null;
	var separator = "/";
	if(fileName.indexOf("\\") != -1) separator = "\\";
	baseName = fileName.substr(fileName.lastIndexOf(separator)+1, fileName.length);
	return baseName;
}

function getRepName(fileName)
{
	repName = fileName.substr(0, fileName.lastIndexOf("/"));
	return repName;
}

var messageDivOpen = false;
function closeMessageDiv()
{
	if(messageDivOpen)
	{
		new Effect.BlindUp('message_div');
		messageDivOpen = false;
	}
}

function tempoMessageDivClosing()
{
	messageDivOpen = true;
	setTimeout('closeMessageDiv()', 10000);
}

function disableTextSelection(target)
{
	if (typeof target.onselectstart!="undefined")
	{ //IE route
		target.onselectstart=function(){return false;}
	}
	else if (typeof target.style.MozUserSelect!="undefined")
	{ //Firefox route
		var defaultValue = target.style.MozUserSelect;
		target.style.MozUserSelect="none";
	}
	if($(target).getElementsBySelector('input[type="text"]').length)
	{
		$(target).getElementsBySelector('input[type="text"]').each(function(element)
		{
			if (typeof element.onselectstart!="undefined")
			{ //IE route
				element.onselectstart=function(){return true;}
			}
			else if (typeof element.style.MozUserSelect!="undefined")
			{ //Firefox route
				element.style.MozUserSelect=defaultValue;
			}
		});
	}
}<commit_msg>new functions editWithCodePress and fitHeightToBottom<commit_after>function getBaseName(fileName)
{
	if(fileName == null) return null;
	var separator = "/";
	if(fileName.indexOf("\\") != -1) separator = "\\";
	baseName = fileName.substr(fileName.lastIndexOf(separator)+1, fileName.length);
	return baseName;
}

function getRepName(fileName)
{
	repName = fileName.substr(0, fileName.lastIndexOf("/"));
	return repName;
}

function editWithCodePress(fileName)
{
	if(fileName.search('\.php$|\.php3$|\.php5$|\.phtml$') > -1) return "php";
	else if (fileName.search("\.js$") > -1) return "javascript";
	else if (fileName.search("\.java$") > -1) return "java";
	else if (fileName.search("\.pl$") > -1) return "perl";
	else if (fileName.search("\.sql$") > -1) return "sql";
	else if (fileName.search("\.htm$|\.html$") > -1) return "html";
	else if (fileName.search("\.css$") > -1) return "css";
	else return "";
}

var messageDivOpen = false;
function closeMessageDiv()
{
	if(messageDivOpen)
	{
		new Effect.BlindUp('message_div');
		messageDivOpen = false;
	}
}

function tempoMessageDivClosing()
{
	messageDivOpen = true;
	setTimeout('closeMessageDiv()', 10000);
}

function disableTextSelection(target)
{
	if (typeof target.onselectstart!="undefined")
	{ //IE route
		target.onselectstart=function(){return false;}
	}
	else if (typeof target.style.MozUserSelect!="undefined")
	{ //Firefox route
		var defaultValue = target.style.MozUserSelect;
		target.style.MozUserSelect="none";
	}
	if($(target).getElementsBySelector('input[type="text"]').length)
	{
		$(target).getElementsBySelector('input[type="text"]').each(function(element)
		{
			if (typeof element.onselectstart!="undefined")
			{ //IE route
				element.onselectstart=function(){return true;}
			}
			else if (typeof element.style.MozUserSelect!="undefined")
			{ //Firefox route
				element.style.MozUserSelect=defaultValue;
			}
		});
	}
}

function fitHeightToBottom(element, parentElement, addMarginBottom, skipListener)
{
	if(typeof(parentElement) == "undefined" || parentElement == null){
		parentElement = Position.offsetParent($(element));
	}
	if(typeof(addMarginBottom) == "undefined" || addMarginBottom == null){
		addMarginBottom = 0;
	}
	if(!skipListener){
		jQuery(parentElement).bind("resize", function(){
			try{
			var $ms = jQuery(element);
			var top = parseInt($ms.offset().top); // from dimensions.js
			if(parentElement != window){
				var parentTop = jQuery(parentElement).offset().top;
				top = top - parentTop;
			}
			//if(jQuery(parentElement).height) return;
			var wTmp = jQuery(parentElement).height();
			var wh = parseInt(jQuery(parentElement).height());
			// Account for margin or border on the splitter container
			var mrg = parseInt($ms.css("marginBottom")) || 0;
			var brd = parseInt($ms.css("borderBottomWidth")) || 0;
			$ms.css("height", (wh-top-mrg-brd-addMarginBottom)+"px");
			//if ( !jQuery.browser.msie )
			$ms.trigger("resize");
			}catch(e){}
		}).trigger("resize");
	}
	else{
		jQuery(parentElement).trigger("resize");
	}
	jQuery(element).trigger("resize");
}<|endoftext|>


<commit_before>/*global URL:false,Blob:false*/
import React, { Component } from 'react';
import { hterm, lib as htermLib } from 'hterm-umd';

hterm.defaultStorage = new htermLib.Storage.Memory();

// override double click behavior to copy
const oldMouse = hterm.Terminal.prototype.onMouse_;
hterm.Terminal.prototype.onMouse_ = function (e) {
  if ('dblclick' === e.type) {
    console.log('[hyperterm+hterm] ignore double click');
    return;
  }
  return oldMouse.call(this, e);
};

// there's no option to turn off the size overlay
hterm.Terminal.prototype.overlaySize = function () {};

// fixing a bug in hterm where a double click triggers
// a non-collapsed selection whose text is '', and results
// in an infinite copy loop
hterm.Terminal.prototype.copySelectionToClipboard = function () {
  var text = this.getSelectionText();
  if (text != null && text !== '') {
    this.copyStringToClipboard(text);
  }
};

// passthrough all the commands that are meant to control
// hyperterm and not the terminal itself
const oldKeyDown = hterm.Keyboard.prototype.onKeyDown_;
hterm.Keyboard.prototype.onKeyDown_ = function (e) {
  if (e.metaKey) {
    return;
  }
  return oldKeyDown.call(this, e);
};

const oldKeyPress = hterm.Keyboard.prototype.onKeyPress_;
hterm.Keyboard.prototype.onKeyPress_ = function (e) {
  if (e.metaKey) {
    return;
  }
  return oldKeyPress.call(this, e);
};

const domainRegex = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/;

export default class Term extends Component {

  componentDidMount () {
    this.term = new hterm.Terminal();

    // the first term that's created has unknown size
    // subsequent new tabs have size
    if (this.props.cols) {
      this.term.realizeSize_(this.props.cols, this.props.rows);
    }

    this.term.prefs_.set('font-family', 'Menlo');
    this.term.prefs_.set('font-size', 11);
    this.term.prefs_.set('cursor-color', '#F81CE5');
    this.term.prefs_.set('enable-clipboard-notice', false);
    this.term.prefs_.set('background-color', '#000');

    this.term.prefs_.set('user-css', URL.createObjectURL(new Blob([`
      .cursor-node[focus="false"] {
        border-width: 1px !important;
      }
    `]), { type: 'text/css' }));

    this.term.onTerminalReady = () => {
      const io = this.term.io.push();
      io.onVTKeystroke = io.sendString = (str) => {
        this.props.onData(str);
      };
      io.onTerminalResize = (cols, rows) => {
        this.props.onResize({ cols, rows });
      };
    };
    this.term.decorate(this.refs.term);
    this.term.installKeyboard();
  }

  getTermDocument () {
    return this.term.document_;
  }

  shouldComponentUpdate (nextProps) {
    if (this.props.url !== nextProps.url) {
      // when the url prop changes, we make sure
      // the terminal starts or stops ignoring
      // key input so that it doesn't conflict
      // with the <webview>
      if (nextProps.url) {
        const io = this.term.io.push();
        io.onVTKeystroke = io.sendString = (str) => {
          if (1 === str.length && 3 === str.charCodeAt(0) /* Ctrl + C */) {
            this.props.onURLAbort();
          }
        };
      } else {
        this.term.io.pop();
      }
      return true;
    }

    return false;
  }

  write (data) {
    const match = data.match(/bash: ((https?:\/\/)|(\/\/))?(.*): ((command not found)|(No such file or directory))/);
    if (match) {
      const url = match[4];
      // extract the domain portion from the url
      const domain = url.split('/')[0];
      if (domainRegex.test(domain)) {
        this.props.onURL(toURL(url));
        return;
      }
    }
    this.term.io.print(data);
  }

  focus () {
    this.term.focus();
  }

  clear () {
    const { term } = this;

    // we re-implement `wipeContents` to preserve the line
    // and cursor position that the client is in.
    // otherwise the user ends up with a completely clear
    // screen which is really strange
    term.scrollbackRows_.length = 0;
    term.scrollPort_.resetCache();

    [term.primaryScreen_, term.alternateScreen_].forEach(function (screen) {
      const bottom = screen.getHeight();
      if (bottom > 0) {
        term.renumberRows_(0, bottom);

        const x = screen.cursorPosition.column;
        const y = screen.cursorPosition.row;

        if (x === 0) {
          // Empty screen, nothing to do.
          return;
        }

        // here we move the row that the user was focused on
        // to the top of the screen
        term.moveRows_(y, 1, 0);

        for (let i = 1; i < bottom; i++) {
          screen.setCursorPosition(i, 0);
          screen.clearCursorRow();
        }

        // we restore the cursor position
        screen.setCursorPosition(0, x);
      }
    });

    term.syncCursorPosition_();
    term.scrollPort_.invalidate();

    // this will avoid a bug where the `wipeContents`
    // hterm API doens't send the scroll to the top
    this.term.scrollPort_.redraw_();
  }

  componentWillUnmount () {
    // there's no need to manually destroy
    // as all the events are attached to the iframe
    // which gets removed
  }

  render () {
    return

      { this.props.url
        ? <webview
            src={this.props.url}
            style={{
              background: '#000',
              position: 'absolute',
              top: 0,
              left: 0,
              display: 'inline-flex',
              width: '100%',
              height: '100%'
            }}></webview>
        : null
      }

;
  }

}

function toURL (domain) {
  if (/^https?:\/\//.test(domain)) {
    return domain;
  }

  if ('//' === domain.substr(0, 2)) {
    return domain;
  }

  return 'http://' + domain;
}
<commit_msg>term: hide them scrolbars (#42)<commit_after>/*global URL:false,Blob:false*/
import React, { Component } from 'react';
import { hterm, lib as htermLib } from 'hterm-umd';

hterm.defaultStorage = new htermLib.Storage.Memory();

// override double click behavior to copy
const oldMouse = hterm.Terminal.prototype.onMouse_;
hterm.Terminal.prototype.onMouse_ = function (e) {
  if ('dblclick' === e.type) {
    console.log('[hyperterm+hterm] ignore double click');
    return;
  }
  return oldMouse.call(this, e);
};

// there's no option to turn off the size overlay
hterm.Terminal.prototype.overlaySize = function () {};

// fixing a bug in hterm where a double click triggers
// a non-collapsed selection whose text is '', and results
// in an infinite copy loop
hterm.Terminal.prototype.copySelectionToClipboard = function () {
  var text = this.getSelectionText();
  if (text != null && text !== '') {
    this.copyStringToClipboard(text);
  }
};

// passthrough all the commands that are meant to control
// hyperterm and not the terminal itself
const oldKeyDown = hterm.Keyboard.prototype.onKeyDown_;
hterm.Keyboard.prototype.onKeyDown_ = function (e) {
  if (e.metaKey) {
    return;
  }
  return oldKeyDown.call(this, e);
};

const oldKeyPress = hterm.Keyboard.prototype.onKeyPress_;
hterm.Keyboard.prototype.onKeyPress_ = function (e) {
  if (e.metaKey) {
    return;
  }
  return oldKeyPress.call(this, e);
};

const domainRegex = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/;

export default class Term extends Component {

  componentDidMount () {
    this.term = new hterm.Terminal();

    // the first term that's created has unknown size
    // subsequent new tabs have size
    if (this.props.cols) {
      this.term.realizeSize_(this.props.cols, this.props.rows);
    }

    this.term.prefs_.set('font-family', 'Menlo');
    this.term.prefs_.set('font-size', 11);
    this.term.prefs_.set('cursor-color', '#F81CE5');
    this.term.prefs_.set('enable-clipboard-notice', false);
    this.term.prefs_.set('background-color', '#000');
    this.term.prefs_.set('scrollbar-visible', false);

    this.term.prefs_.set('user-css', URL.createObjectURL(new Blob([`
      .cursor-node[focus="false"] {
        border-width: 1px !important;
      }
    `]), { type: 'text/css' }));

    this.term.onTerminalReady = () => {
      const io = this.term.io.push();
      io.onVTKeystroke = io.sendString = (str) => {
        this.props.onData(str);
      };
      io.onTerminalResize = (cols, rows) => {
        this.props.onResize({ cols, rows });
      };
    };
    this.term.decorate(this.refs.term);
    this.term.installKeyboard();
  }

  getTermDocument () {
    return this.term.document_;
  }

  shouldComponentUpdate (nextProps) {
    if (this.props.url !== nextProps.url) {
      // when the url prop changes, we make sure
      // the terminal starts or stops ignoring
      // key input so that it doesn't conflict
      // with the <webview>
      if (nextProps.url) {
        const io = this.term.io.push();
        io.onVTKeystroke = io.sendString = (str) => {
          if (1 === str.length && 3 === str.charCodeAt(0) /* Ctrl + C */) {
            this.props.onURLAbort();
          }
        };
      } else {
        this.term.io.pop();
      }
      return true;
    }

    return false;
  }

  write (data) {
    const match = data.match(/bash: ((https?:\/\/)|(\/\/))?(.*): ((command not found)|(No such file or directory))/);
    if (match) {
      const url = match[4];
      // extract the domain portion from the url
      const domain = url.split('/')[0];
      if (domainRegex.test(domain)) {
        this.props.onURL(toURL(url));
        return;
      }
    }
    this.term.io.print(data);
  }

  focus () {
    this.term.focus();
  }

  clear () {
    const { term } = this;

    // we re-implement `wipeContents` to preserve the line
    // and cursor position that the client is in.
    // otherwise the user ends up with a completely clear
    // screen which is really strange
    term.scrollbackRows_.length = 0;
    term.scrollPort_.resetCache();

    [term.primaryScreen_, term.alternateScreen_].forEach(function (screen) {
      const bottom = screen.getHeight();
      if (bottom > 0) {
        term.renumberRows_(0, bottom);

        const x = screen.cursorPosition.column;
        const y = screen.cursorPosition.row;

        if (x === 0) {
          // Empty screen, nothing to do.
          return;
        }

        // here we move the row that the user was focused on
        // to the top of the screen
        term.moveRows_(y, 1, 0);

        for (let i = 1; i < bottom; i++) {
          screen.setCursorPosition(i, 0);
          screen.clearCursorRow();
        }

        // we restore the cursor position
        screen.setCursorPosition(0, x);
      }
    });

    term.syncCursorPosition_();
    term.scrollPort_.invalidate();

    // this will avoid a bug where the `wipeContents`
    // hterm API doens't send the scroll to the top
    this.term.scrollPort_.redraw_();
  }

  componentWillUnmount () {
    // there's no need to manually destroy
    // as all the events are attached to the iframe
    // which gets removed
  }

  render () {
    return

      { this.props.url
        ? <webview
            src={this.props.url}
            style={{
              background: '#000',
              position: 'absolute',
              top: 0,
              left: 0,
              display: 'inline-flex',
              width: '100%',
              height: '100%'
            }}></webview>
        : null
      }

;
  }

}

function toURL (domain) {
  if (/^https?:\/\//.test(domain)) {
    return domain;
  }

  if ('//' === domain.substr(0, 2)) {
    return domain;
  }

  return 'http://' + domain;
}
<|endoftext|>


<commit_before>const should = require('should');
const supertest = require('supertest');
const _ = require('lodash');
const ObjectId = require('bson-objectid');
const moment = require('moment-timezone');
const testUtils = require('../../../utils');
const localUtils = require('./utils');
const config = require('../../../../server/config');
const models = require('../../../../server/models');
const ghost = testUtils.startGhost;
let request;

describe('Pages API', function () {
    let ghostServer;
    let ownerCookie;

    before(function () {
        return ghost()
            .then(function (_ghostServer) {
                ghostServer = _ghostServer;
                request = supertest.agent(config.get('url'));
            })
            .then(function () {
                return localUtils.doAuth(request, 'users:extra', 'posts');
            })
            .then(function (cookie) {
                ownerCookie = cookie;
            });
    });

    it('Can retrieve all pages', function (done) {
        request.get(localUtils.API.getApiQuery('pages/'))
            .set('Origin', config.get('url'))
            .expect('Content-Type', /json/)
            .expect('Cache-Control', testUtils.cacheRules.private)
            .expect(200)
            .end(function (err, res) {
                if (err) {
                    return done(err);
                }

                should.not.exist(res.headers['x-cache-invalidate']);
                const jsonResponse = res.body;
                should.exist(jsonResponse.pages);
                localUtils.API.checkResponse(jsonResponse, 'pages');
                jsonResponse.pages.should.have.length(2);

                localUtils.API.checkResponse(jsonResponse.pages[0], 'page');
                localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
                _.isBoolean(jsonResponse.pages[0].featured).should.eql(true);

                // Absolute urls by default
                jsonResponse.pages[0].url.should.eql(`${config.get('url')}/404/`);
                jsonResponse.pages[1].url.should.eql(`${config.get('url')}/static-page-test/`);

                done();
            });
    });

    it('Can add a page', function () {
        const page = {
            title: 'My Page',
            page: false,
            status: 'published'
        };

        return request.post(localUtils.API.getApiQuery('pages/'))
            .set('Origin', config.get('url'))
            .send({pages: [page]})
            .expect('Content-Type', /json/)
            .expect('Cache-Control', testUtils.cacheRules.private)
            .expect(201)
            .then((res) => {
                res.body.pages.length.should.eql(1);

                // @NOTE: we do not return "excerpt" if custom_excerpt or plaintext is empty
                // @NOTE: we do not return primary_* if null
                localUtils.API.checkResponse(res.body.pages[0], 'page', null, ['excerpt']);
                should.exist(res.headers['x-cache-invalidate']);

                return models.Post.findOne({
                    id: res.body.pages[0].id
                }, testUtils.context.internal);
            })
            .then((model) => {
                model.get('title').should.eql(page.title);
                model.get('status').should.eql(page.status);
                model.get('page').should.eql(true);
            });
    });

    it('Can update a page', function () {
        const page = {
            title: 'updated page',
            page: false
        };

        return request
            .get(localUtils.API.getApiQuery(`pages/${testUtils.DataGenerator.Content.posts[5].id}/`))
            .set('Origin', config.get('url'))
            .expect(200)
            .then((res) => {
                page.updated_at = res.body.pages[0].updated_at;

                return request.put(localUtils.API.getApiQuery('pages/' + testUtils.DataGenerator.Content.posts[5].id))
                    .set('Origin', config.get('url'))
                    .send({pages: [page]})
                    .expect('Content-Type', /json/)
                    .expect('Cache-Control', testUtils.cacheRules.private)
                    .expect(200);
            })
            .then((res) => {
                should.exist(res.headers['x-cache-invalidate']);
                localUtils.API.checkResponse(res.body.pages[0], 'page');

                return models.Post.findOne({
                    id: res.body.pages[0].id
                }, testUtils.context.internal);
            })
            .then((model) => {
                model.get('page').should.eql(true);
            });
    });

    it('Cannot get page via posts endpoint', function () {
        return request.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[5].id}/`))
            .set('Origin', config.get('url'))
            .expect('Content-Type', /json/)
            .expect('Cache-Control', testUtils.cacheRules.private)
            .expect(404);
    });

    it('Cannot update page via posts endpoint', function () {
        const page = {
            title: 'fails',
            updated_at: new Date().toISOString()
        };

        return request.put(localUtils.API.getApiQuery('posts/' + testUtils.DataGenerator.Content.posts[5].id))
            .set('Origin', config.get('url'))
            .send({posts: [page]})
            .expect('Content-Type', /json/)
            .expect('Cache-Control', testUtils.cacheRules.private)
            .expect(404);
    });

    it('Can delete a page', function () {
        return request.del(localUtils.API.getApiQuery('pages/' + testUtils.DataGenerator.Content.posts[5].id))
            .set('Origin', config.get('url'))
            .expect('Cache-Control', testUtils.cacheRules.private)
            .expect(204)
            .then((res) => {
                res.body.should.be.empty();
                res.headers['x-cache-invalidate'].should.eql('/*');
            });
    });
});
<commit_msg>Fixed pages acceptance test<commit_after>const should = require('should');
const supertest = require('supertest');
const _ = require('lodash');
const ObjectId = require('bson-objectid');
const moment = require('moment-timezone');
const testUtils = require('../../../utils');
const localUtils = require('./utils');
const config = require('../../../../server/config');
const models = require('../../../../server/models');
const ghost = testUtils.startGhost;
let request;

describe('Pages API', function () {
    let ghostServer;
    let ownerCookie;

    before(function () {
        return ghost()
            .then(function (_ghostServer) {
                ghostServer = _ghostServer;
                request = supertest.agent(config.get('url'));
            })
            .then(function () {
                return localUtils.doAuth(request, 'users:extra', 'posts');
            })
            .then(function (cookie) {
                ownerCookie = cookie;
            });
    });

    it('Can retrieve all pages', function (done) {
        request.get(localUtils.API.getApiQuery('pages/'))
            .set('Origin', config.get('url'))
            .expect('Content-Type', /json/)
            .expect('Cache-Control', testUtils.cacheRules.private)
            .expect(200)
            .end(function (err, res) {
                if (err) {
                    return done(err);
                }

                should.not.exist(res.headers['x-cache-invalidate']);
                const jsonResponse = res.body;
                should.exist(jsonResponse.pages);
                localUtils.API.checkResponse(jsonResponse, 'pages');
                jsonResponse.pages.should.have.length(2);

                localUtils.API.checkResponse(jsonResponse.pages[0], 'page');
                localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
                _.isBoolean(jsonResponse.pages[0].featured).should.eql(true);

                // Absolute urls by default
                jsonResponse.pages[0].url.should.eql(`${config.get('url')}/404/`);
                jsonResponse.pages[1].url.should.eql(`${config.get('url')}/static-page-test/`);

                done();
            });
    });

    it('Can add a page', function () {
        const page = {
            title: 'My Page',
            page: false,
            status: 'published'
        };

        return request.post(localUtils.API.getApiQuery('pages/'))
            .set('Origin', config.get('url'))
            .send({pages: [page]})
            .expect('Content-Type', /json/)
            .expect('Cache-Control', testUtils.cacheRules.private)
            .expect(201)
            .then((res) => {
                res.body.pages.length.should.eql(1);

                localUtils.API.checkResponse(res.body.pages[0], 'page');
                should.exist(res.headers['x-cache-invalidate']);

                return models.Post.findOne({
                    id: res.body.pages[0].id
                }, testUtils.context.internal);
            })
            .then((model) => {
                model.get('title').should.eql(page.title);
                model.get('status').should.eql(page.status);
                model.get('page').should.eql(true);
            });
    });

    it('Can update a page', function () {
        const page = {
            title: 'updated page',
            page: false
        };

        return request
            .get(localUtils.API.getApiQuery(`pages/${testUtils.DataGenerator.Content.posts[5].id}/`))
            .set('Origin', config.get('url'))
            .expect(200)
            .then((res) => {
                page.updated_at = res.body.pages[0].updated_at;

                return request.put(localUtils.API.getApiQuery('pages/' + testUtils.DataGenerator.Content.posts[5].id))
                    .set('Origin', config.get('url'))
                    .send({pages: [page]})
                    .expect('Content-Type', /json/)
                    .expect('Cache-Control', testUtils.cacheRules.private)
                    .expect(200);
            })
            .then((res) => {
                should.exist(res.headers['x-cache-invalidate']);
                localUtils.API.checkResponse(res.body.pages[0], 'page');

                return models.Post.findOne({
                    id: res.body.pages[0].id
                }, testUtils.context.internal);
            })
            .then((model) => {
                model.get('page').should.eql(true);
            });
    });

    it('Cannot get page via posts endpoint', function () {
        return request.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[5].id}/`))
            .set('Origin', config.get('url'))
            .expect('Content-Type', /json/)
            .expect('Cache-Control', testUtils.cacheRules.private)
            .expect(404);
    });

    it('Cannot update page via posts endpoint', function () {
        const page = {
            title: 'fails',
            updated_at: new Date().toISOString()
        };

        return request.put(localUtils.API.getApiQuery('posts/' + testUtils.DataGenerator.Content.posts[5].id))
            .set('Origin', config.get('url'))
            .send({posts: [page]})
            .expect('Content-Type', /json/)
            .expect('Cache-Control', testUtils.cacheRules.private)
            .expect(404);
    });

    it('Can delete a page', function () {
        return request.del(localUtils.API.getApiQuery('pages/' + testUtils.DataGenerator.Content.posts[5].id))
            .set('Origin', config.get('url'))
            .expect('Cache-Control', testUtils.cacheRules.private)
            .expect(204)
            .then((res) => {
                res.body.should.be.empty();
                res.headers['x-cache-invalidate'].should.eql('/*');
            });
    });
});
<|endoftext|>


<commit_before>"use strict";
var DigitalOceanApi = require('doapi');
var fs = require('fs');
var node_ssh = require('node-ssh')
var inquirer = require('inquirer');

var readable = require('stream').Readable

var client;
var sshKey;
var ssh = new node_ssh()

var configurations = {};
var prompt = inquirer.createPromptModule();
var promptQuestions = [
    {
        type: 'input',
        name: 'do_api_token',
        message: 'Digital Ocean token:'
    }, {
        type: 'input',
        name: 'ssh_key_location',
        message: 'Name of SSH key in ~/.ssh/ to connect to Streisand droplet:'
    }
]
var sequestOpts = {
    privateKey: sshKey,
    readyTimeout: 20000
};
var time = new Date();
var targetRecord;

//gather required info from user
function getSessionInfo() {
    var sessionInfo = {
        do_api_token: null,
        ssh_key_location: null
    }

    return prompt(promptQuestions).then(answers => {
        sessionInfo.do_api_token = answers.do_api_token
        sessionInfo.ssh_key_location = answers.ssh_key_location
        sshKey = process.env.HOME + '/.ssh/' + sessionInfo.ssh_key_location
        client = new DigitalOceanApi({token: sessionInfo.do_api_token});
        console.log(sessionInfo)
        return sessionInfo;
    }).catch(error => console.log(error))
}

//find the latest instance of streisand from Digital Ocean and store it.
function getCurrentServer(sessionInfo) {
    return client.dropletGetAll().then(droplets => {
        return droplets.filter(el => {
            if (el.name.search('streisand-') !== -1) {
                return el.name;
            }
        });
    }).then(droplet => {
        sessionInfo.old_server = droplet[0];
        console.log('The current server is: ' + sessionInfo.old_server.name +
          " " + sessionInfo.old_server.networks.v4[0].ip_address)
        return sessionInfo
    }).catch(error => console.error(error))
}

//using the return from getCurrentServer, start a new droplet using the snapshot of the old server.
function startNewServer(sessionInfo) {
    var newServerDetails = {
        "name": "streisand-" + (time.getMonth() + 1) + "-" + time.getDate() +
          "-" + time.getHours() + "." + time.getMinutes(),
        "region": "sfo2",
        //"region": oldServer.oldserver.region.slug,
        "size": "512mb",
        "image": sessionInfo.old_server.snapshot_ids[0],
        "ssh_keys": [1278744]
    };

    return client.dropletNew(newServerDetails).then(newDroplet => {
        newServerDetails = newDroplet;
        var numAttempts = 0;

        function getIP() {

            return client.dropletGet(newServerDetails.id).then(startingDroplet => {
                numAttempts++
                console.log("Find IP attempt # ", numAttempts);

                if (startingDroplet.networks.v4[0].ip_address != undefined) {
                    newServerDetails = startingDroplet;
                    console.log("newServer updated with IPv4 address: ",
                      startingDroplet.networks.v4[0].ip_address);
                    return newServerDetails;

                } else {
                    if (numAttempts > 15) {
                        console.log("failed to reach server after " + numAttempts
                          + " attempts");
                    } else {
                        return getIP();
                    }
                }
            }).then(server => {
                sessionInfo.new_server = server
                console.log(sessionInfo.new_server.name + " " +
                  sessionInfo.new_server.networks.v4[0].ip_address)
                return sessionInfo
            })
        }
        return getIP();
    }).catch(error => console.log(error))
}

function checkConnection(sessionInfo){
  var attempts = 25
  console.log('Attempting to connect to server ' + sessionInfo.new_server.name + '. . . ');
  console.log('Attempt: #1');
  function connect(attempt) {
    ssh.connect({
      host: sessionInfo.new_server.networks.v4[0].ip_address,
      username: 'root',
      privateKey: sshKey
    }).then( results => {
      return ssh.execCommand('uptime')
    }, rejection => {
      attempts--
      console.error('failed, ' + attempts +  ' attempts left . . .');
      if (attempts > 0) {
      connect(attempts);
    }
    }).then(results => {
      console.log('STDOUT: ' + results.stdout)
      console.log('STDERR: ' + results.stderr)
    }).catch(error => console.error(error))
  }
  connect(attempts)
}

//copy Shadowsocks config from old server onto new server
function getShadowsocks() {
  return ssh.connect({
      //host: sessionInfo.new_server.networks.v4[0].ip_address,
      host: '138.197.193.189',
      username: 'root',
      privateKey: process.env.HOME + '/.ssh/do.priv'
    }).then( () => {
      return ssh.getFile('/etc/shadowsocks-libev/config.json', process.env.HOME + '/config.json.transfered')
    }).then( () => {
      return console.log("The File's contents were successfully downloaded")
    }).then( () => {
      fs.readFile('/etc/passwd', (error, data) => {
        if (error) throw error
        console.log(data)
        sessionInfo.configurations.shadowsocks.server = newServer.networks.v4[0].ip_address
      })
    }).then( () => {
      return ssh.putfile('/path/to/local/file.json', '/path/to/remote/file.json')
    }).catch(error =>{
      console.error('there is a problem', error)
    })
}
getSessionInfo().then(getCurrentServer).then(startNewServer).then(checkConnection)

--------------------------------------------------------------------------------

  function updateShadowsocks() {
    console.log("updateShadowsocks callback started.");
    configurations.shadowsocks.server = newServer.networks.v4[0].ip_address;
    //this is a real hack that requires success, rework.
    updateConfig(serviceRestart);
  };

  function updateConfig(callback) {
    var configReadable = new readable;
    var writer = sequest.put('root@' + newServer.networks.v4[0].ip_address,
    '/etc/shadowsocks-libev/config.json', {
      mode: '0640',
      privateKey: sshKey,
      readyTimeout: 20000
    });

    configReadable.push(JSON.stringify(configurations.shadowsocks, null, 2) + '\n');
    configReadable.push(null);
    configReadable.pipe(writer);
    writer.on('close', function () {
      console.log("finished writing");
      callback('shadowsocks-libev');
    })
  };
  streamToString(oldConfigSSH, configurations, 'shadowsocks', updateShadowsocks);
};

//helper function to push stream into a string variable
 function streamToString (stream, result, resultKey, callback) {
   var data = '';
   var chunk;

   stream.on('readable', function() {
       while ((chunk=this.read()) != null) {
           data += chunk;
           console.log("Reading data . . .");
       }
   });

   stream.on('end', function() {
     data = JSON.parse(data);
     console.log("reading complete");
     result[resultKey] = data;
     callback();
   });
 };

 //genereic sequest callback
 function sequestResponse (error, stdout) {
    if (error) {
      throw error;
    } else {
      console.log(stdout);
      return true;
    }
  };

  function sshCommand (server, options) {
    sequest('root@' + server, sequestOpts, sequestResponse);
  };

--------------------------------------------------------------------------------

//CODE YET TO BE CONVERTED AND IMPLEMENTED
/*

//service restart
function serviceRestart(service) {
  sequestOpts.command = 'service ' + service + ' restart';
  sshCommand(newServer.networks.v4[0].ip_address, sequestOpts);
};

//update domain to reflect new IP.
function updateDomainRecords(domain) {

 client.domainRecordGetAll(domain).then(function(domainRecords) {
   newRecord = {
     "type": "A",
     "data": newServer.networks.v4[0].ip_address,
     "name": "@"
   }
   targetRecord = domainRecords.filter(function(el) {
     return domainRecords;
   });
   if (targetRecord != null){
     targetRecord = targetRecord.filter(function(el) {
       return el.type === "A";
     });
     if (targetRecord[0].data === oldServer[0].networks.v4[0].ip_address) {
       console.log("the targetRecord and current server record match, updating record.");
     } else {
       throw "DNS Records do not match, skipping DNS record update."
     }
     client.domainRecordEdit(domain,targetRecord[0].id,newRecord).then(function (updatedRecord){
       console.log("The new record is : \n", updatedRecord);
     })
   } else {
     throw "The record details could not be found, skipping DNS record update"
   }
 });
}
// Verify domain record has been successfully updated against DO DNS servers

  function isActive(server, delay, timeout) {
    client.dropletGet(server).catch(function (error){
      if (error === 'Error: Request Failed: Error: read ECONNRESET') {
        console.error('there was an error, trying again:', error);
      } else {
      console.error('there was an error, aborting:', error);
    }
    }).then(function statusIs(droplet){
      if (droplet.status !='active') {
        console.log(droplet.status);
        console.log('not yet active');
        isActive(server);
      } else {
        console.log('the server status is ' + droplet.status);
      }
    });
  };

*/

var sessionInfo = {
  do_api_token: null,
  ssh_key_location: null,
  configurations: {
    shadowsocks: {
      ssRemote: '/etc/shadowsocks-libev/config.json',
      ssLocal: process.env.HOME + '/config.json.transfered'
    }
  }
}
function getShadowsocks() {

  return ssh.connect({
      //host: sessionInfo.new_server.networks.v4[0].ip_address,
      host: '138.197.193.189',
      username: 'root',
      privateKey: process.env.HOME + '/.ssh/do.priv'
    }).then( () => {
      return ssh.getFile('/etc/shadowsocks-libev/config.json', process.env.HOME + '/config.json.transfered')
    }).then( () => {
      return console.log("The File's contents were successfully downloaded")
    }).then( () => {
     return fs.readFile(sessionInfo.configurations.shadowsocks.ssLocal, 'utf-8', (error, data) => {
        if (error) throw error
        console.log(data)
        sessionInfo.configurations.shadowsocks.configFile = JSON.parse(data)
        sessionInfo.configurations.shadowsocks.configFile.server = '123.456.789.1'
      })
    }).then( () => {
      return fs.writeFile(sessionInfo.configurations.shadowsocks.ssLocal, JSON.stringify(sessionInfo.configurations.shadowsocks.configFile), (error) => {
        if (error) throw error
        console.log('It\'s saved!')
      })
    }).catch(error =>
    console.error(error))
  }<commit_msg>getShadowsocks() works with IO operation<commit_after>"use strict";
var DigitalOceanApi = require('doapi');
var fs = require('fs');
var node_ssh = require('node-ssh')
var inquirer = require('inquirer');

var readable = require('stream').Readable

var client;
var sshKey;
var ssh = new node_ssh()

var configurations = {};
var prompt = inquirer.createPromptModule();
var promptQuestions = [
    {
        type: 'input',
        name: 'do_api_token',
        message: 'Digital Ocean token:'
    }, {
        type: 'input',
        name: 'ssh_key_location',
        message: 'Name of SSH key in ~/.ssh/ to connect to Streisand droplet:'
    }
]
var sequestOpts = {
    privateKey: sshKey,
    readyTimeout: 20000
};
var time = new Date();
var targetRecord;

//gather required info from user
function getSessionInfo() {
    var sessionInfo = {
        do_api_token: null,
        ssh_key_location: null
    }

    return prompt(promptQuestions).then(answers => {
        sessionInfo.do_api_token = answers.do_api_token
        sessionInfo.ssh_key_location = answers.ssh_key_location
        sshKey = process.env.HOME + '/.ssh/' + sessionInfo.ssh_key_location
        client = new DigitalOceanApi({token: sessionInfo.do_api_token});
        console.log(sessionInfo)
        return sessionInfo;
    }).catch(error => console.log(error))
}

//find the latest instance of streisand from Digital Ocean and store it.
function getCurrentServer(sessionInfo) {
    return client.dropletGetAll().then(droplets => {
        return droplets.filter(el => {
            if (el.name.search('streisand-') !== -1) {
                return el.name;
            }
        });
    }).then(droplet => {
        sessionInfo.old_server = droplet[0];
        console.log('The current server is: ' + sessionInfo.old_server.name +
          " " + sessionInfo.old_server.networks.v4[0].ip_address)
        return sessionInfo
    }).catch(error => console.error(error))
}

//using the return from getCurrentServer, start a new droplet using the snapshot of the old server.
function startNewServer(sessionInfo) {
    var newServerDetails = {
        "name": "streisand-" + (time.getMonth() + 1) + "-" + time.getDate() +
          "-" + time.getHours() + "." + time.getMinutes(),
        "region": "sfo2",
        //"region": oldServer.oldserver.region.slug,
        "size": "512mb",
        "image": sessionInfo.old_server.snapshot_ids[0],
        "ssh_keys": [1278744]
    };

    return client.dropletNew(newServerDetails).then(newDroplet => {
        newServerDetails = newDroplet;
        var numAttempts = 0;

        function getIP() {

            return client.dropletGet(newServerDetails.id).then(startingDroplet => {
                numAttempts++
                console.log("Find IP attempt # ", numAttempts);

                if (startingDroplet.networks.v4[0].ip_address != undefined) {
                    newServerDetails = startingDroplet;
                    console.log("newServer updated with IPv4 address: ",
                      startingDroplet.networks.v4[0].ip_address);
                    return newServerDetails;

                } else {
                    if (numAttempts > 15) {
                        console.log("failed to reach server after " + numAttempts
                          + " attempts");
                    } else {
                        return getIP();
                    }
                }
            }).then(server => {
                sessionInfo.new_server = server
                console.log(sessionInfo.new_server.name + " " +
                  sessionInfo.new_server.networks.v4[0].ip_address)
                return sessionInfo
            })
        }
        return getIP();
    }).catch(error => console.log(error))
}

function checkConnection(sessionInfo){
  var attempts = 25
  console.log('Attempting to connect to server ' + sessionInfo.new_server.name + '. . . ');
  console.log('Attempt: #1');
  function connect(attempt) {
    ssh.connect({
      host: sessionInfo.new_server.networks.v4[0].ip_address,
      username: 'root',
      privateKey: sshKey
    }).then( results => {
      return ssh.execCommand('uptime')
    }, rejection => {
      attempts--
      console.error('failed, ' + attempts +  ' attempts left . . .');
      if (attempts > 0) {
      connect(attempts);
    }
    }).then(results => {
      console.log('STDOUT: ' + results.stdout)
      console.log('STDERR: ' + results.stderr)
    }).catch(error => console.error(error))
  }
  connect(attempts)
}

//copy Shadowsocks config from old server onto new server
function getShadowsocks() {
  return ssh.connect({
      //host: sessionInfo.new_server.networks.v4[0].ip_address,
      host: '138.197.193.189',
      username: 'root',
      privateKey: process.env.HOME + '/.ssh/do.priv'
    }).then( () => {
      return ssh.getFile('/etc/shadowsocks-libev/config.json', process.env.HOME + '/config.json.transfered')
    }).then( () => {
      return console.log("The File's contents were successfully downloaded")
    }).then( () => {
      fs.readFile('/etc/passwd', (error, data) => {
        if (error) throw error
        console.log(data)
        sessionInfo.configurations.shadowsocks.server = newServer.networks.v4[0].ip_address
      })
    }).then( () => {
      return ssh.putfile('/path/to/local/file.json', '/path/to/remote/file.json')
    }).catch(error =>{
      console.error('there is a problem', error)
    })
}
getSessionInfo().then(getCurrentServer).then(startNewServer).then(checkConnection)

--------------------------------------------------------------------------------

  function updateShadowsocks() {
    console.log("updateShadowsocks callback started.");
    configurations.shadowsocks.server = newServer.networks.v4[0].ip_address;
    //this is a real hack that requires success, rework.
    updateConfig(serviceRestart);
  };

  function updateConfig(callback) {
    var configReadable = new readable;
    var writer = sequest.put('root@' + newServer.networks.v4[0].ip_address,
    '/etc/shadowsocks-libev/config.json', {
      mode: '0640',
      privateKey: sshKey,
      readyTimeout: 20000
    });

    configReadable.push(JSON.stringify(configurations.shadowsocks, null, 2) + '\n');
    configReadable.push(null);
    configReadable.pipe(writer);
    writer.on('close', function () {
      console.log("finished writing");
      callback('shadowsocks-libev');
    })
  };
  streamToString(oldConfigSSH, configurations, 'shadowsocks', updateShadowsocks);
};

//helper function to push stream into a string variable
 function streamToString (stream, result, resultKey, callback) {
   var data = '';
   var chunk;

   stream.on('readable', function() {
       while ((chunk=this.read()) != null) {
           data += chunk;
           console.log("Reading data . . .");
       }
   });

   stream.on('end', function() {
     data = JSON.parse(data);
     console.log("reading complete");
     result[resultKey] = data;
     callback();
   });
 };

 //genereic sequest callback
 function sequestResponse (error, stdout) {
    if (error) {
      throw error;
    } else {
      console.log(stdout);
      return true;
    }
  };

  function sshCommand (server, options) {
    sequest('root@' + server, sequestOpts, sequestResponse);
  };

--------------------------------------------------------------------------------

//CODE YET TO BE CONVERTED AND IMPLEMENTED
/*

//service restart
function serviceRestart(service) {
  sequestOpts.command = 'service ' + service + ' restart';
  sshCommand(newServer.networks.v4[0].ip_address, sequestOpts);
};

//update domain to reflect new IP.
function updateDomainRecords(domain) {

 client.domainRecordGetAll(domain).then(function(domainRecords) {
   newRecord = {
     "type": "A",
     "data": newServer.networks.v4[0].ip_address,
     "name": "@"
   }
   targetRecord = domainRecords.filter(function(el) {
     return domainRecords;
   });
   if (targetRecord != null){
     targetRecord = targetRecord.filter(function(el) {
       return el.type === "A";
     });
     if (targetRecord[0].data === oldServer[0].networks.v4[0].ip_address) {
       console.log("the targetRecord and current server record match, updating record.");
     } else {
       throw "DNS Records do not match, skipping DNS record update."
     }
     client.domainRecordEdit(domain,targetRecord[0].id,newRecord).then(function (updatedRecord){
       console.log("The new record is : \n", updatedRecord);
     })
   } else {
     throw "The record details could not be found, skipping DNS record update"
   }
 });
}
// Verify domain record has been successfully updated against DO DNS servers

  function isActive(server, delay, timeout) {
    client.dropletGet(server).catch(function (error){
      if (error === 'Error: Request Failed: Error: read ECONNRESET') {
        console.error('there was an error, trying again:', error);
      } else {
      console.error('there was an error, aborting:', error);
    }
    }).then(function statusIs(droplet){
      if (droplet.status !='active') {
        console.log(droplet.status);
        console.log('not yet active');
        isActive(server);
      } else {
        console.log('the server status is ' + droplet.status);
      }
    });
  };

*/

var sessionInfo = {
  do_api_token: null,
  ssh_key_location: null,
  configurations: {
    shadowsocks: {
      ssRemote: '/etc/shadowsocks-libev/config.json',
      ssLocal: process.env.HOME + '/config.json.transfered'
    }
  }
}
function getShadowsocks() {

  return ssh.connect({
      //host: sessionInfo.new_server.networks.v4[0].ip_address,
      host: '138.197.193.189',
      username: 'root',
      privateKey: process.env.HOME + '/.ssh/do.priv'
    }).then( () => {
      return ssh.getFile('/etc/shadowsocks-libev/config.json', process.env.HOME + '/config.json.transfered')
    }).then( () => {
      return console.log("The File's contents were successfully downloaded")
    }).then( () => {
      const readFile = fs.readFileSync(sessionInfo.configurations.shadowsocks.ssLocal, 'utf-8')
      console.log(readFile)
      sessionInfo.configurations.shadowsocks.configFile = JSON.parse(readFile)
      sessionInfo.configurations.shadowsocks.configFile.server = '123.456.789.1'
      return ('resolved')
    }).then( () => {
      const writeFile = fs.writeFileSync(sessionInfo.configurations.shadowsocks.ssLocal, JSON.stringify(sessionInfo.configurations.shadowsocks.configFile))
      return console.log('It\'s saved!')
    }).catch(error =>
    console.error(error))
  }

  function stream() {

  return ssh.connect({
      //host: sessionInfo.new_server.networks.v4[0].ip_address,
      host: '138.197.193.189',
      username: 'root',
      privateKey: process.env.HOME + '/.ssh/do.priv'
    }).then(createRead)

   var streamData = ''
    function createRead() {
      this.requestSFTP().then( sftp => {
        const readStream = sftp.createReadStream(sessionInfo.configurations.shadowsocks.ssRemote, { flags: 'r',
          encoding: 'utf-8',
          handle: null,
          mode: 0o666,
          autoClose: true
        })

        readStream.on('data', file => {
          streamData += file;
        })
        readStream.on('end', data => {
          console.log(streamData)
          return streamData
        }
      }
        )}
  }<|endoftext|>


<commit_before>var FontsLoaded = function(options){

    var self     = this,
        defaults = {
            fonts    : [],
            complete : null
        };

    this.settings    = this.extend(defaults, options);
    this.fontList    = [];
    this.loadedFonts = 0;

    this.createElements(function () {

        self.loadingTimeout = window.setInterval(self.checkElementWidth, 50, self);

    });

}

FontsLoaded.prototype.createElements = function (cb){
    // Create elements which we will use
    // to detect if the fonts have loaded

    var index, elem, font;

    for (index = 0; index < this.settings.fonts.length; ++index) {

        font = this.settings.fonts[index];

        // Font name to camelcase
        fontId = font
            .toLowerCase()
            .replace(/\s/g, '-')
            .replace(/-(.)/g, function(match, group1) {
                return group1.toUpperCase();
            });

        elem                  = document.createElement('span');
        elem.className        = 'fonts-loaded ';
        elem.id               = fontId;
        elem.style.fontFamily = font;
        elem.innerHTML        = font + ' is loading';

        document.body.appendChild(elem);

        this.fontList.push({
            font   : fontId,
            width  : elem.offsetWidth,
            loaded : false
        });
    }

    if (typeof cb === 'function') {
        cb();
    }

}

FontsLoaded.prototype.checkElementWidth = function (self){

    var index;

    for (index = 0; index < self.fontList.length; ++index) {

        var _this = self.fontList[index],
            el    = document.getElementById(_this.font);

        _this.loaded = el.offsetWidth !== _this.width;

        self.trigger('fonts.' + _this.font, document.body);

        ++self.loadedFonts;

    }

    if (self.loadedFonts === self.fontList.length) {
        window.clearInterval(self.loadingTimeout);

        self.trigger('fonts.all', document.body);

        if (typeof self.settings.complete === 'function') {
            self.settings.complete(self);
        }
    }

}

FontsLoaded.prototype.trigger = function (eventName, el) {

    var event; // The custom event that will be created

    if (document.createEvent) {
        event = document.createEvent('HTMLEvents');
        event.initEvent(eventName, true, true);
    } else {
        event = document.createEventObject();
        event.eventType = eventName;
    }

    event.eventName = eventName;

    if (document.createEvent) {
        el.dispatchEvent(event);
    } else {
        el.fireEvent("on" + event.eventType, event);
    }

}

FontsLoaded.prototype.extend = function (object1, object2) {

    var object3 = {};

    for (var key in object1) { object3[key] = object1[key]; }
    for (var key in object2) { object3[key] = object2[key]; }

    return object3;

}
<commit_msg>Commented all the things<commit_after>/*!
* FontsLoaded 1.0
*
* Copyright 2014, Dirigo Design & Development http://github.com/dirigodev
* Released under the MIT license
*
*/

var FontsLoaded = function(options){

    var self     = this,
        defaults = {
            fonts    : [],
            complete : null
        };

    this.settings    = this.extend(defaults, options);
    this.fontList    = [];
    this.loadedFonts = 0;

    this.createElements(function () {

        self.loadingTimeout = window.setInterval(self.checkElementWidth, 10, self);

    });

}

FontsLoaded.prototype.createElements = function (cb){

    // Create elements which we will use
    // to detect if the fonts have loaded

    var index, elem, font;

    for (index = 0; index < this.settings.fonts.length; ++index) {

        // Get the name of the font
        font = this.settings.fonts[index];

        // Convert font name to camelcase
        fontId = font
            .toLowerCase()
            .replace(/\s/g, '-')
            .replace(/-(.)/g, function(match, group1) {
                return group1.toUpperCase();
            });

        // Create and style element
        elem                  = document.createElement('span');
        elem.className        = 'fonts-loaded ';
        elem.id               = fontId;
        elem.style.fontFamily = font;
        elem.style.fontFamily = font;
        elem.style.position   = 'absolute';
        elem.style.left       = '-9999px';
        elem.innerHTML        = font + ' is loading';

        // Add the element to the body
        document.body.appendChild(elem);

        // Create an object in the fontList array so
        // we can keep track of fonts more easily
        this.fontList.push({
            font   : fontId,
            width  : elem.offsetWidth,
            loaded : false
        });
    }

    // Execute callback function once elements
    // have been created
    if (typeof cb === 'function') {
        cb();
    }

}

FontsLoaded.prototype.checkElementWidth = function (self){

    // Here we're going to compare the current width
    // of the elements we created to their original
    // width. If the width has changed, the font is
    // finished loading.

    var index;

    for (index = 0; index < self.fontList.length; ++index) {

        var _this = self.fontList[index],
            el    = document.getElementById(_this.font);

        if (el.offsetWidth !== _this.width) {
            // Mark font as loaded in fontList
            _this.loaded = true;

            // Trigger an event so we can do something when
            // this particular font has loaded
            self.trigger('fonts.' + _this.font, document.body);

            // Remove the original element from the DOM. We
            // don't need it anymore.
            document.body.removeChild(el);

            // Let everyone know we have loaded one more font
            ++self.loadedFonts;
        }

    }

    // If we have loaded all the fonts, do some stuff
    if (self.loadedFonts === self.fontList.length) {

        // Clear the setInterval
        window.clearInterval(self.loadingTimeout);

        // Trigger an event so we can do something when
        // ALL the fonts have loaded
        self.trigger('fonts.all', document.body);

        // Execute the complete function, if it exists
        if (typeof self.settings.complete === 'function') {
            self.settings.complete(self);
        }

    }

}

FontsLoaded.prototype.trigger = function (eventName, el) {

    var event; // The custom event that will be created

    if (document.createEvent) {
        event = document.createEvent('HTMLEvents');
        event.initEvent(eventName, true, true);
    } else {
        event = document.createEventObject();
        event.eventType = eventName;
    }

    event.eventName = eventName;

    if (document.createEvent) {
        el.dispatchEvent(event);
    } else {
        el.fireEvent("on" + event.eventType, event);
    }

}

FontsLoaded.prototype.extend = function (object1, object2) {

    var object3 = {};

    for (var key in object1) { object3[key] = object1[key]; }
    for (var key in object2) { object3[key] = object2[key]; }

    return object3;

}<|endoftext|>


<commit_before>"use strict";

import Ember  from "ember";
import moment from "moment";

const DAYSINTOMONTH = 7;

export default Ember.Mixin.create({
  queryParams: ['month'],

  month: Ember.computed(function() {
    var date = moment();
    if (date.date() <= DAYSINTOMONTH) {
      date = date.subtract(1, 'month');
    }
    return date.format("YYYY-MM-DD"); // Default value for queryParam
  }),

  months: Ember.computed(function() {
    var months = [];
    for (var i = 0; i < 12; i++) {
      var date = moment().subtract(i, 'month');
      months.push({
        id: date.format("YYYY-MM-DD"),
        name: date.format("MMMM YYYY")
      });
    }
    return months;
  }),

  selectedMonthWord: Ember.computed('month', function() {
    var date = moment(this.get('month'));
    if (date.date() <= DAYSINTOMONTH) {
      date = date.subtract(1, 'month');
    }
    return date.format("MMMM");
  })
});
<commit_msg>Fix selected month to show correct selected month<commit_after>"use strict";

import Ember  from "ember";
import moment from "moment";

const DAYSINTOMONTH = 7;

export default Ember.Mixin.create({
  queryParams: ['month'],

  month: Ember.computed(function() {
    var date = moment();
    if (date.date() <= DAYSINTOMONTH) {
      date = date.subtract(1, 'month');
    }
    return date.format("YYYY-MM-DD"); // Default value for queryParam
  }),

  months: Ember.computed(function() {
    var months = [];
    for (var i = 0; i < 12; i++) {
      var date = moment().subtract(i, 'month');
      months.push({
        id: date.format("YYYY-MM-DD"),
        name: date.format("MMMM YYYY")
      });
    }
    return months;
  }),

  selectedMonthWord: Ember.computed('month', function() {
    var date = moment(this.get('month'));
    return date.format("MMMM");
  })
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';

class App extends Component {
    render() {
        return (

React component newwwww

        );
    }
}

export default App;<commit_msg>minor text change<commit_after>import React, { Component } from 'react';

class App extends Component {
    render() {
        return (

React component

        );
    }
}

export default App;<|endoftext|>