<commit_before>var qs;
(window.onpopstate = function () {
    var match,
        pl     = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
        query  = window.location.search.substring(1);

    qs = {};
    while (match = search.exec(query))
       qs[decode(match[1])] = decode(match[2]);
})();

var channels;
if ("channel" in qs) {
channels = [qs['channel']], // Channels to initially join
	fadeDelay = 5000, // Set to false to disable chat fade
	showChannel = true, // Show repespective channels if the channels is longer than 1
	useColor = true, // Use chatters' colors or to inherit
	showBadges = true, // Show chatters' badges
	showEmotes = true, // Show emotes in the chat
	doTimeouts = true, // Hide the messages of people who are timed-out
	doChatClears = true, // Hide the chat from an entire channel
	showHosting = true, // Show when the channel is hosting or not
	showConnectionNotices = true; // Show messages like "Connected" and "Disconnected"
} else {
channels = ['yongjhih', 'mistakelolz', 'twitchplayspokemon'], // Channels to initially join
	fadeDelay = 5000, // Set to false to disable chat fade
	showChannel = true, // Show repespective channels if the channels is longer than 1
	useColor = true, // Use chatters' colors or to inherit
	showBadges = true, // Show chatters' badges
	showEmotes = true, // Show emotes in the chat
	doTimeouts = true, // Hide the messages of people who are timed-out
	doChatClears = true, // Hide the chat from an entire channel
	showHosting = true, // Show when the channel is hosting or not
	showConnectionNotices = true; // Show messages like "Connected" and "Disconnected"
}
var alias = qs['alias'] ? qs['alias'] : qs['channel'];

var chat = document.getElementById('chat'),
	defaultColors = ['rgb(255, 0, 0)','rgb(0, 0, 255)','rgb(0, 128, 0)','rgb(178, 34, 34)','rgb(255, 127, 80)','rgb(154, 205, 50)','rgb(255, 69, 0)','rgb(46, 139, 87)','rgb(218, 165, 32)','rgb(210, 105, 30)','rgb(95, 158, 160)','rgb(30, 144, 255)','rgb(255, 105, 180)','rgb(138, 43, 226)','rgb(0, 255, 127)'],
	randomColorsChosen = {},
	clientOptions = {
			options: {
					debug: true
				},
			channels: channels
		},
	client = new irc.client(clientOptions);

function dehash(channel) {
	return channel.replace(/^#/, '');
}

function capitalize(n) {
	return n[0].toUpperCase() +  n.substr(1);
}

function htmlEntities(html) {
	function it() {
		return html.map(function(n, i, arr) {
				if(n.length == 1) {
					return n.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
						   return '&#'+i.charCodeAt(0)+';';
						});
				}
				return n;
			});
	}
	var isArray = Array.isArray(html);
	if(!isArray) {
		html = html.split('');
	}
	html = it(html);
	if(!isArray) html = html.join('');
	return html;
}

function formatEmotes(text, emotes) {
	var splitText = text.split('');
	for(var i in emotes) {
		var e = emotes[i];
		for(var j in e) {
			var mote = e[j];
			if(typeof mote == 'string') {
				mote = mote.split('-');
				mote = [parseInt(mote[0]), parseInt(mote[1])];
				var length =  mote[1] - mote[0],
					empty = Array.apply(null, new Array(length + 1)).map(function() { return '' });
				splitText = splitText.slice(0, mote[0]).concat(empty).concat(splitText.slice(mote[1] + 1, splitText.length));
				splitText.splice(mote[0], 1, '');
			}
		}
	}
	return htmlEntities(splitText).join('')
}

function badges(chan, user, isBot) {

	function createBadge(name) {
		var badge = document.createElement('div');
		badge.className = 'chat-badge-' + name;
		return badge;
	}

	var chatBadges = document.createElement('span');
	chatBadges.className = 'chat-badges';

	if(!isBot) {
		if(user.username == chan) {
			chatBadges.appendChild(createBadge('broadcaster'));
		}
		if(user['user-type']) {
			chatBadges.appendChild(createBadge(user['user-type']));
		}
		if(user.turbo) {
			chatBadges.appendChild(createBadge('turbo'));
		}
	}
	else {
		chatBadges.appendChild(createBadge('bot'));
	}

	return chatBadges;
}

function handleChat(channel, user, message, self) {
	var chan = dehash(channel),
		name = user.username,
		chatBubbler = document.createElement('div'),
		chatBubble = document.createElement('span'),
		chatLine = document.createElement('span'),
		chatTail = document.createElement('span'),
		chatChannel = document.createElement('span'),
		chatAvatar = document.createElement('div'),
		chatName = document.createElement('span'),
		chatColon = document.createElement('span'),
		chatMessage = document.createElement('span');

	var color = useColor ? user.color : 'inherit';
	if(color === null) {
		if(!randomColorsChosen.hasOwnProperty(chan)) {
			randomColorsChosen[chan] = {};
		}
		if(randomColorsChosen[chan].hasOwnProperty(name)) {
			color = randomColorsChosen[chan][name];
		}
		else {
			color = defaultColors[Math.floor(Math.random()*defaultColors.length)];
			randomColorsChosen[chan][name] = color;
		}
	}

	chatLine.className = 'chat-line bubble';
	chatLine.dataset.username = name;
	chatLine.dataset.channel = channel;

	if(user['message-type'] == 'action') {
		chatLine.className += ' chat-action';
	}

	chatChannel.className = 'chat-channel';
	chatChannel.innerHTML = chan;

	chatName.className = 'chat-name';
	chatName.style.color = color;
	chatName.innerHTML = user['display-name'] || name;

	chatColon.className = 'chat-colon';

	chatMessage.className = 'chat-message';

	chatMessage.style.color = color;
	chatMessage.innerHTML = showEmotes ? formatEmotes(message, user.emotes) : htmlEntities(message);

	chatBubbler.className = 'chat-bubbler';
	chatAvatar.className = 'chat-avatar';

	if(client.opts.channels.length > 1 && showChannel) chatLine.appendChild(chatChannel);
	if(showBadges) chatLine.appendChild(badges(chan, user, self));
	//chatLine.appendChild(chatName);
	chatAvatar.appendChild(chatName);
	//chatLine.appendChild(chatColon);
	chatAvatar.appendChild(chatColon);
	chatLine.appendChild(chatMessage);
	chatBubble.appendChild(chatLine);
	chatBubbler.appendChild(chatAvatar);
	chatBubbler.appendChild(chatBubble);
	chat.appendChild(chatBubbler);

	if(typeof fadeDelay == 'number') {
		setTimeout(function() {
				chatLine.dataset.faded = '';
			}, fadeDelay);
	}

	if(chat.children.length > 50) {
		var oldMessages = [].slice.call(chat.children).slice(0, 10);
		for(var i in oldMessages) oldMessages[i].remove();
	}
}

function chatNotice(information, noticeFadeDelay, level, additionalClasses) {
	var ele = document.createElement('div');

	ele.className = 'chat-line chat-notice';
	ele.innerHTML = information;

	if(additionalClasses !== undefined) {
		if(Array.isArray(additionalClasses)) {
			additionalClasses = additionalClasses.join(' ');
		}
		ele.className += ' ' + additionalClasses;
	}

	if(typeof level == 'number' && level != 0) {
		ele.dataset.level = level;
	}

	chat.appendChild(ele);

	if(typeof noticeFadeDelay == 'number') {
		setTimeout(function() {
				ele.dataset.faded = '';
			}, noticeFadeDelay || 500);
	}

	return ele;
}

var recentTimeouts = {};

function timeout(channel, username) {
	if(!doTimeouts) return false;
	if(!recentTimeouts.hasOwnProperty(channel)) {
		recentTimeouts[channel] = {};
	}
	if(!recentTimeouts[channel].hasOwnProperty(username) || recentTimeouts[channel][username] + 1000*10 < +new Date) {
		recentTimeouts[channel][username] = +new Date;
		chatNotice(capitalize(username) + ' was timed-out in ' + capitalize(dehash(channel)), 1000, 1, 'chat-delete-timeout')
	};
	var toHide = document.querySelectorAll('.chat-line[data-channel="' + channel + '"][data-username="' + username + '"]:not(.chat-timedout) .chat-message');
	for(var i in toHide) {
		var h = toHide[i];
		if(typeof h == 'object') {
			h.innerText = '<Message deleted>';
			h.parentElement.className += ' chat-timedout';
		}
	}
}
function clearChat(channel) {
	if(!doChatClears) return false;
	var toHide = document.querySelectorAll('.chat-line[data-channel="' + channel + '"]');
	for(var i in toHide) {
		var h = toHide[i];
		if(typeof h == 'object') {
			h.className += ' chat-cleared';
		}
	}
	chatNotice('Chat was cleared in ' + capitalize(dehash(channel)), 1000, 1, 'chat-delete-clear')
}
function hosting(channel, target, viewers, unhost) {
	if(!showHosting) return false;
	if(viewers == '-') viewers = 0;
	var chan = dehash(channel);
	chan = capitalize(chan);
	if(!unhost) {
		var targ = capitalize(target);
		chatNotice(chan + ' is now hosting ' + targ + ' for ' + viewers + ' viewer' + (viewers !== 1 ? 's' : '') + '.', null, null, 'chat-hosting-yes');
	}
	else {
		chatNotice(chan + ' is no longer hosting.', null, null, 'chat-hosting-no');
	}
}

client.addListener('message', handleChat);
client.addListener('timeout', timeout);
client.addListener('clearchat', clearChat);
client.addListener('hosting', hosting);
client.addListener('unhost', function(channel, viewers) { hosting(channel, null, viewers, true) });

var joinAccounced = [];

client.addListener('connecting', function (address, port) {
		if(showConnectionNotices) {
			chatNotice('Connecting', 1000, -4, 'chat-connection-good-connecting');
		}
	});
client.addListener('logon', function () {
		if(showConnectionNotices) chatNotice('Authenticating', 1000, -3, 'chat-connection-good-logon');
	});
client.addListener('connectfail', function () {
		if(showConnectionNotices) chatNotice('Connection failed', 1000, 3, 'chat-connection-bad-fail');
	});
client.addListener('connected', function (address, port) {
		if(showConnectionNotices) chatNotice('Connected', 1000, -2, 'chat-connection-good-connected');
		joinAccounced = [];
	});
client.addListener('disconnected', function (reason) {
		if(showConnectionNotices) chatNotice('Disconnected: ' + (reason || ''), 3000, 2, 'chat-connection-bad-disconnected');
	});
client.addListener('reconnect', function () {
		if(showConnectionNotices) chatNotice('Reconnected', 1000, 'chat-connection-good-reconnect');
	});
client.addListener('join', function (channel, username) {
		if(joinAccounced.indexOf(channel) == -1) {
			if(showConnectionNotices) chatNotice(capitalize(dehash(username)) + ' joined ' + capitalize(dehash(channel)), 1000, -1, 'chat-room-join');
                        var welcomeMsg = '歡迎來到 ' + alias + ' 的遊戲間 ' + username;
                        responsiveVoice.speak(welcomeMsg, 'Chinese Female');
                        var user;
                        user = {
                            username: qs['channel'],
                            name: qs['channel'],
                            emotes: []
                        };

                        handleChat(channel, user, welcomeMsg, true);
			joinAccounced.push(channel);
		}
	});
client.addListener('part', function (channel, username) {
		var index = joinAccounced.indexOf(channel);
		if(index > -1) {
			if(showConnectionNotices) chatNotice(capitalize(dehash(username)) + ' parted ' + capitalize(dehash(channel)), 1000, -1, 'chat-room-part');
			joinAccounced.splice(joinAccounced.indexOf(channel), 1)
		}
	});

client.addListener('crash', function () {
		chatNotice('Crashed', 10000, 4, 'chat-crash');
	});

client.connect();
<commit_msg>Filter justinfan for welcome<commit_after>var qs;
(window.onpopstate = function () {
    var match,
        pl     = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
        query  = window.location.search.substring(1);

    qs = {};
    while (match = search.exec(query))
       qs[decode(match[1])] = decode(match[2]);
})();

var channels;
if ("channel" in qs) {
channels = [qs['channel']], // Channels to initially join
	fadeDelay = 5000, // Set to false to disable chat fade
	showChannel = true, // Show repespective channels if the channels is longer than 1
	useColor = true, // Use chatters' colors or to inherit
	showBadges = true, // Show chatters' badges
	showEmotes = true, // Show emotes in the chat
	doTimeouts = true, // Hide the messages of people who are timed-out
	doChatClears = true, // Hide the chat from an entire channel
	showHosting = true, // Show when the channel is hosting or not
	showConnectionNotices = true; // Show messages like "Connected" and "Disconnected"
} else {
channels = ['yongjhih', 'mistakelolz', 'twitchplayspokemon'], // Channels to initially join
	fadeDelay = 5000, // Set to false to disable chat fade
	showChannel = true, // Show repespective channels if the channels is longer than 1
	useColor = true, // Use chatters' colors or to inherit
	showBadges = true, // Show chatters' badges
	showEmotes = true, // Show emotes in the chat
	doTimeouts = true, // Hide the messages of people who are timed-out
	doChatClears = true, // Hide the chat from an entire channel
	showHosting = true, // Show when the channel is hosting or not
	showConnectionNotices = true; // Show messages like "Connected" and "Disconnected"
}
var alias = qs['alias'] ? qs['alias'] : qs['channel'];

var chat = document.getElementById('chat'),
	defaultColors = ['rgb(255, 0, 0)','rgb(0, 0, 255)','rgb(0, 128, 0)','rgb(178, 34, 34)','rgb(255, 127, 80)','rgb(154, 205, 50)','rgb(255, 69, 0)','rgb(46, 139, 87)','rgb(218, 165, 32)','rgb(210, 105, 30)','rgb(95, 158, 160)','rgb(30, 144, 255)','rgb(255, 105, 180)','rgb(138, 43, 226)','rgb(0, 255, 127)'],
	randomColorsChosen = {},
	clientOptions = {
			options: {
					debug: true
				},
			channels: channels
		},
	client = new irc.client(clientOptions);

function dehash(channel) {
	return channel.replace(/^#/, '');
}

function capitalize(n) {
	return n[0].toUpperCase() +  n.substr(1);
}

function htmlEntities(html) {
	function it() {
		return html.map(function(n, i, arr) {
				if(n.length == 1) {
					return n.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
						   return '&#'+i.charCodeAt(0)+';';
						});
				}
				return n;
			});
	}
	var isArray = Array.isArray(html);
	if(!isArray) {
		html = html.split('');
	}
	html = it(html);
	if(!isArray) html = html.join('');
	return html;
}

function formatEmotes(text, emotes) {
	var splitText = text.split('');
	for(var i in emotes) {
		var e = emotes[i];
		for(var j in e) {
			var mote = e[j];
			if(typeof mote == 'string') {
				mote = mote.split('-');
				mote = [parseInt(mote[0]), parseInt(mote[1])];
				var length =  mote[1] - mote[0],
					empty = Array.apply(null, new Array(length + 1)).map(function() { return '' });
				splitText = splitText.slice(0, mote[0]).concat(empty).concat(splitText.slice(mote[1] + 1, splitText.length));
				splitText.splice(mote[0], 1, '');
			}
		}
	}
	return htmlEntities(splitText).join('')
}

function badges(chan, user, isBot) {

	function createBadge(name) {
		var badge = document.createElement('div');
		badge.className = 'chat-badge-' + name;
		return badge;
	}

	var chatBadges = document.createElement('span');
	chatBadges.className = 'chat-badges';

	if(!isBot) {
		if(user.username == chan) {
			chatBadges.appendChild(createBadge('broadcaster'));
		}
		if(user['user-type']) {
			chatBadges.appendChild(createBadge(user['user-type']));
		}
		if(user.turbo) {
			chatBadges.appendChild(createBadge('turbo'));
		}
	}
	else {
		chatBadges.appendChild(createBadge('bot'));
	}

	return chatBadges;
}

function handleChat(channel, user, message, self) {
	var chan = dehash(channel),
		name = user.username,
		chatBubbler = document.createElement('div'),
		chatBubble = document.createElement('span'),
		chatLine = document.createElement('span'),
		chatTail = document.createElement('span'),
		chatChannel = document.createElement('span'),
		chatAvatar = document.createElement('div'),
		chatName = document.createElement('span'),
		chatColon = document.createElement('span'),
		chatMessage = document.createElement('span');

	var color = useColor ? user.color : 'inherit';
	if(color === null) {
		if(!randomColorsChosen.hasOwnProperty(chan)) {
			randomColorsChosen[chan] = {};
		}
		if(randomColorsChosen[chan].hasOwnProperty(name)) {
			color = randomColorsChosen[chan][name];
		}
		else {
			color = defaultColors[Math.floor(Math.random()*defaultColors.length)];
			randomColorsChosen[chan][name] = color;
		}
	}

	chatLine.className = 'chat-line bubble';
	chatLine.dataset.username = name;
	chatLine.dataset.channel = channel;

	if(user['message-type'] == 'action') {
		chatLine.className += ' chat-action';
	}

	chatChannel.className = 'chat-channel';
	chatChannel.innerHTML = chan;

	chatName.className = 'chat-name';
	chatName.style.color = color;
	chatName.innerHTML = user['display-name'] || name;

	chatColon.className = 'chat-colon';

	chatMessage.className = 'chat-message';

	chatMessage.style.color = color;
	chatMessage.innerHTML = showEmotes ? formatEmotes(message, user.emotes) : htmlEntities(message);

	chatBubbler.className = 'chat-bubbler';
	chatAvatar.className = 'chat-avatar';

	if(client.opts.channels.length > 1 && showChannel) chatLine.appendChild(chatChannel);
	if(showBadges) chatLine.appendChild(badges(chan, user, self));
	//chatLine.appendChild(chatName);
	chatAvatar.appendChild(chatName);
	//chatLine.appendChild(chatColon);
	chatAvatar.appendChild(chatColon);
	chatLine.appendChild(chatMessage);
	chatBubble.appendChild(chatLine);
	chatBubbler.appendChild(chatAvatar);
	chatBubbler.appendChild(chatBubble);
	chat.appendChild(chatBubbler);

	if(typeof fadeDelay == 'number') {
		setTimeout(function() {
				chatLine.dataset.faded = '';
			}, fadeDelay);
	}

	if(chat.children.length > 50) {
		var oldMessages = [].slice.call(chat.children).slice(0, 10);
		for(var i in oldMessages) oldMessages[i].remove();
	}
}

function chatNotice(information, noticeFadeDelay, level, additionalClasses) {
	var ele = document.createElement('div');

	ele.className = 'chat-line chat-notice';
	ele.innerHTML = information;

	if(additionalClasses !== undefined) {
		if(Array.isArray(additionalClasses)) {
			additionalClasses = additionalClasses.join(' ');
		}
		ele.className += ' ' + additionalClasses;
	}

	if(typeof level == 'number' && level != 0) {
		ele.dataset.level = level;
	}

	chat.appendChild(ele);

	if(typeof noticeFadeDelay == 'number') {
		setTimeout(function() {
				ele.dataset.faded = '';
			}, noticeFadeDelay || 500);
	}

	return ele;
}

var recentTimeouts = {};

function timeout(channel, username) {
	if(!doTimeouts) return false;
	if(!recentTimeouts.hasOwnProperty(channel)) {
		recentTimeouts[channel] = {};
	}
	if(!recentTimeouts[channel].hasOwnProperty(username) || recentTimeouts[channel][username] + 1000*10 < +new Date) {
		recentTimeouts[channel][username] = +new Date;
		chatNotice(capitalize(username) + ' was timed-out in ' + capitalize(dehash(channel)), 1000, 1, 'chat-delete-timeout')
	};
	var toHide = document.querySelectorAll('.chat-line[data-channel="' + channel + '"][data-username="' + username + '"]:not(.chat-timedout) .chat-message');
	for(var i in toHide) {
		var h = toHide[i];
		if(typeof h == 'object') {
			h.innerText = '<Message deleted>';
			h.parentElement.className += ' chat-timedout';
		}
	}
}
function clearChat(channel) {
	if(!doChatClears) return false;
	var toHide = document.querySelectorAll('.chat-line[data-channel="' + channel + '"]');
	for(var i in toHide) {
		var h = toHide[i];
		if(typeof h == 'object') {
			h.className += ' chat-cleared';
		}
	}
	chatNotice('Chat was cleared in ' + capitalize(dehash(channel)), 1000, 1, 'chat-delete-clear')
}
function hosting(channel, target, viewers, unhost) {
	if(!showHosting) return false;
	if(viewers == '-') viewers = 0;
	var chan = dehash(channel);
	chan = capitalize(chan);
	if(!unhost) {
		var targ = capitalize(target);
		chatNotice(chan + ' is now hosting ' + targ + ' for ' + viewers + ' viewer' + (viewers !== 1 ? 's' : '') + '.', null, null, 'chat-hosting-yes');
	}
	else {
		chatNotice(chan + ' is no longer hosting.', null, null, 'chat-hosting-no');
	}
}

client.addListener('message', handleChat);
client.addListener('timeout', timeout);
client.addListener('clearchat', clearChat);
client.addListener('hosting', hosting);
client.addListener('unhost', function(channel, viewers) { hosting(channel, null, viewers, true) });

var joinAccounced = [];

client.addListener('connecting', function (address, port) {
		if(showConnectionNotices) {
			chatNotice('Connecting', 1000, -4, 'chat-connection-good-connecting');
		}
	});
client.addListener('logon', function () {
		if(showConnectionNotices) chatNotice('Authenticating', 1000, -3, 'chat-connection-good-logon');
	});
client.addListener('connectfail', function () {
		if(showConnectionNotices) chatNotice('Connection failed', 1000, 3, 'chat-connection-bad-fail');
	});
client.addListener('connected', function (address, port) {
		if(showConnectionNotices) chatNotice('Connected', 1000, -2, 'chat-connection-good-connected');
		joinAccounced = [];
	});
client.addListener('disconnected', function (reason) {
		if(showConnectionNotices) chatNotice('Disconnected: ' + (reason || ''), 3000, 2, 'chat-connection-bad-disconnected');
	});
client.addListener('reconnect', function () {
		if(showConnectionNotices) chatNotice('Reconnected', 1000, 'chat-connection-good-reconnect');
	});
client.addListener('join', function (channel, username) {
		if(joinAccounced.indexOf(channel) == -1) {
                    if (!username.startsWith('justinfan')) {
			if(showConnectionNotices) chatNotice(capitalize(dehash(username)) + ' joined ' + capitalize(dehash(channel)), 1000, -1, 'chat-room-join');
                        var welcomeMsg = '歡迎來到 ' + alias + ' 的遊戲間 ' + username;
                        responsiveVoice.speak(welcomeMsg, 'Chinese Female');
                        var user;
                        user = {
                            username: qs['channel'],
                            name: qs['channel'],
                            emotes: []
                        };

                        handleChat(channel, user, welcomeMsg, true);
			joinAccounced.push(channel);
                    }
		}
	});
client.addListener('part', function (channel, username) {
		var index = joinAccounced.indexOf(channel);
		if(index > -1) {
			if(showConnectionNotices) chatNotice(capitalize(dehash(username)) + ' parted ' + capitalize(dehash(channel)), 1000, -1, 'chat-room-part');
			joinAccounced.splice(joinAccounced.indexOf(channel), 1)
		}
	});

client.addListener('crash', function () {
		chatNotice('Crashed', 10000, 4, 'chat-crash');
	});

client.connect();
<|endoftext|>


<commit_before>const Proxy = require('..')
const test = require('tap').test
const testServer = require('./server')
const testRequest = require('./request')
const localSocket = require('./localSocket')

test('proxy server: simple routing', function (t) {
  const servers = {
    food: makeServer('food'),
    music: makeServer('music'),
    dot: makeServer('dotpath'),
    default: makeServer('default'),
  }

  const proxySocket = localSocket('proxy-test.socket')

  const serverDefs = [
    ['test.localhost', [
      ['/food/*', servers.food.socket],
      ['/music/*', servers.music.socket],
      ['/.*', servers.dot.socket],
      ['*', servers.default.socket],
    ]],
  ]

  const proxy = new Proxy({ servers: serverDefs })

  const gateway = proxy
    .createServer()
    .listen(proxySocket)

  gateway.unref()

  t.plan(4)
  testRequest({
    socketPath: proxySocket,
    path: '/food/sandwiches/blt',
    host: 'test.localhost',
    method: 'GET',
  }, function (proxyRes) {
    t.same(proxyRes.socketPath, servers.food.socket, 'should food')
  })

  testRequest({
    socketPath: proxySocket,
    path: '/music/himalaya/',
    host: 'test.localhost',
    method: 'GET',
  }, function (proxyRes) {
    t.same(proxyRes.socketPath, servers.music.socket, 'should music')
  })

  testRequest({
    socketPath: proxySocket,
    path: '/.link',
    host: 'test.localhost',
    method: 'GET',
  }, function (proxyRes) {
    t.same(proxyRes.socketPath, servers.dot.socket, 'should dot')
  })

  testRequest({
    socketPath: proxySocket,
    path: '/literally/anything/else',
    host: 'test.localhost',
    method: 'GET',
  }, function (proxyRes) {
    t.same(proxyRes.socketPath, servers.default.socket, 'should default')
  })

})

function makeServer(name) {
  return testServer(localSocket(name + '.socket'))
}
<commit_msg>Make sure I'm not a liar.<commit_after>const Proxy = require('..')
const test = require('tap').test
const testServer = require('./server')
const testRequest = require('./request')
const localSocket = require('./localSocket')

test('proxy server: simple routing', function (t) {
  const servers = {
    json: makeServer('json'),
    xml: makeServer('xml'),
    dot: makeServer('dotpath'),
    default: makeServer('default'),
  }

  const proxySocket = localSocket('proxy-test.socket')

  const serverDefs = [
    ['test.localhost', [
      ['/api/*.json', servers.json.socket],
      ['/api/*.xml', servers.xml.socket],
      ['/.*', servers.dot.socket],
      ['*', servers.default.socket],
    ]],
  ]

  const proxy = new Proxy({ servers: serverDefs })

  const gateway = proxy
    .createServer()
    .listen(proxySocket)

  gateway.unref()

  t.plan(4)
  testRequest({
    socketPath: proxySocket,
    path: '/api/x/y/z.json',
    host: 'test.localhost',
    method: 'GET',
  }, function (proxyRes) {
    t.same(proxyRes.socketPath, servers.json.socket, 'should json')
  })

  testRequest({
    socketPath: proxySocket,
    path: '/api/v2/lol/rattleskates.xml',
    host: 'test.localhost',
    method: 'GET',
  }, function (proxyRes) {
    t.same(proxyRes.socketPath, servers.xml.socket, 'should xml')
  })

  testRequest({
    socketPath: proxySocket,
    path: '/.link',
    host: 'test.localhost',
    method: 'GET',
  }, function (proxyRes) {
    t.same(proxyRes.socketPath, servers.dot.socket, 'should dot')
  })

  testRequest({
    socketPath: proxySocket,
    path: '/literally/anything/else',
    host: 'test.localhost',
    method: 'GET',
  }, function (proxyRes) {
    t.same(proxyRes.socketPath, servers.default.socket, 'should default')
  })

})

function makeServer(name) {
  return testServer(localSocket(name + '.socket'))
}
<|endoftext|>


<commit_before>requirejs.config({
  "baseUrl": "./",
  "paths": {
    "jquery":"bower_components/jquery/jquery.min",
    "jquery-ui":"bower_components/jquery-ui/ui/jquery-ui",
    "react": "bower_components/react/react.min",
    "jsx":"bower_components/require-jsx/jsx",
    "JSXTransformer":"http://dragon.ak.fbcdn.net/hphotos-ak-prn1/851547_221914424655081_22271_n",
    "kboard.client": '/api/client'
  },
  "shim": {
    JSXTransformer: {
      exports: "JSXTransformer"
    },
    'kboard.client': {
      exports: 'KboardRestClient'
    }
  }
});

define(['jquery', 'react','kboard.client', 'js/data'],
  function($, React, KboardRestClient, Data) {
    KboardRestClient.authenticate(function (data, err) {
      if(data == true && err == undefined) {

        // successful login. Render board app

        require(['jsx!js/board/app'], function(BoardApplication) {
          Data.getData(function (data) {
            React.renderComponent(
              BoardApplication({'data': data}),
                document.getElementById('content'));
          });
        });

        /*
        require(['jsx!js/dashboard'], function(Dashboard) {
          React.renderComponent(
            Dashboard(), document.getElementById('content'));
        });
        */

      }else{

        // failed login. Render login app.
        require(['jsx!js/login'], function(Login) {
          React.renderComponent(
            Login(), document.getElementById('content'));
        });

      }
    });
  }
);

<commit_msg>Change JSXTransformer URL to non-fb link<commit_after>requirejs.config({
  "baseUrl": "./",
  "paths": {
    "jquery":"bower_components/jquery/jquery.min",
    "jquery-ui":"bower_components/jquery-ui/ui/jquery-ui",
    "react": "bower_components/react/react.min",
    "jsx":"bower_components/require-jsx/jsx",
    "JSXTransformer":"//cdnjs.cloudflare.com/ajax/libs/react/0.8.0/JSXTransformer",
    "kboard.client": '/api/client'
  },
  "shim": {
    JSXTransformer: {
      exports: "JSXTransformer"
    },
    'kboard.client': {
      exports: 'KboardRestClient'
    }
  }
});

define(['jquery', 'react','kboard.client', 'js/data'],
  function($, React, KboardRestClient, Data) {
    KboardRestClient.authenticate(function (data, err) {
      if(data == true && err == undefined) {

        // successful login. Render board app

        require(['jsx!js/board/app'], function(BoardApplication) {
          Data.getData(function (data) {
            React.renderComponent(
              BoardApplication({'data': data}),
                document.getElementById('content'));
          });
        });

        /*
        require(['jsx!js/dashboard'], function(Dashboard) {
          React.renderComponent(
            Dashboard(), document.getElementById('content'));
        });
        */

      }else{

        // failed login. Render login app.
        require(['jsx!js/login'], function(Login) {
          React.renderComponent(
            Login(), document.getElementById('content'));
        });

      }
    });
  }
);

<|endoftext|>


<commit_before>/**
 * Подменяем и расширяем Backbone.View, добавляя в него милые методы для работы с селекторами, выбором элементов и
 * дата атрибутами
 * @class Backbone.ElementsView
 * @extends Backbone.View
 */
Backbone.ElementsView = Backbone.View.redefine(function (origin) {
    return /**@lends Backbone.View*/{

        /**
         * @protected
         */
        _initProperties: function () {
            origin._initProperties.apply(this, arguments);

            /**
             * @type {jQuery}
             * @protected
             */
            this._$window = $(window);

            /**
             * @type {jQuery}
             * @protected
             */
            this._$document = $(document);

            /**
             * @type {jQuery}
             * @protected
             */
            this._$body = $(document.body);
        },

        setElement: function () {
            origin.setElement.apply(this, arguments);

            /**
             * Дата атрибуты {@link Backbone.View.$el} в camelCase
             * @type {Object.<string, string>}
             * @protected
             */
            this._data = this.$el.data() || {};
            this._resetCaches();
            return this;
        },

        /**
         * Сбрасывает кэши клаасов, селекторов и элементов
         * @private
         */
        _resetCaches: function () {

            /**
             * Здесь сохраняются закешированные классы, полученные из
             * {@link Backbone.ElementsView._classes}
             * @type {Object.<string, string>}
             * @private
             */
            this._cachedClasses = this._classes();

            /**
             * Здесь сохраняются закешированные селекторы, в том числе полученные из
             * {@link Backbone.ElementsView._classes}
             * @type {Object.<string, string>}
             * @private
             */
            this._cachedSelectors = this._selectors();

            /**
             * Кеш для {@link Backbone.ElementsView._elem}
             * @type {Object.<string, jQuery>}
             * @private
             */
            this._cachedElements = {};
        },

        /**
         * CSS классы используемые во вьюшке складываются сюда. Ключи - имена элементов, значение - названия классов.
         * Свойство можно переопределять в наследуемых классах
         * @returns {Object.<string, string>}
         * @protected
         * @example
         *     _classes: function(){
         *         return {
         *             table: 'js-table'
         *         };
         *     }
         *
         */
        _classes: function () {
            return {};
        },

        /**
         * Возвращает css класс элемента по его имени, классы берутся из {@link Backbone.ElementsView._classes}
         * @param {String} name название элемента
         * @param {...String} [varArg]
         * @returns {String} css класс
         * @throws {Error} если название елемента нигде не найдено
         * @protected
         */
        _class: function (name, varArg) {
            var cl = this._cachedClasses[name];
            if (cl == null) {
                throw new Error('Selector for ' + name + ' does not found');
            }

            if (arguments.length > 1){
                var args = Array.prototype.slice.call(arguments, 1);
                args.unshift(cl);
                cl = _.sprintf.apply(_, args);
            }

            return cl;
        },

        /**
         * Селекторы используемые во вьюшке описываются здесь. Метод надо переопределять в наследуемых классах
         * @returns {Object.<string, string>} Ключи - названия элементов, значения - селекторы
         * @protected
         * @example
         *      _selectors: function(){
         *          return {
         *              map: '.google-map:first'
         *          };
         *      }
         *
         */
        _selectors: function () {
            return {};
        },

        /**
         * Возвращает селектор элемента по его имени, селекторы берутся из {@link Backbone.ElementsView._selectors} или
         * {@link Backbone.ElementsView._classes}
         * @param {String} name название элемента
         * @param {...String} [varArg]
         * @returns {String} селектор
         * @protected
         * @example
         *      events: function(){
         *          var events = {};
         *          events['click ' + this._selector('map')] = this._clickOnMap;
         *          events['click ' + this._selector('table')] = this._clickOnTable;
         *          return events;
         *      }
         *
         */
        _selector: function (name, varArg) {
            var args = null,
                cacheKey = this._getCacheKey.apply(this, arguments),
                selector = this._cachedSelectors[cacheKey];

            if (selector == null) {
                if (!this._cachedSelectors[name]) {
                    selector = '.' + this._class(name);
                    this._cachedSelectors[name] = selector;
                }

                args = Array.prototype.slice.call(arguments, 1);
                if (args.length) {
                    args.unshift(this._cachedSelectors[name]);
                    selector = _.sprintf.apply(_, args);
                    this._cachedSelectors[cacheKey] = selector;
                }
            }
            return selector;
        },

        /**
         * @param {String} name
         * @returns {Boolean}
         * @protected
         */
        _hasSelector: function (name) {
            return !!(this._cachedClasses[name] || this._cachedSelectors[name]);
        },

        /**
         * Возвращает jQuery коллекцию по имени из {@link Backbone.ElementsView._selectors} или
         * {@link Backbone.ElementsView._classes}. Кэширует результаты, для сброса кеша см.
         * {@link Backbone.ElementsView._dropElemCache}
         * @param {String} name название элемента
         * @param {...String} [varArg]
         * @returns {jQuery}
         * @protected
         * @example
         *     this._elem('table').hide();
         *
         */
        _elem: function (name, varArg) {
            var cacheKey = this._getCacheKey.apply(this, arguments),
                $elem = this._cachedElements[cacheKey];

            if ($elem != null) {
                return $elem;
            }

            $elem = this._findElem.apply(this, arguments);
            this._cachedElements[cacheKey] = $elem;

            return $elem;
        },

        /**
         * @param {String} name
         * @param {...String} [varArg]
         * @returns {string}
         * @private
         */
        _getCacheKey: function (name, varArg) {
            return Array.prototype.join.call(arguments, '|');
        },

        /**
         * Finds element without using cache
         * @param {string} name
         * @param {...String} [varArg]
         * @returns {jQuery}
         * @protected
         */
        _findElem: function (name, varArg) {
            return this.$(this._selector.apply(this, arguments));
        },

        /**
         * Replaces element with passed content
         * @param {string} name
         * @param {HTMLElement|jQuery|string} content
         * @protected
         */
        _replaceElem: function (name, content) {
            var $el = this._elem(name),
                focusOnElem = $el[0] == document.activeElement || $el.has(document.activeElement).length;

            this._elem(name).replaceWith(content);
            this._dropElemCache(name);

            if (focusOnElem) {
                this._fixFocus(this._elem(name));
            }
        },

        /**
         * Sets element innerHTML
         * @param {string} name
         * @param {HTMLElement|jQuery|string} content
         * @protected
         */
        _setElemContent: function (name, content) {
            var $el = this._elem(name),
                focusInsideElem = $el.has(document.activeElement).length;

            $el.html(content);
            if (focusInsideElem) {
                this._fixFocus($el);
            }
        },

        /**
         * Emulate focus on passed element (focuses closest focusable element)
         * @param {jQuery} $el
         * @private
         */
        _fixFocus: function ($el) {
            var $focused = $el.closest('[tabindex],a,button:not(:disabled)');
            if ($focused.length) {
                $focused[0].focus();
            }
        },

        /**
         * Трет кеш для {@link Backbone.ElementsView._elem}
         * @param {String} [name] имя элемента для которого надо убрать кеш, если не задано - сотрется весь кеш
         * @protected
         */
        _dropElemCache: function (name) {
            if (name != null) {
                delete this._cachedElements[this._getCacheKey.apply(this, arguments)];
            }
            else {
                this._cachedElements = {};
            }
            return this;
        },

        /**
         * Возвращает дата атрибуты для элемента по его имени и имени атрибута
         * @param {String} name имя элемента
         * @param {String} [attr] имя атрибута, если не задано, то вернется объект со всеми дата атрибутами для элемента
         * @returns {*|Object}
         * @protected
         */
        _getElemData: function (name, attr) {
            var data = this._elem(name).data();
            if (attr == null) {
                return data;
            }

            return data[attr];
        },

        /**
         * Совместимость с Backbone.Decorate
         */
        beforeDecorate: function () {
            this._resetCaches();

            if (typeof origin.beforeDecorate == "function") {
                origin.beforeDecorate.apply(this, arguments);
            }
        }
    }
});<commit_msg>PSDJS-8031 true highlighting options in selects<commit_after>/**
 * Подменяем и расширяем Backbone.View, добавляя в него милые методы для работы с селекторами, выбором элементов и
 * дата атрибутами
 * @class Backbone.ElementsView
 * @extends Backbone.View
 */
Backbone.ElementsView = Backbone.View.redefine(function (origin) {
    return /**@lends Backbone.View*/{
        /**
         * @type {jQuery}
         * @protected
         */
        _$window: $(window),

        /**
         * @type {jQuery}
         * @protected
         */
        _$document: $(document),

        /**
         * @type {jQuery}
         * @protected
         */
        _$body: $(document.body),

        setElement: function () {
            origin.setElement.apply(this, arguments);

            /**
             * Дата атрибуты {@link Backbone.View.$el} в camelCase
             * @type {Object.<string, string>}
             * @protected
             */
            this._data = this.$el.data() || {};
            this._resetCaches();
            return this;
        },

        /**
         * Сбрасывает кэши клаасов, селекторов и элементов
         * @private
         */
        _resetCaches: function () {

            /**
             * Здесь сохраняются закешированные классы, полученные из
             * {@link Backbone.ElementsView._classes}
             * @type {Object.<string, string>}
             * @private
             */
            this._cachedClasses = this._classes();

            /**
             * Здесь сохраняются закешированные селекторы, в том числе полученные из
             * {@link Backbone.ElementsView._classes}
             * @type {Object.<string, string>}
             * @private
             */
            this._cachedSelectors = this._selectors();

            /**
             * Кеш для {@link Backbone.ElementsView._elem}
             * @type {Object.<string, jQuery>}
             * @private
             */
            this._cachedElements = {};
        },

        /**
         * CSS классы используемые во вьюшке складываются сюда. Ключи - имена элементов, значение - названия классов.
         * Свойство можно переопределять в наследуемых классах
         * @returns {Object.<string, string>}
         * @protected
         * @example
         *     _classes: function(){
         *         return {
         *             table: 'js-table'
         *         };
         *     }
         *
         */
        _classes: function () {
            return {};
        },

        /**
         * Возвращает css класс элемента по его имени, классы берутся из {@link Backbone.ElementsView._classes}
         * @param {String} name название элемента
         * @param {...String} [varArg]
         * @returns {String} css класс
         * @throws {Error} если название елемента нигде не найдено
         * @protected
         */
        _class: function (name, varArg) {
            var cl = this._cachedClasses[name];
            if (cl == null) {
                throw new Error('Selector for ' + name + ' does not found');
            }

            if (arguments.length > 1){
                var args = Array.prototype.slice.call(arguments, 1);
                args.unshift(cl);
                cl = _.sprintf.apply(_, args);
            }

            return cl;
        },

        /**
         * Селекторы используемые во вьюшке описываются здесь. Метод надо переопределять в наследуемых классах
         * @returns {Object.<string, string>} Ключи - названия элементов, значения - селекторы
         * @protected
         * @example
         *      _selectors: function(){
         *          return {
         *              map: '.google-map:first'
         *          };
         *      }
         *
         */
        _selectors: function () {
            return {};
        },

        /**
         * Возвращает селектор элемента по его имени, селекторы берутся из {@link Backbone.ElementsView._selectors} или
         * {@link Backbone.ElementsView._classes}
         * @param {String} name название элемента
         * @param {...String} [varArg]
         * @returns {String} селектор
         * @protected
         * @example
         *      events: function(){
         *          var events = {};
         *          events['click ' + this._selector('map')] = this._clickOnMap;
         *          events['click ' + this._selector('table')] = this._clickOnTable;
         *          return events;
         *      }
         *
         */
        _selector: function (name, varArg) {
            var args = null,
                cacheKey = this._getCacheKey.apply(this, arguments),
                selector = this._cachedSelectors[cacheKey];

            if (selector == null) {
                if (!this._cachedSelectors[name]) {
                    selector = '.' + this._class(name);
                    this._cachedSelectors[name] = selector;
                }

                args = Array.prototype.slice.call(arguments, 1);
                if (args.length) {
                    args.unshift(this._cachedSelectors[name]);
                    selector = _.sprintf.apply(_, args);
                    this._cachedSelectors[cacheKey] = selector;
                }
            }
            return selector;
        },

        /**
         * @param {String} name
         * @returns {Boolean}
         * @protected
         */
        _hasSelector: function (name) {
            return !!(this._cachedClasses[name] || this._cachedSelectors[name]);
        },

        /**
         * Возвращает jQuery коллекцию по имени из {@link Backbone.ElementsView._selectors} или
         * {@link Backbone.ElementsView._classes}. Кэширует результаты, для сброса кеша см.
         * {@link Backbone.ElementsView._dropElemCache}
         * @param {String} name название элемента
         * @param {...String} [varArg]
         * @returns {jQuery}
         * @protected
         * @example
         *     this._elem('table').hide();
         *
         */
        _elem: function (name, varArg) {
            var cacheKey = this._getCacheKey.apply(this, arguments),
                $elem = this._cachedElements[cacheKey];

            if ($elem != null) {
                return $elem;
            }

            $elem = this._findElem.apply(this, arguments);
            this._cachedElements[cacheKey] = $elem;

            return $elem;
        },

        /**
         * @param {String} name
         * @param {...String} [varArg]
         * @returns {string}
         * @private
         */
        _getCacheKey: function (name, varArg) {
            return Array.prototype.join.call(arguments, '|');
        },

        /**
         * Finds element without using cache
         * @param {string} name
         * @param {...String} [varArg]
         * @returns {jQuery}
         * @protected
         */
        _findElem: function (name, varArg) {
            return this.$(this._selector.apply(this, arguments));
        },

        /**
         * Replaces element with passed content
         * @param {string} name
         * @param {HTMLElement|jQuery|string} content
         * @protected
         */
        _replaceElem: function (name, content) {
            var $el = this._elem(name),
                focusOnElem = $el[0] == document.activeElement || $el.has(document.activeElement).length;

            this._elem(name).replaceWith(content);
            this._dropElemCache(name);

            if (focusOnElem) {
                this._fixFocus(this._elem(name));
            }
        },

        /**
         * Sets element innerHTML
         * @param {string} name
         * @param {HTMLElement|jQuery|string} content
         * @protected
         */
        _setElemContent: function (name, content) {
            var $el = this._elem(name),
                focusInsideElem = $el.has(document.activeElement).length;

            $el.html(content);
            if (focusInsideElem) {
                this._fixFocus($el);
            }
        },

        /**
         * Emulate focus on passed element (focuses closest focusable element)
         * @param {jQuery} $el
         * @private
         */
        _fixFocus: function ($el) {
            var $focused = $el.closest('[tabindex],a,button:not(:disabled)');
            if ($focused.length) {
                $focused[0].focus();
            }
        },

        /**
         * Трет кеш для {@link Backbone.ElementsView._elem}
         * @param {String} [name] имя элемента для которого надо убрать кеш, если не задано - сотрется весь кеш
         * @protected
         */
        _dropElemCache: function (name) {
            if (name != null) {
                delete this._cachedElements[this._getCacheKey.apply(this, arguments)];
            }
            else {
                this._cachedElements = {};
            }
            return this;
        },

        /**
         * Возвращает дата атрибуты для элемента по его имени и имени атрибута
         * @param {String} name имя элемента
         * @param {String} [attr] имя атрибута, если не задано, то вернется объект со всеми дата атрибутами для элемента
         * @returns {*|Object}
         * @protected
         */
        _getElemData: function (name, attr) {
            var data = this._elem(name).data();
            if (attr == null) {
                return data;
            }

            return data[attr];
        },

        /**
         * Совместимость с Backbone.Decorate
         */
        beforeDecorate: function () {
            this._resetCaches();

            if (typeof origin.beforeDecorate == "function") {
                origin.beforeDecorate.apply(this, arguments);
            }
        }
    }
});<|endoftext|>


<commit_before>import Settings from './Settings';
import MuinaismuistotMap from './map/MuinaismuistotMap';
import MuinaismuistotUI from './ui/MuinaismuistotUI';
import URLHashHelper from './util/URLHashHelper';

export default function Muinaismuistot() {
  var map;
  var settings;
  var urlHashHelper;
  var ui;

  var init = function() {
    settings = new Settings({
      selectedMapBackgroundLayerChanged: function(layerName) {
        map.setVisibleMaanmittauslaitosLayerName(layerName);
      },
      visibleMuinaismuistotLayersChanged: function(selectedLayerIds) {
        map.updateVisibleMuinaismuistotLayersFromSettings();
        ui.visibleMuinaismuistotLayersChanged(selectedLayerIds);
      },
      filterParametersChanged: function(params) {
        map.updateMuinaismuistotFilterParamsFromSettings();
      }
    });

    urlHashHelper = new URLHashHelper();

    map = new MuinaismuistotMap(settings, {
      muinaisjaannosFeaturesSelected : function(muinaisjaannosFeatures) {
        ui.muinaisjaannosFeaturesSelected(muinaisjaannosFeatures);
      },
      showLoadingAnimation: function() {
        ui.showLoadingAnimation();
      }
    });

    ui = new MuinaismuistotUI(settings, urlHashHelper, {
      searchMuinaismuistoja: function(searchText, callbackFn) {
        map.searchMuinaismuistoja(searchText, callbackFn);
      },
      zoomIn: function() {
        map.zoomIn();
      },
      zoomOut: function() {
        map.zoomOut();
      },
      centerToCurrentPositions: function() {
        map.centerToCurrentPositions();
      }
    });

    window.onhashchange = function(location) {
      setMapLocationFromURLHash();
    };

    determineStartLocation();
  };

  var determineStartLocation = function() {
    if(urlHashHelper.parseCoordinates()) {
      setMapLocationFromURLHash();
    }
    else {
      map.centerToCurrentPositions();
    }
  };

  var setMapLocationFromURLHash = function() {
    var coordinates = urlHashHelper.parseCoordinates();
    if(coordinates) {
      map.setMapLocation(coordinates);
      map.showSelectedLocationMarker(coordinates);
    }
  };

  init();
};
<commit_msg>Korjattu latausanimaation näkyminen kun klikatun featuren tietoja haetaan<commit_after>import Settings from './Settings';
import MuinaismuistotMap from './map/MuinaismuistotMap';
import MuinaismuistotUI from './ui/MuinaismuistotUI';
import URLHashHelper from './util/URLHashHelper';

export default function Muinaismuistot() {
  var map;
  var settings;
  var urlHashHelper;
  var ui;

  var init = function() {
    settings = new Settings({
      selectedMapBackgroundLayerChanged: function(layerName) {
        map.setVisibleMaanmittauslaitosLayerName(layerName);
      },
      visibleMuinaismuistotLayersChanged: function(selectedLayerIds) {
        map.updateVisibleMuinaismuistotLayersFromSettings();
        ui.visibleMuinaismuistotLayersChanged(selectedLayerIds);
      },
      filterParametersChanged: function(params) {
        map.updateMuinaismuistotFilterParamsFromSettings();
      }
    });

    urlHashHelper = new URLHashHelper();

    map = new MuinaismuistotMap(settings, {
      muinaisjaannosFeaturesSelected : function(muinaisjaannosFeatures) {
        ui.muinaisjaannosFeaturesSelected(muinaisjaannosFeatures);
      },
      showLoadingAnimation: function(show) {
        ui.showLoadingAnimation(show);
      }
    });

    ui = new MuinaismuistotUI(settings, urlHashHelper, {
      searchMuinaismuistoja: function(searchText, callbackFn) {
        map.searchMuinaismuistoja(searchText, callbackFn);
      },
      zoomIn: function() {
        map.zoomIn();
      },
      zoomOut: function() {
        map.zoomOut();
      },
      centerToCurrentPositions: function() {
        map.centerToCurrentPositions();
      }
    });

    window.onhashchange = function(location) {
      setMapLocationFromURLHash();
    };

    determineStartLocation();
  };

  var determineStartLocation = function() {
    if(urlHashHelper.parseCoordinates()) {
      setMapLocationFromURLHash();
    }
    else {
      map.centerToCurrentPositions();
    }
  };

  var setMapLocationFromURLHash = function() {
    var coordinates = urlHashHelper.parseCoordinates();
    if(coordinates) {
      map.setMapLocation(coordinates);
      map.showSelectedLocationMarker(coordinates);
    }
  };

  init();
};
<|endoftext|>


<commit_before>/**
 * @file jquery.mask.js
 * @author William Bruno <wbrunom@gmail.com>
 * @date 2013-03-25
 *
 * @use jQuery('input[name="cc"]').mask({mask: 'cc'});
 */
;( function() {
	/*global jQuery: false*/
	'use strict';
	jQuery.fn.mask = function(settings) {
		var v_obj, v_fun;
		var _mascara = function(o,f) {
			v_obj = o;
			v_fun = f;
			setTimeout(_execmascara,1);
		};
		var _execmascara = function() {
			v_obj.value = v_fun(v_obj.value);
		};
		return this.each( function() {
			var $this = jQuery(this),
			opts = jQuery.extend({}, jQuery.fn.mask.defaults, settings ),
			maskFunc = jQuery.fn.mask[opts.mask];

			if(typeof maskFunc === 'function') {
				$this.on('keypress', function(){
					_mascara(this, maskFunc);
					$this.removeClass('is-empty');
				});
				$this.on('blur', function(){
					if($this.val() === '') {
						$this.addClass('is-empty');
					}
				});
			}
		});
	};
	jQuery.fn.mask.defaults = {
		mask: '',
		classEmpty: 'is-empty'
	};
	jQuery.fn.mask.cc = function(v) {
		v = v.replace(/\D/g, "");
		v = v.replace(/^(\d{4})(\d)/g, "$1 $2");
		v = v.replace(/^(\d{4})\s(\d{4})(\d)/g, "$1 $2 $3");
		v = v.replace(/^(\d{4})\s(\d{4})\s(\d{4})(\d)/g, "$1 $2 $3 $4");
		return v;
	};
	jQuery.fn.mask.cep = function(v){
		v = v.replace(/\D/g,"");
		v = v.replace(/^(\d{5})(\d)/, "$1-$2");
		return v;
	};
	jQuery.fn.mask.cnpj = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/^(\d{2})(\d)/, "$1.$2");
		v = v.replace(/^(\d{2})\.(\d{3})(\d)/, "$1.$2.$3");
		v = v.replace(/\.(\d{3})(\d)/, ".$1/$2");
		v = v.replace(/(\d{4})(\d)/, "$1-$2");
		return v;
	};
	jQuery.fn.mask.cpf = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d{3})(\d)/, "$1.$2");
		v = v.replace(/(\d{3})(\d)/, "$1.$2");
		v = v.replace(/(\d{3})(\d{1,2})$/, "$1-$2");
		return v;
	};
	jQuery.fn.mask.dateBR = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d{2})(\d)/, "$1/$2");
		v = v.replace(/(\d{2})(\d)/, "$1/$2");
		v = v.replace(/(\d{2})(\d{2})$/, "$1$2");
		return v;
	};
	jQuery.fn.mask.hour = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d{2})(\d)/, "$1h$2");
		return v;
	};
	jQuery.fn.mask.money = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d)(\d{8})$/, "$1.$2");
		v = v.replace(/(\d)(\d{5})$/, "$1.$2");
		v = v.replace(/(\d)(\d{2})$/, "$1,$2");
		return v;
	};
	jQuery.fn.mask.phone = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/^(\d\d)(\d)/g, "($1) $2");
		v = v.replace(/(\d{4})(\d)/, "$1-$2");
		return v;
	};
	jQuery.fn.mask.rg = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d)(\d{7})$/, "$1.$2");
		v = v.replace(/(\d)(\d{4})$/, "$1.$2");
		v = v.replace(/(\d)(\d)$/, "$1-$2");
		return v;
	};
	jQuery.fn.mask.time = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d{1})(\d{2})(\d{2})/, "$1:$2.$3");
		return v;
	};
})();<commit_msg>melhorada resolucao de escopo na declaracao das funcoes mascara<commit_after>/**
 * @file jquery.mask.js
 * @author William Bruno <wbrunom@gmail.com>
 * @date 2013-03-25
 *
 * @use jQuery('input[name="cc"]').mask({mask: 'cc'});
 */
;( function() {
	/*global jQuery: false*/
	'use strict';

	var plugin = function(settings) {
		var v_obj, v_fun;
		var _mascara = function(o,f) {
			v_obj = o;
			v_fun = f;
			setTimeout(_execmascara,1);
		};
		var _execmascara = function() {
			v_obj.value = v_fun(v_obj.value);
		};
		return this.each( function() {
			var $this = jQuery(this),
			opts = jQuery.extend({}, jQuery.fn.mask.defaults, settings ),
			maskFunc = jQuery.fn.mask[opts.mask];

			if(typeof maskFunc === 'function') {
				$this.on('keypress', function(){
					_mascara(this, maskFunc);
					$this.removeClass('is-empty');
				});
				$this.on('blur', function(){
					if($this.val() === '') {
						$this.addClass('is-empty');
					}
				});
			}
		});
	};
	jQuery.fn.mask = plugin;

	plugin.defaults = {
		mask: '',
		classEmpty: 'is-empty'
	};
	plugin.cc = function(v) {
		v = v.replace(/\D/g, "");
		v = v.replace(/^(\d{4})(\d)/g, "$1 $2");
		v = v.replace(/^(\d{4})\s(\d{4})(\d)/g, "$1 $2 $3");
		v = v.replace(/^(\d{4})\s(\d{4})\s(\d{4})(\d)/g, "$1 $2 $3 $4");
		return v;
	};
	plugin.cep = function(v){
		v = v.replace(/\D/g,"");
		v = v.replace(/^(\d{5})(\d)/, "$1-$2");
		return v;
	};
	plugin.cnpj = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/^(\d{2})(\d)/, "$1.$2");
		v = v.replace(/^(\d{2})\.(\d{3})(\d)/, "$1.$2.$3");
		v = v.replace(/\.(\d{3})(\d)/, ".$1/$2");
		v = v.replace(/(\d{4})(\d)/, "$1-$2");
		return v;
	};
	plugin.cpf = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d{3})(\d)/, "$1.$2");
		v = v.replace(/(\d{3})(\d)/, "$1.$2");
		v = v.replace(/(\d{3})(\d{1,2})$/, "$1-$2");
		return v;
	};
	plugin.dateBR = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d{2})(\d)/, "$1/$2");
		v = v.replace(/(\d{2})(\d)/, "$1/$2");
		v = v.replace(/(\d{2})(\d{2})$/, "$1$2");
		return v;
	};
	plugin.hour = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d{2})(\d)/, "$1h$2");
		return v;
	};
	plugin.money = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d)(\d{8})$/, "$1.$2");
		v = v.replace(/(\d)(\d{5})$/, "$1.$2");
		v = v.replace(/(\d)(\d{2})$/, "$1,$2");
		return v;
	};
	plugin.phone = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/^(\d\d)(\d)/g, "($1) $2");
		v = v.replace(/(\d{4})(\d)/, "$1-$2");
		return v;
	};
	plugin.rg = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d)(\d{7})$/, "$1.$2");
		v = v.replace(/(\d)(\d{4})$/, "$1.$2");
		v = v.replace(/(\d)(\d)$/, "$1-$2");
		return v;
	};
	plugin.time = function(v){
		v = v.replace(/\D/g, "");
		v = v.replace(/(\d{1})(\d{2})(\d{2})/, "$1:$2.$3");
		return v;
	};
})();<|endoftext|>


<commit_before>/*
 *
 * (c) Copyright Ascensio System SIA 2010-2019
 *
 * This program is a free software product. You can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License (AGPL)
 * version 3 as published by the Free Software Foundation. In accordance with
 * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
 * that Ascensio System SIA expressly excludes the warranty of non-infringement
 * of any third-party rights.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. For
 * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
 *
 * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
 * street, Riga, Latvia, EU, LV-1050.
 *
 * The  interactive user interfaces in modified source and object code versions
 * of the Program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU AGPL version 3.
 *
 * Pursuant to Section 7(b) of the License you must retain the original Product
 * logo when distributing the program. Pursuant to Section 7(e) we decline to
 * grant you any rights under trademark law for use of our trademarks.
 *
 * All the Product's GUI elements, including illustrations and icon sets, as
 * well as technical writing content are licensed under the terms of the
 * Creative Commons Attribution-ShareAlike 4.0 International. See the License
 * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
 *
 */
/**
 * Controller wraps up interaction with desktop app
 *
 * Created by Maxim.Kadushkin on 2/16/2018.
 */

define([
    'core'
], function () {
    'use strict';

    var native = window.AscDesktopEditor;
    !!native && native.execCommand('webapps:features', JSON.stringify({
        version: '{{PRODUCT_VERSION}}',
        eventloading: true,
        titlebuttons: true
    }));

    var Desktop = function () {
        var config = {version:'{{PRODUCT_VERSION}}'};
        var webapp = window.DE || window.PE || window.SSE;
        var titlebuttons;
        var btnsave_icons = {
            'btn-save': 'save',
            'btn-save-coauth': 'coauth',
            'btn-synch': 'synch' };

        if ( !!native ) {
            window.on_native_message = function (cmd, param) {
                if (/^style:change/.test(cmd)) {
                    var obj = JSON.parse(param);

                    if ( obj.element == 'toolbar' ) {
                        if ( obj.action == 'off' && obj.style == 'native-color' ) {
                            $('.toolbar').removeClass('editor-native-color');
                        }
                    } else
                    if ( obj.element == 'body' ) {
                        if ( obj.action == 'merge' ) {
                            var style = document.createElement('style');
                            style.innerHTML = obj.style;
                            document.body.appendChild(style);
                        }
                    }
                } else
                if (/window:features/.test(cmd)) {
                    var obj = JSON.parse(param);

                    if ( obj.canUndock == 'true' ) {
                        if ( !config.canUndock ) {
                            config.canUndock = true;

                            if ( !_.isEmpty(config) )
                                Common.NotificationCenter.trigger('app:config', {canUndock:true});
                        }
                    }

                    if (_.isNumber(obj.skiptoparea)) {
                        Common.Utils.InternalSettings.set('window-inactive-area-top', obj.skiptoparea);
                    }
                } else
                if (/window:status/.test(cmd)) {
                    var obj = JSON.parse(param);

                    if ( obj.action == 'undocking' ) {
                        Common.NotificationCenter.trigger('undock:status', {status:obj.status=='undocked'?'undocked':'docked'});
                    }
                } else
                if (/editor:config/.test(cmd)) {
                    if ( param == 'request' ) {
                        if ( !!titlebuttons ) {
                            var opts = {
                                user: config.user,
                                title: { buttons: [] }
                            };

                            var header = webapp.getController('Viewport').getView('Common.Views.Header');
                            if ( header ) {
                                for (var i in titlebuttons) {
                                    opts.title.buttons.push(_serializeHeaderButton(i, titlebuttons[i]));
                                }
                            }

                            native.execCommand('editor:config', JSON.stringify(opts));
                        } else
                        if ( !config.callback_editorconfig ) {
                            config.callback_editorconfig = function() {
                                setTimeout(function(){window.on_native_message(cmd, param);},0);
                            }
                        }
                    }
                } else
                if (/button:click/.test(cmd)) {
                    var obj = JSON.parse(param);
                    if ( !!obj.action ) {
                        titlebuttons[obj.action].btn.click();
                    }
                } else
                if (/element:show/.test(cmd)) {
                    var _mr = /title:(?:(true|show)|(false|hide))/.exec(param);
                    if ( _mr ) {
                        if (!!_mr[1]) $('#app-title').show();
                        else if (!!_mr[2]) $('#app-title').hide();
                    }
                }
            };

            if ( !!window.native_message_cmd ) {
                for ( var c in window.native_message_cmd ) {
                    window.on_native_message(c, window.native_message_cmd[c]);
                }
            }

            native.execCommand('webapps:features', JSON.stringify({version: config.version, eventloading:true, titlebuttons:true}));
        }

        var _serializeHeaderButton = function(action, config) {
            return {
                action: action,
                icon: config.icon || undefined,
                hint: config.btn.options.hint,
                disabled: config.btn.isDisabled()
            };
        };

        var _onTitleButtonDisabled = function (action, e, status) {
            var _buttons = {};
            _buttons[action] = status;
            native.execCommand('title:button', JSON.stringify({disabled: _buttons}));
        };

        var _onSaveIconChanged = function (e, opts) {
            native.execCommand('title:button', JSON.stringify({'icon:changed': {'save': btnsave_icons[opts.next]}}));
        };

        var _onModalDialog = function (status) {
            if ( status == 'open' ) {
                native.execCommand('title:button', JSON.stringify({disabled: {'all':true}}));
            } else {
                var _buttons = {};
                for (var i in titlebuttons) {
                    _buttons[i] = titlebuttons[i].btn.isDisabled();
                }

                native.execCommand('title:button', JSON.stringify({'disabled': _buttons}));
            }
        };

        return {
            init: function (opts) {
                _.extend(config, opts);

                if ( config.isDesktopApp ) {
                    Common.NotificationCenter.on('app:ready', function (opts) {
                        _.extend(config, opts);
                        !!native && native.execCommand('doc:onready', '');

                        $('.toolbar').addClass('editor-native-color');
                    });

                    Common.NotificationCenter.on('action:undocking', function (opts) {
                        native.execCommand('editor:event', JSON.stringify({action:'undocking', state: opts == 'dock' ? 'dock' : 'undock'}));
                    });

                    Common.NotificationCenter.on('app:face', function (mode) {
                        if ( config.canUndock ) {
                            Common.NotificationCenter.trigger('app:config', {canUndock: true});
                        }

                        var header = webapp.getController('Viewport').getView('Common.Views.Header');
                        titlebuttons = {};
                        if ( !!header.btnSave ) {
                            titlebuttons['save'] = {btn: header.btnSave};

                            var iconname = /\s?([^\s]+)$/.exec(titlebuttons.save.btn.$icon.attr('class'));
                            !!iconname && iconname.length && (titlebuttons.save.icon = btnsave_icons[iconname]);
                        }

                        if ( !!header.btnPrint )
                            titlebuttons['print'] = {btn: header.btnPrint};

                        if ( !!header.btnUndo )
                            titlebuttons['undo'] = {btn: header.btnUndo};

                        if ( !!header.btnRedo )
                            titlebuttons['redo'] = {btn: header.btnRedo};

                        for (var i in titlebuttons) {
                            titlebuttons[i].btn.options.signals = ['disabled'];
                            titlebuttons[i].btn.on('disabled', _onTitleButtonDisabled.bind(this, i));
                        }

                        if (!!titlebuttons.save) {
                            titlebuttons.save.btn.options.signals.push('icon:changed');
                            titlebuttons.save.btn.on('icon:changed', _onSaveIconChanged.bind(this));
                        }

                        if ( !!config.callback_editorconfig ) {
                            config.callback_editorconfig();
                            delete config.callback_editorconfig;
                        }
                    });

                    Common.NotificationCenter.on({
                        'modal:show': _onModalDialog.bind(this, 'open'),
                        'modal:close': _onModalDialog.bind(this, 'close')
                    });
                }
            },
            process: function (opts) {
                if ( config.isDesktopApp && !!native ) {
                    if ( opts == 'goback' ) {
                        native.execCommand('go:folder',
                            config.isOffline ? 'offline' : config.customization.goback.url);
                        return true;
                    } else
                    if ( opts == 'preloader:hide' ) {
                        native.execCommand('editor:onready', '');
                        return true;
                    } else
                    if ( opts == 'create:new' ) {
                        if (config.createUrl == 'desktop://create.new') {
                            native.LocalFileCreate(!!window.SSE ? 2 : !!window.PE ? 1 : 0);
                            return true;
                        }
                    }
                }

                return false;
            },
            requestClose: function () {
                if ( config.isDesktopApp && !!native ) {
                    native.execCommand('editor:event', JSON.stringify({action:'close', url: config.customization.goback.url}));
                }
            }
        };
    };

    Common.Controllers.Desktop = new Desktop();
});
<commit_msg>[desktop] hide modal window's mask<commit_after>/*
 *
 * (c) Copyright Ascensio System SIA 2010-2019
 *
 * This program is a free software product. You can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License (AGPL)
 * version 3 as published by the Free Software Foundation. In accordance with
 * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
 * that Ascensio System SIA expressly excludes the warranty of non-infringement
 * of any third-party rights.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. For
 * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
 *
 * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
 * street, Riga, Latvia, EU, LV-1050.
 *
 * The  interactive user interfaces in modified source and object code versions
 * of the Program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU AGPL version 3.
 *
 * Pursuant to Section 7(b) of the License you must retain the original Product
 * logo when distributing the program. Pursuant to Section 7(e) we decline to
 * grant you any rights under trademark law for use of our trademarks.
 *
 * All the Product's GUI elements, including illustrations and icon sets, as
 * well as technical writing content are licensed under the terms of the
 * Creative Commons Attribution-ShareAlike 4.0 International. See the License
 * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
 *
 */
/**
 * Controller wraps up interaction with desktop app
 *
 * Created by Maxim.Kadushkin on 2/16/2018.
 */

define([
    'core'
], function () {
    'use strict';

    var native = window.AscDesktopEditor;
    !!native && native.execCommand('webapps:features', JSON.stringify({
        version: '{{PRODUCT_VERSION}}',
        eventloading: true,
        titlebuttons: true
    }));

    var Desktop = function () {
        var config = {version:'{{PRODUCT_VERSION}}'};
        var webapp = window.DE || window.PE || window.SSE;
        var titlebuttons;
        var btnsave_icons = {
            'btn-save': 'save',
            'btn-save-coauth': 'coauth',
            'btn-synch': 'synch' };

        if ( !!native ) {
            window.on_native_message = function (cmd, param) {
                if (/^style:change/.test(cmd)) {
                    var obj = JSON.parse(param);

                    if ( obj.element == 'toolbar' ) {
                        if ( obj.action == 'off' && obj.style == 'native-color' ) {
                            $('.toolbar').removeClass('editor-native-color');
                        }
                    } else
                    if ( obj.element == 'body' ) {
                        if ( obj.action == 'merge' ) {
                            var style = document.createElement('style');
                            style.innerHTML = obj.style;
                            document.body.appendChild(style);
                        }
                    }
                } else
                if (/window:features/.test(cmd)) {
                    var obj = JSON.parse(param);

                    if ( obj.canUndock == 'true' ) {
                        if ( !config.canUndock ) {
                            config.canUndock = true;

                            if ( !_.isEmpty(config) )
                                Common.NotificationCenter.trigger('app:config', {canUndock:true});
                        }
                    }

                    if (_.isNumber(obj.skiptoparea)) {
                        Common.Utils.InternalSettings.set('window-inactive-area-top', obj.skiptoparea);
                    }
                } else
                if (/window:status/.test(cmd)) {
                    var obj = JSON.parse(param);

                    if ( obj.action == 'undocking' ) {
                        Common.NotificationCenter.trigger('undock:status', {status:obj.status=='undocked'?'undocked':'docked'});
                    }
                } else
                if (/editor:config/.test(cmd)) {
                    if ( param == 'request' ) {
                        if ( !!titlebuttons ) {
                            var opts = {
                                user: config.user,
                                title: { buttons: [] }
                            };

                            var header = webapp.getController('Viewport').getView('Common.Views.Header');
                            if ( header ) {
                                for (var i in titlebuttons) {
                                    opts.title.buttons.push(_serializeHeaderButton(i, titlebuttons[i]));
                                }
                            }

                            native.execCommand('editor:config', JSON.stringify(opts));
                        } else
                        if ( !config.callback_editorconfig ) {
                            config.callback_editorconfig = function() {
                                setTimeout(function(){window.on_native_message(cmd, param);},0);
                            }
                        }
                    }
                } else
                if (/button:click/.test(cmd)) {
                    var obj = JSON.parse(param);
                    if ( !!obj.action ) {
                        titlebuttons[obj.action].btn.click();
                    }
                } else
                if (/element:show/.test(cmd)) {
                    var _mr = /title:(?:(true|show)|(false|hide))/.exec(param);
                    if ( _mr ) {
                        if (!!_mr[1]) $('#app-title').show();
                        else if (!!_mr[2]) $('#app-title').hide();
                    }
                }
            };

            if ( !!window.native_message_cmd ) {
                for ( var c in window.native_message_cmd ) {
                    window.on_native_message(c, window.native_message_cmd[c]);
                }
            }

            native.execCommand('webapps:features', JSON.stringify({version: config.version, eventloading:true, titlebuttons:true}));

            // hide mask for modal window
            var style = document.createElement('style');
            style.appendChild(document.createTextNode('.modals-mask{opacity:0;}'));
            document.getElementsByTagName('head')[0].appendChild(style);
        }

        var _serializeHeaderButton = function(action, config) {
            return {
                action: action,
                icon: config.icon || undefined,
                hint: config.btn.options.hint,
                disabled: config.btn.isDisabled()
            };
        };

        var _onTitleButtonDisabled = function (action, e, status) {
            var _buttons = {};
            _buttons[action] = status;
            native.execCommand('title:button', JSON.stringify({disabled: _buttons}));
        };

        var _onSaveIconChanged = function (e, opts) {
            native.execCommand('title:button', JSON.stringify({'icon:changed': {'save': btnsave_icons[opts.next]}}));
        };

        var _onModalDialog = function (status) {
            if ( status == 'open' ) {
                native.execCommand('title:button', JSON.stringify({disabled: {'all':true}}));
            } else {
                var _buttons = {};
                for (var i in titlebuttons) {
                    _buttons[i] = titlebuttons[i].btn.isDisabled();
                }

                native.execCommand('title:button', JSON.stringify({'disabled': _buttons}));
            }
        };

        return {
            init: function (opts) {
                _.extend(config, opts);

                if ( config.isDesktopApp ) {
                    Common.NotificationCenter.on('app:ready', function (opts) {
                        _.extend(config, opts);
                        !!native && native.execCommand('doc:onready', '');

                        $('.toolbar').addClass('editor-native-color');
                    });

                    Common.NotificationCenter.on('action:undocking', function (opts) {
                        native.execCommand('editor:event', JSON.stringify({action:'undocking', state: opts == 'dock' ? 'dock' : 'undock'}));
                    });

                    Common.NotificationCenter.on('app:face', function (mode) {
                        if ( config.canUndock ) {
                            Common.NotificationCenter.trigger('app:config', {canUndock: true});
                        }

                        var header = webapp.getController('Viewport').getView('Common.Views.Header');
                        titlebuttons = {};
                        if ( !!header.btnSave ) {
                            titlebuttons['save'] = {btn: header.btnSave};

                            var iconname = /\s?([^\s]+)$/.exec(titlebuttons.save.btn.$icon.attr('class'));
                            !!iconname && iconname.length && (titlebuttons.save.icon = btnsave_icons[iconname]);
                        }

                        if ( !!header.btnPrint )
                            titlebuttons['print'] = {btn: header.btnPrint};

                        if ( !!header.btnUndo )
                            titlebuttons['undo'] = {btn: header.btnUndo};

                        if ( !!header.btnRedo )
                            titlebuttons['redo'] = {btn: header.btnRedo};

                        for (var i in titlebuttons) {
                            titlebuttons[i].btn.options.signals = ['disabled'];
                            titlebuttons[i].btn.on('disabled', _onTitleButtonDisabled.bind(this, i));
                        }

                        if (!!titlebuttons.save) {
                            titlebuttons.save.btn.options.signals.push('icon:changed');
                            titlebuttons.save.btn.on('icon:changed', _onSaveIconChanged.bind(this));
                        }

                        if ( !!config.callback_editorconfig ) {
                            config.callback_editorconfig();
                            delete config.callback_editorconfig;
                        }
                    });

                    Common.NotificationCenter.on({
                        'modal:show': _onModalDialog.bind(this, 'open'),
                        'modal:close': _onModalDialog.bind(this, 'close')
                    });
                }
            },
            process: function (opts) {
                if ( config.isDesktopApp && !!native ) {
                    if ( opts == 'goback' ) {
                        native.execCommand('go:folder',
                            config.isOffline ? 'offline' : config.customization.goback.url);
                        return true;
                    } else
                    if ( opts == 'preloader:hide' ) {
                        native.execCommand('editor:onready', '');
                        return true;
                    } else
                    if ( opts == 'create:new' ) {
                        if (config.createUrl == 'desktop://create.new') {
                            native.LocalFileCreate(!!window.SSE ? 2 : !!window.PE ? 1 : 0);
                            return true;
                        }
                    }
                }

                return false;
            },
            requestClose: function () {
                if ( config.isDesktopApp && !!native ) {
                    native.execCommand('editor:event', JSON.stringify({action:'close', url: config.customization.goback.url}));
                }
            }
        };
    };

    Common.Controllers.Desktop = new Desktop();
});
<|endoftext|>


<commit_before>module.exports = {

    decide: function(link) {

        if(!link.memory.type) {
            if(link.pos.findInRange(FIND_SOURCES, 2).length) {
                link.memory.type = "dispatch";
            } else {
                link.memory.type = "recieve";
            }
        }

        if(link.energy) {
            var closeBuilders = [];
            Memory.roleList.Builder.forEach(function(name) {
                var builder = Game.creeps[name];
                if(link.pos.isNearTo(builder) && builder.energy < builder.energyCapacity) {
                    closeBuilders.push(builder);
                }
            });
            closeBuilders.sort(function(a, b) {
                return a.energy - b.energy;
            });
            if(closeBuilders.length) {
                var energyLeft = closeBuilders[0].energyCapacity - closeBuilders[0].energy;
                link.transferEnergy(closeBuilders[0], energyLeft < link.energy ? energyLeft : link.energy);
            }
        }

        if(link.memory.type === "dispatch" && link.energy === link.energyCapacity && !link.cooldown) {
            var recieveLinks = [];
            Memory.linkList.forEach(function(linkId) {
                var targetLink = Game.structures[linkId];
                if(targetLink.memory.type === "recieve" && targetLink.energy <= targetLink.energyCapacity/2 && link.pos.room === targetLink.pos.room) {
                    recieveLinks.push(targetLink);
                }
            });
            recieveLinks.sort(function(a, b) {
                return a.energy - b.energy;
            });
            link.transferEnergy(recieveLinks, link.energyCapacity/2);
        }
    }
};
<commit_msg>Fix link controllers not sending energy to each other<commit_after>module.exports = {

    decide: function(link) {

        if(!link.memory.type) {
            if(link.pos.findInRange(FIND_SOURCES, 2).length) {
                link.memory.type = "dispatch";
            } else {
                link.memory.type = "recieve";
            }
        }

        if(link.energy) {
            var closeBuilders = [];
            Memory.roleList.Builder.forEach(function(name) {
                var builder = Game.creeps[name];
                if(link.pos.isNearTo(builder) && builder.energy < builder.energyCapacity) {
                    closeBuilders.push(builder);
                }
            });
            closeBuilders.sort(function(a, b) {
                return a.energy - b.energy;
            });
            if(closeBuilders.length) {
                var energyLeft = closeBuilders[0].energyCapacity - closeBuilders[0].energy;
                link.transferEnergy(closeBuilders[0], energyLeft < link.energy ? energyLeft : link.energy);
            }
        }

        if(link.memory.type === "dispatch" && link.energy === link.energyCapacity && !link.cooldown) {
            var recieveLinks = [];
            Memory.linkList.forEach(function(linkId) {
                var targetLink = Game.structures[linkId];
                if(targetLink.memory.type === "recieve" && targetLink.energy <= targetLink.energyCapacity/2 && link.pos.room === targetLink.pos.room) {
                    recieveLinks.push(targetLink);
                }
            });
            recieveLinks.sort(function(a, b) {
                return a.energy - b.energy;
            });
            link.transferEnergy(recieveLinks[0], link.energyCapacity/2);
        }
    }
};
<|endoftext|>


<commit_before>'use strict';

// The Package is past automatically as first parameter
module.exports = function(Dashboard, app, auth, database) {

  app.get('/dashboard/example/anyone', function(req, res, next) {
    res.send('Anyone can access this');
  });

  app.get('/dashboard/example/auth', auth.requiresLogin, function(req, res, next) {
    res.send('Only authenticated users can access this');
  });

  app.get('/dashboard/example/admin', auth.requiresAdmin, function(req, res, next) {
    res.send('Only users with Admin role can access this');
  });

  app.get('/dashboard/example/render', function(req, res, next) {
    Dashboard.render('index', {
      package: 'dashboard'
    }, function(err, html) {
      //Rendering a view from the Package server/views
      res.send(html);
    });
  });
};
<commit_msg>removed unused server routes on dashboard package<commit_after>'use strict';

// The Package is past automatically as first parameter
module.exports = function(Dashboard, app, auth, database) {
};
<|endoftext|>