<commit_before>// ==UserScript==
// @name         SideTube
// @namespace    dairful
// @version      0.0.1
// @description  Reorder content panels and resize panels into a scrollable panel
// @author       Dairful
// @include      *://www.youtube.com/*
// @grant        none
// @require      http://code.jquery.com/jquery-latest.js
// @downloadURL  https://github.com/Dairful/SideTube/raw/master/SideTube.user.js
// ==/UserScript==

function main(){
    // Check if current page is a video page
    if($("#page").hasClass("watch")){
      // Reorder content panels
        $("#watch7-sidebar-contents").before($("#watch-discussion"));
        $("#watch-discussion").after($("#watch7-sidebar-contents"));
        $("#watch7-sidebar-contents").after($("#watch-discussion"));
      // CSS modifications
        $("#watch-discussion").css({"height":"auto",
                                       "max-height":"550px",
                                       "overflow":"auto",
                                       "overflow-x":"hidden"});
        $("#action-panel-details").css({"height":"auto",
                                           "max-height":"550px",
                                           "overflow":"auto"});
        $("#watch7-sidebar-contents").css({"height":"auto",
                                              "min-height":"153px",
                                              "max-height":"153px",
                                              "overflow":"auto"});
    }
}

main();
$(document).on("spfdone", main);<commit_msg>Fix to page scrolling<commit_after>// ==UserScript==
// @name         SideTube
// @namespace    dairful
// @version      0.0.2
// @description  Reorder content panels and resize panels into a scrollable panel
// @author       Dairful
// @include      *://www.youtube.com/*
// @grant        none
// @require      http://code.jquery.com/jquery-latest.js
// @downloadURL  https://github.com/Dairful/SideTube/raw/master/SideTube.user.js
// ==/UserScript==

function main(){
    // Check if current page is a video page
    if($("#page").hasClass("watch")){
        var $upnext = $("#watch7-sidebar-contents");
        var $comments = $("#watch-discussion");
        var $description = $("#action-panel-details");
        // Reorder content panels
        $upnext.before($comments);
        $comments.after($upnext);
        $upnext.after($comments);
        // CSS modifications (could be put in CSS using Stylish instead)
        $upnext.css({"height":"auto",
                     "min-height":"153px",
                     "max-height":"153px",
                     "overflow":"auto"});
        $comments.css({"height":"auto",
                       "max-height":"550px",
                       "overflow":"auto",
                       "overflow-x":"hidden"});
        $description.css({"height":"auto",
                          "max-height":"550px",
                          "overflow":"auto"});
        // Prevent page scroll when textbox scrolls to bottom
        $upnext.bind( 'mousewheel DOMMouseScroll', function ( e ) {
            var e0 = e.originalEvent,
                delta = e0.wheelDelta || -e0.detail;

            this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
            e.preventDefault();
        });
        $comments.bind( 'mousewheel DOMMouseScroll', function ( e ) {
            var e0 = e.originalEvent,
                delta = e0.wheelDelta || -e0.detail;

            this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
            e.preventDefault();
        });
    }
}

main();
$(document).on("spfdone", main);
<|endoftext|>


<commit_before>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/* global Ext */

var CoreUtil = {
	showContextMenu: function (menu, event) {

		event.stopEvent();
		menu.showAt(0, 0);

		var avaliableHeight = Ext.getBody().getHeight();
		var avaliableWidth = Ext.getBody().getWidth();

		var maxHeight = avaliableHeight - menu.getHeight();
		var maxWidth = avaliableWidth - menu.getWidth();

		var showHeight = event.getY() + menu.getHeight();
		var showWidth = event.getX() + menu.getWidth();

		var x = event.getX();
		var y = event.getY();
		if (showHeight > maxHeight)
		{
			y = event.getY() - menu.getHeight();
		}

		if (showWidth > maxWidth)
		{
			x = event.getX() - menu.getWidth();
		}
		menu.showAt(x, y);
	},
	lookupStore: function (options) {

		var model = 'LookupDataModel';
		if (options.model)
		{
			model = options.model;
		}

		var autoLoad = true;
		if (options.autoLoad !== undefined && options.autoLoad !== null)
		{
			autoLoad = options.autoLoad;
		}

		var store;
		if (options.customStore) {
			store = Ext.create('Ext.data.Store', options.customStore);
		} else {
			store = Ext.create('Ext.data.Store', Ext.applyIf({
				model: model,
				autoLoad: autoLoad,
				proxy: {
					type: 'ajax',
					url: options.url
				}
			}, options));
			if (options.addRecords) {
				store.on('load', function (myStore, records, sucessful, opts) {
					myStore.add(options.addRecords);
				});
			}
		}

		return store;
	},
	downloadCSVFile: function (filename, csvContent) {
		var charset = "utf-8";
		var blob = new Blob([csvContent], {
			type: "text/csv;charset=" + charset + ";"
		});
		if (window.navigator.msSaveOrOpenBlob) {
			//console.log("Save Blob");
			window.navigator.msSaveBlob(blob, filename);
		} else {
			//console.log("Create Link");
			var link = document.createElement("a");
			if (link.download !== undefined) { // feature detection
				// Browsers that support HTML5 download attribute
				var url = URL.createObjectURL(blob);
				link.setAttribute("href", url);
				link.setAttribute("download", filename);
				link.style.visibility = 'hidden';
				document.body.appendChild(link);
				link.click();
				document.body.removeChild(link);
			}
		}
	},
	csvToHTML: function (csvData) {

		var lines = csvData.split("\n");
		var rows = [];
		var maxCols = 0;
		var htmlData = '';
		var foundHeaderFlag = 0;
		var lengthCheck = 3;
		var lengthCheckFlag = 0;

		for (ctr = 0; ctr < lines.length; ctr++) {
			var tmpRow = lines[ctr].split('",');

			if (tmpRow[0] === '' && tmpRow.length === 1)
			{
				continue;
			}

			for (ctr2 = 0; ctr2 < tmpRow.length; ctr2++) {
				tmpRow[ctr2] = tmpRow[ctr2].replace(/["]+/g, '');
			}
			if (tmpRow.length > maxCols) {
				maxCols = tmpRow.length;
			}

			rows.push(tmpRow);

		}

		htmlData += '';

		for (ctr = 0; ctr < rows.length; ctr++) {
			for (ctr2 = 0; ctr2 < rows[ctr].length; ctr2++) {
				if (foundHeaderFlag === 0) {
					if (rows[ctr].length === maxCols) //This is the header
					{
						if (ctr2 === 0) { //Start Header
							htmlData += '

' + rows[ctr][ctr2] + '	';
						}

						if ((ctr2 + 1) === maxCols) { //End Row
							foundHeaderFlag = 1;
							if (ctr2 !== 0) {
								htmlData += '' + rows[ctr][ctr2] + '
';
							}
							else {
								htmlData += '
';
							}

						}
						else if (ctr2 !== 0) {//Normal Header Col
							htmlData += '' + rows[ctr][ctr2] + '	';
						}
					}
					else  //Data before the header
					{

						if (ctr2 === 0) {
							if (rows[ctr].length > lengthCheck) {

								if (!lengthCheckFlag) {
									htmlData += '
';
									lengthCheckFlag = 1;
								}
								htmlData += '
' + rows[ctr][ctr2] + '	';

							}
							else {
								if (lengthCheckFlag) {
									htmlData += '
';
									lengthCheckFlag = 0;
								}
								htmlData += '
' + rows[ctr][ctr2];
							}

						}

						if ((ctr2 + 1) === rows[ctr].length) { //Last Col

							if (rows[ctr].length > lengthCheck) {
								if (ctr2 !== 0) {
									htmlData += '' + rows[ctr][ctr2] + '
';
								}
								else {
									htmlData += '
';
								}
							}
							else {
								if (ctr2 !== 0) {
									htmlData += rows[ctr][ctr2] + '
';
								}
								else
								{
									htmlData += '
';
								}

							}
						}
						else if (ctr2 !== 0) { //Middle Col
							if (rows[ctr].length > lengthCheck) {

								htmlData += '' + rows[ctr][ctr2] + '	';
							}
							else {
								htmlData += rows[ctr][ctr2];
							}

						}
					}
				}
				else { //Regular table data

					if (ctr2 === 0) { //Start new row
						htmlData += '
' + rows[ctr][ctr2] + '	';
					}

					if ((ctr2 + 1) === rows[ctr].length) { //End row
						if (ctr2 !== 0) {
							htmlData += '' + rows[ctr][ctr2] + '
';
						}
						else {
							htmlData += '
';
						}

					}
					else if (ctr2 !== 0) { //Normal Data

						htmlData += '' + rows[ctr][ctr2] + '	';
					}

				}
			}
		}
		htmlData += '
';
		htmlData = htmlData.replace(/<\/td>/g, '&nbsp	');

		return htmlData;
	},
	popupMessage: function (title, message, delay) {
		if (delay)
		{
			delay = 1000;
		}

		//'t' top and 'b' , 'r' 'l' (See the Fx class overview for valid anchor point options)
		if (!CoreUtil.popupMessageMsgCt) {
			CoreUtil.popupMessageMsgCt = Ext.core.DomHelper.insertFirst(document.body, {id: 'msg-div'}, true);
		}
		var m = Ext.core.DomHelper.append(CoreUtil.popupMessageMsgCt, '

' + title + '

' + message + '

', true);
		m.hide();
		m.slideIn('t').ghost('t', {delay: delay, remove: true});
	},
	/**
	 * Chain load the store and then the form...so the form loads correctly
	 *
	 * options:
	 *
	 * Stores (Array of stores)
	 * Form (form to load)
	 * formLoadOpts
	 * Components to mask
	 *  @param options
	 */
	chainedStoreLoad: function (options) {

		//mask componets
		if (options.maskComponents)
		{
			if (Ext.isArray(options.maskComponents))
			{
				for (var i = 0; i < options.maskComponents.length; i++) {
					options.maskComponents[i].setLoading(true);
				}
			}
			else
			{
				options.maskComponents.setLoading(true);
			}
		}

		var loadFormFunc = function () {
			var options = this;
			if (options.maskComponents)
			{
				if (Ext.isArray(options.maskComponents))
				{
					for (var i = 0; i < options.maskComponents.length; i++) {
						options.maskComponents[i].setLoading(false);
					}
				}
				else
				{
					options.maskComponents.setLoading(false);
				}
			}

			options.form.load(options.formLoadOpts);
		};

		//chain the stores
		if (Ext.isArray(options.stores))
		{
			for (var i = 0; i < options.stores.length; i++) {

				if (i === (options.stores.length - 1)) {
					options.stores[i].on('load', loadFormFunc, options);
				} else {
					options.stores[i].on('load', function () {
						this.load();
					}, options.stores[i + 1]);
				}

			}
		}
		else
		{
			options.stores.on('load', loadFormFunc, options);
		}
	},
	cloneStoreRecords: function (originalStore)
	{
		var newStore = Ext.create('Ext.data.Store', {
			model: originalStore.model,
			fields: originalStore.fields
		});

		originalStore.each(function (record) {
			newStore.add(record);
		});

		return newStore;
	},
	sessionStorage: function () {
		if (sessionStorage) {
			return sessionStorage;
		} else {
			CoreUtil.popupMessage('Session Storage', 'Not Supported');
			return null;
		}
	},
	localStorage: function () {
		if (localStorage) {
			return localStorage;
		} else {
			CoreUtil.popupMessage('Local Storage', 'Not Supported');
			return null;
		}
	},
	removeBlankDataItem: function (originalData) {
		Ext.Object.each(originalData, function (key, value, data) {
			if (value === "") {
				delete data[key];
			}
		});
	},
	submitForm: function (options) {

		if (options.removeBlankDataItems) {
			Ext.Object.each(options.data, function (key, value, data) {
				if (value === "") {
					delete data[key];
				}
			});
		}

		var failurehandler = function (response, opts) {
			options.form.setLoading(false);

			var errorResponse = Ext.decode(response.responseText);
			var errorObj = {};
			Ext.Array.each(errorResponse.errors.entry, function (item, index, entry) {
				errorObj[item.key] = item.value;
			});
			options.form.getForm().markInvalid(errorObj);
			options.failure(response, opts);
		};

		var loadingText = options.loadingText ? options.loadingText : 'Saving...';

		options.form.setLoading(loadingText);
		Ext.Ajax.request({
			url: options.url,
			method: options.method,
			jsonData: options.data,
			success: function (response, opts) {
				options.form.setLoading(false);
				if (response) {
					var data = Ext.decode(response.responseText);
					if ((data.success !== undefined && data.success !== null && data.success) ||
							data.success === undefined)
					{
						options.success(response, opts);
					} else {
						failurehandler(response, opts);
					}
				}
			},
			failure: function (response, opts) {
				failurehandler(response, opts);
			}
		});

	},
	pagingProxy: function (options) {
		var proxy = Ext.create('Ext.data.proxy.Ajax', {
			url: options.url,
			actionMethods: options.actionMethods ? options.actionMethods : {create: 'POST', read: 'GET', update: 'POST', destroy: 'POST'},
			params: options.params ? options.params : {},
			extraParams: options.extraParams ? options.extraParams : {},
			directionParam: 'sortOrder',
			sortParam: 'sortField',
			startParam: 'offset',
			limitParam: 'max',
			simpleSortMode: true,
			reader: options.reader ? options.reader : {type: 'json'}
		});

		return proxy;
	}

};<commit_msg>Fixed issues with CSV to HTML display<commit_after>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/* global Ext */

var CoreUtil = {
	showContextMenu: function (menu, event) {

		event.stopEvent();
		menu.showAt(0, 0);

		var avaliableHeight = Ext.getBody().getHeight();
		var avaliableWidth = Ext.getBody().getWidth();

		var maxHeight = avaliableHeight - menu.getHeight();
		var maxWidth = avaliableWidth - menu.getWidth();

		var showHeight = event.getY() + menu.getHeight();
		var showWidth = event.getX() + menu.getWidth();

		var x = event.getX();
		var y = event.getY();
		if (showHeight > maxHeight)
		{
			y = event.getY() - menu.getHeight();
		}

		if (showWidth > maxWidth)
		{
			x = event.getX() - menu.getWidth();
		}
		menu.showAt(x, y);
	},
	lookupStore: function (options) {

		var model = 'LookupDataModel';
		if (options.model)
		{
			model = options.model;
		}

		var autoLoad = true;
		if (options.autoLoad !== undefined && options.autoLoad !== null)
		{
			autoLoad = options.autoLoad;
		}

		var store;
		if (options.customStore) {
			store = Ext.create('Ext.data.Store', options.customStore);
		} else {
			store = Ext.create('Ext.data.Store', Ext.applyIf({
				model: model,
				autoLoad: autoLoad,
				proxy: {
					type: 'ajax',
					url: options.url
				}
			}, options));
			if (options.addRecords) {
				store.on('load', function (myStore, records, sucessful, opts) {
					myStore.add(options.addRecords);
				});
			}
		}

		return store;
	},
	downloadCSVFile: function (filename, csvContent) {
		var charset = "utf-8";
		var blob = new Blob([csvContent], {
			type: "text/csv;charset=" + charset + ";"
		});
		if (window.navigator.msSaveOrOpenBlob) {
			//console.log("Save Blob");
			window.navigator.msSaveBlob(blob, filename);
		} else {
			//console.log("Create Link");
			var link = document.createElement("a");
			if (link.download !== undefined) { // feature detection
				// Browsers that support HTML5 download attribute
				var url = URL.createObjectURL(blob);
				link.setAttribute("href", url);
				link.setAttribute("download", filename);
				link.style.visibility = 'hidden';
				document.body.appendChild(link);
				link.click();
				document.body.removeChild(link);
			}
		}
	},
	csvToHTML: function (csvData) {

		var lines = csvData.split("\n");
		var rows = [];
		var maxCols = 0;
		var htmlData = '';
		var foundHeaderFlag = 0;
		var lengthCheck = 3;
		var lengthCheckFlag = 0;

        var csv= Ext.util.CSV.decode(csvData);
		//console.log("CSV:",csv);
		for (ctr=0; ctr<csv.length; ctr++){
			if(csv[ctr][0] === '' && csv[ctr].length === 1)
			{
			  csv.splice(ctr,1);
			  continue;
			}
			if(csv[ctr].length>maxCols){
				maxCols = csv[ctr].length;
			}
		}

		htmlData += '
';

		for (ctr = 0; ctr < csv.length; ctr++) {
			for (ctr2 = 0; ctr2 < csv[ctr].length; ctr2++) {
				if(typeof csv[ctr][ctr2]=== 'undefined'){
					csv[ctr][ctr2] = ' ';
				}

				var colDiff = maxCols-ctr2;
				if (ctr2 === 0) { //Start new row

					if ((ctr2 + 1) === csv[ctr].length) {
						if(colDiff !==0 ){
							htmlData += '
' + csv[ctr][ctr2] + '
';
						}
						else{
							htmlData += '
' + csv[ctr][ctr2] + '
';
						}
					}
					else{
						htmlData += '
' + csv[ctr][ctr2] + '	';
					}

				}

				if ((ctr2 + 1) === csv[ctr].length) { //End row
					if (ctr2 !== 0) {
						if(colDiff !==0 ){
							htmlData += '' + csv[ctr][ctr2] + '
';
						}
						else{
							htmlData += '' + csv[ctr][ctr2] + '
';
						}
					}
				}
				else if (ctr2 !== 0) { //Normal Data

					htmlData += '' + csv[ctr][ctr2] + '	';
				}
			}
		}
		htmlData += '
';
		htmlData = htmlData.replace(/<\/td>/g, '&nbsp	');
        //console.log("htmlData",htmlData);
		return htmlData;
	},
	popupMessage: function (title, message, delay) {
		if (delay)
		{
			delay = 1000;
		}

		//'t' top and 'b' , 'r' 'l' (See the Fx class overview for valid anchor point options)
		if (!CoreUtil.popupMessageMsgCt) {
			CoreUtil.popupMessageMsgCt = Ext.core.DomHelper.insertFirst(document.body, {id: 'msg-div'}, true);
		}
		var m = Ext.core.DomHelper.append(CoreUtil.popupMessageMsgCt, '

' + title + '

' + message + '

', true);
		m.hide();
		m.slideIn('t').ghost('t', {delay: delay, remove: true});
	},
	/**
	 * Chain load the store and then the form...so the form loads correctly
	 *
	 * options:
	 *
	 * Stores (Array of stores)
	 * Form (form to load)
	 * formLoadOpts
	 * Components to mask
	 *  @param options
	 */
	chainedStoreLoad: function (options) {

		//mask componets
		if (options.maskComponents)
		{
			if (Ext.isArray(options.maskComponents))
			{
				for (var i = 0; i < options.maskComponents.length; i++) {
					options.maskComponents[i].setLoading(true);
				}
			}
			else
			{
				options.maskComponents.setLoading(true);
			}
		}

		var loadFormFunc = function () {
			var options = this;
			if (options.maskComponents)
			{
				if (Ext.isArray(options.maskComponents))
				{
					for (var i = 0; i < options.maskComponents.length; i++) {
						options.maskComponents[i].setLoading(false);
					}
				}
				else
				{
					options.maskComponents.setLoading(false);
				}
			}

			options.form.load(options.formLoadOpts);
		};

		//chain the stores
		if (Ext.isArray(options.stores))
		{
			for (var i = 0; i < options.stores.length; i++) {

				if (i === (options.stores.length - 1)) {
					options.stores[i].on('load', loadFormFunc, options);
				} else {
					options.stores[i].on('load', function () {
						this.load();
					}, options.stores[i + 1]);
				}

			}
		}
		else
		{
			options.stores.on('load', loadFormFunc, options);
		}
	},
	cloneStoreRecords: function (originalStore)
	{
		var newStore = Ext.create('Ext.data.Store', {
			model: originalStore.model,
			fields: originalStore.fields
		});

		originalStore.each(function (record) {
			newStore.add(record);
		});

		return newStore;
	},
	sessionStorage: function () {
		if (sessionStorage) {
			return sessionStorage;
		} else {
			CoreUtil.popupMessage('Session Storage', 'Not Supported');
			return null;
		}
	},
	localStorage: function () {
		if (localStorage) {
			return localStorage;
		} else {
			CoreUtil.popupMessage('Local Storage', 'Not Supported');
			return null;
		}
	},
	removeBlankDataItem: function (originalData) {
		Ext.Object.each(originalData, function (key, value, data) {
			if (value === "") {
				delete data[key];
			}
		});
	},
	submitForm: function (options) {

		if (options.removeBlankDataItems) {
			Ext.Object.each(options.data, function (key, value, data) {
				if (value === "") {
					delete data[key];
				}
			});
		}

		var failurehandler = function (response, opts) {
			options.form.setLoading(false);

			var errorResponse = Ext.decode(response.responseText);
			var errorObj = {};
			Ext.Array.each(errorResponse.errors.entry, function (item, index, entry) {
				errorObj[item.key] = item.value;
			});
			options.form.getForm().markInvalid(errorObj);
			options.failure(response, opts);
		};

		var loadingText = options.loadingText ? options.loadingText : 'Saving...';

		options.form.setLoading(loadingText);
		Ext.Ajax.request({
			url: options.url,
			method: options.method,
			jsonData: options.data,
			success: function (response, opts) {
				options.form.setLoading(false);
				if (response) {
					var data = Ext.decode(response.responseText);
					if ((data.success !== undefined && data.success !== null && data.success) ||
							data.success === undefined)
					{
						options.success(response, opts);
					} else {
						failurehandler(response, opts);
					}
				}
			},
			failure: function (response, opts) {
				failurehandler(response, opts);
			}
		});

	},
	pagingProxy: function (options) {
		var proxy = Ext.create('Ext.data.proxy.Ajax', {
			url: options.url,
			actionMethods: options.actionMethods ? options.actionMethods : {create: 'POST', read: 'GET', update: 'POST', destroy: 'POST'},
			params: options.params ? options.params : {},
			extraParams: options.extraParams ? options.extraParams : {},
			directionParam: 'sortOrder',
			sortParam: 'sortField',
			startParam: 'offset',
			limitParam: 'max',
			simpleSortMode: true,
			reader: options.reader ? options.reader : {type: 'json'}
		});

		return proxy;
	}

};<|endoftext|>


<commit_before>var app = getApp()
var socketOpen = false;
Page({
  data: {
    messageTip: '',
    messageTextArr:[],
    userinfo:{}
  },
  //sendMessage
  formSubmit: function(e) {
    var that = this;
    var msg =  e.detail.value.messageContent;
    console.log('send message:' +msg );
     if (socketOpen) {
      wx.sendSocketMessage({
      data:msg
      })
    } else {
      that.setData({
        messageTip:'WebSocket 链接失败，请重新连接！'
      })
    }
  },
  onLoad: function () {
    console.log('onLoad')
    var that = this

   //连接 Websocket
    wx.connectSocket({
      //url: 'wss://sdk.weixin.senparc.com/api/WxWebSocket/App',
      url: 'wss://sdk.weixin.senparc.com/WxWebSocket.ashx',
      header:{
        'content-type': 'application/json'
      },
      method:"GET"
    });

    wx.onSocketOpen(function(res) {
      console.log('WebSocket 连接成功！')
      socketOpen = true;
      that.setData({
        messageTip:'WebSocket 连接成功！'
      })
    })

    wx.onSocketMessage(function(res) {
      console.log(that,res);
      console.log('收到服务器内容：' + res.data)
      var jsonResult = JSON.parse(res.data);
      var currentIndex= that.data.messageTextArr.length+1;
      var newArr = that.data.messageTextArr;
      newArr.push(
        {
          index:currentIndex,
          content:jsonResult.content,
          time:jsonResult.time
        });
        console.log(that);
      that.setData({
        messageTextArr:newArr
      });
      // that.data.messageTextArr.push(
      //   {
      //     index:currentIndex,
      //     content:jsonResult.content,
      //     time:jsonResult.time
      //   });
      //console.log(that.data.messageTextArr);
    })

    wx.onSocketClose(function(res) {
      console.log('WebSocket 已关闭！')
      socketOpen = false;
    })

    wx.onSocketError(function(res){
      console.log('WebSocket连接打开失败，请检查！')
        // console.log(res);
    })

    //调用应用实例的方法获取全局数据
    app.getUserInfo(function(userInfo){
      //更新数据
      that.setData({
        userInfo:userInfo
      })
    })
  }
})
<commit_msg>调试小程序Demo<commit_after>var app = getApp()
var socketOpen = false;
Page({
  data: {
    messageTip: '',
    messageTextArr:[],
    userinfo:{}
  },
  //sendMessage
  formSubmit: function(e) {
    var that = this;
    var msg =  e.detail.value.messageContent;
    console.log('send message:' +msg );
     if (socketOpen) {
      wx.sendSocketMessage({
      data:msg
      })
    } else {
      that.setData({
        messageTip:'WebSocket 链接失败，请重新连接！'
      })
    }
  },
  onLoad: function () {
    console.log('onLoad')
    var that = this

   //连接 Websocket
    wx.connectSocket({
      //url: 'wss://sdk.weixin.senparc.com/api/WxWebSocket/App',
      //url: 'wss://sdk.weixin.senparc.com/WxWebSocket.ashx',
      url: 'wss://sdk.weixin.senparc.com/SenparcWebSocket',
      header:{
        'content-type': 'application/json'
      },
      method:"GET"
    });

    wx.onSocketOpen(function(res) {
      console.log('WebSocket 连接成功！')
      socketOpen = true;
      that.setData({
        messageTip:'WebSocket 连接成功！'
      })
    })

    wx.onSocketMessage(function(res) {
      console.log(that,res);
      console.log('收到服务器内容：' + res.data)
      var jsonResult = JSON.parse(res.data);
      var currentIndex= that.data.messageTextArr.length+1;
      var newArr = that.data.messageTextArr;
      newArr.push(
        {
          index:currentIndex,
          content:jsonResult.content,
          time:jsonResult.time
        });
        console.log(that);
      that.setData({
        messageTextArr:newArr
      });
      // that.data.messageTextArr.push(
      //   {
      //     index:currentIndex,
      //     content:jsonResult.content,
      //     time:jsonResult.time
      //   });
      //console.log(that.data.messageTextArr);
    })

    wx.onSocketClose(function(res) {
      console.log('WebSocket 已关闭！')
      socketOpen = false;
    })

    wx.onSocketError(function(res){
      console.log('WebSocket连接打开失败，请检查！')
        // console.log(res);
    })

    //调用应用实例的方法获取全局数据
    app.getUserInfo(function(userInfo){
      //更新数据
      that.setData({
        userInfo:userInfo
      })
    })
  }
})
<|endoftext|>


<commit_before>/**
 * @author Jose A. Dianes <jdianes@ebi.ac.uk>
 *
 * The prc-peptide-viewer directive allows us to reuse a list of Peptides everywhere we want to show it (e.g.
 * in the clusterDetail-view)
 *
 */

var peptideViewerDirective = angular.module('prideClusterApp.peptideViewerDirective', ['ngTable']);

peptideViewerDirective.directive('prcPeptideViewer', function () {
    return {
        restrict: 'EA',
        scope: {
            clusterId: '=clusterid'
        },
        controller: 'PeptideViewerCtrl',
        //link: link,
        templateUrl: 'components/directives/peptideViewer-directive/peptideViewer-directive.html'
    };
});

peptideViewerDirective.controller("PeptideViewerCtrl", ['$scope', '$filter', 'ClusterPeptides', 'ngTableParams', function($scope, $filter, ClusterPeptides, ngTableParams) {
    $scope.peptides = [];

    $scope.getPeptides = function() {
        ClusterPeptides.get(
            {clusterId: $scope.clusterId},
            function (data) {

                $scope.peptides = data.clusteredPeptides;

                // here we create a simplified modification list for each peptide that is used for
                // showing tooltips as required by the <prc-peptide-sequence-viewer> directive
                for (j = 0; j < $scope.peptides.length; j++) {
                    var peptide = $scope.peptides[j];
                    peptide.mods = [];
                    if (peptide.modifications != null) {
                        for (i = 0; i < peptide.modifications.length; i++) {
                            peptide.mods[peptide.modifications[i].mainPosition - 1] = peptide.modifications[i].name;
                        }
                    }
                }

                $scope.tableParams.reload();
            }
        );

    };

    $scope.tableParams = new ngTableParams({
            page: 1,            // show first page
            count: 10,           // count per page
            sorting: {
                numberOfPSMs: 'desc'
            }
        }, {
            total: $scope.peptides.length, // length of data
            getData: function($defer, params) {

                // use build-in angular filter
                var orderedData = params.sorting() ?
                    $filter('orderBy')($scope.peptides, params.orderBy()) :
                    data;

                params.total(orderedData.length);
                $scope.peptides_slice = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());
                $defer.resolve($scope.peptides_slice);
            }
    });
}]);<commit_msg>add documentations<commit_after>/**
 * @author Jose A. Dianes <jdianes@ebi.ac.uk>
 *
 * The prc-peptide-viewer directive allows us to reuse a list of Peptides everywhere we want to show it (e.g.
 * in the clusterDetail-view)
 *
 */

var peptideViewerDirective = angular.module('prideClusterApp.peptideViewerDirective', ['ngTable']);

peptideViewerDirective.directive('prcPeptideViewer', function () {
    return {
        restrict: 'EA',
        scope: {
            clusterId: '=clusterid'
        },
        controller: 'PeptideViewerCtrl',
        //link: link,
        templateUrl: 'components/directives/peptideViewer-directive/peptideViewer-directive.html'
    };
});

peptideViewerDirective.controller("PeptideViewerCtrl", ['$scope', '$filter', 'ClusterPeptides', 'ngTableParams', function($scope, $filter, ClusterPeptides, ngTableParams) {
    // init an empty array of peptides
    $scope.peptides = [];

    // function to be called at init to get peptides using remote web service
    $scope.getPeptides = function() {
        ClusterPeptides.get(
            {clusterId: $scope.clusterId},
            function (data) {

                $scope.peptides = data.clusteredPeptides;

                // here we create a simplified modification list for each peptide that is used for
                // showing tooltips as required by the <prc-peptide-sequence-viewer> directive
                for (j = 0; j < $scope.peptides.length; j++) {
                    var peptide = $scope.peptides[j];
                    peptide.mods = [];
                    if (peptide.modifications != null) {
                        for (i = 0; i < peptide.modifications.length; i++) {
                            peptide.mods[peptide.modifications[i].mainPosition - 1] = peptide.modifications[i].name;
                        }
                    }
                }

                $scope.tableParams.reload();
            }
        );

    };

    // setup ng-table with sorting and pagination
    $scope.tableParams = new ngTableParams({
            page: 1,            // show first page
            count: 10,           // count per page
            sorting: {
                numberOfPSMs: 'desc'
            }
        }, {
            total: $scope.peptides.length, // length of data
            getData: function($defer, params) {

                // use build-in angular filter
                var orderedData = params.sorting() ?
                    $filter('orderBy')($scope.peptides, params.orderBy()) :
                    data;

                params.total(orderedData.length);
                $scope.peptides_slice = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());
                $defer.resolve($scope.peptides_slice);
            }
    });
}]);<|endoftext|>


<commit_before>// Things to know:
// - `test` is a global function from Jest:
//   `test(messageString, testerFunction)`
//   Learn more here: https://facebook.github.io/jest/docs/api.html#testname-fn
// - `expect` is a global function from Jest
//   which allows you to make assertsions. For
//   example:
//     `expect(1).toBe(1)`
//   Learn more here: https://facebook.github.io/jest/docs/expect.html
//
// Write unit tests for getTokenFromHeader.
// See `api/src/routes/utils/get-token-from-header.js`
// to see how this function has been implemented and
// how it's intended to be used. Write at least two unit
// tests to ensure that that use case is always supported.
import getTokenFromHeader from '../get-token-from-header'

test('this is the title of your test', () => {
  // this is where you put your test code. Write code that will
  // throw an error if getTokenFromHeader has a bug. The `expect`
  // global is a utility that makes writting such assertions easier,
  // but you can do it however you like.
})

//////// Elaboration & Feedback /////////
// When you've finished with the exercises:
// 1. Copy the URL below into your browser and fill out the form
// 2. remove the `.skip` from the test below
// 3. Change submitted from `false` to `true`
// 4. And you're all done!
/*
http://ws.kcd.im/?ws=Testing&e=API%20Unit&em=hello@jmsmrgn.com*/
test.skip('I submitted my elaboration and feedback', () => {
  const submitted = false // change this when you've submitted!
  expect(true).toBe(submitted)
})
////////////////////////////////
<commit_msg>test getTokenFromHeader<commit_after>import getTokenFromHeader from '../get-token-from-header'

test('getTokenFromHeader returns null if there is no token', () => {
  const req = getReq()
  const result = getTokenFromHeader(req)
  expect(result).toBeNull()
})

test('getTokenFromHeader returns the token when provided', () => {
  const token = 'some.token.thing'
  const authorization = `Token ${token}`
  const req = getReq(authorization)
  const result = getTokenFromHeader(req)
  expect(result).toBe(token)
})

function getReq(authorization) {
  return {headers: {authorization}}
}

//////// Elaboration & Feedback /////////
// When you've finished with the exercises:
// 1. Copy the URL below into your browser and fill out the form
// 2. remove the `.skip` from the test below
// 3. Change submitted from `false` to `true`
// 4. And you're all done!
/*
http://ws.kcd.im/?ws=Testing&e=API%20Unit&em=hello@jmsmrgn.com*/
test('I submitted my elaboration and feedback', () => {
  const submitted = true // change this when you've submitted!
  expect(true).toBe(submitted)
})
////////////////////////////////
<|endoftext|>


<commit_before>define([
    'q',
    'knockout',
    'util/galaxy',
    'util/form',
    'store/Accounts',
    'store/Profiles',
    'store/Formulas',
    'store/InstanceSizes',
    'store/Blueprints',
    'store/Regions',
    'store/Snapshots',
    'store/HostAccessRules',
    'store/HostVolumes',
    'store/BlueprintHosts',
    'store/FormulaComponents',
    'store/BlueprintComponents',
    'api/api',
    'model/models'
],
function (Q, ko, $galaxy, formutils, AccountStore, ProfileStore, FormulaStore, InstanceSizeStore, BlueprintStore, RegionStore, SnapshotStore,
          HostRuleStore, HostVolumeStore, BlueprintHostStore, FormulaComponentStore, BlueprintComponentStore, API, models) {
    var vm = function () {
        var self = this;

        /*
         *  ==================================================================================
         *   V I E W   V A R I A B L E S
         *  ==================================================================================
        */
        self.selectedProfile = null;
        self.selectedBlueprint = ko.observable(null);
        self.blueprintTitle = ko.observable();
        self.blueprintProperties = ko.observable();
        self.blueprintPropertiesStringified = ko.observable();
        self.hostIsSpotInstance = ko.observable(false);
        self.vpcEnabled = ko.observable(false);
        self.subnets = ko.observable([]);

        self.zones = ko.observableArray();

        self.$galaxy = $galaxy;

        self.ProfileStore = ProfileStore;
        self.FormulaStore = FormulaStore;
        self.InstanceSizeStore = InstanceSizeStore;
        self.BlueprintStore = BlueprintStore;
        self.RegionStore = RegionStore;
        self.SnapshotStore = SnapshotStore;
        self.HostRuleStore = HostRuleStore;
        self.HostVolumeStore = HostVolumeStore;
        self.BlueprintHostStore = BlueprintHostStore;

        /*
         *  ==================================================================================
         *   R E G I S T R A T I O N   S E C T I O N
         *  ==================================================================================
        */
        self.id = 'host.detail';
        self.templatePath = 'host.html';
        self.domBindingId = '#host-detail';

        try {
            $galaxy.join(self);
        } catch (ex) {
            console.log(ex);
        }

        /*
         *  ==================================================================================
         *   E V E N T   S U B S C R I P T I O N S
         *  ==================================================================================
         */
        $galaxy.network.subscribe(self.id + '.docked', function (data) {
            FormulaStore.populate().then(function (formulas) {
                FormulaStore.collection().forEach(function (formula) {
                    for (var c in formula.components) {
                        FormulaComponentStore.add(new models.FormulaComponent().create(formula.components[c]));
                    }
                });
            });

            SnapshotStore.populate();

            // Load accounts, profiles, blueprints, instance sizes and availability zones
            AccountStore.populate().then(function () {
                return ProfileStore.populate();
            }).then(function () {
                return BlueprintStore.populate();
            }).then(function () {
                return InstanceSizeStore.populate();
            }).then(function () {
                return RegionStore.populate();
            }).then(function () {
                self.init(data);
            });
        });

        $galaxy.network.subscribe('newhost', function () {
            formutils.clearForm('blueprint-host-form');
        });

        /*
         *  ==================================================================================
         *   V I E W   M E T H O D S
         *  ==================================================================================
         */

        self.init = function (data) {
            var blueprint = null;
            var profile = null;
            var provider = null;

            // $('#formula_components').selectpicker();
            // $('#host_instance_size').selectpicker();
            // $('#availability_zone').selectpicker();

            if (data.hasOwnProperty('blueprint')) {
                blueprint = BlueprintStore.collection().filter(function (p) {
                    return p.id === parseInt(data.blueprint, 10);
                })[0];

                self.selectedBlueprint(blueprint);
                self.blueprintTitle(blueprint.title);
            } else {
                self.blueprintTitle('New Blueprint');
            }

            if (data.hasOwnProperty('profile')) {
                profile = ProfileStore.collection().filter(function (p) {
                    return p.id === parseInt(data.profile, 10);
                })[0];

                self.selectedProfile = profile;
                $('#host_instance_size').val(profile.default_instance_size);

                var profileAccount = AccountStore.collection().filter(function (account) {
                    return account.id === profile.cloud_provider;
                })[0];

                // VPC-related logic
                self.vpcEnabled(profileAccount.vpc_id.length > 0);
                API.Accounts.subnets(profileAccount).then(function(subnets) {
                    self.subnets(subnets);
                });

                var region = RegionStore.collection().filter(function (region) {
                    return region.id === profileAccount.region;
                })[0];

                API.Regions.getZones(region).then(function (zones) {
                    zones.forEach(function (zone) {
                        self.zones.push(zone);
                    });
                });

                $('#availability_zone').val();

            }

            // Only show spot instance price box if the spot instance checkbox is checked
            $('#spot_instance').click(function () {
                self.hostIsSpotInstance(this.checked);
            });
        };

        self._subnetLabel = function(subnet) {
            if(subnet.tags && subnet.tags.Name) {
                return subnet.tags.Name + ' (' + subnet.id + ' | ' + subnet.availability_zone + ')';
            } else {
                return subnet.id;
            }
        };

        self.resetFormFields = function () {
            $("#formula_components").attr('selectedIndex', '-1').find("option:selected").removeAttr("selected");
            $('#spot_instance_price').val('');

            // Set spot instance boolean to false in order to hide the input field for next time
            self.hostIsSpotInstance(false);
        };

        self.cancelHostCreation = function () {
            formutils.clearForm('blueprint-host-form');
            self.resetFormFields();

            if (self.selectedBlueprint() === null) {
                $galaxy.transport('blueprint.detail');
            } else {
                $galaxy.transport({
                    location: 'blueprint.detail',
                    payload: {
                        blueprint: self.selectedBlueprint().id
                    }
                });
            }
        };

        self.createHost = function (model, evt) {
            var record = formutils.collectFormFields(evt.target.form);
            var v, vol;

            var params = {
                id: '',
                formulas: [],
                title: record.host_title.value,
                description: record.host_description.value,
                count: parseInt(record.host_count.value, 10),
                size: parseInt(record.host_instance_size.value, 10),
                hostname_template: record.host_hostname.value,
                zone: parseInt(record.availability_zone.value, 10),
                subnet_id: record.subnet_id.value,
                cloud_profile: self.selectedProfile.id,
                access_rules: HostRuleStore.collection().map(function (host) { return host; }),
                volumes: HostVolumeStore.collection().map(function (volume) { return volume; }),
                formula_components: record.formula_components.map(function (g) { return { id: g.value.split('|')[1], order: 0 }; })
            };

            // Create a new host definition
            var host = new models.BlueprintHost().create(params);

            // Get the properties for each formula component the user chose
            record.formula_components.forEach(function (component) {
                var formulaId = parseInt(component.value.split('|')[0], 10);
                var componentId = parseInt(component.value.split('|')[1], 10);
                var propBuilder = self.blueprintProperties();

                // Find the formula matching the id chosen in the component field
                var formula = _.find(FormulaStore.collection(), function (formula) {
                    return formula.id === formulaId;
                });

                // Find the formula matching the id chosen in the component field
                var component = _.find(FormulaComponentStore.collection(), function (comp) {
                    return comp.id === componentId;
                });

                // Provide a default component orchestration order of 0
                component.order = 0;
                component.host = { title: host.title };

                if (typeof _.findWhere(BlueprintComponentStore.collection(), { id: component.id }) === "undefined") {
                    BlueprintComponentStore.add(component);
                }

                host.formulas.push(formula);
            });

            // Add the instance size object to the host so the title can be displayed in UI
            host.instance_size = _.find(InstanceSizeStore.collection(), function (i) {
                return i.id === parseInt(record.host_instance_size.value, 10);
            });

            // Add some HTML to display for the chosen roles
            host.flat_components = _.map(record.formula_components, function (fc) {
                return '
' + fc.text + '
';
            }).join('');

            // Add some HTML to display for the added volumes
            host.flat_volumes = host.volumes.map(function (volume) {
                var snapshot = SnapshotStore.collection().filter(function (snapshot) {
                    return snapshot.id === parseInt(volume.snapshot, 10);
                })[0];
                return '
Snapshot '+ snapshot.title + ' (' + volume.device + ') mounted to '+volume.mount_point+'
';
            }).join('');

            // Add some HTML to display for the chosen security groups
            host.flat_access_rules = HostRuleStore.collection().map(function (rule) {
                return '
Port(s) '+rule.from_port+'-'+rule.to_port+' allow '+rule.rule+'
';
            }).join('');

            // Add spot instance config
            if (record.spot_instance_price.value !== '') {
                host.spot_config = {};
                host.spot_config.spot_price = parseFloat(record.spot_instance_price.value);
            }

            // Request the forumula properties
            var formulaPromises = [];
            var propBuilder = {};

            host.formulas.forEach(function (formula) {
                var promise = API.Formulas.getProperties(formula).then(function (properties) {

                    // Loop through the received properties and assign them to self.blueprintProperties
                    for (var key in properties) {
                        propBuilder[key] = properties[key];
                    }
                });

                formulaPromises[formulaPromises.length] = promise;
            });

            // Get all formula components and add
            Q.all(formulaPromises).then(function () {

                host.properties = propBuilder;

                // Clear hosts from the store
                self.BlueprintHostStore.add(host);

                // Clear out the forumla select control
                // $('#formula_components').selectpicker('deselectAll');

                self.resetFormFields();

                // Clear volume and access rules stores
                self.HostRuleStore.empty();
                self.HostVolumeStore.empty();

                self.viewBlueprint();
            }).done();

        };

        self.viewBlueprint = function () {
            if (self.selectedBlueprint() === null) {
                $galaxy.transport('blueprint.detail');
            } else {
                $galaxy.transport({
                    location: 'blueprint.detail',
                    payload: {
                        blueprint: self.selectedBlueprint().id
                    }
                });
            }
        };

        self.addAccessRule = function () {
            if (self.selectedBlueprint() === null) {
                $galaxy.transport('accessrule.detail');
            } else {
                $galaxy.transport({
                    location: 'accessrule.detail',
                    payload: {
                        blueprint: self.selectedBlueprint().id
                    }
                });
            }
        };

        self.addVolume = function () {
            if (self.selectedBlueprint() === null) {
                $galaxy.transport('volume.detail');
            } else {
                $galaxy.transport({
                    location: 'volume.detail',
                    payload: {
                        blueprint: self.selectedBlueprint().id
                    }
                });
            }
        };

    };
    return new vm();
});
<commit_msg>Fixed issue where zones were added multiple times to the blueprint host screen<commit_after>define([
    'q',
    'knockout',
    'util/galaxy',
    'util/form',
    'store/Accounts',
    'store/Profiles',
    'store/Formulas',
    'store/InstanceSizes',
    'store/Blueprints',
    'store/Regions',
    'store/Snapshots',
    'store/HostAccessRules',
    'store/HostVolumes',
    'store/BlueprintHosts',
    'store/FormulaComponents',
    'store/BlueprintComponents',
    'api/api',
    'model/models'
],
function (Q, ko, $galaxy, formutils, AccountStore, ProfileStore, FormulaStore, InstanceSizeStore, BlueprintStore, RegionStore, SnapshotStore,
          HostRuleStore, HostVolumeStore, BlueprintHostStore, FormulaComponentStore, BlueprintComponentStore, API, models) {
    var vm = function () {
        var self = this;

        /*
         *  ==================================================================================
         *   V I E W   V A R I A B L E S
         *  ==================================================================================
        */
        self.selectedProfile = null;
        self.selectedBlueprint = ko.observable(null);
        self.blueprintTitle = ko.observable();
        self.blueprintProperties = ko.observable();
        self.blueprintPropertiesStringified = ko.observable();
        self.hostIsSpotInstance = ko.observable(false);
        self.vpcEnabled = ko.observable(false);
        self.subnets = ko.observable([]);

        self.zones = ko.observableArray();

        self.$galaxy = $galaxy;

        self.ProfileStore = ProfileStore;
        self.FormulaStore = FormulaStore;
        self.InstanceSizeStore = InstanceSizeStore;
        self.BlueprintStore = BlueprintStore;
        self.RegionStore = RegionStore;
        self.SnapshotStore = SnapshotStore;
        self.HostRuleStore = HostRuleStore;
        self.HostVolumeStore = HostVolumeStore;
        self.BlueprintHostStore = BlueprintHostStore;

        /*
         *  ==================================================================================
         *   R E G I S T R A T I O N   S E C T I O N
         *  ==================================================================================
        */
        self.id = 'host.detail';
        self.templatePath = 'host.html';
        self.domBindingId = '#host-detail';

        try {
            $galaxy.join(self);
        } catch (ex) {
            console.log(ex);
        }

        /*
         *  ==================================================================================
         *   E V E N T   S U B S C R I P T I O N S
         *  ==================================================================================
         */
        $galaxy.network.subscribe(self.id + '.docked', function (data) {
            FormulaStore.populate().then(function (formulas) {
                FormulaStore.collection().forEach(function (formula) {
                    for (var c in formula.components) {
                        FormulaComponentStore.add(new models.FormulaComponent().create(formula.components[c]));
                    }
                });
            });

            SnapshotStore.populate();

            // Load accounts, profiles, blueprints, instance sizes and availability zones
            AccountStore.populate().then(function () {
                return ProfileStore.populate();
            }).then(function () {
                return BlueprintStore.populate();
            }).then(function () {
                return InstanceSizeStore.populate();
            }).then(function () {
                return RegionStore.populate();
            }).then(function () {
                self.init(data);
            });
        });

        $galaxy.network.subscribe('newhost', function () {
            formutils.clearForm('blueprint-host-form');
        });

        /*
         *  ==================================================================================
         *   V I E W   M E T H O D S
         *  ==================================================================================
         */

        self.init = function (data) {
            var blueprint = null;
            var profile = null;
            var provider = null;

            // $('#formula_components').selectpicker();
            // $('#host_instance_size').selectpicker();
            // $('#availability_zone').selectpicker();

            if (data.hasOwnProperty('blueprint')) {
                blueprint = BlueprintStore.collection().filter(function (p) {
                    return p.id === parseInt(data.blueprint, 10);
                })[0];

                self.selectedBlueprint(blueprint);
                self.blueprintTitle(blueprint.title);
            } else {
                self.blueprintTitle('New Blueprint');
            }

            if (data.hasOwnProperty('profile')) {
                profile = ProfileStore.collection().filter(function (p) {
                    return p.id === parseInt(data.profile, 10);
                })[0];

                self.selectedProfile = profile;
                $('#host_instance_size').val(profile.default_instance_size);

                var profileAccount = AccountStore.collection().filter(function (account) {
                    return account.id === profile.cloud_provider;
                })[0];

                // VPC-related logic
                self.vpcEnabled(profileAccount.vpc_id.length > 0);
                API.Accounts.subnets(profileAccount).then(function(subnets) {
                    self.subnets(subnets);
                });

                var region = RegionStore.collection().filter(function (region) {
                    return region.id === profileAccount.region;
                })[0];

                API.Regions.getZones(region).then(function (zones) {
                    self.zones.removeAll();
                    zones.forEach(function (zone) {
                        self.zones.push(zone);
                    });
                });

                $('#availability_zone').val();

            }

            // Only show spot instance price box if the spot instance checkbox is checked
            $('#spot_instance').click(function () {
                self.hostIsSpotInstance(this.checked);
            });
        };

        self._subnetLabel = function(subnet) {
            if(subnet.tags && subnet.tags.Name) {
                return subnet.tags.Name + ' (' + subnet.id + ' | ' + subnet.availability_zone + ')';
            } else {
                return subnet.id;
            }
        };

        self.resetFormFields = function () {
            $("#formula_components").attr('selectedIndex', '-1').find("option:selected").removeAttr("selected");
            $('#spot_instance_price').val('');

            // Set spot instance boolean to false in order to hide the input field for next time
            self.hostIsSpotInstance(false);
        };

        self.cancelHostCreation = function () {
            formutils.clearForm('blueprint-host-form');
            self.resetFormFields();

            if (self.selectedBlueprint() === null) {
                $galaxy.transport('blueprint.detail');
            } else {
                $galaxy.transport({
                    location: 'blueprint.detail',
                    payload: {
                        blueprint: self.selectedBlueprint().id
                    }
                });
            }
        };

        self.createHost = function (model, evt) {
            var record = formutils.collectFormFields(evt.target.form);
            var v, vol;

            var params = {
                id: '',
                formulas: [],
                title: record.host_title.value,
                description: record.host_description.value,
                count: parseInt(record.host_count.value, 10),
                size: parseInt(record.host_instance_size.value, 10),
                hostname_template: record.host_hostname.value,
                zone: parseInt(record.availability_zone.value, 10),
                subnet_id: record.subnet_id.value,
                cloud_profile: self.selectedProfile.id,
                access_rules: HostRuleStore.collection().map(function (host) { return host; }),
                volumes: HostVolumeStore.collection().map(function (volume) { return volume; }),
                formula_components: record.formula_components.map(function (g) { return { id: g.value.split('|')[1], order: 0 }; })
            };

            // Create a new host definition
            var host = new models.BlueprintHost().create(params);

            // Get the properties for each formula component the user chose
            record.formula_components.forEach(function (component) {
                var formulaId = parseInt(component.value.split('|')[0], 10);
                var componentId = parseInt(component.value.split('|')[1], 10);
                var propBuilder = self.blueprintProperties();

                // Find the formula matching the id chosen in the component field
                var formula = _.find(FormulaStore.collection(), function (formula) {
                    return formula.id === formulaId;
                });

                // Find the formula matching the id chosen in the component field
                var component = _.find(FormulaComponentStore.collection(), function (comp) {
                    return comp.id === componentId;
                });

                // Provide a default component orchestration order of 0
                component.order = 0;
                component.host = { title: host.title };

                if (typeof _.findWhere(BlueprintComponentStore.collection(), { id: component.id }) === "undefined") {
                    BlueprintComponentStore.add(component);
                }

                host.formulas.push(formula);
            });

            // Add the instance size object to the host so the title can be displayed in UI
            host.instance_size = _.find(InstanceSizeStore.collection(), function (i) {
                return i.id === parseInt(record.host_instance_size.value, 10);
            });

            // Add some HTML to display for the chosen roles
            host.flat_components = _.map(record.formula_components, function (fc) {
                return '
' + fc.text + '
';
            }).join('');

            // Add some HTML to display for the added volumes
            host.flat_volumes = host.volumes.map(function (volume) {
                var snapshot = SnapshotStore.collection().filter(function (snapshot) {
                    return snapshot.id === parseInt(volume.snapshot, 10);
                })[0];
                return '
Snapshot '+ snapshot.title + ' (' + volume.device + ') mounted to '+volume.mount_point+'
';
            }).join('');

            // Add some HTML to display for the chosen security groups
            host.flat_access_rules = HostRuleStore.collection().map(function (rule) {
                return '
Port(s) '+rule.from_port+'-'+rule.to_port+' allow '+rule.rule+'
';
            }).join('');

            // Add spot instance config
            if (record.spot_instance_price.value !== '') {
                host.spot_config = {};
                host.spot_config.spot_price = parseFloat(record.spot_instance_price.value);
            }

            // Request the forumula properties
            var formulaPromises = [];
            var propBuilder = {};

            host.formulas.forEach(function (formula) {
                var promise = API.Formulas.getProperties(formula).then(function (properties) {

                    // Loop through the received properties and assign them to self.blueprintProperties
                    for (var key in properties) {
                        propBuilder[key] = properties[key];
                    }
                });

                formulaPromises[formulaPromises.length] = promise;
            });

            // Get all formula components and add
            Q.all(formulaPromises).then(function () {

                host.properties = propBuilder;

                // Clear hosts from the store
                self.BlueprintHostStore.add(host);

                // Clear out the forumla select control
                // $('#formula_components').selectpicker('deselectAll');

                self.resetFormFields();

                // Clear volume and access rules stores
                self.HostRuleStore.empty();
                self.HostVolumeStore.empty();

                self.viewBlueprint();
            }).done();

        };

        self.viewBlueprint = function () {
            if (self.selectedBlueprint() === null) {
                $galaxy.transport('blueprint.detail');
            } else {
                $galaxy.transport({
                    location: 'blueprint.detail',
                    payload: {
                        blueprint: self.selectedBlueprint().id
                    }
                });
            }
        };

        self.addAccessRule = function () {
            if (self.selectedBlueprint() === null) {
                $galaxy.transport('accessrule.detail');
            } else {
                $galaxy.transport({
                    location: 'accessrule.detail',
                    payload: {
                        blueprint: self.selectedBlueprint().id
                    }
                });
            }
        };

        self.addVolume = function () {
            if (self.selectedBlueprint() === null) {
                $galaxy.transport('volume.detail');
            } else {
                $galaxy.transport({
                    location: 'volume.detail',
                    payload: {
                        blueprint: self.selectedBlueprint().id
                    }
                });
            }
        };

    };
    return new vm();
});
<|endoftext|>


<commit_before>angular.module("Prometheus.directives").directive('ngChanged', function() {
  return {
    restrict: "A",
    link: function(scope, element, attrs) {
      element.bind("change", function() {
        scope.$eval(attrs.ngChanged);
      });
    }
  };
});
<commit_msg>Use $apply() in ngChanged to immediately propagate model changes.<commit_after>angular.module("Prometheus.directives").directive('ngChanged', function() {
  return {
    restrict: "A",
    link: function(scope, element, attrs) {
      element.bind("change", function() {
        scope.$apply(attrs.ngChanged);
      });
    }
  };
});
<|endoftext|>


<commit_before>(function(){

    var cIncludedFiles = {};

    window.include = function(sFile, bEngineInclude){
        try
        {
            if (!cIncludedFiles[sFile])
            {
                var cRequest = new XMLHttpRequest();

                var sIncludePath = bEngineInclude ? window.EN.settings.enginePath : window.EN.settings.gamePath;

                cRequest.open("GET", sIncludePath + sFile, false);
                cRequest.send(null);

                if (cRequest.status === 200)
                {
                    (function(){
                        var exports = {};

                        eval(cRequest.responseText);

                        for (var sExport in exports)
                        {
                            window[sExport] = exports[sExport];
                        }
                    })();

                    cIncludedFiles[sFile] = true;
                }
                else
                {
                    throw new Error("Unable to include file: " + sFile);
                }
            }
        }
        catch (e)
        {
            console.error(e.stack);
            throw e;
        }
    };
})();

if (typeof window["EN"] == "undefined")
{
    window.EN = {
        settings: {
            includePath: "/"
        }
    };
}

include("lib/hammer/hammer-1.0.6dev.min.js", true);

include("base/base.js", true);
include("base/logging.js", true);
include("base/game.js", true);

window.EN.Init = function(fOnInit){
    var fInit = function(){
        try
        {
            fOnInit();
        }
        catch (e)
        {
            console.error(e.stack);
            throw e;
        }

        fInit = null;
    };

    var cParams = parseQueryParams();

    if (isset(cParams.Playground))
    {
        window.addEventListener("message", (function(){
            var cParentWindow = null;

            var aValidInstruments = ["FPSUpdate", "DebugLog"];

            return function(cEvent){
                switch (cEvent.data.message)
                {
                    case "HandShake":
                        cParentWindow = cEvent.source;
                        cParentWindow.postMessage({ message: "HandShakeSuccessful" }, "*");
                        break;
                    case "InstrumentUpdate":
                        aValidInstruments.forEach(function(sInstrument){
                            if (isset(cEvent.data.data[sInstrument]) && cEvent.data.data[sInstrument])
                            {
                                window["playground" + sInstrument] = (function(sInstrument){
                                    return function(data){
                                        try
                                        {
                                            cParentWindow.postMessage({
                                                message: sInstrument,
                                                data: data
                                            }, "*");
                                        }
                                        catch (e){}
                                    };
                                })(sInstrument);
                            }
                            else
                            {
                                delete window["playground" + sInstrument];
                            }
                        });

                        if (fInit)
                        {
                            fInit();
                        }

                        break;
                }
            };
        })(), false);
    }
    else
    {
        fInit();
    }
};<commit_msg>cleanup<commit_after>(function(){

    var cIncludedFiles = {};

    window.include = function(sFile, bEngineInclude){
        try
        {
            if (!cIncludedFiles[sFile])
            {
                var cRequest = new XMLHttpRequest();

                var sIncludePath = bEngineInclude ? EN.settings.enginePath : EN.settings.gamePath;

                cRequest.open("GET", sIncludePath + sFile, false);
                cRequest.send(null);

                if (cRequest.status === 200)
                {
                    (function(){
                        var exports = {};

                        eval(cRequest.responseText);

                        for (var sExport in exports)
                        {
                            window[sExport] = exports[sExport];
                        }
                    })();

                    cIncludedFiles[sFile] = true;
                }
                else
                {
                    throw new Error("Unable to include file: " + sFile);
                }
            }
        }
        catch (e)
        {
            console.error(e.stack);
            throw e;
        }
    };
})();

if (typeof EN == "undefined")
{
    EN = {
        settings: {
            includePath: "/"
        }
    };
}

include("lib/hammer/hammer-1.0.6dev.min.js", true);

include("base/base.js", true);
include("base/logging.js", true);
include("base/game.js", true);

EN.Init = function(fOnInit){
    var fInit = function(){
        try
        {
            fOnInit();
        }
        catch (e)
        {
            console.error(e.stack);
            throw e;
        }

        fInit = null;
    };

    var cParams = parseQueryParams();

    if (isset(cParams.Playground))
    {
        window.addEventListener("message", (function(){
            var cParentWindow = null;

            var aValidInstruments = ["FPSUpdate", "DebugLog"];

            return function(cEvent){
                switch (cEvent.data.message)
                {
                    case "HandShake":
                        cParentWindow = cEvent.source;
                        cParentWindow.postMessage({ message: "HandShakeSuccessful" }, "*");
                        break;
                    case "InstrumentUpdate":
                        aValidInstruments.forEach(function(sInstrument){
                            if (isset(cEvent.data.data[sInstrument]) && cEvent.data.data[sInstrument])
                            {
                                window["playground" + sInstrument] = (function(sInstrument){
                                    return function(data){
                                        try
                                        {
                                            cParentWindow.postMessage({
                                                message: sInstrument,
                                                data: data
                                            }, "*");
                                        }
                                        catch (e){}
                                    };
                                })(sInstrument);
                            }
                            else
                            {
                                delete window["playground" + sInstrument];
                            }
                        });

                        if (fInit)
                        {
                            fInit();
                        }

                        break;
                }
            };
        })(), false);
    }
    else
    {
        fInit();
    }
};<|endoftext|>


<commit_before>import CleansUp from 'discourse/mixins/cleans-up';

var clickOutsideEventName = "mousedown.outside-user-card",
    clickDataExpand = "click.discourse-user-card",
    clickMention = "click.discourse-user-mention";

export default Discourse.View.extend(CleansUp, {
  elementId: 'user-card',
  classNameBindings: ['controller.visible::hidden', 'controller.showBadges', 'controller.hasCardBadgeImage'],
  allowBackgrounds: Discourse.computed.setting('allow_profile_backgrounds'),

  addBackground: function() {
    var url = this.get('controller.user.card_background');
    if (!this.get('allowBackgrounds')) { return; }

    var $this = this.$();
    if (!$this) { return; }

    if (Ember.empty(url)) {
      $this.css('background-image', '').addClass('no-bg');
    } else {
      $this.css('background-image', "url(" + url + ")").removeClass('no-bg');
    }
  }.observes('controller.user.card_background'),

  _setup: function() {
    var self = this;
    this.appEvents.on('poster:expand', this, '_posterExpand');

    $('html').off(clickOutsideEventName).on(clickOutsideEventName, function(e) {
      if (self.get('controller.visible')) {
        var $target = $(e.target);
        if ($target.closest('[data-user-card]').data('userCard') ||
            $target.closest('a.mention').length > 0 ||
            $target.closest('#user-card').length > 0) {
          return;
        }

        self.get('controller').close();
      }

      return true;
    });

    var expand = function(username, $target){
      self._posterExpand($target);
      self.get('controller').show(username, $target[0]);
      return false;
    };

    $('#main-outlet').on(clickDataExpand, '[data-user-card]', function(e) {
      var $target = $(e.currentTarget);
      var username = $target.data('user-card');
      return expand(username, $target);
    });

    $('#main-outlet').on(clickMention, 'a.mention', function(e) {
      var $target = $(e.target);
      var username = $target.text().replace(/^@/, '');
      return expand(username, $target);
    });
  }.on('didInsertElement'),

  _posterExpand: function(target) {
    if (!target) { return; }
    var self = this,
        width = this.$().width();
    Em.run.schedule('afterRender', function() {
      if (target) {
        var position = target.offset();
        if (position) {
          position.left += target.width() + 10;

          var overage = ($(window).width() - 50) - (position.left + width);
          if (overage < 0) {
            position.left += overage;
            position.top += target.height() + 5;
          }

          position.top -= $('#main-outlet').offset().top;
          self.$().css(position);
        }
      }
    });
  },

  cleanUp: function() {
    this.get('controller').close();
  },

  _removeEvents: function() {
    $('html').off(clickOutsideEventName);
    $('#main').off(clickDataExpand);
    $('#main').off(clickMention);

    this.appEvents.off('poster:expand', this, '_posterExpand');
  }.on('willDestroyElement')

});
<commit_msg>tweak positioning when it has no room to right<commit_after>import CleansUp from 'discourse/mixins/cleans-up';

var clickOutsideEventName = "mousedown.outside-user-card",
    clickDataExpand = "click.discourse-user-card",
    clickMention = "click.discourse-user-mention";

export default Discourse.View.extend(CleansUp, {
  elementId: 'user-card',
  classNameBindings: ['controller.visible::hidden', 'controller.showBadges', 'controller.hasCardBadgeImage'],
  allowBackgrounds: Discourse.computed.setting('allow_profile_backgrounds'),

  addBackground: function() {
    var url = this.get('controller.user.card_background');
    if (!this.get('allowBackgrounds')) { return; }

    var $this = this.$();
    if (!$this) { return; }

    if (Ember.empty(url)) {
      $this.css('background-image', '').addClass('no-bg');
    } else {
      $this.css('background-image', "url(" + url + ")").removeClass('no-bg');
    }
  }.observes('controller.user.card_background'),

  _setup: function() {
    var self = this;
    this.appEvents.on('poster:expand', this, '_posterExpand');

    $('html').off(clickOutsideEventName).on(clickOutsideEventName, function(e) {
      if (self.get('controller.visible')) {
        var $target = $(e.target);
        if ($target.closest('[data-user-card]').data('userCard') ||
            $target.closest('a.mention').length > 0 ||
            $target.closest('#user-card').length > 0) {
          return;
        }

        self.get('controller').close();
      }

      return true;
    });

    var expand = function(username, $target){
      self._posterExpand($target);
      self.get('controller').show(username, $target[0]);
      return false;
    };

    $('#main-outlet').on(clickDataExpand, '[data-user-card]', function(e) {
      var $target = $(e.currentTarget);
      var username = $target.data('user-card');
      return expand(username, $target);
    });

    $('#main-outlet').on(clickMention, 'a.mention', function(e) {
      var $target = $(e.target);
      var username = $target.text().replace(/^@/, '');
      return expand(username, $target);
    });
  }.on('didInsertElement'),

  _posterExpand: function(target) {
    if (!target) { return; }
    var self = this,
        width = this.$().width();
    Em.run.schedule('afterRender', function() {
      if (target) {
        var position = target.offset();
        if (position) {
          position.left += target.width() + 10;

          var overage = ($(window).width() - 50) - (position.left + width);
          if (overage < 0) {
            position.left -= (width/2) - 10;
            position.top += target.height() + 8;
          }

          position.top -= $('#main-outlet').offset().top;
          self.$().css(position);
        }
      }
    });
  },

  cleanUp: function() {
    this.get('controller').close();
  },

  _removeEvents: function() {
    $('html').off(clickOutsideEventName);
    $('#main').off(clickDataExpand);
    $('#main').off(clickMention);

    this.appEvents.off('poster:expand', this, '_posterExpand');
  }.on('willDestroyElement')

});
<|endoftext|>


<commit_before>// @flow
/* eslint import/no-extraneous-dependencies: ["error", {"peerDependencies": true}] */

// Integration tests for skeleton.js

import test from "ava";
import mockRequire from "mock-require";
import _ from "lodash";
import { createNodeAction, createTreeAction, deleteNodeAction, createBranchPointAction, setActiveNodeRadiusAction } from "oxalis/model/actions/skeletontracing_actions";

mockRequire.stopAll();
mockRequire("app", { currentUser: { firstName: "SCM", lastName: "Boy" } });
mockRequire("libs/window", {
  alert: console.log.bind(console),
  requestAnimationFrame: resolve => resolve(),
  app: null,
});
const Utils = mockRequire.reRequire("libs/utils").default;
const NodeShader = mockRequire.reRequire("oxalis/geometries/materials/node_shader");
const Store = mockRequire.reRequire("oxalis/store").default;
const Skeleton = mockRequire.reRequire("oxalis/geometries/skeleton").default;

test.before((t) => {
  const rotation = [0.5, 0.5, 0.5];
  const viewport = 0;
  const resolution = 0;

  // create 20 trees with 100 nodes each
  for (let i = 0; i < 2000; i++) {
    if (i % 100 === 0) {
      Store.dispatch(createTreeAction());
    }
    Store.dispatch(createNodeAction([i, i, i], rotation, viewport, resolution));
  }
  const trees = Store.getState().skeletonTracing.trees;
  t.is(_.size(trees), 20);
  for (const tree of Object.values(trees)) {
    t.is(_.size(tree.nodes), 100);
  }
});

test.serial("Skeleton should initialize correctly using the store's state", (t) => {
  const trees = Store.getState().skeletonTracing.trees;
  const skeleton = new Skeleton();

  t.is(skeleton.nodes.buffers.length, 1);
  t.is(skeleton.edges.buffers.length, 1);

  const nodeCapacity = 2000;
  const edgeCapacity = 1980;

  let nodePositions = [];
  const nodeTypes = [];
  const nodeRadii = [];
  const nodeIds = [];
  const nodeTreeIds = [];
  let edgePositions = [];
  const edgeTreeIds = [];
  let treeColors = [0, 0, 0]; // tree ids start at index 1

  for (const tree of Object.values(trees)) {
    treeColors = treeColors.concat(tree.color);
    for (const node of Object.values(tree.nodes)) {
      nodePositions = nodePositions.concat(node.position);
      nodeTreeIds.push(tree.treeId);
      nodeRadii.push(node.radius);
      nodeIds.push(node.id);
      nodeTypes.push(NodeShader.NodeTypes.NORMAL);
    }
    for (const edge of tree.edges) {
      const sourcePosition = tree.nodes[edge.source].position;
      const targetPosition = tree.nodes[edge.target].position;
      edgePositions = edgePositions.concat(sourcePosition).concat(targetPosition);
      edgeTreeIds.push(tree.treeId, tree.treeId);
    }
  }

  const nodeBufferGeometryAttributes = skeleton.nodes.buffers[0].geometry.attributes;
  t.is(nodeBufferGeometryAttributes.position.array.length, 3 * nodeCapacity);
  t.is(nodeBufferGeometryAttributes.radius.array.length, nodeCapacity);
  t.is(nodeBufferGeometryAttributes.type.array.length, nodeCapacity);
  t.is(nodeBufferGeometryAttributes.nodeId.array.length, nodeCapacity);
  t.is(nodeBufferGeometryAttributes.treeId.array.length, nodeCapacity);

  t.deepEqual(nodeBufferGeometryAttributes.position.array, new Float32Array(nodePositions));
  t.deepEqual(nodeBufferGeometryAttributes.radius.array, new Float32Array(nodeRadii));
  t.deepEqual(nodeBufferGeometryAttributes.type.array, new Float32Array(nodeTypes));
  t.deepEqual(nodeBufferGeometryAttributes.nodeId.array, new Float32Array(nodeIds));
  t.deepEqual(nodeBufferGeometryAttributes.treeId.array, new Float32Array(nodeTreeIds));

  const edgeBufferGeometryAttributes = skeleton.edges.buffers[0].geometry.attributes;
  t.is(edgeBufferGeometryAttributes.position.array.length, 6 * edgeCapacity);
  t.is(edgeBufferGeometryAttributes.treeId.array.length, 2 * edgeCapacity);

  t.deepEqual(edgeBufferGeometryAttributes.position.array, new Float32Array(edgePositions));
  t.deepEqual(edgeBufferGeometryAttributes.treeId.array, new Float32Array(edgeTreeIds));

  const textureData = new Float32Array(NodeShader.COLOR_TEXTURE_WIDTH * NodeShader.COLOR_TEXTURE_WIDTH * 3);
  textureData.set(treeColors);
  t.deepEqual(skeleton.treeColorTexture.image.data, textureData);
});

test.serial("Skeleton should increase its buffers once the max capacity is reached", async (t) => {
  const skeleton = new Skeleton();

  Store.dispatch(createNodeAction([2001, 2001, 2001], [0.5, 0.5, 0.5], 0, 0));

  await Utils.sleep(100);
  t.is(skeleton.nodes.buffers.length, 2);
  t.is(skeleton.edges.buffers.length, 2);
});

test.serial("Skeleton should invalidate a node upon deletion", async (t) => {
  const skeleton = new Skeleton();

  // do index lookup before "dispatch" because index will be deleted as well
  const id = skeleton.combineIds(1, 1);
  const index = skeleton.nodes.idToBufferPosition.get(id).index;

  Store.dispatch(deleteNodeAction(1, 1));
  await Utils.sleep(50);
  t.is(skeleton.nodes.buffers[0].geometry.attributes.type.array[index], NodeShader.NodeTypes.INVALID);
});

test.serial("Skeleton should invalidate an edge upon deletion", async (t) => {
  const skeleton = new Skeleton();

  // do index lookup before "dispatch" because index will be deleted as well
  const id = skeleton.combineIds(2, 1);
  const index = skeleton.nodes.idToBufferPosition.get(id).index;

  Store.dispatch(deleteNodeAction(2, 1));
  await Utils.sleep(50);
  t.deepEqual(skeleton.edges.buffers[0].geometry.attributes.position.array.subarray(index * 6, index * 6 + 6), new Float32Array([0, 0, 0, 0, 0, 0]));
});

test.serial("Skeleton should update node types for branchpoints", async (t) => {
  const skeleton = new Skeleton();

  Store.dispatch(createBranchPointAction(3, 1));

  await Utils.sleep(50);
  const id = skeleton.combineIds(3, 1);
  const index = skeleton.nodes.idToBufferPosition.get(id).index;
  t.is(skeleton.nodes.buffers[0].geometry.attributes.type.array[index], NodeShader.NodeTypes.BRANCH_POINT);
});

test.serial("Skeleton should update node radius", async (t) => {
  const skeleton = new Skeleton();
  const { activeNodeId, activeTreeId } = Store.getState().skeletonTracing;

  Store.dispatch(setActiveNodeRadiusAction(2));

  await Utils.sleep(50);
  const id = skeleton.combineIds(activeNodeId, activeTreeId);
  const index = skeleton.nodes.idToBufferPosition.get(id).index;
  t.is(skeleton.nodes.buffers[0].geometry.attributes.radius.array[index], 2);
});

test.serial("Skeleton should update tree colors upon tree creation", async (t) => {
  const skeleton = new Skeleton();

  Store.dispatch(createTreeAction());
  const { activeTreeId, trees } = Store.getState().skeletonTracing;

  await Utils.sleep(50);
  t.deepEqual(skeleton.treeColorTexture.image.data.subarray(activeTreeId * 3, activeTreeId * 3 + 3), new Float32Array(trees[activeTreeId].color));
});
<commit_msg>added PR feedback<commit_after>// @flow
/* eslint import/no-extraneous-dependencies: ["error", {"peerDependencies": true}] */

// Integration tests for skeleton.js

import test from "ava";
import mockRequire from "mock-require";
import _ from "lodash";
import { createNodeAction, createTreeAction, deleteNodeAction, createBranchPointAction, setActiveNodeRadiusAction } from "oxalis/model/actions/skeletontracing_actions";

mockRequire.stopAll();
mockRequire("app", { currentUser: { firstName: "SCM", lastName: "Boy" } });
mockRequire("libs/window", {
  alert: console.log.bind(console),
  requestAnimationFrame: resolve => resolve(),
  app: null,
});
const Utils = mockRequire.reRequire("libs/utils").default;
const NodeShader = mockRequire.reRequire("oxalis/geometries/materials/node_shader");
const Store = mockRequire.reRequire("oxalis/store").default;
const Skeleton = mockRequire.reRequire("oxalis/geometries/skeleton").default;

test.before((t) => {
  const rotation = [0.5, 0.5, 0.5];
  const viewport = 0;
  const resolution = 0;

  // create 20 trees with 100 nodes each
  for (let i = 0; i < 2000; i++) {
    if (i % 100 === 0) {
      Store.dispatch(createTreeAction());
    }
    Store.dispatch(createNodeAction([i, i, i], rotation, viewport, resolution));
  }
  const trees = Store.getState().skeletonTracing.trees;
  t.is(_.size(trees), 20);
  for (const tree of Object.values(trees)) {
    t.is(_.size(tree.nodes), 100);
  }
});

test.serial("Skeleton should initialize correctly using the store's state", (t) => {
  const trees = Store.getState().skeletonTracing.trees;
  const skeleton = new Skeleton();

  t.is(skeleton.nodes.buffers.length, 1);
  t.is(skeleton.edges.buffers.length, 1);

  const nodeCapacity = 2000;
  const edgeCapacity = 1980;

  let nodePositions = [];
  const nodeTypes = [];
  const nodeRadii = [];
  const nodeIds = [];
  const nodeTreeIds = [];
  let edgePositions = [];
  const edgeTreeIds = [];
  let treeColors = [0, 0, 0]; // tree ids start at index 1 so add one bogus RGB value

  for (const tree of Object.values(trees)) {
    treeColors = treeColors.concat(tree.color);
    for (const node of Object.values(tree.nodes)) {
      nodePositions = nodePositions.concat(node.position);
      nodeTreeIds.push(tree.treeId);
      nodeRadii.push(node.radius);
      nodeIds.push(node.id);
      nodeTypes.push(NodeShader.NodeTypes.NORMAL);
    }
    for (const edge of tree.edges) {
      const sourcePosition = tree.nodes[edge.source].position;
      const targetPosition = tree.nodes[edge.target].position;
      edgePositions = edgePositions.concat(sourcePosition).concat(targetPosition);
      edgeTreeIds.push(tree.treeId, tree.treeId);
    }
  }

  const nodeBufferGeometryAttributes = skeleton.nodes.buffers[0].geometry.attributes;
  t.is(nodeBufferGeometryAttributes.position.array.length, 3 * nodeCapacity);
  t.is(nodeBufferGeometryAttributes.radius.array.length, nodeCapacity);
  t.is(nodeBufferGeometryAttributes.type.array.length, nodeCapacity);
  t.is(nodeBufferGeometryAttributes.nodeId.array.length, nodeCapacity);
  t.is(nodeBufferGeometryAttributes.treeId.array.length, nodeCapacity);

  t.deepEqual(nodeBufferGeometryAttributes.position.array, new Float32Array(nodePositions));
  t.deepEqual(nodeBufferGeometryAttributes.radius.array, new Float32Array(nodeRadii));
  t.deepEqual(nodeBufferGeometryAttributes.type.array, new Float32Array(nodeTypes));
  t.deepEqual(nodeBufferGeometryAttributes.nodeId.array, new Float32Array(nodeIds));
  t.deepEqual(nodeBufferGeometryAttributes.treeId.array, new Float32Array(nodeTreeIds));

  const edgeBufferGeometryAttributes = skeleton.edges.buffers[0].geometry.attributes;
  t.is(edgeBufferGeometryAttributes.position.array.length, 6 * edgeCapacity);
  t.is(edgeBufferGeometryAttributes.treeId.array.length, 2 * edgeCapacity);

  t.deepEqual(edgeBufferGeometryAttributes.position.array, new Float32Array(edgePositions));
  t.deepEqual(edgeBufferGeometryAttributes.treeId.array, new Float32Array(edgeTreeIds));

  const textureData = new Float32Array(NodeShader.COLOR_TEXTURE_WIDTH * NodeShader.COLOR_TEXTURE_WIDTH * 3);
  textureData.set(treeColors);
  t.deepEqual(skeleton.treeColorTexture.image.data, textureData);
});

test.serial("Skeleton should increase its buffers once the max capacity is reached", async (t) => {
  const skeleton = new Skeleton();

  Store.dispatch(createNodeAction([2001, 2001, 2001], [0.5, 0.5, 0.5], 0, 0));

  await Utils.sleep(100);
  t.is(skeleton.nodes.buffers.length, 2);
  t.is(skeleton.edges.buffers.length, 2);
});

test.serial("Skeleton should invalidate a node upon deletion", async (t) => {
  const skeleton = new Skeleton();

  // do index lookup before "dispatch" because index will be deleted as well
  const id = skeleton.combineIds(1, 1);
  const index = skeleton.nodes.idToBufferPosition.get(id).index;

  Store.dispatch(deleteNodeAction(1, 1));
  await Utils.sleep(50);
  t.is(skeleton.nodes.buffers[0].geometry.attributes.type.array[index], NodeShader.NodeTypes.INVALID);
});

test.serial("Skeleton should invalidate an edge upon deletion", async (t) => {
  const skeleton = new Skeleton();

  // do index lookup before "dispatch" because index will be deleted as well
  const id = skeleton.combineIds(2, 1);
  const index = skeleton.nodes.idToBufferPosition.get(id).index;

  Store.dispatch(deleteNodeAction(2, 1));
  await Utils.sleep(50);
  t.deepEqual(skeleton.edges.buffers[0].geometry.attributes.position.array.subarray(index * 6, index * 6 + 6), new Float32Array([0, 0, 0, 0, 0, 0]));
});

test.serial("Skeleton should update node types for branchpoints", async (t) => {
  const skeleton = new Skeleton();

  Store.dispatch(createBranchPointAction(3, 1));

  await Utils.sleep(50);
  const id = skeleton.combineIds(3, 1);
  const index = skeleton.nodes.idToBufferPosition.get(id).index;
  t.is(skeleton.nodes.buffers[0].geometry.attributes.type.array[index], NodeShader.NodeTypes.BRANCH_POINT);
});

test.serial("Skeleton should update node radius", async (t) => {
  const skeleton = new Skeleton();
  const { activeNodeId, activeTreeId } = Store.getState().skeletonTracing;

  Store.dispatch(setActiveNodeRadiusAction(2));

  await Utils.sleep(50);
  const id = skeleton.combineIds(activeNodeId, activeTreeId);
  const index = skeleton.nodes.idToBufferPosition.get(id).index;
  t.is(skeleton.nodes.buffers[0].geometry.attributes.radius.array[index], 2);
});

test.serial("Skeleton should update tree colors upon tree creation", async (t) => {
  const skeleton = new Skeleton();

  Store.dispatch(createTreeAction());
  const { activeTreeId, trees } = Store.getState().skeletonTracing;

  await Utils.sleep(50);
  t.deepEqual(skeleton.treeColorTexture.image.data.subarray(activeTreeId * 3, activeTreeId * 3 + 3), new Float32Array(trees[activeTreeId].color));
});
<|endoftext|>


<commit_before>/* global gl */
/* eslint-disable no-param-reassign */

((gl) => {
  gl.PipelineStore = class {
    fetchDataLoop(Vue) {
      const goFetch = vue =>
        this.$http.get(`/api/v3/projects/${this.scope}/pipelines`)
          .then((response) => {
            vue.set(this, 'pipelines', JSON.parse(response.body));
          }, () => {
            vue.set(this, 'pipelines', []);
          });

      goFetch(Vue);
      setInterval(() => {
        console.log('DID IT');
        goFetch(Vue);
      }, 3000);
    }
  };
})(window.gl || (window.gl = {}));
<commit_msg>will discuss what to do on error at a later time<commit_after>/* global gl */
/* eslint-disable no-param-reassign */

((gl) => {
  gl.PipelineStore = class {
    fetchDataLoop(Vue) {
      const goFetch = vue =>
        this.$http.get(`/api/v3/projects/${this.scope}/pipelines`)
          .then((response) => {
            vue.set(this, 'pipelines', JSON.parse(response.body));
          }, () => {
            console.error('API Error for Pipelines');
          });

      goFetch(Vue);
      setInterval(() => {
        console.log('DID IT');
        goFetch(Vue);
      }, 3000);
    }
  };
})(window.gl || (window.gl = {}));
<|endoftext|>