<commit_before>
import {Service} from './Service';
import {LoginController} from './LoginController';

let ngModule = 'monad.Authentication';
angular.module(ngModule, [])
    .service('monad.Authentication.Service', Service)
    .controller('monad.Authentication.LoginController', LoginController);

export default ngModule;

<commit_msg>this can be simplified now<commit_after>
import {Service} from './Service';
import {LoginController} from './LoginController';

let ngModule = 'monad.Authentication';
angular.module(ngModule, ['ng'])
    .service('Service', Service)
    .controller('LoginController', LoginController);

export default ngModule;

<|endoftext|>


<commit_before>/* @flow */

import { getSDKMeta } from '@paypal/sdk-client/src';
import { ZalgoPromise } from 'zalgo-promise/src';

export function fixCreditRedirect() {

    try {
        if (!window.injector) {
            return;
        }

        const $util = window.injector.get('$util');

        if (!$util || !$util.redirect) {
            return;
        }

        const redirect = $util.redirect;

        $util.redirect = function overrideRedirect(url, ...args) : ZalgoPromise<void> {

            try {
                if (url.indexOf('/ppcreditapply') !== -1 && url.indexOf('key=') !== -1) {
                    url += `&sdkMeta=${ getSDKMeta() }`;
                }

            // eslint-disable-next-line unicorn/catch-error-name
            } catch (err2) {
                // pass
            }

            return redirect.call(this, url, ...args);
        };

    } catch (err) {
        // pass
    }
}
<commit_msg>Do not add sdkMeta to credit url with sdkMeta already set<commit_after>/* @flow */

import { getSDKMeta } from '@paypal/sdk-client/src';
import { ZalgoPromise } from 'zalgo-promise/src';

export function fixCreditRedirect() {

    try {
        if (!window.injector) {
            return;
        }

        const $util = window.injector.get('$util');

        if (!$util || !$util.redirect) {
            return;
        }

        const redirect = $util.redirect;

        $util.redirect = function overrideRedirect(url, ...args) : ZalgoPromise<void> {

            try {
                if (url.indexOf('/ppcreditapply') !== -1 && url.indexOf('key=') !== -1 && url.indexOf('sdkMeta') === -1) {
                    url += `&sdkMeta=${ getSDKMeta() }`;
                }

            // eslint-disable-next-line unicorn/catch-error-name
            } catch (err2) {
                // pass
            }

            return redirect.call(this, url, ...args);
        };

    } catch (err) {
        // pass
    }
}
<|endoftext|>


<commit_before>(function (that, factory) { // ustache.js by dandavis [CCBY4]  https://github.com/rndme/ustache
 if(typeof module === 'object')   			factory(module, 1); 		// CommonJS
 else if(typeof define === 'function' && define.amd)	define(['exports'], factory); 	// AMD
 else							factory(that) 	// script, wsh, asp
}(this, function(that,cjs) { //  syntax RegExps		approximation/eg
	var rxImports = /\{\{>\s*([\w\W]+?)\s*\}\}/g,	// {{>...}}
	rxIndex = /\$\{INDEX\}/g, 			// ${INDEX}
	rxRazor=/(\W)@([#\^!\/\.\)\(]?[\w\.$]+)/g,	// @[#^!/.)(]*ab.c
	rxElse = /\{\{\|([\w\W]+?)\}\}/g,		// {{!...}}
	rxSep = /\$\{SEP\}([\w\W]+?)\$\{\/SEP\}/g, 	// ${SEP}...${/SEP}
	rxComments = /\{\{\![\w\W]*?\}\}/g,		// {{!...}}
	rxInject = /\{\{=([\w\W]+?)\}\}/g,		// {{=...}}
	rxBraces = /\{?\{\{&?([\w\W]+?)\}\}\}?/g,	// {{...}}
	rxNot =  /\$\{(\^)([\w\W]+?)\}(.+?)\$\{\/\2/g,	// ${^ ...}...${$1}
	rxCond = /\$\{(\?)([\w\W]+?)\}(.+?)\$\{\/\2/g,	// ${? ...}...${$1}
	rxIf =   /\$\{(\#)\s*([\w\W]+?)\s*\}([\w\W]+?)?\$\{\/\s*\2/g,	// ${^ ...}...${$1}
	rxObj = /\$\{\$([\w.]+?)\}([\w\W]+?)\$\{\/\1/g,	// ${$:. ...}...${$1}
	rxCarrot = /\$\{\.\}/g,				// ${.}
	rxPath = /\$\{\s*([\w\.]+)\s*\}/g,		// ${...}
	rxReserved = /\b((this)|(SEP)|(INDEX)|(KEY)|(__)|(SCOPE))\b/,
	rxDouble = /(this\.\.)|(this\.this)/g,
	rxThisDot = /this\.([\W$])/g,
	json = JSON.stringify;

	function _tmp(strTemplate, objContext, SCOPE, numIndex, blnInnerCall, arrList, varAllData) {	// string to ES6 converter/executer
		strTemplate = String(strTemplate)		// string FunctionBody of the dynamic rednerer
		.replace(rxIndex, numIndex + 1) 			// turn INDEX keyword into numeric literal
		.replace(rxRazor, "$1{{this.$2}}") 		// convert Razor to normal syntax
		.replace(rxInject, "{{ok(this.$1,this,true)}}") 	// make injections safe
		.replace(rxElse, "{{/$1}}{{^$1}}") 		// turn ELSE expressions into conditional syntax
		.replace(rxSep, arrList && (numIndex<arrList.length-1) ? "$1" : "" )	// replace SEP mini-sections with contents, or nothing of last
		.replace(rxComments, "") 			// strip comment blocks
		.replace(rxBraces, "${$1}")			// turn brace expressions into template string literals
		.replace(rxNot, "${(!this.$2||Array.isArray(this.$2)&&this.$2.length===0)?\"$3\":''")		// condense NOT block into template w/ mustache rules
		.replace(rxObj, function(j,o,s){return "${Object.keys(this."+o+").map(function(a,b,c){return _tmp.call(this,"+json(s)+",this[a]||a,SCOPE,b,true,c,__);},this["+json(o)+"]).join('')";}) // object iteration
		.replace(rxCond, "${this.$2?\"$3\":''")		// condense conditional block into ES6 template expression
		.replace(rxIf, function(j,k,arr,content){var tt= "this["+json(arr)+"]";	return "${ " + tt +" ? ( typeof "+tt+"=='object' ? ( Array.isArray("+tt+")? ("+tt+") : ["+tt+"]   ).map((a,b,c)=>_tmp.call(this,"+json(content)+",a,SCOPE,b,true,c,__),this).join('') :  _tmp.call(this,(typeof "+tt+"=='function'?"+tt+".call(this,"+json(content)+"):"+json(content)+"),this,SCOPE,0,true,[],'') 		  ) : '' ";})
		.replace(rxCarrot, "${this}")			// replace {{.}} with this pointer
		.replace(rxPath, function(j,path){ return rxReserved.test(path) ? "${"+path+"}" : "${ok(this."+path+",this)}"; })
		.replace(rxDouble,"this.") 			// fix possible dot dot bug to pass mustache unit tests
		.replace(rxThisDot ,"this$1")			// fix "this." dandling dots
		var rez = Function("_tmp, ob, __, KEY, SCOPE", "\"use strict\"; "+escapeHtml+ok+" return `" + strTemplate + "`;");	// build string output renderer function
		if(blnInnerCall) return rez.call(objContext, _tmp, objContext, varAllData, arrList[numIndex],SCOPE);// if internally called, returns composited  string using context (not whole data)
		function _apply(data) { return rez.call(data||{}, _tmp, data, data,"__",SCOPE); }; // returns a render function bound to the template internal renderer
		_apply.SCOPE=SCOPE;
		return _apply;
	}

	return that[cjs ? "exports" : "ustache"] = function ustache(strTemplate, data, objImports, SCOPE){	// accepts a string, data, and imports
		// run imports by replacing tokens with values from the imports object:
		if(objImports) strTemplate=strTemplate.replace(rxImports, function(j, name){ return objImports[name]; });
		return data ? // return a render function, or if given data also, a composited string result:
			_tmp.call(this, strTemplate, 0, SCOPE||{}).call(this, data) :
			_tmp(strTemplate, 0, SCOPE||{}) ;
    	};

  function ok(v,c,esc){var u; return (esc===true?escapeHtml:String)(v==u?'':(typeof v==='function'? v.call(c,v) : v));}
  function escapeHtml(a){return String(a).replace(/[&<>"'`=\/]/g,function(a){return{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="}[a]})};
}));
<commit_msg>comment typo<commit_after>(function (that, factory) { // ustache.js by dandavis [CCBY4]  https://github.com/rndme/ustache
 if(typeof module === 'object')   			factory(module, 1); 		// CommonJS
 else if(typeof define === 'function' && define.amd)	define(['exports'], factory); 	// AMD
 else							factory(that) 	// script, wsh, asp
}(this, function(that,cjs) { //  syntax RegExps		approximation/eg
	var rxImports = /\{\{>\s*([\w\W]+?)\s*\}\}/g,	// {{>...}}
	rxIndex = /\$\{INDEX\}/g, 			// ${INDEX}
	rxRazor=/(\W)@([#\^!\/\.\)\(]?[\w\.$]+)/g,	// @[#^!/.)(]*ab.c
	rxElse = /\{\{\|([\w\W]+?)\}\}/g,		// {{!...}}
	rxSep = /\$\{SEP\}([\w\W]+?)\$\{\/SEP\}/g, 	// ${SEP}...${/SEP}
	rxComments = /\{\{\![\w\W]*?\}\}/g,		// {{!...}}
	rxInject = /\{\{=([\w\W]+?)\}\}/g,		// {{=...}}
	rxBraces = /\{?\{\{&?([\w\W]+?)\}\}\}?/g,	// {{...}}
	rxNot =  /\$\{(\^)([\w\W]+?)\}(.+?)\$\{\/\2/g,	// ${^ ...}...${$1}
	rxCond = /\$\{(\?)([\w\W]+?)\}(.+?)\$\{\/\2/g,	// ${? ...}...${$1}
	rxIf =   /\$\{(\#)\s*([\w\W]+?)\s*\}([\w\W]+?)?\$\{\/\s*\2/g,	// ${^ ...}...${$1}
	rxObj = /\$\{\$([\w.]+?)\}([\w\W]+?)\$\{\/\1/g,	// ${$:. ...}...${$1}
	rxCarrot = /\$\{\.\}/g,				// ${.}
	rxPath = /\$\{\s*([\w\.]+)\s*\}/g,		// ${...}
	rxReserved = /\b((this)|(SEP)|(INDEX)|(KEY)|(__)|(SCOPE))\b/,
	rxDouble = /(this\.\.)|(this\.this)/g,
	rxThisDot = /this\.([\W$])/g,
	json = JSON.stringify;

	function _tmp(strTemplate, objContext, SCOPE, numIndex, blnInnerCall, arrList, varAllData) {	// string to ES6 converter/executer
		strTemplate = String(strTemplate)		// string FunctionBody of the dynamic rednerer
		.replace(rxIndex, numIndex + 1) 			// turn INDEX keyword into numeric literal
		.replace(rxRazor, "$1{{this.$2}}") 		// convert Razor to normal syntax
		.replace(rxInject, "{{ok(this.$1,this,true)}}") 	// make injections safe
		.replace(rxElse, "{{/$1}}{{^$1}}") 		// turn ELSE expressions into conditional syntax
		.replace(rxSep, arrList && (numIndex<arrList.length-1) ? "$1" : "" )	// replace SEP mini-sections with contents, or nothing of last
		.replace(rxComments, "") 			// strip comment blocks
		.replace(rxBraces, "${$1}")			// turn brace expressions into template string literals
		.replace(rxNot, "${(!this.$2||Array.isArray(this.$2)&&this.$2.length===0)?\"$3\":''")		// condense NOT block into template w/ mustache rules
		.replace(rxObj, function(j,o,s){return "${Object.keys(this."+o+").map(function(a,b,c){return _tmp.call(this,"+json(s)+",this[a]||a,SCOPE,b,true,c,__);},this["+json(o)+"]).join('')";}) // object iteration
		.replace(rxCond, "${this.$2?\"$3\":''")		// condense conditional block into ES6 template expression
		.replace(rxIf, function(j,k,arr,content){var tt= "this["+json(arr)+"]";	return "${ " + tt +" ? ( typeof "+tt+"=='object' ? ( Array.isArray("+tt+")? ("+tt+") : ["+tt+"]   ).map((a,b,c)=>_tmp.call(this,"+json(content)+",a,SCOPE,b,true,c,__),this).join('') :  _tmp.call(this,(typeof "+tt+"=='function'?"+tt+".call(this,"+json(content)+"):"+json(content)+"),this,SCOPE,0,true,[],'') 		  ) : '' ";})
		.replace(rxCarrot, "${this}")			// replace {{.}} with this pointer
		.replace(rxPath, function(j,path){ return rxReserved.test(path) ? "${"+path+"}" : "${ok(this."+path+",this)}"; })
		.replace(rxDouble,"this.") 			// fix possible dot dot bug to pass mustache unit tests
		.replace(rxThisDot ,"this$1")			// fix "this." dangling dots
		var rez = Function("_tmp, ob, __, KEY, SCOPE", "\"use strict\"; "+escapeHtml+ok+" return `" + strTemplate + "`;");	// build string output renderer function
		if(blnInnerCall) return rez.call(objContext, _tmp, objContext, varAllData, arrList[numIndex],SCOPE);// if internally called, returns composited  string using context (not whole data)
		function _apply(data) { return rez.call(data||{}, _tmp, data, data,"__",SCOPE); }; // returns a render function bound to the template internal renderer
		_apply.SCOPE=SCOPE;
		return _apply;
	}

	return that[cjs ? "exports" : "ustache"] = function ustache(strTemplate, data, objImports, SCOPE){	// accepts a string, data, and imports
		// run imports by replacing tokens with values from the imports object:
		if(objImports) strTemplate=strTemplate.replace(rxImports, function(j, name){ return objImports[name]; });
		return data ? // return a render function, or if given data also, a composited string result:
			_tmp.call(this, strTemplate, 0, SCOPE||{}).call(this, data) :
			_tmp(strTemplate, 0, SCOPE||{}) ;
    	};

  function ok(v,c,esc){var u; return (esc===true?escapeHtml:String)(v==u?'':(typeof v==='function'? v.call(c,v) : v));}
  function escapeHtml(a){return String(a).replace(/[&<>"'`=\/]/g,function(a){return{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="}[a]})};
}));
<|endoftext|>


<commit_before>function submit_score(score) {
    auth_data = get_auth_data()
    submit_data = auth_data + "&" + score
    call_api("set_score", submit_data)
}

function get_auth_data() {
    hash = window.location.hash
    auth_data = hash.substring(1)
    additionalDataStart = auth_data.indexOf("&")
    if (additionalDataStart > 0) {
        auth_data = auth_data.substring(0, additionalDataStart)
    }
    return auth_data
}

function call_api(name, data) {
    request = new XMLHttpRequest()
    request.open("POST", "https://cgb.ohbah.com:4343/cgbapi/" + name)
    request.send(window.location.hash)
}
<commit_msg>Revert "Try sending the full hash to api"<commit_after>function submit_score(score) {
    auth_data = get_auth_data()
    submit_data = auth_data + "&" + score
    call_api("set_score", submit_data)
}

function get_auth_data() {
    hash = window.location.hash
    auth_data = hash.substring(1)
    additionalDataStart = auth_data.indexOf("&")
    if (additionalDataStart > 0) {
        auth_data = auth_data.substring(0, additionalDataStart)
    }
    return auth_data
}

function call_api(name, data) {
    request = new XMLHttpRequest()
    request.open("POST", "https://cgb.ohbah.com:4343/cgbapi/" + name)
    request.send(data)
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

var Config = {

	URL : {
		BUNDLE_ROOT : "/dev/_bundle/",
		MY_DASHBOARD: "/dev/my_sakai.html",
		SDATA_FETCH: "/",
		API_GOOGLE_CHARTS: "http://chart.apis.google.com/chart",
		GATEWAY_URL : "/dev/index.html",
		LOGOUT_URL : "/dev/logout.html",
		PATCH_PROFILE_URL: "/_user/public/__USERID__/authprofile",
		PEOPLE_URL: "/dev/people.html",
		PROFILE_URL: "/dev/profile.html",
		SEARCH_GENERAL_URL: "search_b.html",
		SEARCH_SITES_URL: "search_b_sites.html",
		SEARCH_CONTENT_URL: "search_b_content.html",
		SEARCH_PEOPLE_URL: "search_b_people.html",
		PERSON_ICON_URL: "/dev/_images/person_icon.jpg",
		POLL_DROPDOWN_ICON_URL : "/devwidgets/poll/images/poll_drop_down.gif",
		RECENT_SITES_URL: "/_user/private/recentsites.json",
		SDATA_FETCH_BASIC_URL: "/sites/__PLACEMENT__/__TUID__",
		SDATA_FETCH_PLACEMENT_URL: "/sites/__PLACEMENT__",
		SDATA_FETCH_PRIVATE_URL: "/_user/private",
		SDATA_FETCH_PUBLIC_URL: "/_user/public/__USERID__",
		SDATA_FETCH_URL: "/sites/__PLACEMENT__/__TUID__/__NAME__",
		SDATA_FUNCTION_PROPERTIES: "/sdata/f/__URL__?f=pr",
		SDATA_FUNCTION_PERMISSIONS: "/sdata/f/__URL__?f=pe",
		GENERAL_SEARCH_SERVICE: "/var/search/page.json",
		SITE_GROUPDEF_URL: "/sites/__SITEID__/groupdef.json",
		SITE_CONFIGFOLDER: "/sites/__SITEID__",
		SITE_PAGECONFIGURATION: "/sites/__SITEID__/pageconfiguration",
		SITE_NAVIGATION: "/sites/__SITEID__/_navigation",
		SITE_NAVIGATION_CONTENT: "/sites/__SITEID__/_navigation/content",
		SITE_PRINT_URL: "/dev/print.html?pagetitle=__CURRENTSITENAME__",
		SITE_URL: "/dev/site.html",
		SITE_URL_SITEID: "/dev/site.html?siteid=__SITEID__",
		TINY_MCE_CONTENT_CSS: "/dev/_css/FSS/fluid.reset.css,/dev/_css/FSS/fluid.theme.mist.css,/dev/_css/FSS/fluid.theme.hc.css,/dev/_css/FSS/fluid.theme.rust.css,/dev/_css/FSS/fluid.layout.css,/dev/_css/FSS/fluid.text.css,/dev/_css/Sakai%20CSS/sakai.core.2.css,/dev/_css/Sakai%20CSS/sakai.css,/dev/_css/Sakai%20CSS/sakai.editor.css",
		WEBDAV_PRIVATE_URL: "/webdav/_private",
		CHAT_GET_SERVICE: "/_rest/chat/get",
		CHAT_SEND_SERVICE: "/_rest/chat/send",
		CREATE_USER_SERVICE: "/system/userManager/user.create.html",
		FRIEND_STATUS_SERVICE: "/rest/friend/status",
		FRIEND_CONNECT_SERVICE: "/rest/friend/connect/request",
		FRIEND_ACCEPTED_SERVICE: "/_user/contacts/accepted.json",
		IMAGE_SERVICE: "/system/image/cropit",
		LOGIN_SERVICE: "/system/sling/formlogin",
		LOGOUT_SERVICE : "/system/sling/formlogin",
		ME_SERVICE: "/system/me",
		ME_SERVICE_USERS: "/rest/me/__USERS__",
		MESSAGES_COUNT_SERVICE: "/_user/message.count.json?filters=sakai:messagebox,sakai:read&values=inbox,false",
		MESSAGES_SEND_SERVICE: "/_rest/messages/send",
		MESSAGES_MESSAGES_SERVICE: "/_rest/messages/messages",
		MESSAGES_DELETE_SERVICE : "/_rest/messages/delete",
		PATCH_SERVICE: "/rest/patch",
		PRESENCE_FRIENDS_SERVICE: "/_rest/presencewow/friends",
		PROXY_SERVICE: "/system/proxy",
		SEARCH_SERVICE: "/var/search/users",
		SITE_GET_SERVICE: "/_rest/site/get",
		SITE_CREATE_SERVICE: "/_rest/site/create",
		SITE_UPDATE_SERVICE: "/_rest/site/update/sites/__SITEID__",
		SITE_GET_MEMBERS_SERVICE: "/sites/__SITE__.members.json",
		SITE_ADD_MEMBERS_SERVICE: "/_rest/site/members/add/__SITE__",
		SITE_REMOVE_MEMBERS_SERVICE: "/_rest/site/members/remove/__SITE__",
		SITES_SERVICE: "/system/sling/membership",
		USER_EXISTENCE_SERVICE: "/system/userManager/user/__USERID__.json",
		USER_CHANGEPASS_SERVICE: "/system/userManager/user/__USERID__.changePassword.html",
		USER_CHANGELOCALE_SERVICE: "/rest/user/changelocale/__USERID__",
		TEMPLATES: "/_user/private/_templates/pages/",
		TEMPLATES_CONFIG: "/_user/private/_templates/pages/configuration"
	},

	SakaiDomain : "http://localhost:8080/",
	Profile : {
		// Fields that cannot be edited and so controlled by LDAP, ...
   		uneditable : ["txt_firstname","txt_lastname"]
	},

	Connections : {
		/*
		 * Email message that will be sent when inviting someone to become a connection.
		 * ${user} will be replaced by the name of the current user and ${comment} will
		 * be replaced by the personal message left by the inviter.
		 */
		Invitation : {
			title : "${user} has invited you to become a connection",
			body : "Hi, \n\n ${user} has invited you to become a connection. \nHe/She has also left the following message: \n\n ${comment} \n\nTo accept this invitation, please click on the accept button. \n\nKind regards,\n\nThe Sakai Team"
		}
	},

	Site : {
		// Default roles that will be available within a site, next to Owner
		Roles : ["Collaborator", "Viewer"],
		Styles : {
			original : {
				name : "Original sakai theme",
				image : "_images/sakai_grey.png",
				URL : "/dev/_skins/original/original.html"
			},
			camuniversity : {
				name : "Cambridge University theme",
				image : "/dev/_skins/camuniversity/images/camuniversity.png",
				URL : "/dev/_skins/camuniversity/camuniversity.html"
			}
		}
	},

	Messages : {
		Types : {
			inbox : "inbox",
			sent : "sent",
			trash : "trash"
		},
		Categories : {
	        message: 'Message',
	        announcement: 'Announcement',
	        chat: 'Chat',
	        invitation: 'Invitation'
		},
		Subject : "subject",
		Type : "type",
		Body : "body",
		To : "to",
		read : "read"
	},

	L10N: {
		DateFormat: "dd/MM/yyyy",
		TimeFormat: "HH:mm:ss",
		DateTimeFormat: "EEEEE, d MMMMM yy",
		DecimalPoint: ",",
		NumberSeparator: "."
	},

	displayDebugInfo: true
};<commit_msg>Config update for Twitter widget<commit_after>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

var Config = {

	URL : {
		BUNDLE_ROOT : "/dev/_bundle/",
		MY_DASHBOARD: "/dev/my_sakai.html",
		SDATA_FETCH: "/",
		API_GOOGLE_CHARTS: "http://chart.apis.google.com/chart",
		GATEWAY_URL : "/dev/index.html",
		LOGOUT_URL : "/dev/logout.html",
		PATCH_PROFILE_URL: "/_user/public/__USERID__/authprofile",
		PEOPLE_URL: "/dev/people.html",
		PROFILE_URL: "/dev/profile.html",
		SEARCH_GENERAL_URL: "search_b.html",
		SEARCH_SITES_URL: "search_b_sites.html",
		SEARCH_CONTENT_URL: "search_b_content.html",
		SEARCH_PEOPLE_URL: "search_b_people.html",
		PERSON_ICON_URL: "/dev/_images/person_icon.jpg",
		POLL_DROPDOWN_ICON_URL : "/devwidgets/poll/images/poll_drop_down.gif",
		RECENT_SITES_URL: "/_user/private/recentsites.json",
		SDATA_FETCH_BASIC_URL: "/sites/__PLACEMENT__/__TUID__",
		SDATA_FETCH_PLACEMENT_URL: "/sites/__PLACEMENT__",
		SDATA_FETCH_PRIVATE_URL: "/_user/private",
		SDATA_FETCH_PUBLIC_URL: "/_user/public/__USERID__",
		SDATA_FETCH_URL: "/sites/__PLACEMENT__/__TUID__/__NAME__",
		SDATA_FUNCTION_PROPERTIES: "/sdata/f/__URL__?f=pr",
		SDATA_FUNCTION_PERMISSIONS: "/sdata/f/__URL__?f=pe",
		GENERAL_SEARCH_SERVICE: "/var/search/page.json",
		SITE_GROUPDEF_URL: "/sites/__SITEID__/groupdef.json",
		SITE_CONFIGFOLDER: "/sites/__SITEID__",
		SITE_PAGECONFIGURATION: "/sites/__SITEID__/pageconfiguration",
		SITE_NAVIGATION: "/sites/__SITEID__/_navigation",
		SITE_NAVIGATION_CONTENT: "/sites/__SITEID__/_navigation/content",
		SITE_PRINT_URL: "/dev/print.html?pagetitle=__CURRENTSITENAME__",
		SITE_URL: "/dev/site.html",
		SITE_URL_SITEID: "/dev/site.html?siteid=__SITEID__",
		TINY_MCE_CONTENT_CSS: "/dev/_css/FSS/fluid.reset.css,/dev/_css/FSS/fluid.theme.mist.css,/dev/_css/FSS/fluid.theme.hc.css,/dev/_css/FSS/fluid.theme.rust.css,/dev/_css/FSS/fluid.layout.css,/dev/_css/FSS/fluid.text.css,/dev/_css/Sakai%20CSS/sakai.core.2.css,/dev/_css/Sakai%20CSS/sakai.css,/dev/_css/Sakai%20CSS/sakai.editor.css",
		WEBDAV_PRIVATE_URL: "/webdav/_private",
		CHAT_GET_SERVICE: "/_rest/chat/get",
		CHAT_SEND_SERVICE: "/_rest/chat/send",
		CREATE_USER_SERVICE: "/system/userManager/user.create.html",
		FRIEND_STATUS_SERVICE: "/rest/friend/status",
		FRIEND_CONNECT_SERVICE: "/rest/friend/connect/request",
		FRIEND_ACCEPTED_SERVICE: "/_user/contacts/accepted.json",
		IMAGE_SERVICE: "/system/image/cropit",
		LOGIN_SERVICE: "/system/sling/formlogin",
		LOGOUT_SERVICE : "/system/sling/formlogin",
		ME_SERVICE: "/system/me",
		ME_SERVICE_USERS: "/rest/me/__USERS__",
		MESSAGES_COUNT_SERVICE: "/_user/message.count.json?filters=sakai:messagebox,sakai:read&values=inbox,false",
		MESSAGES_SEND_SERVICE: "/_rest/messages/send",
		MESSAGES_MESSAGES_SERVICE: "/_rest/messages/messages",
		MESSAGES_DELETE_SERVICE : "/_rest/messages/delete",
		PATCH_SERVICE: "/rest/patch",
		PRESENCE_FRIENDS_SERVICE: "/_rest/presencewow/friends",
		PROXY_SERVICE: "/system/proxy",
		SEARCH_SERVICE: "/var/search/users",
		SITE_GET_SERVICE: "/_rest/site/get",
		SITE_CREATE_SERVICE: "/_rest/site/create",
		SITE_UPDATE_SERVICE: "/_rest/site/update/sites/__SITEID__",
		SITE_GET_MEMBERS_SERVICE: "/sites/__SITE__.members.json",
		SITE_ADD_MEMBERS_SERVICE: "/_rest/site/members/add/__SITE__",
		SITE_REMOVE_MEMBERS_SERVICE: "/_rest/site/members/remove/__SITE__",
		SITES_SERVICE: "/system/sling/membership",
		USER_EXISTENCE_SERVICE: "/system/userManager/user/__USERID__.json",
		USER_CHANGEPASS_SERVICE: "/system/userManager/user/__USERID__.changePassword.html",
		USER_CHANGELOCALE_SERVICE: "/rest/user/changelocale/__USERID__",
		TEMPLATES: "/_user/private/_templates/pages/",
		TEMPLATES_CONFIG: "/_user/private/_templates/pages/configuration",

		TWITTER_GET_URL: "/var/proxy/twitter/status.json",
		TWITTER_POST_URL: "/var/proxy/twitter/update_status.json"

	},

	SakaiDomain : "http://localhost:8080/",
	Profile : {
		// Fields that cannot be edited and so controlled by LDAP, ...
   		uneditable : ["txt_firstname","txt_lastname"]
	},

	Connections : {
		/*
		 * Email message that will be sent when inviting someone to become a connection.
		 * ${user} will be replaced by the name of the current user and ${comment} will
		 * be replaced by the personal message left by the inviter.
		 */
		Invitation : {
			title : "${user} has invited you to become a connection",
			body : "Hi, \n\n ${user} has invited you to become a connection. \nHe/She has also left the following message: \n\n ${comment} \n\nTo accept this invitation, please click on the accept button. \n\nKind regards,\n\nThe Sakai Team"
		}
	},

	Site : {
		// Default roles that will be available within a site, next to Owner
		Roles : ["Collaborator", "Viewer"],
		Styles : {
			original : {
				name : "Original sakai theme",
				image : "_images/sakai_grey.png",
				URL : "/dev/_skins/original/original.html"
			},
			camuniversity : {
				name : "Cambridge University theme",
				image : "/dev/_skins/camuniversity/images/camuniversity.png",
				URL : "/dev/_skins/camuniversity/camuniversity.html"
			}
		}
	},

	Messages : {
		Types : {
			inbox : "inbox",
			sent : "sent",
			trash : "trash"
		},
		Categories : {
	        message: 'Message',
	        announcement: 'Announcement',
	        chat: 'Chat',
	        invitation: 'Invitation'
		},
		Subject : "subject",
		Type : "type",
		Body : "body",
		To : "to",
		read : "read"
	},

	L10N: {
		DateFormat: "dd/MM/yyyy",
		TimeFormat: "HH:mm:ss",
		DateTimeFormat: "EEEEE, d MMMMM yy",
		DecimalPoint: ",",
		NumberSeparator: "."
	},

	displayDebugInfo: true
};<|endoftext|>


<commit_before>(function() {
    'use strict';

    angular.module('brewApp.services').factory('Configuration', ['Helper', configuration]);

    function configuration(Helper) {
        var baseUrl = new Helper.Url('http://blabdatadev01.cloudapp.net:3000'),
            storeUrl = baseUrl.route('api', '/api/v1/'),
            authUrl = baseUrl.route('auth', '/auth/v1/');

        return {
            store: {
                url: storeUrl
            },
            auth: {
                url: authUrl
            },
            currentUser: {
                cacheRecipes: true
            }
        };
    }
})();<commit_msg>Added logging route info.<commit_after>(function() {
    'use strict';

    angular.module('brewApp.services').factory('Configuration', ['Helper', configuration]);

    function configuration(Helper) {
        var baseUrl = new Helper.Url('http://blabdatadev01.cloudapp.net:3000'),
            storeUrl = baseUrl.route('api', '/api/v1/'),
            authUrl = baseUrl.route('auth', '/auth/v1/'),
            loggingUrl = baseUrl.route('logging', '/logging/v1/');

        return {
            store: {
                url: storeUrl
            },
            auth: {
                url: authUrl
            },
            logging: {
                url: loggingUrl
            },
            currentUser: {
                cacheRecipes: true
            }
        };
    }
})();<|endoftext|>


<commit_before>// See README file.

function show_products(json) {

  var bgn_title = '';
  var end_title = '
';

  var bgn_price = 'Pris: ';
  var end_price = ' Kr.
';

  var bgn_description = '';
  var end_description = '
';

  var bgn_photo = '
';

  var bgn_row = '

';
  var end_row = '

';

  var bgn_cart_view = bgn_row;
  var end_cart_view = end_row;

  var paypal_id = 'JU24PYRGKMZCW';

  //var paypal_buy_now_1 = '<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_xclick"><input type="hidden" name="business" value="';
  //var paypal_buy_now_2 = '"><input type="hidden" name="lc" value="DK"><input type="hidden" name="item_name" value="';
  //var paypal_buy_now_3 = '"><input type="hidden" name="amount" value="';
  //var paypal_buy_now_4 = '"><input type="hidden" name="currency_code" value="DKK"><input type="hidden" name="button_subtype" value="services"><input type="hidden" name="no_note" value="0"><input type="hidden" name="cn" value="Add special instructions to the seller"><input type="hidden" name="no_shipping" value="2"><input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynowCC_LG.gif:NonHosted"><input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"></form>';

  var paypal_cart_add_1 ='<form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_cart"><input type="hidden" name="business" value="';
  var paypal_cart_add_2 ='"><input type="hidden" name="lc" value="DK"><input type="hidden" name="item_name" value="';
  var paypal_cart_add_3 ='"><input type="hidden" name="amount" value="';
  var paypal_cart_add_4 ='"><input type="hidden" name="currency_code" value="DKK"><input type="hidden" name="button_subtype" value="products"><input type="hidden" name="no_note" value="0"><input type="hidden" name="cn" value="Add special instructions to the seller"><input type="hidden" name="no_shipping" value="2"><input type="hidden" name="add" value="1"><input type="hidden" name="bn" value="PP-ShopCartBF:btn_cart_LG.gif:NonHosted"><input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_cart_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"></form>';

  var paypal_cart_view_1 ='<form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_cart"><input type="hidden" name="business" value="';
  var paypal_cart_view_2 ='"><input type="hidden" name="display" value="1"><input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_viewcart_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"></form>

';

  //var paypal_part1 = paypal_buy_now_1;
  //var paypal_part2 = paypal_buy_now_2;
  //var paypal_part3 = paypal_buy_now_3;
  //var paypal_part4 = paypal_buy_now_4;

  var paypal_part1 = paypal_cart_add_1;
  var paypal_part2 = paypal_cart_add_2;
  var paypal_part3 = paypal_cart_add_3;
  var paypal_part4 = paypal_cart_add_4;

  var len = json.feed.entry.length;

  for (var i=0; i<len; i++) {

    if (json.feed.entry[i].gsx$available.$t != 'Y') {
      continue;
    }

    document.write(bgn_row);

    document.write(bgn_title +
                   json.feed.entry[i].gsx$title.$t +
                   end_title);

    document.write(bgn_photo +
                   json.feed.entry[i].gsx$photo.$t +
                   end_photo);

    document.write(bgn_description +
                   json.feed.entry[i].gsx$description.$t +
                   end_description);

    document.write(bgn_price +
                   json.feed.entry[i].gsx$price.$t +
                   end_price);

    var product = json.feed.entry[i].gsx$title.$t;
    product = product.replace('æ','ae');
    product = product.replace('ø','oe');
    product = product.replace('å','aa');
    product = product.replace('Æ','AE');
    product = product.replace('Ø','OE');
    product = product.replace('Å','AA');

    document.write(paypal_part1 +
                   paypal_id +
                   paypal_part2 +
                   product +
                   paypal_part3 +
                   json.feed.entry[i].gsx$price.$t +
                   paypal_part4);

    document.write(end_row);

  }

  document.write(bgn_cart_view);
  document.write(paypal_cart_view_1 +
                 paypal_id +
                 paypal_cart_view_2);
  document.write(end_cart_view);

}

function show_webshop() {

  document.write('');

}

function page_start() {

  document.write(''
    + ''
    + ''
  );

  document.write(''
    + '
'
    + ''
    + '
'
  );

//  var myWidth = 0;
//  var myHeight = 0;
//  if( typeof( window.innerWidth ) == 'number' ) {
//    //Non-IE
//    myWidth = window.innerWidth;
//    myHeight = window.innerHeight;
//  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//    //IE 6+ in 'standards compliant mode'
//    myWidth = document.documentElement.clientWidth;
//    myHeight = document.documentElement.clientHeight;
//  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//    //IE 4 compatible
//    myWidth = document.body.clientWidth;
//    myHeight = document.body.clientHeight;
//  }
//
//  var mySize = myHeight;
//  if (myWidth < mySize)
//    mySize = myWidth;
//  var mySize = Math.floor(mySize*0.9);
//  var myMargin = Math.floor(mySize / 2);
//
//  document.write(''
//    + '
'
//    + ''
//    + '
'
//  );

}

function show_1_random_post_body(json) {

//  var i = Math.floor(Math.random()*json.feed.openSearch$totalResults.$t);
  var i = Math.random()*1000) % json.feed.openSearch$totalResults.$t;

  document.write(json.feed.entry[i].content.$t);

}

function show_1_random_blog_post_body(label) {

  document.write('yyy');

}

function show_1_random_sponsor(label) {

  show_1_random_blog_post_body(label);

}<commit_msg>sponsor<commit_after>// See README file.

function show_products(json) {

  var bgn_title = '';
  var end_title = '
';

  var bgn_price = 'Pris: ';
  var end_price = ' Kr.
';

  var bgn_description = '';
  var end_description = '
';

  var bgn_photo = '
';

  var bgn_row = '

';
  var end_row = '

';

  var bgn_cart_view = bgn_row;
  var end_cart_view = end_row;

  var paypal_id = 'JU24PYRGKMZCW';

  //var paypal_buy_now_1 = '<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_xclick"><input type="hidden" name="business" value="';
  //var paypal_buy_now_2 = '"><input type="hidden" name="lc" value="DK"><input type="hidden" name="item_name" value="';
  //var paypal_buy_now_3 = '"><input type="hidden" name="amount" value="';
  //var paypal_buy_now_4 = '"><input type="hidden" name="currency_code" value="DKK"><input type="hidden" name="button_subtype" value="services"><input type="hidden" name="no_note" value="0"><input type="hidden" name="cn" value="Add special instructions to the seller"><input type="hidden" name="no_shipping" value="2"><input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynowCC_LG.gif:NonHosted"><input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"></form>';

  var paypal_cart_add_1 ='<form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_cart"><input type="hidden" name="business" value="';
  var paypal_cart_add_2 ='"><input type="hidden" name="lc" value="DK"><input type="hidden" name="item_name" value="';
  var paypal_cart_add_3 ='"><input type="hidden" name="amount" value="';
  var paypal_cart_add_4 ='"><input type="hidden" name="currency_code" value="DKK"><input type="hidden" name="button_subtype" value="products"><input type="hidden" name="no_note" value="0"><input type="hidden" name="cn" value="Add special instructions to the seller"><input type="hidden" name="no_shipping" value="2"><input type="hidden" name="add" value="1"><input type="hidden" name="bn" value="PP-ShopCartBF:btn_cart_LG.gif:NonHosted"><input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_cart_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"></form>';

  var paypal_cart_view_1 ='<form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_cart"><input type="hidden" name="business" value="';
  var paypal_cart_view_2 ='"><input type="hidden" name="display" value="1"><input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_viewcart_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"></form>

';

  //var paypal_part1 = paypal_buy_now_1;
  //var paypal_part2 = paypal_buy_now_2;
  //var paypal_part3 = paypal_buy_now_3;
  //var paypal_part4 = paypal_buy_now_4;

  var paypal_part1 = paypal_cart_add_1;
  var paypal_part2 = paypal_cart_add_2;
  var paypal_part3 = paypal_cart_add_3;
  var paypal_part4 = paypal_cart_add_4;

  var len = json.feed.entry.length;

  for (var i=0; i<len; i++) {

    if (json.feed.entry[i].gsx$available.$t != 'Y') {
      continue;
    }

    document.write(bgn_row);

    document.write(bgn_title +
                   json.feed.entry[i].gsx$title.$t +
                   end_title);

    document.write(bgn_photo +
                   json.feed.entry[i].gsx$photo.$t +
                   end_photo);

    document.write(bgn_description +
                   json.feed.entry[i].gsx$description.$t +
                   end_description);

    document.write(bgn_price +
                   json.feed.entry[i].gsx$price.$t +
                   end_price);

    var product = json.feed.entry[i].gsx$title.$t;
    product = product.replace('æ','ae');
    product = product.replace('ø','oe');
    product = product.replace('å','aa');
    product = product.replace('Æ','AE');
    product = product.replace('Ø','OE');
    product = product.replace('Å','AA');

    document.write(paypal_part1 +
                   paypal_id +
                   paypal_part2 +
                   product +
                   paypal_part3 +
                   json.feed.entry[i].gsx$price.$t +
                   paypal_part4);

    document.write(end_row);

  }

  document.write(bgn_cart_view);
  document.write(paypal_cart_view_1 +
                 paypal_id +
                 paypal_cart_view_2);
  document.write(end_cart_view);

}

function show_webshop() {

  document.write('');

}

function page_start() {

  document.write(''
    + ''
    + ''
  );

  document.write(''
    + '
'
    + ''
    + '
'
  );

//  var myWidth = 0;
//  var myHeight = 0;
//  if( typeof( window.innerWidth ) == 'number' ) {
//    //Non-IE
//    myWidth = window.innerWidth;
//    myHeight = window.innerHeight;
//  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//    //IE 6+ in 'standards compliant mode'
//    myWidth = document.documentElement.clientWidth;
//    myHeight = document.documentElement.clientHeight;
//  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//    //IE 4 compatible
//    myWidth = document.body.clientWidth;
//    myHeight = document.body.clientHeight;
//  }
//
//  var mySize = myHeight;
//  if (myWidth < mySize)
//    mySize = myWidth;
//  var mySize = Math.floor(mySize*0.9);
//  var myMargin = Math.floor(mySize / 2);
//
//  document.write(''
//    + '
'
//    + ''
//    + '
'
//  );

}

function show_1_random_post_body(json) {

//  var i = Math.floor(Math.random()*json.feed.openSearch$totalResults.$t);
  var i = (Math.random()*1000) % json.feed.openSearch$totalResults.$t;
document.write('i='+i);

  document.write(json.feed.entry[i].content.$t);

}

function show_1_random_blog_post_body(label) {

  document.write('yyy');

}

function show_1_random_sponsor(label) {

  show_1_random_blog_post_body(label);

}<|endoftext|>


<commit_before>/*
 * This file is part of Cockpit.
 *
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Cockpit is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Cockpit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */

define([
    "jquery",
    "kubernetes/angular",
    "kubernetes/d3",
    "kubernetes/topology-graph"
], function($, angular, d3) {
    "use strict";

    var icons = {
        Pod: '#vertex-Pod',
        ReplicationController: '#vertex-ReplicationController',
        Node: '#vertex-Node',
        Service: '#vertex-Service',
    };

    return angular.module('kubernetes.topology', [ 'ngRoute', 'kubernetesUI' ])
        .config(['$routeProvider', function($routeProvider) {
            $routeProvider.when('/topology', {
                templateUrl: 'topology.html',
                controller: 'TopologyCtrl'
            });
        }])

        .controller('TopologyCtrl', [
            '$scope',
            function($scope) {
                $scope.items = { };
                $scope.relations = [ ];
                $scope.selected = null;

                var client = $scope.client;
                var ready = false;
                var all = { };

                client.wait(function() {
                    all = client.select();
                    client.track(all);
                    $(all).on("changed", digest);
                    digest();
                });

                /* TODO: This should be made unnecessary by parsing endpoints */
                function weak(item) {
                    if (item.status && item.status.phase && item.status.phase !== "Running")
                        return true;
                    return false;
                }

                function digest() {
                    var items = { };
                    var relations = [ ];

                    /* Items we're going to use for links */
                    var leaves = { "Service": { }, "Node": { }, "ReplicationController": { } };

                    var item, key, leaf, kind, pods;
                    for (key in all) {
                        item = all[key];
                        kind = item.kind;
                        leaf = leaves[kind];

                        if (leaf)
                            leaf[key] = item;
                        else if (kind !== "Pod")
                            continue;

                        items[key] = item;
                    }

                    var isnode, isservice, pkey;
                    for (kind in leaves) {
                        leaf = leaves[kind];
                        isnode = kind === "Node";
                        isservice = kind === "Service";
                        for (key in leaf) {
                            item = leaf[key];
                            if (isnode)
                                pods = client.hosting("Pod", item.metadata.name);
                            else
                                pods = client.select("Pod", item.metadata.namespace, item.spec.selector || { });
                            for (pkey in pods) {
                                if (isservice && weak(pods[pkey]))
                                    continue;
                                relations.push({ source: key, target: pkey });
                            }
                        }
                    }

                    $scope.items = items;
                    $scope.relations = relations;

                    if (ready)
                        $scope.$digest();
                }

                $scope.selected = null;
                $scope.$on("select", function(ev, item) {
                    $scope.selected = item;
                    $scope.$digest();
                });

                /* Make a copy since we modify */
                $scope.kinds = angular.copy(icons);

                function resized() {
                    $scope.height = { height: (window.innerHeight - 15) + "px" };
                    if (ready)
                        $scope.$digest();
                }
                $(window).on('resize', resized);
                resized();

                $scope.$on("$destroy", function() {
                    $(window).off('resize', resized);
                    client.track(all, false);
                    $(all).off();
                });

                all = client.select();
                client.track(all);
                $(all).on("changed", digest);
                digest();

                ready = true;
            }
        ]);
});
<commit_msg>kubernetes: Fix exception regression when using Topology view<commit_after>/*
 * This file is part of Cockpit.
 *
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Cockpit is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Cockpit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */

define([
    "jquery",
    "kubernetes/angular",
    "kubernetes/d3",
    "kubernetes/topology-graph"
], function($, angular, d3) {
    "use strict";

    var icons = {
        Pod: '#vertex-Pod',
        ReplicationController: '#vertex-ReplicationController',
        Node: '#vertex-Node',
        Service: '#vertex-Service',
    };

    return angular.module('kubernetes.topology', [ 'ngRoute', 'kubernetesUI' ])
        .config(['$routeProvider', function($routeProvider) {
            $routeProvider.when('/topology', {
                templateUrl: 'topology.html',
                controller: 'TopologyCtrl'
            });
        }])

        .controller('TopologyCtrl', [
            '$scope',
            function($scope) {
                $scope.items = { };
                $scope.relations = [ ];
                $scope.selected = null;

                var client = $scope.client;
                var ready = false;

                var all = client.select();
                client.track(all);
                $(all).on("changed", digest);
                digest();

                /* TODO: This should be made unnecessary by parsing endpoints */
                function weak(item) {
                    if (item.status && item.status.phase && item.status.phase !== "Running")
                        return true;
                    return false;
                }

                function digest() {
                    var items = { };
                    var relations = [ ];

                    /* Items we're going to use for links */
                    var leaves = { "Service": { }, "Node": { }, "ReplicationController": { } };

                    var item, key, leaf, kind, pods;
                    for (key in all) {
                        item = all[key];
                        kind = item.kind;
                        leaf = leaves[kind];

                        if (leaf)
                            leaf[key] = item;
                        else if (kind !== "Pod")
                            continue;

                        items[key] = item;
                    }

                    var isnode, isservice, pkey;
                    for (kind in leaves) {
                        leaf = leaves[kind];
                        isnode = kind === "Node";
                        isservice = kind === "Service";
                        for (key in leaf) {
                            item = leaf[key];
                            if (isnode)
                                pods = client.hosting("Pod", item.metadata.name);
                            else
                                pods = client.select("Pod", item.metadata.namespace, item.spec.selector || { });
                            for (pkey in pods) {
                                if (isservice && weak(pods[pkey]))
                                    continue;
                                relations.push({ source: key, target: pkey });
                            }
                        }
                    }

                    $scope.items = items;
                    $scope.relations = relations;

                    if (ready)
                        $scope.$digest();
                }

                $scope.selected = null;
                $scope.$on("select", function(ev, item) {
                    $scope.selected = item;
                    $scope.$digest();
                });

                /* Make a copy since we modify */
                $scope.kinds = angular.copy(icons);

                function resized() {
                    $scope.height = { height: (window.innerHeight - 15) + "px" };
                    if (ready)
                        $scope.$digest();
                }
                $(window).on('resize', resized);
                resized();

                $scope.$on("$destroy", function() {
                    $(window).off('resize', resized);
                    client.track(all, false);
                    $(all).off();
                });

                all = client.select();
                client.track(all);
                $(all).on("changed", digest);
                digest();

                ready = true;
            }
        ]);
});
<|endoftext|>


<commit_before>/**
 * Created by Piotr Walczyszyn (outof.me | @pwalczyszyn)
 *
 * Date: 2/8/12
 * Time: 4:38 PM
 *
 */

(function (root, factory) {
    // Set up BackStack appropriately for the environment.
    if (typeof exports !== 'undefined') {
        // Node/CommonJS, no need for jQuery in that case.
        factory(root, exports, require('underscore'), require('jquery'), require('Backbone'));
    } else if (typeof define === 'function' && define.amd) {
        // AMD
        define(['underscore', 'jquery', 'Backbone', 'exports'],
            function (_, $, Backbone, exports) {
                // Export global even in AMD case in case this script is loaded with
                // others that may still expect a global Backbone.
                root.BackStack = factory(root, exports, _, $, Backbone);
            });
    } else {
        // Browser globals
        root.BackStack = factory(root, {}, root._, root.jQuery, root.Backbone);
    }
}(this, function (root, BackStack, _, $, Backbone) {

    /**
     * Helper function to detect browser vendor prefix.
     * Thanks to Lea Verou: http://lea.verou.me/2009/02/find-the-vendor-prefix-of-the-current-browser/
     * I just modified it slightly as I expect it to be used in mobile/WebKit scenarios mostly.
     */
    var getVendorPrefix = BackStack.getVendorPrefix = function () {
        if ('result' in arguments.callee) return arguments.callee.result;

        var regex = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;

        var someScript = document.getElementsByTagName('script')[0];

        // Exception for WebKit based browsers
        if ('WebkitOpacity' in someScript.style) return arguments.callee.result = 'Webkit';
        if ('KhtmlOpacity' in someScript.style) return arguments.callee.result = 'Khtml';

        for (var prop in someScript.style) {
            if (regex.test(prop)) {
                // test is faster than match, so it's better to perform
                // that on the lot and match only when necessary
                return arguments.callee.result = prop.match(regex)[0];
            }
        }
        return arguments.callee.result = '';
    };

    var StackNavigatorSlideEffect = BackStack.StackNavigatorSlideEffect = function (stackNavigator) {
        this.stackNavigator = stackNavigator;
    };
    StackNavigatorSlideEffect.prototype.play = function (fromView, toView, direction, callback, context) {

        var vendor = getVendorPrefix(),
            activeTransitions = 0,
            transitionEndEvent,
            transformParams,
            fromViewTransitionParams = 'all 0.4s ease-out 0.1s',
            toViewTransitionParams = 'all 0.4s ease-out 0.1s';

        if (vendor == 'Moz' || vendor == '')
            transitionEndEvent = 'transitionend';
        else if (vendor == 'ms')
            transitionEndEvent = 'MSTransitionEnd';
        else
            transitionEndEvent = vendor.toLowerCase() + 'TransitionEnd';

        var transitionEndHandler = function (event) {
            activeTransitions--;
            $(event.target)[0].style[vendor + 'Transition'] = '';

            if (activeTransitions == 0 && callback) {
                callback.call(context);
            }
        };

        if (fromView) {
            fromView.one(transitionEndEvent, transitionEndHandler);
            fromView.css('left', 0);
            fromView[0].style[vendor + 'Transition'] = fromViewTransitionParams;

            activeTransitions++;
        }

        if (toView) {
            toView.one(transitionEndEvent, transitionEndHandler);
            toView.css('left', direction == 'left' ? this.stackNavigator.width() : -this.stackNavigator.width());
            toView[0].style[vendor + 'Transition'] = toViewTransitionParams;

            this.stackNavigator.append(toView);

            activeTransitions++;
        }

        if (fromView || toView) {
            // This is a hack to force DOM reflow before transition starts
            this.stackNavigator.css('width');

            transformParams = 'translateX(' + (direction == 'left' ? -this.stackNavigator.width() : this.stackNavigator.width()) + 'px)';
        }

        if (fromView && toView)
            fromView[0].style[vendor + 'Transform'] = toView[0].style[vendor + 'Transform'] = transformParams;
        else if (toView)
            toView[0].style[vendor + 'Transform'] = transformParams;
        else if (fromView)
            fromView[0].style[vendor + 'Transform'] = transformParams;
    };

    var StackNavigatorEvent = BackStack.StackNavigatorEvent =
        function (action, oldViewClass, oldView, newViewClass, newView) {

            this.action = action;

            this.oldViewClass = oldViewClass;

            this.oldView = oldView;

            this.newViewClass = newViewClass;

            this.newView = newView;

            var defaultPrevented = false;

            this.preventDefault = function () {
                this.defaultPrevented = true;
            }

            this.isDefaultPrevented = function () {
                return defaultPrevented;
            }
        };

    /**
     * Extended Backbone.View with additional properties like viewPath, destructionPolicy and a reference to parent
     * StackNavigator.
     */
    var View = BackStack.StackView = Backbone.View.extend({

        viewPath:undefined,

        // Posible options auto or never
        destructionPolicy:"auto",

        stackNavigator:undefined,

        setStackNavigator:function (stackNavigator, navigationOptions) {
            this.stackNavigator = stackNavigator;

            if (navigationOptions) {
                if (navigationOptions.destructionPolicy)
                    this.destructionPolicy = navigationOptions.destructionPolicy;
            }

            // Setting default styles
            this.$el.css({position:'absolute', overflow:'hidden', width:'100%', height:'100%'});
        }
    });

    BackStack.StackNavigator = Backbone.View.extend({

        tagName:'div',

        viewsStack:new Array(),

        initialize:function (options) {
            if (options && options.firstView)
                this.pushView(options.firstView, options.firstViewOptions);

            // Setting default styles
            this.$el.css({position:'absolute', overflow:'hidden', width:'100%', height:'100%'});
        },

        pushView:function (viewClass, viewOptions) {
            var toView, fromViewRef;

            if (this.viewsStack.length > 0)
                fromViewRef = this.viewsStack[this.viewsStack.length - 1];

            toView = new viewClass(viewOptions);
            toView.setStackNavigator(this, viewOptions ? viewOptions.navigationOptions : null);

            var event = new StackNavigatorEvent('push', fromViewRef ? fromViewRef.viewClass : null,
                fromViewRef ? fromViewRef.instance : null, viewClass, toView);
            this.trigger(event.action, event);

            if (!event.isDefaultPrevented()) {
                this.viewsStack.push({instance:toView, viewClass:viewClass, options:viewOptions});

                var slideEffect = new StackNavigatorSlideEffect(this.$el);
                slideEffect.play(fromViewRef ? fromViewRef.instance.$el : null, toView.render().$el, 'left',
                    function () {

                        toView.$el.trigger('viewActivate');

                        if (fromViewRef) {
                            fromViewRef.instance.$el.trigger('viewDeactivate');

                            if (fromViewRef.instance.destructionPolicy == 'never') {
                                fromViewRef.instance.$el.detach();
                            } else {
                                fromViewRef.instance.$el.remove();
                                fromViewRef.instance = null;
                            }
                        }
                    }, this);
            }
        },

        popView:function () {
            var toViewRef, fromViewRef;
            if (this.viewsStack.length > 0)
                fromViewRef = this.viewsStack[this.viewsStack.length - 1];

            if (this.viewsStack.length > 1)
                toViewRef = this.viewsStack[this.viewsStack.length - 2];

            var event = new StackNavigatorEvent('pop',
                fromViewRef ? fromViewRef.viewClass : null, fromViewRef ? fromViewRef.instance : null,
                toViewRef ? toViewRef.viewClass : null, toViewRef ? toViewRef.instance : null);
            this.trigger(event.action, event);

            if (!event.isDefaultPrevented()) {
                this.viewsStack.pop();

                if (toViewRef && !toViewRef.instance) {
                    var viewClass = toViewRef.viewClass;
                    toViewRef.instance = new viewClass(toViewRef.options);
                    toViewRef.instance.setStackNavigator(this, toViewRef.options ? toViewRef.options.navigationOptions : null);
                    toViewRef.instance.render();
                }
                var slideEffect = new StackNavigatorSlideEffect(this.$el);
                slideEffect.play(fromViewRef.instance.$el, toViewRef ? toViewRef.instance.$el : null, 'right',
                    function () {
                        if (toViewRef)
                            toViewRef.instance.$el.trigger('viewActivate');

                        fromViewRef.instance.$el.trigger('viewDeactivate');
                        fromViewRef.instance.$el.remove();
                        fromViewRef.instance = null;
                    }, this);
            }
        }
    });

    return BackStack;
}));<commit_msg>- refactored DOM appending sequance, added view is hidden using display: hidden property, next it is added to DOM and afterward rendered<commit_after>/**
 * Created by Piotr Walczyszyn (outof.me | @pwalczyszyn)
 *
 * Date: 2/8/12
 * Time: 4:38 PM
 *
 */

(function (root, factory) {
    // Set up BackStack appropriately for the environment.
    if (typeof exports !== 'undefined') {
        // Node/CommonJS, no need for jQuery in that case.
        factory(root, exports, require('underscore'), require('jquery'), require('Backbone'));
    } else if (typeof define === 'function' && define.amd) {
        // AMD
        define(['underscore', 'jquery', 'Backbone', 'exports'],
            function (_, $, Backbone, exports) {
                // Export global even in AMD case in case this script is loaded with
                // others that may still expect a global Backbone.
                root.BackStack = factory(root, exports, _, $, Backbone);
            });
    } else {
        // Browser globals
        root.BackStack = factory(root, {}, root._, root.jQuery, root.Backbone);
    }
}(this, function (root, BackStack, _, $, Backbone) {

    /**
     * Helper function to detect browser vendor prefix.
     * Thanks to Lea Verou: http://lea.verou.me/2009/02/find-the-vendor-prefix-of-the-current-browser/
     * I just modified it slightly as I expect it to be used in mobile/WebKit scenarios mostly.
     */
    var getVendorPrefix = BackStack.getVendorPrefix = function () {
        if ('result' in arguments.callee) return arguments.callee.result;

        var regex = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;

        var someScript = document.getElementsByTagName('script')[0];

        // Exception for WebKit based browsers
        if ('WebkitOpacity' in someScript.style) return arguments.callee.result = 'Webkit';
        if ('KhtmlOpacity' in someScript.style) return arguments.callee.result = 'Khtml';

        for (var prop in someScript.style) {
            if (regex.test(prop)) {
                // test is faster than match, so it's better to perform
                // that on the lot and match only when necessary
                return arguments.callee.result = prop.match(regex)[0];
            }
        }
        return arguments.callee.result = '';
    };

    /**
     * Fade transition effect implementation.
     */
    var StackNavigatorFadeEffect = BackStack.StackNavigatorFadeEffect = function (stackNavigator, effectParams) {
        this.stackNavigator = stackNavigator;
        this.effectParams = 'opacity ' + (effectParams) ? effectParams : '0.2s linear 0.1s';
        this.vendorPrefix = getVendorPrefix();
    };
    StackNavigatorFadeEffect.prototype.play = function (fromView, toView, callback, context) {
        var activeTransitions = 0,
            transitionEndEvent;

        if (this.vendorPrefix == 'Moz' || this.vendorPrefix == '')
            transitionEndEvent = 'transitionend';
        else if (this.vendorPrefix == 'ms')
            transitionEndEvent = 'MSTransitionEnd';
        else
            transitionEndEvent = this.vendorPrefix.toLowerCase() + 'TransitionEnd';

        var transitionEndHandler = function (event) {
            activeTransitions--;
            $(event.target)[0].style[this.vendorPrefix + 'Transition'] = '';

            if (activeTransitions == 0 && callback) {
                callback.call(context);
            }
        };

        if (fromView) {
            fromView.one(transitionEndEvent, transitionEndHandler);
            fromView[0].style[this.vendorPrefix + 'Transition'] = this.effectParams;

            activeTransitions++;
        }

        if (toView) {
            // Setting initial opacity
            toView.css('opacity', 0);
            toView.one(transitionEndEvent, transitionEndHandler);
            toView[0].style[this.vendorPrefix + 'Transition'] = this.effectParams;

            activeTransitions++;

            // Showing the view
            toView.css('display', 'inherit');
        }

        // This is a hack to force DOM reflow before transition starts
        this.stackNavigator.$el.css('width');

        if (toView)
            toView.css('opacity', 1);

        if (fromView)
            fromView.css('opacity', 0);

        var that = this;
        setTimeout(function () {
            if (activeTransitions > 0) {
                activeTransitions = 0;

                if (toView)
                    toView[0].style[that.vendorPrefix + 'Transition'] = '';
                if (fromView)
                    fromView[0].style[that.vendorPrefix + 'Transition'] = '';

                callback.call(context);
            }
        }, 350);
    };

    /**
     * Slide transition effect implementation.
     */
    var StackNavigatorSlideEffect = BackStack.StackNavigatorSlideEffect = function (stackNavigator, direction, effectParams) {
        this.stackNavigator = stackNavigator;
        this.direction = direction ? direction : 'left';
        this.effectParams = 'all ' + (effectParams ? effectParams : '0.4s ease-out 0.1s');
        this.vendorPrefix = getVendorPrefix();
    };
    StackNavigatorSlideEffect.prototype.play = function (fromView, toView, callback, context) {
        var activeTransitions = 0,
            transitionEndEvent,
            transformParams;

        if (this.vendorPrefix == 'Moz' || this.vendorPrefix == '')
            transitionEndEvent = 'transitionend';
        else if (this.vendorPrefix == 'ms')
            transitionEndEvent = 'MSTransitionEnd';
        else
            transitionEndEvent = this.vendorPrefix.toLowerCase() + 'TransitionEnd';

        var transitionEndHandler = function (event) {
            activeTransitions--;
            $(event.target)[0].style[this.vendorPrefix + 'Transition'] = '';

            if (activeTransitions == 0 && callback) {
                callback.call(context);
            }
        };

        if (fromView) {
            fromView.one(transitionEndEvent, transitionEndHandler);
            fromView.css('left', 0);
            fromView[0].style[this.vendorPrefix + 'Transition'] = this.effectParams;

            activeTransitions++;
        }

        if (toView) {
            toView.one(transitionEndEvent, transitionEndHandler);
            toView.css('left', this.direction == 'left' ? this.stackNavigator.$el.width() : -this.stackNavigator.$el.width());
            toView[0].style[this.vendorPrefix + 'Transition'] = this.effectParams;

            activeTransitions++;

            // Showing the view
            toView.css('display', 'inherit');
        }

        if (fromView || toView) {
            // This is a hack to force DOM reflow before transition starts
            this.stackNavigator.$el.css('width');

            transformParams = 'translateX(' + (this.direction == 'left' ? -this.stackNavigator.$el.width() : this.stackNavigator.$el.width()) + 'px)';
        }

        if (fromView && toView)
            fromView[0].style[this.vendorPrefix + 'Transform'] = toView[0].style[this.vendorPrefix + 'Transform'] = transformParams;
        else if (toView)
            toView[0].style[this.vendorPrefix + 'Transform'] = transformParams;
        else if (fromView)
            fromView[0].style[this.vendorPrefix + 'Transform'] = transformParams;
    };

    /**
     * Extended Backbone.View with additional properties like viewPath, destructionPolicy and a reference to parent
     * StackNavigator.
     */
    var View = BackStack.StackView = Backbone.View.extend({

        /**
         * Posible options auto or never
         */
        destructionPolicy:"auto",

        /**
         * Reference to parent StackNavigator
         */
        stackNavigator:undefined,

        /**
         *
         */
        rendered:false,

        setStackNavigator:function (stackNavigator, navigationOptions) {
            this.stackNavigator = stackNavigator;

            if (navigationOptions) {
                if (navigationOptions.destructionPolicy)
                    this.destructionPolicy = navigationOptions.destructionPolicy;
            }

            // Setting default styles
            this.$el.css({position:'absolute', overflow:'hidden', width:'100%', height:'100%'});
        }
    });

    /**
     * Private common push method.
     *
     * @param fromViewRef - reference to from view
     * @param toViewRef - reference to to view
     * @param transition - transition to played during push
     */
    var push = function (fromViewRef, toViewRef, transition) {

        // Hiding view
        toViewRef.instance.$el.css('display', 'none');
        // Adding view to the DOM
        this.$el.append(toViewRef.instance.$el);
        // Rendering view if required
        if (!toViewRef.instance.rendered) {
            toViewRef.instance.render();
            toViewRef.instance.rendered = true;
        }
        // Adding view to the stack internal array
        this.viewsStack.push(toViewRef);

        transition = transition || this.defaultPushTransition || (this.defaultPushTransition = new StackNavigatorSlideEffect(this, 'left'));
        transition.play(fromViewRef ? fromViewRef.instance.$el : null, toViewRef.instance.$el,
            function () {

                this.activeView = toViewRef.instance;
                toViewRef.instance.$el.trigger('viewActivate');

                if (fromViewRef) {
                    fromViewRef.instance.$el.trigger('viewDeactivate');

                    if (fromViewRef.instance.destructionPolicy == 'never') {
                        fromViewRef.instance.$el.detach();
                    } else {
                        fromViewRef.instance.remove();
                        fromViewRef.instance = null;
                    }
                }
            }, this);
    };

    var pop = function (fromViewRef, toViewRef, transition) {

        // Removing top view ref from the stack array
        this.viewsStack.pop();

        if (toViewRef) {

            if (!toViewRef.instance) {
                // Getting view class declaration
                var viewClass = toViewRef.viewClass;
                // Creating view instance
                toViewRef.instance = new viewClass(toViewRef.options);
                // Setting ref to StackNavigator
                toViewRef.instance.setStackNavigator(this, toViewRef.options ? toViewRef.options.navigationOptions : null);
            }

            // Hiding view
            toViewRef.instance.$el.css('display', 'none');
            // Adding view to the DOM
            this.$el.append(toViewRef.instance.$el);
            // Rendering view if required
            if (!toViewRef.instance.rendered) {
                toViewRef.instance.render();
                toViewRef.instance.rendered = true;
            }

        }

        transition = transition || this.defaultPopTransition || (this.defaultPopTransition = new StackNavigatorSlideEffect(this, 'right'));
        transition.play(fromViewRef.instance.$el, toViewRef ? toViewRef.instance.$el : null,
            function () {

                if (toViewRef) {
                    this.activeView = toViewRef.instance;
                    toViewRef.instance.$el.trigger('viewActivate');
                } else {
                    this.activeView = null;
                }

                fromViewRef.instance.$el.trigger('viewDeactivate');
                fromViewRef.instance.remove();
                fromViewRef.instance = null;
            }, this);
    };

    /**
     * StackNavigator manages navigation between application views. It provides functions like pushView, popView,
     * replaceView.
     *
     * When view gets on top of the stack it triggers viewActivate event, when its popped or overlayed with other
     * view it triggers viewDeactivate events.
     */
    BackStack.StackNavigator = Backbone.View.extend({

        tagName:'div',

        viewsStack:new Array(),

        activeView:null,

        defaultPushTransition:null,

        defaultPopTransition:null,

        events:{
            'viewActivate':'proxyActivationEvents',
            'viewDeactivate':'proxyActivationEvents'
        },

        proxyActivationEvents:function (event) {
            this.trigger(event.type, event);
        },

        initialize:function (options) {
            // Setting default styles
            this.$el.css({overflow:'hidden'});
        },

        pushView:function (view, viewOptions, transition) {
            var toView, toViewRef,
                isViewInstance = (typeof view !== 'function'),
                fromViewRef = _.last(this.viewsStack);

            toView = (!isViewInstance) ? new view(viewOptions) : view;
            toView.setStackNavigator(this, (viewOptions) ? viewOptions.navigationOptions : null);
            toViewRef = {instance:toView, viewClass:toView.constructor, options:viewOptions};

            var event = $.Event('viewChanging',
                {
                    action:'push',
                    fromViewClass:fromViewRef ? fromViewRef.viewClass : null,
                    fromView:fromViewRef ? fromViewRef.instance : null,
                    toViewClass:toViewRef.viewClass,
                    toView:toViewRef.instance
                });
            this.trigger(event.type, event);

            if (!event.isDefaultPrevented()) {

                push.call(this, fromViewRef, toViewRef, transition);

                return toView;
            }

            return null;
        },

        popView:function (transition) {
            var toViewRef, fromViewRef;
            if (this.viewsStack.length > 0)
                fromViewRef = this.viewsStack[this.viewsStack.length - 1];

            if (this.viewsStack.length > 1)
                toViewRef = this.viewsStack[this.viewsStack.length - 2];

            var event = $.Event('viewChanging',
                {
                    action:'pop',
                    fromViewClass:fromViewRef ? fromViewRef.viewClass : null,
                    fromView:fromViewRef ? fromViewRef.instance : null,
                    toViewClass:toViewRef ? toViewRef.viewClass : null,
                    toView:toViewRef ? toViewRef.instance : null
                });
            this.trigger(event.type, event);

            if (!event.isDefaultPrevented()) {

                var fromView = fromViewRef.instance;
                pop.call(this, fromViewRef, toViewRef, transition);

                return fromView;
            }

            return null;
        },

        replaceView:function (view, viewOptions, transition) {
            if (this.viewsStack.length > 0) {

                var toView, toViewRef,
                    isViewInstance = (typeof view !== 'function'),
                    fromViewRef = this.viewsStack[this.viewsStack.length - 1];

                toView = (!isViewInstance) ? new view(viewOptions) : view;
                toView.setStackNavigator(this, (viewOptions) ? viewOptions.navigationOptions : null);
                toViewRef = {instance:toView, viewClass:toView.constructor, options:viewOptions};

                var event = $.Event('viewChanging',
                    {
                        action:'replace',
                        fromViewClass:fromViewRef.viewClass,
                        fromView:fromViewRef.instance,
                        toViewClass:toViewRef.viewClass,
                        toView:toViewRef.instance
                    });
                this.trigger(event.type, event);

                if (!event.isDefaultPrevented()) {

                    this.viewsStack.pop();
                    push.call(this, fromViewRef, toViewRef, transition);

                    return toView;
                }
            }
            return null;
        }

    });

    return BackStack;
}));<|endoftext|>


<commit_before>/**
 * Add leading zeros
 *
 * @param {string} num  - number to pad with zeros
 * @param {int}    size - length of number
 * @return {string}     - padded number string
 */
export const pad = (num, size = 2) => {
    let paddedNum = `${num}`;

    while (paddedNum.length < size) {
        paddedNum = `0${paddedNum}`;
    }
    return paddedNum;
};

/**
 * Format date to dd.mm.yyyy, hh:mm
 *
 * @param {string}  dateString - iso string date
 * @return {string}            - formatted string
 */
export const formatDate = (dateString) => {
    const date = new Date(dateString);

    return `${pad(date.getDate())}.${pad(date.getMonth())}.${date.getFullYear()},
            ${pad(date.getHours())}:${pad(date.getMinutes())}`;
};

/**
 * Format Money with point delimiter and fixed to two floats
 *
 * @param {number} price - convert to currency string
 * @param {string} sign  - (optional) currency sign € to be appended
 * @return {string}      - currency string
 */
export const formatMoney = (price, sign = '') => {
    const pieces = parseFloat(price).toFixed(2).replace('.', ',').split('');
    let ii = pieces.length - 3;

    while ((ii -= 3) > 0) {
        pieces.splice(ii, 0, '.');
    }

    return pieces.join('') + sign;
};

/**
 * Clear arrays of any type from duplicate entries in this set
 * https://twitter.com/_ericelliott/status/832065642987524096?lang=de
 *
 * @param {Array} arr - array with duplication [1,1,3]
 * @return {Array}    - new array without duplications [1,3]
 */
export const unique = (arr) => [...new Set(arr)];
<commit_msg>catch wrong date format error, return - instead<commit_after>/**
 * Add leading zeros
 *
 * @param {string} num  - number to pad with zeros
 * @param {int}    size - length of number
 * @return {string}     - padded number string
 */
export const pad = (num, size = 2) => {
    let paddedNum = `${num}`;

    while (paddedNum.length < size) {
        paddedNum = `0${paddedNum}`;
    }

    return paddedNum;
};

/**
 * Format date to dd.mm.yyyy, hh:mm
 *
 * @param {string}  dateString - iso string date
 * @return {string}            - formatted string
 */
export const formatDate = (dateString) => {
    // catch wrong date format
    if (isNaN(Date.parse(dateString))) {
        return '-';
    }

    const date = new Date(dateString);

    return `${pad(date.getDate())}.${pad(date.getMonth())}.${date.getFullYear()},
            ${pad(date.getHours())}:${pad(date.getMinutes())}`;
};

/**
 * Format Money with point delimiter and fixed to two floats
 *
 * @param {number} price - convert to currency string
 * @param {string} sign  - (optional) currency sign € to be appended
 * @return {string}      - currency string
 */
export const formatMoney = (price, sign = '') => {
    const pieces = parseFloat(price).toFixed(2).replace('.', ',').split('');
    let ii = pieces.length - 3;

    while ((ii -= 3) > 0) {
        pieces.splice(ii, 0, '.');
    }

    return pieces.join('') + sign;
};

/**
 * Clear arrays of any type from duplicate entries in this set
 * https://twitter.com/_ericelliott/status/832065642987524096?lang=de
 *
 * @param {Array} arr - array with duplication [1,1,3]
 * @return {Array}    - new array without duplications [1,3]
 */
export const unique = (arr) => [...new Set(arr)];
<|endoftext|>


<commit_before>// ReactGIFs - React-based image sharing platform
// veeti "walther" haapsamo 2016

// Post has a title, one or more images with captions, and a comment box
var Post = React.createClass({
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
    console.log("Post debug: url = " + this.props.url);
    var page = this;
    var loadPage = fetch(page.props.url)
    .then(function (response) {
      return response.json()
    })
    .then(function (data) {
      console.log("Data response: " + data)
      page.setState({data: data})
    });
  },
  render: function() {
    console.log("Post debug: Images: " + this.state.data.images);
    if (this.state.data.images) {
      var images = this.state.data.images.map(function(image) {
        return (
          <Image alt={image.alt} src={image.src} txt={image.txt} key={image.src} />
        )
      })
    } else {
      return (
loading...
);
    }

    return (

{this.state.data.title}

posted by: {this.state.data.author}

        {images}
        <CommentList comments={this.state.data.comments} profile={this.props.profile} />

    );
  }
})

// Class for the image posting form
var ImageForm = React.createClass({
  getInitialState: function() {
    return {title: '', caption: '', profile: this.props.profile};
  },
  handleTitleChange: function(e) {
    this.setState({title: e.target.value});
  },
  handleCaptionChange: function(e) {
    this.setState({caption: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    var author = this.props.profile.nickname;
    var title = this.state.title.trim();
    var caption = this.state.caption.trim();
    if (!title || !caption ) {
      console.log("something was empty")
      return;
    }

    var data = new FormData();
    data.append("author", author);
    data.append("title", title);
    data.append("caption", caption);
    var files = document.querySelector('#file').files;
    var i=0;
    for (var file in files) {
      data.append('file-'+i, files[file]);
      i++;
    }

    var form = document.querySelector('form')
    var postImages = fetch('/upload', {
      body: data,
      headers: {
        'Authorization': 'Bearer ' + localStorage.getItem('userToken')
      },
      method: 'POST'
    });

    postImages.then(function (response) {
      response.json().then(function (data) {
        console.log("Data response: " + data)
        window.location.pathname=data;
      });

    });
  },

  render: function() {
    if (this.props.profile) {
      return (
        <form className="imageForm" encType="multipart/form-data" onSubmit={this.handleSubmit}>
          <input type="hidden" name="command" value="post" />

Logged in and posting as: {this.props.profile.nickname}

          <input
            type="text"
            placeholder="Title"
            value={this.state.title}
            onChange={this.handleTitleChange}
          />

          <input id="file" type="file" name="file" />

          <input
            type="text"
            placeholder="Caption"
            value={this.state.caption}
            onChange={this.handleCaptionChange}
          />

          <input type="submit" value="Post image" className="button"/>
        </form>
      );
    } else {
      return (

Loading profile data

      );
    }
  }
});

// Individual image object
var Image = React.createClass({
  render: function() {
    return (

{this.props.txt}

    );
  }
});

// Comments

var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.comments.map(function(comment) {
    return (
      <Comment author={comment.author} key={comment.id}>
        {comment.text}
      </Comment>
    )
    });
    if (this.props.profile) {
      return (

Comments

        {commentNodes}
        <CommentForm profile={this.props.profile}/>

      )
    } else {
        return (

Comments

        {commentNodes}

          <button onClick={this.showLock}>Sign in to comment</button>

      )
    }
  }
});

var CommentForm = React.createClass({
  getInitialState: function() {
    return {author: '', text: ''};
  },
  handleAuthorChange: function(e) {
    this.setState({author: e.target.value});
  },
  handleTextChange: function(e) {
    this.setState({text: e.target.value});
  },
  handleSubmit: function(e) {
    console.log("button clicked")
    e.preventDefault();
    var author = this.props.profile.nickname;
    var text = this.state.text.trim();
    if (!author || !text ) {
      console.log("something was empty")
      return;
    }

    var commentObject = {
      "command": "comment",
      "author": author,
      "text": text,
      "imageid": location.pathname.slice(1)
    }

    var postImages = fetch('/api', {
      body: JSON.stringify(commentObject),
      headers: {
        'Authorization': 'Bearer ' + localStorage.getItem('userToken'),
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      method: 'POST'
    });

    this.setState(this.getInitialState());
    location.reload();
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>

Posting comment as {this.props.profile.nickname}

        <input
          type="text"
          placeholder="Text"
          value={this.state.text}
          onChange={this.handleTextChange}
        />

        <input className="button" type="submit" value="Submit comment" />
      </form>
    );
  }
});

var Comment = React.createClass({
  render: function() {
    return (

          {this.props.author}:

        {this.props.children}

    );
  }
});

// Login box
var LoginBox = React.createClass({
  showLock: function() {
    // We receive lock from the parent component in this case
    // If you instantiate it in this component, just do this.lock.show()
    this.props.lock.show();
  },

  render: function() {
    return (

      <buttton className="button" onClick={this.showLock}>Sign in to post</buttton>

);
  }
});

// Main render function;
// serve either index page or the page content requested
var Main = React.createClass({
  // Instantiate idToken / auth0
  getInitialState: function() {
    return {profile: null};
  },
  componentWillMount: function() {
    this.lock = new Auth0Lock('N1zyz6FaQspe9Z0bX9QrUPMbp5rWEidR', 'reactgifs.eu.auth0.com');
    this.setState({idToken: this.getIdToken()});
  },
  componentDidMount: function() {
    this.lock.getProfile(this.state.idToken, function (err, profile) {
      if (err) {
        console.log("Error loading the Profile", err);
        return;
      }
      this.setState({profile: profile});
      console.log("Profile: " + profile)
    }.bind(this));
  },
  getIdToken: function() {
    var idToken = localStorage.getItem('userToken');
    var authHash = this.lock.parseHash(window.location.hash);
    if (!idToken && authHash) {
      if (authHash.id_token) {
        idToken = authHash.id_token
        localStorage.setItem('userToken', authHash.id_token);
        window.location.hash = '';
      }
      if (authHash.error) {
        console.log("Error signing in", authHash);
        return null;
      }
    }
    return idToken;
  },
  render: function() {
    var pageId = window.location.pathname.slice(1);
    console.log("current page id: " + pageId);
    // Index page
    if (pageId.length === 0) {
      // Logged in, show submit form
      if (this.state.idToken) {
        return(

ReactGIFs

ReactGIFs is a React-based image sharing site.

Kindly note the 2MB image size limit.

            <ImageForm profile={this.state.profile}/>

        );
        }
      // Not logged in, show login form
      else {
        return(

ReactGIFs

ReactGIFs is a React-based image sharing site.

            <LoginBox lock={this.lock}/>

        );
      }
    }
    else {
      // Image post page, show post + comments
      pageId = "data/" + pageId;
      return(<Post url={pageId} profile={this.state.profile}/>);
    }
  }
})

// Run main at least once on initial load
ReactDOM.render(, document.getElementById('content'));
<commit_msg>Rename 'Post' to 'Gallery' to reduce confusion<commit_after>// ReactGIFs - React-based image sharing platform
// veeti "walther" haapsamo 2016

// Gallery has a title, one or more images with captions, and a comment box
var Gallery = React.createClass({
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
    console.log("Gallery debug: url = " + this.props.url);
    var page = this;
    var loadPage = fetch(page.props.url)
    .then(function (response) {
      return response.json()
    })
    .then(function (data) {
      console.log("Data response: " + data)
      page.setState({data: data})
    });
  },
  render: function() {
    console.log("Gallery debug: Images: " + this.state.data.images);
    if (this.state.data.images) {
      var images = this.state.data.images.map(function(image) {
        return (
          <Image alt={image.alt} src={image.src} txt={image.txt} key={image.src} />
        )
      })
    } else {
      return (
loading...
);
    }

    return (

{this.state.data.title}

posted by: {this.state.data.author}

        {images}
        <CommentList comments={this.state.data.comments} profile={this.props.profile} />

    );
  }
})

// Class for the image posting form
var ImageForm = React.createClass({
  getInitialState: function() {
    return {title: '', caption: '', profile: this.props.profile};
  },
  handleTitleChange: function(e) {
    this.setState({title: e.target.value});
  },
  handleCaptionChange: function(e) {
    this.setState({caption: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    var author = this.props.profile.nickname;
    var title = this.state.title.trim();
    var caption = this.state.caption.trim();
    if (!title || !caption ) {
      console.log("something was empty")
      return;
    }

    var data = new FormData();
    data.append("author", author);
    data.append("title", title);
    data.append("caption", caption);
    var files = document.querySelector('#file').files;
    var i=0;
    for (var file in files) {
      data.append('file-'+i, files[file]);
      i++;
    }

    var form = document.querySelector('form')
    var postImages = fetch('/upload', {
      body: data,
      headers: {
        'Authorization': 'Bearer ' + localStorage.getItem('userToken')
      },
      method: 'POST'
    });

    postImages.then(function (response) {
      response.json().then(function (data) {
        console.log("Data response: " + data)
        window.location.pathname=data;
      });

    });
  },

  render: function() {
    if (this.props.profile) {
      return (
        <form className="imageForm" encType="multipart/form-data" onSubmit={this.handleSubmit}>
          <input type="hidden" name="command" value="post" />

Logged in and posting as: {this.props.profile.nickname}

          <input
            type="text"
            placeholder="Title"
            value={this.state.title}
            onChange={this.handleTitleChange}
          />

          <input id="file" type="file" name="file" />

          <input
            type="text"
            placeholder="Caption"
            value={this.state.caption}
            onChange={this.handleCaptionChange}
          />

          <input type="submit" value="Post image" className="button"/>
        </form>
      );
    } else {
      return (

Loading profile data

      );
    }
  }
});

// Individual image object
var Image = React.createClass({
  render: function() {
    return (

{this.props.txt}

    );
  }
});

// Comments

var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.comments.map(function(comment) {
    return (
      <Comment author={comment.author} key={comment.id}>
        {comment.text}
      </Comment>
    )
    });
    if (this.props.profile) {
      return (

Comments

        {commentNodes}
        <CommentForm profile={this.props.profile}/>

      )
    } else {
        return (

Comments

        {commentNodes}

          <button onClick={this.showLock}>Sign in to comment</button>

      )
    }
  }
});

var CommentForm = React.createClass({
  getInitialState: function() {
    return {author: '', text: ''};
  },
  handleAuthorChange: function(e) {
    this.setState({author: e.target.value});
  },
  handleTextChange: function(e) {
    this.setState({text: e.target.value});
  },
  handleSubmit: function(e) {
    console.log("button clicked")
    e.preventDefault();
    var author = this.props.profile.nickname;
    var text = this.state.text.trim();
    if (!author || !text ) {
      console.log("something was empty")
      return;
    }

    var commentObject = {
      "command": "comment",
      "author": author,
      "text": text,
      "imageid": location.pathname.slice(1)
    }

    var postImages = fetch('/api', {
      body: JSON.stringify(commentObject),
      headers: {
        'Authorization': 'Bearer ' + localStorage.getItem('userToken'),
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      method: 'POST'
    });

    this.setState(this.getInitialState());
    location.reload();
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>

Posting comment as {this.props.profile.nickname}

        <input
          type="text"
          placeholder="Text"
          value={this.state.text}
          onChange={this.handleTextChange}
        />

        <input className="button" type="submit" value="Submit comment" />
      </form>
    );
  }
});

var Comment = React.createClass({
  render: function() {
    return (

          {this.props.author}:

        {this.props.children}

    );
  }
});

// Login box
var LoginBox = React.createClass({
  showLock: function() {
    // We receive lock from the parent component in this case
    // If you instantiate it in this component, just do this.lock.show()
    this.props.lock.show();
  },

  render: function() {
    return (

      <buttton className="button" onClick={this.showLock}>Sign in to post</buttton>

);
  }
});

// Main render function;
// serve either index page or the page content requested
var Main = React.createClass({
  // Instantiate idToken / auth0
  getInitialState: function() {
    return {profile: null};
  },
  componentWillMount: function() {
    this.lock = new Auth0Lock('N1zyz6FaQspe9Z0bX9QrUPMbp5rWEidR', 'reactgifs.eu.auth0.com');
    this.setState({idToken: this.getIdToken()});
  },
  componentDidMount: function() {
    this.lock.getProfile(this.state.idToken, function (err, profile) {
      if (err) {
        console.log("Error loading the Profile", err);
        return;
      }
      this.setState({profile: profile});
      console.log("Profile: " + profile)
    }.bind(this));
  },
  getIdToken: function() {
    var idToken = localStorage.getItem('userToken');
    var authHash = this.lock.parseHash(window.location.hash);
    if (!idToken && authHash) {
      if (authHash.id_token) {
        idToken = authHash.id_token
        localStorage.setItem('userToken', authHash.id_token);
        window.location.hash = '';
      }
      if (authHash.error) {
        console.log("Error signing in", authHash);
        return null;
      }
    }
    return idToken;
  },
  render: function() {
    var pageId = window.location.pathname.slice(1);
    console.log("current page id: " + pageId);
    // Index page
    if (pageId.length === 0) {
      // Logged in, show submit form
      if (this.state.idToken) {
        return(

ReactGIFs

ReactGIFs is a React-based image sharing site.

Kindly note the 2MB image size limit.

            <ImageForm profile={this.state.profile}/>

        );
        }
      // Not logged in, show login form
      else {
        return(

ReactGIFs

ReactGIFs is a React-based image sharing site.

            <LoginBox lock={this.lock}/>

        );
      }
    }
    else {
      // Image post page, show post + comments
      pageId = "data/" + pageId;
      return(<Gallery url={pageId} profile={this.state.profile}/>);
    }
  }
})

// Run main at least once on initial load
ReactDOM.render(, document.getElementById('content'));
<|endoftext|>


<commit_before><commit_msg>#1817: fixed Click_LabelDelete typo<commit_after><|endoftext|>


<commit_before>describe('React server side rendering', function () {
    it('should be good', function () {
        browser.get('product?id=124');
        expect(element.all(by.css('ul li')).count()).toEqual(3);
    });

    it('price should be 12400', function () {
        browser.get('product?id=124');
        expect(element(by.css('div span')).getInnerHtml()).toMatch(/12400/);
    });
});<commit_msg>fix spec<commit_after>describe('React server side rendering', function () {
    it('should be good', function () {
        browser.get('product?id=124');
        expect(element.all(by.css('h4')).count()).toEqual(1);
    });

    it('price should be 12400', function () {
        browser.get('product?id=124');
        expect(element(by.css('div span')).getInnerHtml()).toMatch(/12400/);
    });
});<|endoftext|>