<commit_before>/**
 * @author Sergey Chikuyonok (serge.che@gmail.com)
 * @link http://chikuyonok.ru
 */
var base64 = {
	chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	mime_types: {
		'gif': 'image/gif',
		'png': 'image/png',
		'jpg': 'image/jpeg',
		'jpeg': 'image/jpeg',
		'svg': 'image/svg+xml',
		'html': 'text/html',
		'htm': 'text/html'
	},

	encode: function(input) {
		var output = [];
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0, il = input.length, b64_str = this.chars;

		while (i < il) {

			chr1 = input.charCodeAt(i++) & 0xff;
			chr2 = input.charCodeAt(i++) & 0xff;
			chr3 = input.charCodeAt(i++) & 0xff;

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}

			output.push(
				b64_str.charAt(enc1) + b64_str.charAt(enc2) +
				b64_str.charAt(enc3) + b64_str.charAt(enc4)
			);
		}

		return output.join('');
	},

	/**
	 * Decodes string using MIME base64 algorithm
	 * @author Tyler Akins (http://rumkin.com)
	 * @param {String} data
	 * @return {String}
	 */
	decode: function(data) {
		var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, dec = "", tmp_arr = [];
		var b64 = this.chars, il = data.length;

		if (!data) {
			return data;
		}

		data += '';

		do {  // unpack four hexets into three octets using index points in b64
			h1 = b64.indexOf(data.charAt(i++));
			h2 = b64.indexOf(data.charAt(i++));
			h3 = b64.indexOf(data.charAt(i++));
			h4 = b64.indexOf(data.charAt(i++));

			bits = h1<<18 | h2<<12 | h3<<6 | h4;

			o1 = bits>>16 & 0xff;
			o2 = bits>>8 & 0xff;
			o3 = bits & 0xff;

			if (h3 == 64) {
				tmp_arr[ac++] = String.fromCharCode(o1);
			} else if (h4 == 64) {
				tmp_arr[ac++] = String.fromCharCode(o1, o2);
			} else {
				tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
			}
		} while (i < il);

		return tmp_arr.join('');
	}
};<commit_msg>Applied panychy's patch to base64 encoder for MS WSH support http://code.google.com/p/zen-coding/issues/detail?id=205<commit_after>/**
 * @author Sergey Chikuyonok (serge.che@gmail.com)
 * @link http://chikuyonok.ru
 */
var base64 = {
	chars : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	mime_types : {
		'gif' : 'image/gif',
		'png' : 'image/png',
		'jpg' : 'image/jpeg',
		'jpeg' : 'image/jpeg',
		'svg' : 'image/svg+xml',
		'html' : 'text/html',
		'htm' : 'text/html'
	},

	encode : function(input) {
		var output = [];
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4, cdp1, cdp2, cdp3;
		var i = 0, il = input.length, b64_str = this.chars;

		while (i < il) {

			cdp1 = input.charCodeAt(i++);
			cdp2 = input.charCodeAt(i++);
			cdp3 = input.charCodeAt(i++);

			chr1 = cdp1 & 0xff;
			chr2 = cdp2 & 0xff;
			chr3 = cdp3 & 0xff;

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(cdp2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(cdp3)) {
				enc4 = 64;
			}

			output.push(b64_str.charAt(enc1) + b64_str.charAt(enc2) + b64_str.charAt(enc3) + b64_str.charAt(enc4));
		}

		return output.join('');
	},

	/**
	 * Decodes string using MIME base64 algorithm
	 *
	 * @author Tyler Akins (http://rumkin.com)
	 * @param {String}
	 *            data
	 * @return {String}
	 */
	decode : function(data) {
		var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, dec = "", tmp_arr = [];
		var b64 = this.chars, il = data.length;

		if (!data) {
			return data;
		}

		data += '';

		do { // unpack four hexets into three octets using index points in b64
			h1 = b64.indexOf(data.charAt(i++));
			h2 = b64.indexOf(data.charAt(i++));
			h3 = b64.indexOf(data.charAt(i++));
			h4 = b64.indexOf(data.charAt(i++));

			bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;

			o1 = bits >> 16 & 0xff;
			o2 = bits >> 8 & 0xff;
			o3 = bits & 0xff;

			if (h3 == 64) {
				tmp_arr[ac++] = String.fromCharCode(o1);
			} else if (h4 == 64) {
				tmp_arr[ac++] = String.fromCharCode(o1, o2);
			} else {
				tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
			}
		} while (i < il);

		return tmp_arr.join('');
	}
};<|endoftext|>


<commit_before>/* eslint-disable max-len */
import 'newrelic'
import 'babel-polyfill'
import 'isomorphic-fetch'

function handleZlibError(error) {
  if (error.code === 'Z_BUF_ERROR') {
    console.error(error)
  } else {
    console.log(error.stack)
    throw error
  }
}
process.on('uncaughtException', handleZlibError)

import express from 'express'
import morgan from 'morgan'
import throng from 'throng'
import librato from 'librato-node'
import path from 'path'
import fs from 'fs'
import React from 'react'
import { renderToString } from 'react-dom/server'
import { createMemoryHistory, match, RouterContext } from 'react-router'
import { Provider } from 'react-redux'
import { createElloStore } from './src/store'
import { updateStrings as updateTimeAgoStrings } from './src/vendor/time_ago_in_words'
import addOauthRoute from './oauth'
import createRoutes from './src/routes'
import { replace, syncHistoryWithStore } from 'react-router-redux'

// load env vars first
require('dotenv').load({ silent: process.env.NODE_ENV === 'production' })
global.ENV = require('./env')
updateTimeAgoStrings({ about: '' })

const app = express()

// Log requests with Morgan
app.use(morgan('combined'))

// Send stats to Librato
librato.configure({ email: process.env.LIBRATO_EMAIL,
                    token: process.env.LIBRATO_TOKEN })
librato.start()
app.use(librato.middleware())

librato.on('error', (err) => {
  console.log('ELLO LIBRATO ERROR', err)
})

let indexStr = ''
// grab out the index.html string first thing
fs.readFile(path.join(__dirname, './public/index.html'), 'utf-8', (err, data) => {
  if (!err) {
    indexStr = data
  }
})

// Wire up OAuth route
addOauthRoute(app)

// Assets
app.use(express.static('public'))
app.use('/static', express.static('public/static'))

// Return promises for initial loads
function preRender(renderProps, store) {
  const promises = renderProps.components.map(component => (component && component.preRender) ? component.preRender(store, renderProps) : null).filter(component => !!component)
  return Promise.all(promises)
}

function renderFromServer(req, res) {
  const memoryHistory = createMemoryHistory(req.originalUrl)
  const store = createElloStore(memoryHistory)
  const routes = createRoutes(store)
  const history = syncHistoryWithStore(memoryHistory, store)

  match({ history, routes, location: req.url }, (error, redirectLocation, renderProps) => {
    // populate the rouer store object for initial render
    if (error) {
      console.log('ELLO MATCH ERROR', error)
    } else if (redirectLocation) {
      console.log('ELLO HANDLE REDIRECT', redirectLocation)
      res.redirect(redirectLocation.pathname)
      return
    } else if (!renderProps) { return }
    store.dispatch(replace(renderProps.location.pathname))

    preRender(renderProps, store).then(() => {
      const InitialComponent = (
        <Provider store={store}>
          <RouterContext {...renderProps} />
        </Provider>
      )
      const componentHTML = renderToString(InitialComponent)
      const state = store.getState()
      const initialStateTag = `<script id="initial-state">window.__INITIAL_STATE__ = ${JSON.stringify(state)}</script>`
      indexStr = indexStr.replace('

', `<div id="root">${componentHTML}</div>${initialStateTag}`)
      res.send(indexStr)
    }).catch((err) => {
      // this will give you a js error like:
      // `window is not defined`
      console.log('ELLO CATCH ERROR', err)
    })
  })
}

const loggedOutPaths = {
  explore: /^\/explore/,
  explore_recent: /^\/explore\/recent/,
  explore_trending: /^\/explore\/trending/,
  find: /^\/find$/,
  forgot_password: /^\/forgot-password/,
  signup: /^\/signup/,
}

app.use((req, res) => {
  let isLoggedOutPath = false
  for (const re in loggedOutPaths) {
    if (req.url.match(loggedOutPaths[re])) {
      isLoggedOutPath = true
      break
    }
  }
  console.log('ELLO START URL', req.url, isLoggedOutPath)
  if (isLoggedOutPath) {
    renderFromServer(req, res)
  } else {
    res.send(indexStr)
  }
})

const port = process.env.PORT || 6660
const workers = process.env.WEB_CONCURRENCY || 1;
const start = (workerId) => {
  app.listen(port, (err) => {
    if (err) {
      console.log(err)
      return
    }
    console.log('Worker ' + workerId + ' listening at http://localhost:' + port)
  })
}

if (workers > 1) {
  throng(start, {
    workers: workers,
    lifetime: Infinity,
  })
} else {
  start(1)
}
<commit_msg>Rewind Helmet, apply meta stuff<commit_after>/* eslint-disable max-len */
import 'newrelic'
import 'babel-polyfill'
import 'isomorphic-fetch'

function handleZlibError(error) {
  if (error.code === 'Z_BUF_ERROR') {
    console.error(error)
  } else {
    console.log(error.stack)
    throw error
  }
}
process.on('uncaughtException', handleZlibError)

import express from 'express'
import morgan from 'morgan'
import throng from 'throng'
import librato from 'librato-node'
import path from 'path'
import fs from 'fs'
import React from 'react'
import Helmet from 'react-helmet'
import { renderToString } from 'react-dom/server'
import { createMemoryHistory, match, RouterContext } from 'react-router'
import { Provider } from 'react-redux'
import { createElloStore } from './src/store'
import { updateStrings as updateTimeAgoStrings } from './src/vendor/time_ago_in_words'
import addOauthRoute from './oauth'
import createRoutes from './src/routes'
import { replace, syncHistoryWithStore } from 'react-router-redux'

// load env vars first
require('dotenv').load({ silent: process.env.NODE_ENV === 'production' })
global.ENV = require('./env')
updateTimeAgoStrings({ about: '' })

const app = express()

// Log requests with Morgan
app.use(morgan('combined'))

// Send stats to Librato
librato.configure({ email: process.env.LIBRATO_EMAIL,
                    token: process.env.LIBRATO_TOKEN })
librato.start()
app.use(librato.middleware())

librato.on('error', (err) => {
  console.log('ELLO LIBRATO ERROR', err)
})

let indexStr = ''
// grab out the index.html string first thing
fs.readFile(path.join(__dirname, './public/index.html'), 'utf-8', (err, data) => {
  if (!err) {
    indexStr = data
  }
})

// Wire up OAuth route
addOauthRoute(app)

// Assets
app.use(express.static('public'))
app.use('/static', express.static('public/static'))

// Return promises for initial loads
function preRender(renderProps, store) {
  const promises = renderProps.components.map(component => (component && component.preRender) ? component.preRender(store, renderProps) : null).filter(component => !!component)
  return Promise.all(promises)
}

function renderFromServer(req, res) {
  const memoryHistory = createMemoryHistory(req.originalUrl)
  const store = createElloStore(memoryHistory)
  const routes = createRoutes(store)
  const history = syncHistoryWithStore(memoryHistory, store)

  match({ history, routes, location: req.url }, (error, redirectLocation, renderProps) => {
    // populate the rouer store object for initial render
    if (error) {
      console.log('ELLO MATCH ERROR', error)
    } else if (redirectLocation) {
      console.log('ELLO HANDLE REDIRECT', redirectLocation)
      res.redirect(redirectLocation.pathname)
      return
    } else if (!renderProps) { return }
    store.dispatch(replace(renderProps.location.pathname))

    preRender(renderProps, store).then(() => {
      const InitialComponent = (
        <Provider store={store}>
          <RouterContext {...renderProps} />
        </Provider>
      )
      const componentHTML = renderToString(InitialComponent)
      const head = Helmet.rewind()
      const state = store.getState()
      const initialStateTag = `<script id="initial-state">window.__INITIAL_STATE__ = ${JSON.stringify(state)}</script>`
      const html = `
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    ${head.title.toString()}
    ${head.meta.toString()}
    ${head.link.toString()}

  <link href="/static/bundle.css?6af200e078361dc409c0" rel="stylesheet">

${componentHTML}

    ${initialStateTag}

`
      res.send(html)
    }).catch((err) => {
      // this will give you a js error like:
      // `window is not defined`
      console.log('ELLO CATCH ERROR', err)
    })
  })
}

const loggedOutPaths = {
  explore: /^\/explore/,
  explore_recent: /^\/explore\/recent/,
  explore_trending: /^\/explore\/trending/,
  find: /^\/find$/,
  forgot_password: /^\/forgot-password/,
  signup: /^\/signup/,
}

app.use((req, res) => {
  let isLoggedOutPath = false
  for (const re in loggedOutPaths) {
    if (req.url.match(loggedOutPaths[re])) {
      isLoggedOutPath = true
      break
    }
  }
  console.log('ELLO START URL', req.url, isLoggedOutPath)
  if (isLoggedOutPath) {
    renderFromServer(req, res)
  } else {
    res.send(indexStr)
  }
})

const port = process.env.PORT || 6660
const workers = process.env.WEB_CONCURRENCY || 1;
const start = (workerId) => {
  app.listen(port, (err) => {
    if (err) {
      console.log(err)
      return
    }
    console.log('Worker ' + workerId + ' listening at http://localhost:' + port)
  })
}

if (workers > 1) {
  throng(start, {
    workers: workers,
    lifetime: Infinity,
  })
} else {
  start(1)
}
<|endoftext|>


<commit_before>"use strict";

$(function () {
    var client = new TalkClient();

    // for better performance - to avoid searching in DOM
    var header = $('#header');
    var content = $('#chatMessages');
    var input = $('#inputMessage');
    var status = $('#status');

    client.me.name = getURLParameter('username');
    client.channelId = channel || 'default';

    var usernameStoragePath = 'bongtalk({channel=' + client.channelId + '}).savedName';

    var reconnected = false;
    // open connection
    var connection = null;
    createConnection();
    function createConnection(){
        if (connection !== null){
            connection.close();
        }

        var socketUrl = 'http://' + location.host;
        if (client.channelId){
            socketUrl = socketUrl + '?channelId=' + client.channelId;
        }
        connection = io.connect(socketUrl,{
            'max reconnection attempts' : Infinity
        });

        connection.on('connect', function() {writeSystemMessage('Connected', 'success');});
        connection.on('connecting', function () {writeSystemMessage('Connecting...', 'warning');});
        connection.on('connect_failed', function () {writeSystemMessage('Connect fail', 'error');});

        connection.on('disconnect', function(){writeSystemMessage('Disconnected', 'warning'); onDisconnect(); });
        connection.on('error', function () {writeSystemMessage('Error', 'error');});

        connection.on('reconnect', function () {writeSystemMessage('Reconnected', 'success'); reconnected = true; input.removeAttr('disabled'); input.focus();});
        connection.on('reconnecting', function () {writeSystemMessage('Reconnecting...', 'warning');});
        connection.on('reconnect_failed', function () {writeSystemMessage('Reconnect fail', 'error');});

        connection.on('sendProfile', function(data){
            //server 부터 받은 profile
            client.me.id = data.id;

            if (reconnected) {
                joinChannel();
            }
            else {
                if (data.name) {
                    // session 에 저장되었던 name 사용.
                    setName(data.name);
                    joinChannel();
                }
                else {
                    // 이름을 결정한 뒤 Join 하라.
                    var savedName = null;
                    if (IsSupportStorage())
                    {
                        savedName = localStorage[usernameStoragePath];
                    }

                    // 브라우저에 저장되었던 이름 있으면 loginModal에 적용.
                    if (savedName)
                    {
                        $('#loginSavedNameButton').text('Use \'' + savedName + '\'');
                        $('#loginNameInput').val(savedName);
                        $('#loginSavedNameButton').show();
                    }
                    else
                    {
                        $('#loginSavedNameButton').hide();
                    }

                    $('#loginModal').modal('show');
                    $('#loginNameInput').focus();
                }

            }
        });

        connection.on('newUser', function(data){
            if (client.addUser(new TalkUser(data.id, data.name))){
                writeSystemMessage(data.name + ' joined.', 'info');
            }
        });

        connection.on('sendChannelInfo',function(data){
            //history 로드
            if (data.history){
                data.history.forEach(function(item){
                    addMessage(item);
                });
            }

            // 사용자 list 초기화
            if (data.connectedUsers){
                data.connectedUsers.forEach(function(item) {
                    client.addUser(new TalkUser(item.id, item.name));
                });
            }

            writeSystemMessage('Join success.', 'info');

            if (client.getOtherUserNames().length > 0)
            {
                var otherNames =  client.getOtherUserNames().reduce(function(x, y){ return x + ", " + y;});
                writeSystemMessage('Connected users : ' + otherNames, 'info');
            }

            input.removeAttr('disabled');
            input.focus();

            // 참여가 완료 된것으로 봄.
            reconnected = false;
        });

        connection.on('sendMessage', function(data){
            addMessage(data);
        });

        connection.on('changeName', function(data){
            var targetUser = client.getUser(data.id);
            if (targetUser)
            {
                writeSystemMessage(targetUser.name + ' changed name → ' + data.name, 'info');
                targetUser.name = data.name;
            }
        });

        connection.on('removeUser', function(data){
            var removedUser = client.removeUser(data.id);
            if (removedUser)
            {
                writeSystemMessage(removedUser.name + ' out.', 'info');
            }
        });

        connection.on('userPropertyChanged', function(data){
            var targetUser = client.getUser(data.user.id);
            if (targetUser && data.property && data.property.name)
            {
                var oldValue = targetUser[data.property.name];

                if (oldValue !== data.property.value){
                    targetUser[data.property.name] = data.property.value;

                    writeSystemMessage(targetUser.name + '\'s ' + data.property.name  +' changed ' + oldValue + ' → ' + data.property.value, 'info');
                }
            }
        });
    }

    function joinChannel(){
        connection.emit('joinChannel', {user:client.me.getSimpleUser(), channelId:client.channelId});
    }

    function onDisconnect() {
        client.others = [];
        input.attr('disabled', 'disabled');
    }

    $('#loginNewNameButton').click(function(){
        setName($('#loginNameInput').val());
        joinChannel();
    });

    function setName(newName){

        if (newName === client.me.name)
        {
            return;
        }

        client.me.name = newName;

        status.text(client.me.name);

        header.text(client.me.name);

        if (IsSupportStorage())
        {
            localStorage[usernameStoragePath] = client.me.name;
//            useSavedNameButton.text('Use \'' + client.me.name + '\'');
        }

        input.focus();
    }

    /**
     * Send mesage when user presses Enter key
     */
    input.keydown(function(e) {
        if (e.keyCode === 13) { // Enter 키
            sendMessage();
        }
    });

    $('#sendButton').click(sendMessage);

    function getURLParameter(name) {
        return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null;
    }

    function sendMessage(){
        var msg = input.val();
        if (!msg) { // 입력한거 없음 안보냄?
            return;
        }
        // send the message as an ordinary text
//        connection.send(JSON.stringify({type:"sendMessage", payload:{message: msg, style: input[0].style.cssText}}));
        connection.emit('sendMessage', msg);
        input.val('');
        input.focus();
        // 서버에서 응답 오기전까지 입력창 막음 . 잘하는 짓인가?
        //input.attr('disabled', 'disabled');
    }

    var lastMessageElement = null;
    /**
     * 메세지 라인추가.
     */
    function addMessage(messageObject) {

        if (messageObject && messageObject.message){
            messageObject.message = replaceURLWithHTMLLinks(messageObject.message);
        }

        if (lastMessageElement
            && client.lastMessage
            && client.lastMessage.user.id === messageObject.user.id
            && ((messageObject.time - client.lastMessage.time) / 60000) < 1) {
            // append
            lastMessageElement.find('.message_content').append('
' + messageObject.message + '
');
            lastMessageElement.find('time').text(dateTimeToString(new Date(messageObject.time)));
        }
        else {
            // add
            var messageElement = (messageObject.user.id === client.me.id)
                ? createMyMessageElement(messageObject.id, messageObject.message, new Date(messageObject.time))
                : createOthersMessageElement(messageObject.id, messageObject.user.id, messageObject.user.name, messageObject.message, new Date(messageObject.time));

            content.append(messageElement);

            lastMessageElement = $('#m' + messageObject.id);
        }

        client.lastMessage = messageObject;
        scrollEnd();
    }

    function createMyMessageElement(id, message, dateTime) {
        return '
' +
            '

'+ message +'

' +
            '<time class="sender_time sender_time--alt">' + dateTimeToString(dateTime) + '</time>

';
    }

    function createOthersMessageElement(id, userId, username, message, dateTime) {
        return '
' +
            '' +
            '
' +
            '' + username + '' +
            '
' +
            '

' + message + '

' +
            '<time class="sender_time">' + dateTimeToString(dateTime) + '</time>' +
            '

';
    }

    function dateTimeToString(dateTime)
    {
        return (dateTime.getHours() < 10 ? '0' + dateTime.getHours() : dateTime.getHours())
            + ':' +
        (dateTime.getMinutes() < 10 ? '0' + dateTime.getMinutes() : dateTime.getMinutes());
    }

    function replaceURLWithHTMLLinks(text)
    {
        var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
        return text.replace(exp,"$1");
    }

    /**
     * 스크롤 끝으로 옮김.
     */
    function scrollEnd(){
        var body = $('body');
        body[0].scrollTop = body[0].scrollHeight;
        window.scrollTo(0,document.body.scrollHeight);
    }

    $('#loginSavedNameButton').click(function(){
        $('#changeNameInput').val(localStorage[usernameStoragePath]);
        setName(localStorage[usernameStoragePath]);
        joinChannel();
    });

    $('#saveChangeNameButton').click(function(){
        setName($('#changeNameInput').val());
        connection.emit('changeName', client.me.name);
    });

    $('#leaveChannelModalButton').click(function(){
        connection.emit('leaveChannel');
        location.href = location.origin + '/status';
    });

    /**
     * warning, error, info, sucess
     */
    function writeSystemMessage(message, level){
        var levels = ['warning', 'error', 'info', 'success'];

        var selectedClass = levels.some(function (item){return item === level;}) ? "text-" + level : "muted";

        var line = '
' + message + '
';

        content.append(line);

        scrollEnd();
    }

    /**
     * @return {boolean}
     */
    function IsSupportStorage() {
        try {
            return 'localStorage' in window && window.localStorage !== null;
        } catch (e) {
            return false;
        }
    }
});<commit_msg>change user avatar url<commit_after>"use strict";

$(function () {
    var client = new TalkClient();

    // for better performance - to avoid searching in DOM
    var header = $('#header');
    var content = $('#chatMessages');
    var input = $('#inputMessage');
    var status = $('#status');

    client.me.name = getURLParameter('username');
    client.channelId = channel || 'default';

    var usernameStoragePath = 'bongtalk({channel=' + client.channelId + '}).savedName';

    var reconnected = false;
    // open connection
    var connection = null;
    createConnection();
    function createConnection(){
        if (connection !== null){
            connection.close();
        }

        var socketUrl = 'http://' + location.host;
        if (client.channelId){
            socketUrl = socketUrl + '?channelId=' + client.channelId;
        }
        connection = io.connect(socketUrl,{
            'max reconnection attempts' : Infinity
        });

        connection.on('connect', function() {writeSystemMessage('Connected', 'success');});
        connection.on('connecting', function () {writeSystemMessage('Connecting...', 'warning');});
        connection.on('connect_failed', function () {writeSystemMessage('Connect fail', 'error');});

        connection.on('disconnect', function(){writeSystemMessage('Disconnected', 'warning'); onDisconnect(); });
        connection.on('error', function () {writeSystemMessage('Error', 'error');});

        connection.on('reconnect', function () {writeSystemMessage('Reconnected', 'success'); reconnected = true; input.removeAttr('disabled'); input.focus();});
        connection.on('reconnecting', function () {writeSystemMessage('Reconnecting...', 'warning');});
        connection.on('reconnect_failed', function () {writeSystemMessage('Reconnect fail', 'error');});

        connection.on('sendProfile', function(data){
            //server 부터 받은 profile
            client.me.id = data.id;

            if (reconnected) {
                joinChannel();
            }
            else {
                if (data.name) {
                    // session 에 저장되었던 name 사용.
                    setName(data.name);
                    joinChannel();
                }
                else {
                    // 이름을 결정한 뒤 Join 하라.
                    var savedName = null;
                    if (IsSupportStorage())
                    {
                        savedName = localStorage[usernameStoragePath];
                    }

                    // 브라우저에 저장되었던 이름 있으면 loginModal에 적용.
                    if (savedName)
                    {
                        $('#loginSavedNameButton').text('Use \'' + savedName + '\'');
                        $('#loginNameInput').val(savedName);
                        $('#loginSavedNameButton').show();
                    }
                    else
                    {
                        $('#loginSavedNameButton').hide();
                    }

                    $('#loginModal').modal('show');
                    $('#loginNameInput').focus();
                }

            }
        });

        connection.on('newUser', function(data){
            if (client.addUser(new TalkUser(data.id, data.name))){
                writeSystemMessage(data.name + ' joined.', 'info');
            }
        });

        connection.on('sendChannelInfo',function(data){
            //history 로드
            if (data.history){
                data.history.forEach(function(item){
                    addMessage(item);
                });
            }

            // 사용자 list 초기화
            if (data.connectedUsers){
                data.connectedUsers.forEach(function(item) {
                    client.addUser(new TalkUser(item.id, item.name));
                });
            }

            writeSystemMessage('Join success.', 'info');

            if (client.getOtherUserNames().length > 0)
            {
                var otherNames =  client.getOtherUserNames().reduce(function(x, y){ return x + ", " + y;});
                writeSystemMessage('Connected users : ' + otherNames, 'info');
            }

            input.removeAttr('disabled');
            input.focus();

            // 참여가 완료 된것으로 봄.
            reconnected = false;
        });

        connection.on('sendMessage', function(data){
            addMessage(data);
        });

        connection.on('changeName', function(data){
            var targetUser = client.getUser(data.id);
            if (targetUser)
            {
                writeSystemMessage(targetUser.name + ' changed name → ' + data.name, 'info');
                targetUser.name = data.name;
            }
        });

        connection.on('removeUser', function(data){
            var removedUser = client.removeUser(data.id);
            if (removedUser)
            {
                writeSystemMessage(removedUser.name + ' out.', 'info');
            }
        });

        connection.on('userPropertyChanged', function(data){
            var targetUser = client.getUser(data.user.id);
            if (targetUser && data.property && data.property.name)
            {
                var oldValue = targetUser[data.property.name];

                if (oldValue !== data.property.value){
                    targetUser[data.property.name] = data.property.value;

                    writeSystemMessage(targetUser.name + '\'s ' + data.property.name  +' changed ' + oldValue + ' → ' + data.property.value, 'info');
                }
            }
        });
    }

    function joinChannel(){
        connection.emit('joinChannel', {user:client.me.getSimpleUser(), channelId:client.channelId});
    }

    function onDisconnect() {
        client.others = [];
        input.attr('disabled', 'disabled');
    }

    $('#loginNewNameButton').click(function(){
        setName($('#loginNameInput').val());
        joinChannel();
    });

    function setName(newName){

        if (newName === client.me.name)
        {
            return;
        }

        client.me.name = newName;

        status.text(client.me.name);

        header.text(client.me.name);

        if (IsSupportStorage())
        {
            localStorage[usernameStoragePath] = client.me.name;
//            useSavedNameButton.text('Use \'' + client.me.name + '\'');
        }

        input.focus();
    }

    /**
     * Send mesage when user presses Enter key
     */
    input.keydown(function(e) {
        if (e.keyCode === 13) { // Enter 키
            sendMessage();
        }
    });

    $('#sendButton').click(sendMessage);

    function getURLParameter(name) {
        return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null;
    }

    function sendMessage(){
        var msg = input.val();
        if (!msg) { // 입력한거 없음 안보냄?
            return;
        }
        // send the message as an ordinary text
//        connection.send(JSON.stringify({type:"sendMessage", payload:{message: msg, style: input[0].style.cssText}}));
        connection.emit('sendMessage', msg);
        input.val('');
        input.focus();
        // 서버에서 응답 오기전까지 입력창 막음 . 잘하는 짓인가?
        //input.attr('disabled', 'disabled');
    }

    var lastMessageElement = null;
    /**
     * 메세지 라인추가.
     */
    function addMessage(messageObject) {

        if (messageObject && messageObject.message){
            messageObject.message = replaceURLWithHTMLLinks(messageObject.message);
        }

        if (lastMessageElement
            && client.lastMessage
            && client.lastMessage.user.id === messageObject.user.id
            && ((messageObject.time - client.lastMessage.time) / 60000) < 1) {
            // append
            lastMessageElement.find('.message_content').append('
' + messageObject.message + '
');
            lastMessageElement.find('time').text(dateTimeToString(new Date(messageObject.time)));
        }
        else {
            // add
            var messageElement = (messageObject.user.id === client.me.id)
                ? createMyMessageElement(messageObject.id, messageObject.message, new Date(messageObject.time))
                : createOthersMessageElement(messageObject.id, messageObject.user.id, messageObject.user.name, messageObject.message, new Date(messageObject.time));

            content.append(messageElement);

            lastMessageElement = $('#m' + messageObject.id);
        }

        client.lastMessage = messageObject;
        scrollEnd();
    }

    function createMyMessageElement(id, message, dateTime) {
        return '
' +
            '

'+ message +'

' +
            '<time class="sender_time sender_time--alt">' + dateTimeToString(dateTime) + '</time>

';
    }

    function createOthersMessageElement(id, userId, username, message, dateTime) {
        return '
' +
            '' +
            '
' +
            '' + username + '' +
            '
' +
            '

' + message + '

' +
            '<time class="sender_time">' + dateTimeToString(dateTime) + '</time>' +
            '

';
    }

    function dateTimeToString(dateTime)
    {
        return (dateTime.getHours() < 10 ? '0' + dateTime.getHours() : dateTime.getHours())
            + ':' +
        (dateTime.getMinutes() < 10 ? '0' + dateTime.getMinutes() : dateTime.getMinutes());
    }

    function replaceURLWithHTMLLinks(text)
    {
        var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
        return text.replace(exp,"$1");
    }

    /**
     * 스크롤 끝으로 옮김.
     */
    function scrollEnd(){
        var body = $('body');
        body[0].scrollTop = body[0].scrollHeight;
        window.scrollTo(0,document.body.scrollHeight);
    }

    $('#loginSavedNameButton').click(function(){
        $('#changeNameInput').val(localStorage[usernameStoragePath]);
        setName(localStorage[usernameStoragePath]);
        joinChannel();
    });

    $('#saveChangeNameButton').click(function(){
        setName($('#changeNameInput').val());
        connection.emit('changeName', client.me.name);
    });

    $('#leaveChannelModalButton').click(function(){
        connection.emit('leaveChannel');
        location.href = location.origin + '/status';
    });

    /**
     * warning, error, info, sucess
     */
    function writeSystemMessage(message, level){
        var levels = ['warning', 'error', 'info', 'success'];

        var selectedClass = levels.some(function (item){return item === level;}) ? "text-" + level : "muted";

        var line = '
' + message + '
';

        content.append(line);

        scrollEnd();
    }

    /**
     * @return {boolean}
     */
    function IsSupportStorage() {
        try {
            return 'localStorage' in window && window.localStorage !== null;
        } catch (e) {
            return false;
        }
    }
});<|endoftext|>


<commit_before><commit_msg>More octree code.<commit_after><|endoftext|>


<commit_before>import React from 'react'
import styled from 'styled-components'

var TxtType = function(el, toRotate, period) {
  this.toRotate = toRotate
  this.el = el
  this.loopNum = 0
  this.period = parseInt(period, 10) || 2000
  this.txt = ''
  this.tick()
  this.isDeleting = false
}

TxtType.prototype.tick = function() {
  var i = this.loopNum % this.toRotate.length
  var fullTxt = this.toRotate[i]

  if (this.isDeleting) {
    this.txt = fullTxt.substring(0, this.txt.length - 1)
  } else {
    this.txt = fullTxt.substring(0, this.txt.length + 1)
  }

  this.el.innerHTML =
    '' + this.txt.replace(/_/g, ' ') + ''

  var that = this
  var delta = 200 - Math.random() * 100

  if (this.isDeleting) {
    delta /= 2
  }

  if (!this.isDeleting && this.txt === fullTxt) {
    delta = this.period
    this.isDeleting = true
  } else if (this.isDeleting && this.txt === '') {
    this.isDeleting = false
    this.loopNum++
    delta = 500
  }

  setTimeout(function() {
    that.tick()
  }, delta)
}

class IntroBase extends React.Component {
  constructor(props) {
    super(props)
    if (this.props.phrases) {
      this.phrases = this.props.phrases
    }
  }
  componentDidMount() {
    new TxtType(this.el, this.phrases, 2000)
  }
  phrases = [
    'Visuals, Software UX,Layouts',
    'Interaction, Empathy, Engagement',
    'Digital, Geometry, Environment',
    'Strategy, Emotion, Language',
  ]
  render() {
    return (

         (this.el = el)} />

    )
  }
}

export const Intro = styled(IntroBase)`
  font-family: 'Space Mono', monospace;
  font-size: 4.2vw;
  word-break: keep-all;
  font-weight: 300;
  line-height: ${1.38};
  min-height: ${1.38 * 3}em;
  text-align: left;
  color: #FFFFFF;
  padding: 26px;
  margin: 26px 0px;
  box-sizing: content-box;

  @media (min-width: 1920px) {
    font-size: 74px;
    margin: 72px 60px;
  }

  @media (max-width: 1300px) {
    font-size: 50px;
    min-height: ${1.4 * 3}em;
    margin: 72px 60px;
  }

  @media (max-width: 500px) {
    font-size: 38px;
    margin: 26px 0px;
    line-height: ${1.32}em;
    min-height: ${1.32 * 3} em;
  }

  .wrap {
    border-right: 0.08em solid #5261ff;
    padding-right: 10px;
  }
`
<commit_msg>new font size for intro – iphone 5se fix<commit_after>import React from 'react'
import styled from 'styled-components'

var TxtType = function(el, toRotate, period) {
  this.toRotate = toRotate
  this.el = el
  this.loopNum = 0
  this.period = parseInt(period, 10) || 2000
  this.txt = ''
  this.tick()
  this.isDeleting = false
}

TxtType.prototype.tick = function() {
  var i = this.loopNum % this.toRotate.length
  var fullTxt = this.toRotate[i]

  if (this.isDeleting) {
    this.txt = fullTxt.substring(0, this.txt.length - 1)
  } else {
    this.txt = fullTxt.substring(0, this.txt.length + 1)
  }

  this.el.innerHTML =
    '' + this.txt.replace(/_/g, ' ') + ''

  var that = this
  var delta = 200 - Math.random() * 100

  if (this.isDeleting) {
    delta /= 2
  }

  if (!this.isDeleting && this.txt === fullTxt) {
    delta = this.period
    this.isDeleting = true
  } else if (this.isDeleting && this.txt === '') {
    this.isDeleting = false
    this.loopNum++
    delta = 500
  }

  setTimeout(function() {
    that.tick()
  }, delta)
}

class IntroBase extends React.Component {
  constructor(props) {
    super(props)
    if (this.props.phrases) {
      this.phrases = this.props.phrases
    }
  }
  componentDidMount() {
    new TxtType(this.el, this.phrases, 2000)
  }
  phrases = [
    'Visuals, Software UX,Layouts',
    'Interaction, Empathy, Engagement',
    'Digital, Geometry, Environment',
    'Strategy, Emotion, Language',
  ]
  render() {
    return (

         (this.el = el)} />

    )
  }
}

export const Intro = styled(IntroBase)`
  font-family: 'Space Mono', monospace;
  font-size: 4.2vw;
  word-break: keep-all;
  font-weight: 300;
  line-height: ${1.38};
  min-height: ${1.38 * 3}em;
  text-align: left;
  color: #FFFFFF;
  padding: 26px;
  margin: 26px 0px;
  box-sizing: content-box;

  @media (min-width: 1920px) {
    font-size: 74px;
    margin: 72px 60px;
  }

  @media (max-width: 1300px) {
    font-size: 50px;
    min-height: ${1.4 * 3}em;
    margin: 72px 60px;
  }

  @media (max-width: 500px) {
    font-size: 35px;
    margin: 26px 0px;
    line-height: ${1.32}em;
    min-height: ${1.32 * 3} em;
  }

  .wrap {
    border-right: 0.08em solid #5261ff;
    padding-right: 10px;
  }
`
<|endoftext|>


<commit_before><commit_msg>Increase timeout for drag<commit_after><|endoftext|>


<commit_before>/*
 * tabslideshow.js
 *
 * Tab Slideshow Firefox extension
 * emsearcy@gmail.com
 *
 * Licensed under MPL (http://www.mozilla.org/MPL/MPL-1.1.html)
 */

var tabslideshow = {
    prefs: null,
    /* active values:
        0: inactive
        1: going to inactive (next timeout)
        2: active
    */
    active: 0,
    time: 5,
    refresh: false,

    // initialize the extension
    startup: function()
    {
        // grab services
        this.prefs = Components.classes['@mozilla.org/preferences-service;1']
                .getService(Components.interfaces.nsIPrefService)
                .getBranch('tabslideshow.');
        this.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
        this.prefs.addObserver('', this, false);

        // save prefs
        this.time = this.prefs.getIntPref('time');
        this.refresh = this.prefs.getBoolPref('refresh');

        // add tab context menu entries and hook
        var tabmenu = tabslideshow_gettabcontextmenu();
        var target = document.getElementById('context_openTabInWindow');
        if (target) target = target.nextSibling;
        if (target) {
            tabmenu.insertBefore(document.getElementById(
                    'tabslideshow-separator'), target);
            tabmenu.insertBefore(document.getElementById(
                    'tabslideshow-refresh'), target);
        } else {
            tabmenu.appendChild(document.getElementById(
                    'tabslideshow-separator'));
            tabmenu.appendChild(document.getElementById(
                    'tabslideshow-refresh'));
        }
        tabmenu.addEventListener('popupshowing', tabslideshow.tabmenushow,
                false);
        // remove now-empty menupopup container
        var popup = document.getElementById("tabslideshowPopup");
        popup.parentNode.removeChild(popup);

        // initial tabs refresh settings
        for ( var tab in gBrowser.tabContainer.childNodes ) {
            gBrowser.tabContainer.childNodes[tab].tabslideshowrefresh =
                    this.refresh;
        }

        // add listener for new tabs
        gBrowser.tabContainer.addEventListener('TabOpen', function(e) {
                tabslideshow.checknewtab(e);
            }, false);

        // initial slideshow
        if (this.prefs.getBoolPref('start')) {
            this.toggle();
        }
    },

    // timer function to cycle tabs
    cycle: function(p_this)
    {
        // only cycle if active
        if (p_this.active < 2) {
            p_this.active = 0;
            return;
        }

        // get tab info
        var numtabs = gBrowser.tabContainer.childNodes.length;
        var currenttabnum = gBrowser.tabContainer.selectedIndex;
        var nexttab = gBrowser.tabContainer.childNodes[
            (currenttabnum + 1) % numtabs];
        var upcomingtab = gBrowser.tabContainer.childNodes[
            (currenttabnum + 2) % numtabs];

        // set next tab
        gBrowser.selectedTab = nexttab;

        // optionally refresh upcoming tab
        if (upcomingtab.tabslideshowrefresh && (nexttab != upcomingtab)) {
            gBrowser.reloadTab(upcomingtab);
        }

        // next cycle
        setTimeout(p_this.cycle, 1000 * p_this.time, p_this);
    },

    // handler for prefs change
    observe: function(subject, topic, data)
    {
        if (topic != 'nsPref:changed') return;

        switch(data) {
            case 'time':
                this.time = this.prefs.getIntPref('time');
                break;
            case 'refresh':
                this.refresh = this.prefs.getBoolPref('refresh');
                break;
        }
    },

    // handle new tab refresh settings
    checknewtab: function(e)
    {
        //Components.utils.reportError("checknewtab")
        e.target.tabslideshowrefresh = this.refresh;
    },

    // per-tab menu adjustments
    tabmenushow: function(e)
    {
        //Components.utils.reportError('tabmenushow');
        if (e.originalTarget != gBrowser.tabContextMenu) {
            return true;
        }

        var item;
        var refresh = document.getElementById('tabslideshow-refresh');
        if (document.popupNode.parentNode) {
            item = document.popupNode.parentNode.parentNode.id;
        }
        // XXX: copied from tabmixplus, not sure what does
        if (item && (item == "btn_tabslist" || item == "btn_tabslistSorted" ||
                item == "alltabs-button")) {
            gBrowser.mContextTab = document.popupNode.tab;
        }

        // detect whether clicked right of tabs (not needed in Firefox 4)
        var clickOutTabs = document.popupNode.localName == "tabs";
        var aTab = clickOutTabs ? gBrowser.mCurrentTab : gBrowser.mContextTab;

        // disable refresh option for current tab when clicked outside
        //if (clickOutTabs) refresh.setAttribute("disabled", "true");
        //else refresh.setAttribute("disabled", "false");

        if (aTab.tabslideshowrefresh) {
            refresh.setAttribute("checked", "true");
        } else {
            refresh.removeAttribute("checked");
        }

    },

    // toggle whether slideshowing
    toggle: function()
    {
        if (this.active == 2) {
            // disabled
            var node = document.getElementById('tabslideshow-toggle');
            if (node) node.setAttribute('label', 'Start Tab Slideshow');
            var node = document.getElementById('tabslideshow-appmenu-toggle');
            if (node) node.setAttribute('label', 'Start Tab Slideshow');
            this.active = 1;
        } else if (this.active == 1) {
            // disabled with active timeout
            var node = document.getElementById('tabslideshow-toggle');
            if (node) node.setAttribute('label', 'Stop Tab Slideshow');
            var node = document.getElementById('tabslideshow-appmenu-toggle');
            if (node) node.setAttribute('label', 'Stop Tab Slideshow');
            this.active = 2;
        } else {
            // disabled, no active timeout
            var node = document.getElementById('tabslideshow-toggle');
            if (node) node.setAttribute('label', 'Stop Tab Slideshow');
            var node = document.getElementById('tabslideshow-appmenu-toggle');
            if (node) node.setAttribute('label', 'Stop Tab Slideshow');
            this.active = 2;
            setTimeout(this.cycle, 1500, this);
        }
    },

    // change refresh flag on tab
    togglerefresh: function(e)
    {
        //Components.utils.reportError('togglerefresh');
        e.tabslideshowrefresh = !e.tabslideshowrefresh;
    },

    // clean up
    shutdown: function()
    {
        this.prefs.removeObserver("", this);
    },

}

// return tab context menu
function tabslideshow_gettabcontextmenu()
{
    if (gBrowser.tabContextMenu) return gBrowser.tabContextMenu;

    var tabmenu = document.getAnonymousElementByAttribute(
            gBrowser, "anonid", "tabContextMenu");
    if (tabmenu) {
        gBrowser.tabContextMenu = tabmenu;
    } else if (gBrowser.tabContainer && gBrowser.tabContainer.contextMenu) {
        gBrowser.tabContextMenu = gBrowser.tabContainer.contextMenu;
    } else {
        gBrowser.tabContextMenu = document.getElementById('tabContextMenu');
    }

    if (!gBrowser.tabContextMenu.hasAttribute("id"))
        gBrowser.tabContextMenu.setAttribute("id", "tabContextMenu");

    return gBrowser.tabContextMenu;
}

window.addEventListener('load', function(e) { tabslideshow.startup(); },
        false);
window.addEventListener('unload', function(e) { tabslideshow.shutdown(); },
        false);
<commit_msg>Start work on tabslideshow changes<commit_after>/*
 * tabslideshow.js
 *
 * Tab Slideshow Firefox extension
 * emsearcy@gmail.com
 *
 * Licensed under MPL (http://www.mozilla.org/MPL/MPL-1.1.html)
 */

var tabslideshow = {
    prefs: null,
    /* active values:
        0: inactive
        1: going to inactive (next timeout)
        2: active
    */
    active: true,
    delay: 5,
    refresh: false,
    timer: null,

    // initialize the extension
    startup: function()
    {
        // grab services
        this.prefs = Components.classes['@mozilla.org/preferences-service;1']
                .getService(Components.interfaces.nsIPrefService)
                .getBranch('tabslideshow.');
        this.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
        this.prefs.addObserver('', this, false);
        this.timer = Components.classes["@mozilla.org/timer;1"]
                .createInstance(Components.interfaces.nsITimer);

        // save prefs
        this.delay = this.prefs.getIntPref('time');
        this.refresh = this.prefs.getBoolPref('refresh');

        // add tab context menu entries and hook
        var tabmenu = tabslideshow_gettabcontextmenu();
        var target = document.getElementById('context_openTabInWindow');
        if (target) target = target.nextSibling;
        if (target) {
            tabmenu.insertBefore(document.getElementById(
                    'tabslideshow-separator'), target);
            tabmenu.insertBefore(document.getElementById(
                    'tabslideshow-refresh'), target);
        } else {
            tabmenu.appendChild(document.getElementById(
                    'tabslideshow-separator'));
            tabmenu.appendChild(document.getElementById(
                    'tabslideshow-refresh'));
        }
        tabmenu.addEventListener('popupshowing', tabslideshow.tabmenushow,
                false);
        // remove now-empty menupopup container
        var popup = document.getElementById("tabslideshowPopup");
        popup.parentNode.removeChild(popup);

        // initial tabs refresh settings
        for (var tab in gBrowser.tabContainer.childNodes) {
            gBrowser.tabContainer.childNodes[tab].tabslideshowrefresh =
                    this.refresh;
        }

        // add listener for new tabs
        gBrowser.tabContainer.addEventListener('TabOpen', function(e) {
                tabslideshow.checknewtab(e);
            }, false);

        // initial slideshow
        if (this.prefs.getBoolPref('start')) {
            this.toggle();
        }
    },

    // timer function to cycle tabs
    cycle: function(p_this)
    {
        // only cycle if active
        if (!p_this.active) {
            return;
        }

        // get tab info
        var numtabs = gBrowser.tabContainer.childNodes.length;
        var currenttabnum = gBrowser.tabContainer.selectedIndex;
        var nexttab = gBrowser.tabContainer.childNodes[
            (currenttabnum + 1) % numtabs];
        var upcomingtab = gBrowser.tabContainer.childNodes[
            (currenttabnum + 2) % numtabs];

        // set next tab
        gBrowser.selectedTab = nexttab;

        // optionally refresh upcoming tab
        if (upcomingtab.tabslideshowrefresh && (nexttab != upcomingtab)) {
            gBrowser.reloadTab(upcomingtab);
        }

        // next cycle
        setTimeout(p_this.cycle, 1000 * p_this.delay, p_this);
    },

    // handler for prefs change
    observe: function(subject, topic, data)
    {
        if (topic != 'nsPref:changed') return;

        switch(data) {
            case 'time':
                this.delay = this.prefs.getIntPref('time');
                break;
            case 'refresh':
                this.refresh = this.prefs.getBoolPref('refresh');
                break;
        }
    },

    // handle new tab refresh settings
    checknewtab: function(e)
    {
        //Components.utils.reportError("checknewtab")
        e.target.tabslideshowrefresh = this.refresh;
    },

    // per-tab menu adjustments
    tabmenushow: function(e)
    {
        //Components.utils.reportError('tabmenushow');
        if (e.originalTarget != gBrowser.tabContextMenu) {
            return true;
        }

        var item;
        var refresh = document.getElementById('tabslideshow-refresh');
        if (document.popupNode.parentNode) {
            item = document.popupNode.parentNode.parentNode.id;
        }
        // XXX: copied from tabmixplus, not sure what does
        if (item && (item == "btn_tabslist" || item == "btn_tabslistSorted" ||
                item == "alltabs-button")) {
            gBrowser.mContextTab = document.popupNode.tab;
        }

        // detect whether clicked right of tabs (not needed in Firefox 4)
        var clickOutTabs = document.popupNode.localName == "tabs";
        var aTab = clickOutTabs ? gBrowser.mCurrentTab : gBrowser.mContextTab;

        // disable refresh option for current tab when clicked outside
        //if (clickOutTabs) refresh.setAttribute("disabled", "true");
        //else refresh.setAttribute("disabled", "false");

        if (aTab.tabslideshowrefresh) {
            refresh.setAttribute("checked", "true");
        } else {
            refresh.removeAttribute("checked");
        }

    },

    // toggle whether slideshowing
    toggle: function()
    {
        if (this.active) {
            // enabled
            var node = document.getElementById('tabslideshow-toggle');
            if (node) node.setAttribute('label', 'Start Tab Slideshow');
            var node = document.getElementById('tabslideshow-appmenu-toggle');
            if (node) node.setAttribute('label', 'Start Tab Slideshow');
            this.active = false;
        } else if (this.active == 1) {
            // disabled with active timeout
            var node = document.getElementById('tabslideshow-toggle');
            if (node) node.setAttribute('label', 'Stop Tab Slideshow');
            var node = document.getElementById('tabslideshow-appmenu-toggle');
            if (node) node.setAttribute('label', 'Stop Tab Slideshow');
            this.active = true;
        } else {
            // disabled, no active timeout
            var node = document.getElementById('tabslideshow-toggle');
            if (node) node.setAttribute('label', 'Stop Tab Slideshow');
            var node = document.getElementById('tabslideshow-appmenu-toggle');
            if (node) node.setAttribute('label', 'Stop Tab Slideshow');
            this.active = 2;
            setTimeout(this.cycle, 1500, this);
        }
    },

    // change refresh flag on tab
    togglerefresh: function(e)
    {
        //Components.utils.reportError('togglerefresh');
        e.tabslideshowrefresh = !e.tabslideshowrefresh;
    },

    // clean up
    shutdown: function()
    {
        this.prefs.removeObserver("", this);
    },

}

// return tab context menu
function tabslideshow_gettabcontextmenu()
{
    if (gBrowser.tabContextMenu) return gBrowser.tabContextMenu;

    var tabmenu = document.getAnonymousElementByAttribute(
            gBrowser, "anonid", "tabContextMenu");
    if (tabmenu) {
        gBrowser.tabContextMenu = tabmenu;
    } else if (gBrowser.tabContainer && gBrowser.tabContainer.contextMenu) {
        gBrowser.tabContextMenu = gBrowser.tabContainer.contextMenu;
    } else {
        gBrowser.tabContextMenu = document.getElementById('tabContextMenu');
    }

    if (!gBrowser.tabContextMenu.hasAttribute("id"))
        gBrowser.tabContextMenu.setAttribute("id", "tabContextMenu");

    return gBrowser.tabContextMenu;
}

window.addEventListener('load', function(e) { tabslideshow.startup(); },
        false);
window.addEventListener('unload', function(e) { tabslideshow.shutdown(); },
        false);
<|endoftext|>


<commit_before>/*
 * SVGeezy.js
 *
 * Copyright 2016, Ben Howdle http://benhowdle.im
 *
 * Date: Sun Aug 26 20:38 2012 GMT
 */

/*
	//call like so, pass in a class name that you don't want it to check and a filetype to replace .svg with
	svgeezy.init('nocheck', 'png');
*/

window.svgeezy = function() {

	return {

		init: function(avoid, filetype, forceFallbackAlways) {
			this.avoid = avoid || false;
			this.filetype = filetype || 'png';
			this.svgSupport = !forceFallbackAlways || this.supportsSvg();
			if(!this.svgSupport) {
				this.images = document.getElementsByTagName('img');
				this.imgL = this.images.length;
				this.fallbacks();
			}
		},

		fallbacks: function() {
			if (this.imgL == 0) {
				return;
			}
			while(--this.imgL) {
				if(this.avoid && this.hasClass(this.images[this.imgL], this.avoid)) {
					continue;
				}
				var src = this.images[this.imgL].getAttribute('src');
				if(src === null || this.getFileExt(src) != 'svg') {
					continue;
				}
				var newSrc = src.replace('.svg', '.' + this.filetype);
				this.images[this.imgL].setAttribute('src', newSrc);

			}
		},

		getFileExt: function(src) {
			var ext = src.split('.').pop();

			if(ext.indexOf("?") !== -1) {
				ext = ext.split('?')[0];
			}

			return ext;
		},

		hasClass: function(element, cls) {
			return(' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
		},

		supportsSvg: function() {
			return document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
		}
	};

}();
<commit_msg>#28 Fixed logic issue on force fallback.<commit_after>/*
 * SVGeezy.js
 *
 * Copyright 2016, Ben Howdle http://benhowdle.im
 *
 * Date: Sun Aug 26 20:38 2012 GMT
 */

/*
	//call like so, pass in a class name that you don't want it to check and a filetype to replace .svg with
	svgeezy.init('nocheck', 'png');
*/

window.svgeezy = function() {

	return {

		init: function(avoid, filetype, forceFallbackAlways) {
			this.avoid = avoid || false;
			this.filetype = filetype || 'png';
			this.svgSupport = false
			if (!forceFallbackAlways) {
				this.svgSupport = this.supportsSvg();
			}
			if(!this.svgSupport) {
				this.images = document.getElementsByTagName('img');
				this.imgL = this.images.length;
				this.fallbacks();
			}
		},

		fallbacks: function() {
			if (this.imgL == 0) {
				return;
			}
			while(--this.imgL) {
				if(this.avoid && this.hasClass(this.images[this.imgL], this.avoid)) {
					continue;
				}
				var src = this.images[this.imgL].getAttribute('src');
				if(src === null || this.getFileExt(src) != 'svg') {
					continue;
				}
				var newSrc = src.replace('.svg', '.' + this.filetype);
				this.images[this.imgL].setAttribute('src', newSrc);

			}
		},

		getFileExt: function(src) {
			var ext = src.split('.').pop();

			if(ext.indexOf("?") !== -1) {
				ext = ext.split('?')[0];
			}

			return ext;
		},

		hasClass: function(element, cls) {
			return(' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
		},

		supportsSvg: function() {
			return document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
		}
	};

}();
<|endoftext|>


<commit_before>/*
 * grunt-force
 * https://github.com/couchand/grunt-force
 *
 * Copyright (c) 2013 Andrew Couch
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  grunt.registerMultiTask('force', 'Interact with a Salesforce.com environment', function(sftask) {
    var done = this.async();
    var options = this.options();
    var sfdc = require('../lib/force-0.1.0.js');
    var promise = require('node-promise');
    var file_groups = this.files;

    grunt.log.writeln('force plugin executing task '+sftask);
    grunt.log.writeln('loading credentials from '+options.credentials);

    var credfile = grunt.file.read(options.credentials);
    var module = {};
    eval(credfile);
    var creds = module.exports;

    grunt.log.writeln('logging in to '+creds.login_url+' as '+creds.username);

    if ( sftask !== 'deploy' ) {
      grunt.fail.warn('unknown task');
      return 42;
    }

    var conn;
    var data = {};

    sfdc.connect(creds).then(function(c) {
      grunt.log.writeln('logged in successfully');
      conn = c;

      grunt.log.writeln('looking for container');
      return conn.tooling.query('select Id from MetadataContainer where Name = \'' + options.container + "'");
    }).then(function(containers) {
      if ( containers && containers.length ) {
        grunt.log.writeln('found container');
        // found container, use it
        var now = new promise.Deferred();
        now.resolve( containers[0].Id );
        return now;
      }
      return conn.tooling.insert('MetadataContainer', { 'Name': options.container });
    }).then(function(new_id) {

      data.containerId = new_id;
      var junctionInserts = [];

      grunt.log.writeln('created MetadataContainer with Id '+new_id);
      grunt.log.writeln('creating junction objects now...');

      // Iterate over all specified file groups.
      file_groups.forEach(function(fileObj) {
        // The source files to be concatenated. The "nonull" option is used
        // to retain invalid files/patterns so they can be warned about.
        var files = grunt.file.expand({nonull: true}, fileObj.src);

        files.map(function(filepath) {
          var class_name = filepath.match(/\/([^\/]*)\.cls$/)[1];

          // Warn if a source file/pattern was invalid.
          if (!grunt.file.exists(filepath)) {
            grunt.log.error('Source file "' + filepath + '" not found.');
            return '';
          }

          grunt.log.writeln('adding class ' + class_name);

          junctionInserts.push(
            conn.query('select Id from ApexClass where Name = \''+class_name+"'").then(function(classes) {
              var classId = classes[0].Id;
              grunt.log.writeln('found class '+class_name+' with id '+classId);

              return conn.insert('ApexClassMember', {
                'MetadataContainerId': data.containerId,
                'ContentEntityId': classId,
                'Body': grunt.file.read(filepath)
              });
            })
          );
        });
      });

      grunt.log.writeln('waiting for all adds to complete');

      return promise.all.apply(promise, junctionInserts);
    }).then(function(new_members) {
      grunt.log.writeln('all adds complete');

      new_members.map(function(member) {
        grunt.log.writeln('new member id' + member);
      });

      grunt.log.writeln('submitting deployment request');

      return conn.tooling.deploy(data.containerId);
    }).then(function(results) {

      grunt.log.writeln('deployment complete');
      done();
    });
  });

};
<commit_msg>refactor login and deployment and use promises<commit_after>/*
 * grunt-force
 * https://github.com/couchand/grunt-force
 *
 * Copyright (c) 2013 Andrew Couch
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  grunt.registerMultiTask('force', 'Interact with a Salesforce.com environment', function(sftask) {
    var done = this.async();
    var options = this.options();
    var file_groups = this.files;

    grunt.log.writeln('force plugin executing task '+sftask);

    if ( sftask !== 'deploy' ) {
      grunt.fail.warn('unknown task');
      return 42;
    }

    login(options).then(function(conn) {
      return deploy(conn, file_groups, options);
    }).then(done);
  });

  function login(options) {
    var sfdc = require('../lib/force-0.1.0.js');

    grunt.log.writeln('loading credentials from '+options.credentials);

    var credfile = grunt.file.read(options.credentials);
    var module = {};
    eval(credfile);
    var creds = module.exports;

    grunt.log.writeln('logging in to '+creds.login_url+' as '+creds.username);

    return sfdc.connect(creds).then(function(c) {
      grunt.log.writeln('logged in successfully');
      return c;
    });
  }

  function deploy(conn, file_groups, options) {
    var promise = require('node-promise');
    var data = {};

    grunt.log.writeln('looking for container');

    return conn.tooling.query('select Id from MetadataContainer where Name = \'' + options.container + "'").then(function(containers) {
      if ( containers && containers.length ) {
        grunt.log.writeln('found container');
        // found container, use it
        var now = new promise.Deferred();
        now.resolve( containers[0].Id );
        return now;
      }
      return conn.tooling.insert('MetadataContainer', { 'Name': options.container });
    }).then(function(new_id) {

      data.containerId = new_id;
      var junctionInserts = [];

      grunt.log.writeln('created MetadataContainer with Id '+new_id);
      grunt.log.writeln('creating junction objects now...');

      // Iterate over all specified file groups.
      file_groups.forEach(function(fileObj) {
        // The source files to be concatenated. The "nonull" option is used
        // to retain invalid files/patterns so they can be warned about.
        var files = grunt.file.expand({nonull: true}, fileObj.src);

        files.map(function(filepath) {
          var class_name = filepath.match(/\/([^\/]*)\.cls$/)[1];

          // Warn if a source file/pattern was invalid.
          if (!grunt.file.exists(filepath)) {
            grunt.log.error('Source file "' + filepath + '" not found.');
            return '';
          }

          grunt.log.writeln('adding class ' + class_name);

          junctionInserts.push(
            conn.query('select Id from ApexClass where Name = \''+class_name+"'").then(function(classes) {
              var classId = classes[0].Id;
              grunt.log.writeln('found class '+class_name+' with id '+classId);

              return conn.insert('ApexClassMember', {
                'MetadataContainerId': data.containerId,
                'ContentEntityId': classId,
                'Body': grunt.file.read(filepath)
              });
            })
          );
        });
      });

      grunt.log.writeln('waiting for all adds to complete');

      return promise.all.apply(promise, junctionInserts);
    }).then(function(new_members) {
      grunt.log.writeln('all adds complete');

      new_members.map(function(member) {
        grunt.log.writeln('new member id' + member);
      });

      grunt.log.writeln('submitting deployment request');

      return conn.tooling.deploy(data.containerId);
    }).then(function(results) {

      grunt.log.writeln('deployment complete');
    });
  }

};
<|endoftext|>


<commit_before>var App = (function () {

	var $map = null;
	var $console = null;
	var $search = null;

	var map = null;
	var markers = [];
	var geocoder = null;

	var $searchBtn = null;
	var $clearBtn = null;
	var $exportBtn = null;

	$.fn.getAttributes = function () {
		var attributes = {};

		if (this.length) {
			$.each(this[0].attributes, function (index, attr) {
				attributes[ attr.name ] = attr.value;
			});
		}

		return attributes;
	};

	var onAppReady = function (ev) {
		console.log('App ready');

		$map = $('#map');
		$console = $('#console');
		$search = $('#search');

		$clearBtn = $console.find('button.btn-clear');
		$searchBtn = $console.find('button.btn-search');
		$exportBtn = $console.find('button.btn-export');

		$clearBtn.on('click', onClearMap);
		$clearBtn.on('click', onExportMap);

		$console.on('submit', onConsoleSubmit);
		$search.on('submit', onSearchSubmit);

		var mapOptions = {
			center: new google.maps.LatLng(46.8032826, -71.242796),
			zoom: 17,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};

		map = new google.maps.Map($map.get(0), mapOptions);

		geocoder = new google.maps.Geocoder();

		google.maps.event.addListener(map, 'center_changed', onMapChange);
		google.maps.event.addListener(map, 'zoom_changed', onMapChange);

		google.maps.event.addListenerOnce(map, 'idle', function () {
			google.maps.event.trigger(map, 'zoom_changed');
		});
	}

	var onExportMap = function (ev) {
		ev.preventDefault();

	}

	var onClearMap = function (ev) {
		ev.preventDefault();

		$.each(markers, function (i, marker) {
			marker.setMap(null);
		});

		markers = [];

		$clearBtn.attr('disabled', true);
		$exportBtn.attr('disabled', true);
	}

	var onConsoleSubmit = function (ev) {
		ev.preventDefault();

		$clearBtn.trigger('click');

		var $form = $(this);

		console.log($form.serializeArray());

		$.ajax({
			url: $form.attr('action'),
			type: $form.attr('method'),
			data: $form.serializeArray(),
			//dataType: 'json',
			success: function (data) {
				console.log(data);
				return true;

				$clearBtn.attr('disabled', false);
				$exportBtn.attr('disabled', false);

				onDataReceived(data);
			},
			complete: function () {
				$form.find(':input').attr('disabled', false);
			},
			error: function (request, error, message) {
				console.log(request, error, message);
			}
		});

		$form.find(':input').attr('disabled', true);
	}

	var onDataReceived = function (data) {
		// Loop through intersections to display markers
		$.each(data, function (i, intersection) {
			// Create marker
			var marker = new google.maps.Marker({
				position: new google.maps.LatLng(intersection.lat, intersection.lng),
				map: map,
				title: intersection.id.toString(),
				data: intersection,
				icon:createMarker()
			});

			google.maps.event.addListener(marker, 'click', onMarkerClick);

			// Store marker in array
			markers.push(marker);
		});
	}

	var onMapChange = function (ev) {
		// Get bounds
		var bounds = map.getBounds();

		// Change bounds
		$console.find('input#maxlon').val(map.getBounds().getNorthEast().lng());
		$console.find('input#minlon').val(map.getBounds().getSouthWest().lng());
		$console.find('input#maxlat').val(map.getBounds().getNorthEast().lat());
		$console.find('input#minlat').val(map.getBounds().getSouthWest().lat());
	}

	var onSearchSubmit = function (ev) {
		ev.preventDefault();

		var $form = $(this);
		var query = $form.find('input:first').val();

		$form.find(':input').attr('disabled', true);

		geocoder.geocode({'address': query}, function (results, status) {
			$form.find(':input').attr('disabled', false);

			if (status == google.maps.GeocoderStatus.OK) {
				map.setCenter(results[0].geometry.location);
			}
		});
	}

	var findMarkersInWay = function(wayId, excludeNodeId) {
		var markersInWay = [];

		for (var i = 0; i < markers.length; i++) {
			var marker = markers[i];

			if (marker.data.id === excludeNodeId) {
				continue;
			}

			if ($.inArray(wayId, marker.data.ways) !== -1) {
				markersInWay.push(marker);
			}
		}

		return markersInWay;
	}

	var findMarkerById = function(nodeId) {
		for (var i = 0; i < markers.length; i++) {
			if (markers[i].data.id === nodeId) {
				return markers[i];
			}
		}

		return null;
	}

	var resetMarkers = function() {
		for (var i = 0; i < markers.length; i++) {
			markers[i].setIcon(createMarker());
		}
	}

	var onMarkerClick = function (ev, marker) {
		resetMarkers();

		var currentMarker = this;

		/*
		var markersInWay = [];

		for (var i = 0; i < this.data.ways.length; i++) {
			$.merge(markersInWay, findMarkersInWay(this.data.ways[i], currentMarker.data.id));
		}

		for (var i = 0; i < markersInWay.length; i++) {
			markersInWay[i].setIcon(createMarker('FFFFFF'));
		}
		*/

		for (var i = 0; i < this.data.adjacentNodes.length; i++) {
			var adjacentMarker = findMarkerById(this.data.adjacentNodes[i]);

			if (adjacentMarker) {
				adjacentMarker.setIcon(createMarker('000000'));
			}
		}

		// Identify current clicked marker
		currentMarker.setIcon(createMarker('00FF00'));
	}

	var createMarker = function(color) {
		return new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|" + (color || 'FE7569'),
		        new google.maps.Size(21, 34),
		        new google.maps.Point(0,0),
		        new google.maps.Point(10, 34));
	}

	var construct = (function () {
		google.maps.event.addDomListener(window, 'load', onAppReady);
	})();

})();<commit_msg>javascript initial version<commit_after>var App = (function () {

	var $map = null;
	var $console = null;
	var $search = null;

	var map = null;
	var markers = [];
	var geocoder = null;

	var $searchBtn = null;
	var $clearBtn = null;
	var $exportBtn = null;

	$.fn.getAttributes = function () {
		var attributes = {};

		if (this.length) {
			$.each(this[0].attributes, function (index, attr) {
				attributes[ attr.name ] = attr.value;
			});
		}

		return attributes;
	};

	var onAppReady = function (ev) {
		console.log('App ready');

		$map = $('#map');
		$console = $('#console');
		$search = $('#search');

		$clearBtn = $console.find('button.btn-clear');
		$searchBtn = $console.find('button.btn-search');
		$exportBtn = $console.find('button.btn-export');

		$clearBtn.on('click', onClearMap);
		$clearBtn.on('click', onExportMap);

		$console.on('submit', onConsoleSubmit);
		$search.on('submit', onSearchSubmit);

		var mapOptions = {
			center: new google.maps.LatLng(46.8032826, -71.242796),
			zoom: 17,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};

		map = new google.maps.Map($map.get(0), mapOptions);

		geocoder = new google.maps.Geocoder();

		google.maps.event.addListener(map, 'center_changed', onMapChange);
		google.maps.event.addListener(map, 'zoom_changed', onMapChange);

		google.maps.event.addListenerOnce(map, 'idle', function () {
			google.maps.event.trigger(map, 'zoom_changed');
		});
	}

	var onExportMap = function (ev) {
		ev.preventDefault();

	}

	var onClearMap = function (ev) {
		ev.preventDefault();

		$.each(markers, function (i, marker) {
			marker.setMap(null);
		});

		markers = [];

		$clearBtn.attr('disabled', true);
		$exportBtn.attr('disabled', true);
	}

	var onConsoleSubmit = function (ev) {
		ev.preventDefault();

		$clearBtn.trigger('click');

		var $form = $(this);

		console.log($form.serializeArray());

		$.ajax({
			url: $form.attr('action'),
			type: $form.attr('method'),
			data: $form.serializeArray(),
			dataType: 'json',
			dataFilter:filterData,
			success: function (data) {
				$clearBtn.attr('disabled', false);
				$exportBtn.attr('disabled', false);

				onDataReceived(data);
			},
			complete: function () {
				$form.find(':input').attr('disabled', false);
			},
			error: function (request, error, message) {
				console.log(request, error, message);
			}
		});

		$form.find(':input').attr('disabled', true);
	}

	var filterData = function(data) {
		// Parse XML file
		var xml = $.parseXML(data);

		// XPath filters to remove unnecessary information
		var filters = [
			'@k="building"',
			'@k="building:part"',
			'@k="amenity"',
			'@k="historic"',
			'@k="natural"',
			'@k="waterway"',
			'@k="leisure"',
			'@k="bridge"',
			'@k="railway"',
			'@k="service"',

			'@v="footway"',
			'@v="industrial"',
			'@v="recreation_ground"',
			'@v="dyke"',
			'@v="cycleway"',
			'@v="pedestrian"',
			'@v="track"',
			'@v="grass"',
			'@v="cemetery"',
		];

		console.log("XML has " + document.evaluate('count(//*)', xml, null, XPathResult.NUMBER_TYPE, null).numberValue + " elements.");

		var badNodes = document.evaluate('/osm/way[tag[' + filters.join(' or ') + ']] | //tag | /osm/relation | /osm/bounds', xml, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)

		// Clean up to speed up, mothertrucker!
		deleted = 0;
		for (var i = 0 ; i < badNodes.snapshotLength; i++) {
			var node = badNodes.snapshotItem(i);
			node.parentNode.removeChild(node);
		}

		console.log("After clean up, XML has " + document.evaluate('count(//*)', xml, null, XPathResult.NUMBER_TYPE, null).numberValue + " elements.");

		// Node references, convert to integers
		var refNodes = document.evaluate('/osm/way/nd/@ref', xml, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		var refs = [];

		for (var i = 0 ; i < refNodes.snapshotLength; i++) {
			var node = refNodes.snapshotItem(i);

			refs.push(parseInt(node.nodeValue));
		}

		console.log("Found " + refs.length + " node references.");

		var sortedRefs = refs.sort();
		var repeatedRefs = [];

		for (var i = 0; i < refs.length - 1; i++) {
			if (sortedRefs[i + 1] == sortedRefs[i]) {
				repeatedRefs.push(sortedRefs[i]);
			}
		}

		console.log("Found " + repeatedRefs.length + " intersections.");

		var intersections = [];

		for (var i in repeatedRefs) {
			var nodeId = repeatedRefs[i];
			var node = document.evaluate('/osm/node[@id="' + nodeId + '"]', xml, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);

			var adjacentNodes = xml.evaluate('/osm/way/nd[@ref="' + nodeId + '"]/following-sibling::nd[1]/@ref | /osm/way/nd[@ref="' + nodeId + '"]/preceding-sibling::nd[1]/@ref', xml, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
			var adjacents = [];

			for (var i = 0 ; i < adjacentNodes.snapshotLength; i++) {
				adjacents.push(parseInt(adjacentNodes.snapshotItem(i).nodeValue));
			}

			var intersection = {
				id: nodeId,
				lat: parseFloat(node.singleNodeValue.attributes.getNamedItem('lat').value),
				lng: parseFloat(node.singleNodeValue.attributes.getNamedItem('lon').value),
				adjacentNodes: adjacents
			};

			intersections.push(intersection);
		}

		return JSON.stringify(intersections);
	}

	var onDataReceived = function (data) {
		// Loop through intersections to display markers
		$.each(data, function (i, intersection) {
			// Create marker
			var marker = new google.maps.Marker({
				position: new google.maps.LatLng(intersection.lat, intersection.lng),
				map: map,
				title: intersection.id.toString(),
				data: intersection,
				icon:createMarker()
			});

			google.maps.event.addListener(marker, 'click', onMarkerClick);

			// Store marker in array
			markers.push(marker);
		});
	}

	var onMapChange = function (ev) {
		// Get bounds
		var bounds = map.getBounds();

		// Change bounds
		$console.find('input#maxlon').val(map.getBounds().getNorthEast().lng());
		$console.find('input#minlon').val(map.getBounds().getSouthWest().lng());
		$console.find('input#maxlat').val(map.getBounds().getNorthEast().lat());
		$console.find('input#minlat').val(map.getBounds().getSouthWest().lat());
	}

	var onSearchSubmit = function (ev) {
		ev.preventDefault();

		var $form = $(this);
		var query = $form.find('input:first').val();

		$form.find(':input').attr('disabled', true);

		geocoder.geocode({'address': query}, function (results, status) {
			$form.find(':input').attr('disabled', false);

			if (status == google.maps.GeocoderStatus.OK) {
				map.setCenter(results[0].geometry.location);
			}
		});
	}

	var findMarkersInWay = function(wayId, excludeNodeId) {
		var markersInWay = [];

		for (var i = 0; i < markers.length; i++) {
			var marker = markers[i];

			if (marker.data.id === excludeNodeId) {
				continue;
			}

			if ($.inArray(wayId, marker.data.ways) !== -1) {
				markersInWay.push(marker);
			}
		}

		return markersInWay;
	}

	var findMarkerById = function(nodeId) {
		for (var i = 0; i < markers.length; i++) {
			if (markers[i].data.id === nodeId) {
				return markers[i];
			}
		}

		return null;
	}

	var resetMarkers = function() {
		for (var i = 0; i < markers.length; i++) {
			markers[i].setIcon(createMarker());
		}
	}

	var onMarkerClick = function (ev, marker) {
		resetMarkers();

		var currentMarker = this;

		/*
		var markersInWay = [];

		for (var i = 0; i < this.data.ways.length; i++) {
			$.merge(markersInWay, findMarkersInWay(this.data.ways[i], currentMarker.data.id));
		}

		for (var i = 0; i < markersInWay.length; i++) {
			markersInWay[i].setIcon(createMarker('FFFFFF'));
		}
		*/

		for (var i = 0; i < this.data.adjacentNodes.length; i++) {
			var adjacentMarker = findMarkerById(this.data.adjacentNodes[i]);

			if (adjacentMarker) {
				adjacentMarker.setIcon(createMarker('000000'));
			}
		}

		// Identify current clicked marker
		currentMarker.setIcon(createMarker('00FF00'));
	}

	var createMarker = function(color) {
		return new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|" + (color || 'FE7569'),
		        new google.maps.Size(21, 34),
		        new google.maps.Point(0,0),
		        new google.maps.Point(10, 34));
	}

	var construct = (function () {
		google.maps.event.addDomListener(window, 'load', onAppReady);
	})();

})();<|endoftext|>


<commit_before>// A tiny js library to perform string substitution for translation

// This is intended to be the simplest thing that could possibly work
// We'll build up from there as needs arise
//
// Uses the concept of translations packs
// which are JS Modules with the following form:

// var simple_pack = {
//   code: 'eng',
//   namespace: 'main',
//   nplurals: 2,
//   pluralizer: function(n){
//     return n ? 1 : 0;
//   },
//   strings: {
//     "not_found_project":"This project (%s) does not contain any documents.",
//     "no_reviewer_on_document":[
//       "The document %2$s does not have a reviewer",
//       "There are %d reviewers on document %s."
//     ]
//   }
// };
//
// Each pack is assigned:
//   A namespace.  This is the area where it will be utilized, i.e. WS for WorkSpace, DV for Document Viewer.
//   This is needed to accomodate loading multiple translation objects in the same page,
//   such as when the Viewer is embedded into the workspace
//
//   A language code.  The ISO 639-3 code that it corresponds to.
//
//   A pluralizer function.  This is takes a number and returns the index of the string that should be used.
//   Concept originated with gettext: http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms

// Example Usage:

// var encoding = new I18n( { namespace: 'main', language: 'spa', fallback: 'eng' } );
// _.t = encoding.translate

// This could also come before the object creation
// I18n.load( simple_pack );

// using the above pack as an example:

// _.t('not_found_project','TestingOnly')
// returns: "This project (TestingOnly) does not contain any documents."
//
// _.t('no_reviewer_on_document',2,'GoodDoc')
// would return: "There are 2 reviewers on document GoodDoc."
// but _.t('no_reviewer_on_document',1,'GoodDoc')
// would return: "The document GoodDoc does not have a reviewer."

// Special care has been taken to allow differing orders of initialization.  In some cases the library may be initialized
// before the packs are loaded, or it may be initalized and then the language codes changed later.

(function(root,undefined) {
  var _ = root._, jQuery = root.jQuery;

  var previousI18n = root.I18n;

  // There can be only one!
  if ( ! _.isUndefined( root.I18n ) )
    return;

  var LOG;
  if ( root.console ){
    LOG=window.console;
  } else {
    LOG = {
      warn: jQuery.noop, error: jQuery.noop
    };
  }

  // stores all available language
  // packs
  var ALL_PACKS = {};
  // keeps references to all i18n instances that are created.
  // This way they can all be contacted for reconfiguration when additional packs are loaded
  var ALL_INSTANCES = [];

  function I18n( options ){
    this.codes    = {};
    this.sprintf = root.sprintf.noConflict();
    this.reconfigure( options );
    this.translate = _.bind( this.translate, this );
    ALL_INSTANCES.push(this);
  };

  I18n.noConflict = function(){
    root.I18n = previousI18n;
    return this;
  };

  // static method.  Stores packs for
  // later use by individual translators
  I18n.load = function( pack ){
    if ( ALL_PACKS[ pack.namespace ] )
      ALL_PACKS[ pack.namespace ].push( pack );
    else
      ALL_PACKS[ pack.namespace ] = [ pack ];

    _.each( ALL_INSTANCES, function(lib){
      lib.reconfigure();
    });
    return true;
  };

  // private(ish) method to set either the
  // language or fallback code
  I18n.prototype._set = function( type, code ){
    if ( ! code ) {
      code = root.DC_LANGUAGE_CODES ? root.DC_LANGUAGE_CODES[ type ] : 'eng';
    }
    this.codes[ type ] = code;
    this[ type ] = this.packForCode( code );
    return this[ type ];
  };

  // reconfigure the language and fallback in use
  I18n.prototype.reconfigure = function( options ){
    if (_.isUndefined(options)){
      options=this.options;
    } else {
      this.options = options;
    }
    if ( ALL_PACKS[options.namespace] ){
      this.packs = ALL_PACKS[options.namespace];
    }

    if ( options.language ){
      var pack = this._set( 'language', options.language );
      if ( pack && _.isFunction( pack['initialize'] ) ) {
        pack.initialize();
      }
    }
    if ( options.fallback )
      this._set( 'fallback', options.fallback );
  };

  I18n.prototype.packForCode = function( code ){
    return _.detect( this.packs, function( pack ){
      return pack.code == code;
    });
  };

  // our raison d'etre.
  // Looks up a translation string for a given key
  // and applies pluralization & sprintf substitions to it
  I18n.prototype.translate = function( key, args ){

    var match, pack;
    pack = this.language;
    if ( ! pack || ! ( match = pack.strings[ key ] ) ){
      LOG.warn( '[i18n] lookup for ' + key + ' in \'' +
                ( pack ? pack.code : this.options.language + ' (missing)' ) +
                '\' failed.' );
      pack = this.fallback;
      if ( ! pack || ! ( match = pack.strings[ key ] ) ){
        LOG.error( '[i18n] lookup for ' + key + ' failed in all languages' );
        return key;  // something is better than nothing (perhaps?)
      }
    };

    // if the match is an array then perform an additional lookup
    // using the pluralization lookup rules from the pack
    if ( _.isArray( match ) ){
      match = match[ pack.pluralizer( _.isUndefined(args) ? 1 : args ) ];
    }

    return this.sprintf.with_array( match, _.toArray( arguments ).slice(1) );

  };

  // export ourselves
  root.I18n = I18n;

})(this);
<commit_msg>Use what's available in case of missing plurals<commit_after>// A tiny js library to perform string substitution for translation

// This is intended to be the simplest thing that could possibly work
// We'll build up from there as needs arise
//
// Uses the concept of translations packs
// which are JS Modules with the following form:

// var simple_pack = {
//   code: 'eng',
//   namespace: 'main',
//   nplurals: 2,
//   pluralizer: function(n){
//     return n ? 1 : 0;
//   },
//   strings: {
//     "not_found_project":"This project (%s) does not contain any documents.",
//     "no_reviewer_on_document":[
//       "The document %2$s does not have a reviewer",
//       "There are %d reviewers on document %s."
//     ]
//   }
// };
//
// Each pack is assigned:
//   A namespace.  This is the area where it will be utilized, i.e. WS for WorkSpace, DV for Document Viewer.
//   This is needed to accomodate loading multiple translation objects in the same page,
//   such as when the Viewer is embedded into the workspace
//
//   A language code.  The ISO 639-3 code that it corresponds to.
//
//   A pluralizer function.  This is takes a number and returns the index of the string that should be used.
//   Concept originated with gettext: http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms

// Example Usage:

// var encoding = new I18n( { namespace: 'main', language: 'spa', fallback: 'eng' } );
// _.t = encoding.translate

// This could also come before the object creation
// I18n.load( simple_pack );

// using the above pack as an example:

// _.t('not_found_project','TestingOnly')
// returns: "This project (TestingOnly) does not contain any documents."
//
// _.t('no_reviewer_on_document',2,'GoodDoc')
// would return: "There are 2 reviewers on document GoodDoc."
// but _.t('no_reviewer_on_document',1,'GoodDoc')
// would return: "The document GoodDoc does not have a reviewer."

// Special care has been taken to allow differing orders of initialization.  In some cases the library may be initialized
// before the packs are loaded, or it may be initalized and then the language codes changed later.

(function(root,undefined) {
  var _ = root._, jQuery = root.jQuery;

  var previousI18n = root.I18n;

  // There can be only one!
  if ( ! _.isUndefined( root.I18n ) )
    return;

  var LOG;
  if ( root.console ){
    LOG=window.console;
  } else {
    LOG = {
      warn: jQuery.noop, error: jQuery.noop
    };
  }

  // stores all available language
  // packs
  var ALL_PACKS = {};
  // keeps references to all i18n instances that are created.
  // This way they can all be contacted for reconfiguration when additional packs are loaded
  var ALL_INSTANCES = [];

  function I18n( options ){
    this.codes    = {};
    this.sprintf = root.sprintf.noConflict();
    this.reconfigure( options );
    this.translate = _.bind( this.translate, this );
    ALL_INSTANCES.push(this);
  };

  I18n.noConflict = function(){
    root.I18n = previousI18n;
    return this;
  };

  // static method.  Stores packs for
  // later use by individual translators
  I18n.load = function( pack ){
    if ( ALL_PACKS[ pack.namespace ] )
      ALL_PACKS[ pack.namespace ].push( pack );
    else
      ALL_PACKS[ pack.namespace ] = [ pack ];

    _.each( ALL_INSTANCES, function(lib){
      lib.reconfigure();
    });
    return true;
  };

  // private(ish) method to set either the
  // language or fallback code
  I18n.prototype._set = function( type, code ){
    if ( ! code ) {
      code = root.DC_LANGUAGE_CODES ? root.DC_LANGUAGE_CODES[ type ] : 'eng';
    }
    this.codes[ type ] = code;
    this[ type ] = this.packForCode( code );
    return this[ type ];
  };

  // reconfigure the language and fallback in use
  I18n.prototype.reconfigure = function( options ){
    if (_.isUndefined(options)){
      options=this.options;
    } else {
      this.options = options;
    }
    if ( ALL_PACKS[options.namespace] ){
      this.packs = ALL_PACKS[options.namespace];
    }

    if ( options.language ){
      var pack = this._set( 'language', options.language );
      if ( pack && _.isFunction( pack['initialize'] ) ) {
        pack.initialize();
      }
    }
    if ( options.fallback )
      this._set( 'fallback', options.fallback );
  };

  I18n.prototype.packForCode = function( code ){
    return _.detect( this.packs, function( pack ){
      return pack.code == code;
    });
  };

  // our raison d'etre.
  // Looks up a translation string for a given key
  // and applies pluralization & sprintf substitions to it
  I18n.prototype.translate = function( key, args ){

    var match, pack;
    pack = this.language;
    if ( ! pack || ! ( match = pack.strings[ key ] ) ){
      LOG.warn( '[i18n] lookup for ' + key + ' in \'' +
                ( pack ? pack.code : this.options.language + ' (missing)' ) +
                '\' failed.' );
      pack = this.fallback;
      if ( ! pack || ! ( match = pack.strings[ key ] ) ){
        LOG.error( '[i18n] lookup for ' + key + ' failed in all languages' );
        return key;  // something is better than nothing (perhaps?)
      }
    };

    // if the match is an array then perform an additional lookup
    // using the pluralization lookup rules from the pack
    if ( _.isArray( match ) ){
      // find either the indicated form, or the last form present if the proper
      // plural form is missing (because the translator didn't fill it out).
      var index = _.min([pack.pluralizer( _.isUndefined(args) ? 1 : args ), match.length-1 ]);
      match = match[ index ];
    }

    return this.sprintf.with_array( match, _.toArray( arguments ).slice(1) );

  };

  // export ourselves
  root.I18n = I18n;

})(this);
<|endoftext|>


<commit_before><commit_msg>Add the getFiles test suite<commit_after><|endoftext|>


<commit_before>import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { transform } from 'babel-core'
import babelPresetEs2015 from 'babel-preset-es2015'
import babelPresetReact from 'babel-preset-react'

class LivePreview extends Component {
  componentDidMount() {
    this.executeCode(this.props.code)
  }

  componentDidUpdate(prevProps) {
    if (this.props.code !== prevProps.code) {
      this.executeCode(this.props.code)
    }
  }

  compileCode(code) {
    return transform(
      code,
      { presets: [babelPresetEs2015, babelPresetReact] }
    ).code
  }

  executeCode(code) {
    // Remove previous result
    ReactDOM.unmountComponentAtNode(this.livePreview)

    try {
      const compiledCode = this.compileCode(code)
      // Prevent eval to touch global module and exports
      const execute = (0, eval)(`
        (function(module, exports, React) {
          ${compiledCode}
        })
      `)
      const privateModule = { exports: { } }
      execute(privateModule, privateModule.exports, React)
      const result = privateModule.exports.default

      ReactDOM.render(result, this.livePreview)
    } catch (err) {
      ReactDOM.render(

{err.toString()}
,
        this.livePreview
      )
    }
  }

  render() {
    return (

 { this.livePreview = ref }}>
        Live Preview

    )
  }
}

LivePreview.propTypes = {
  code: React.PropTypes.string.isRequired,
}

export default LivePreview
<commit_msg>Refact eval to function<commit_after>import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { transform } from 'babel-core'
import babelPresetEs2015 from 'babel-preset-es2015'
import babelPresetReact from 'babel-preset-react'

class LivePreview extends Component {
  componentDidMount() {
    this.executeCode(this.props.code)
  }

  componentDidUpdate(prevProps) {
    if (this.props.code !== prevProps.code) {
      this.executeCode(this.props.code)
    }
  }

  compileCode(code) {
    return transform(
      code,
      { presets: [babelPresetEs2015, babelPresetReact] }
    ).code
  }

  executeCode(code) {
    // Remove previous result
    ReactDOM.unmountComponentAtNode(this.livePreview)

    try {
      const compiledCode = this.compileCode(code)

      // Prevent eval to touch global module and exports
      const privateModule = { exports: { } }

      // Construct a function taking 3 params (module, exports, React) and will run compiledCode
      const execute = new Function(['module', 'exports', 'React'], compiledCode)

      // Run compiledCode with injected module, exports, and React
      execute(privateModule, privateModule.exports, React)

      // Code must end with 'export default <ReactClass />' for being rendered with ReactDOM
      const result = privateModule.exports.default

      ReactDOM.render(result, this.livePreview)
    } catch (err) {
      ReactDOM.render(

{err.toString()}
,
        this.livePreview
      )
    }
  }

  render() {
    return (

 { this.livePreview = ref }}>
        Live Preview

    )
  }
}

LivePreview.propTypes = {
  code: React.PropTypes.string.isRequired,
}

export default LivePreview
<|endoftext|>


<commit_before>
const RG = require('../../../client/src/battles');
const expect = require('chai').expect;
const TemplLevel = require('../../../client/src/template.level');

describe('Template.Level', () => {
    it('creates a 2-d map of the level', () => {
        const level = new TemplLevel(10, 7);

        RG.RAND.setSeed(new Date().getTime());

        level.setGenParams([1, 2, 1, 1]);
        level.setRoomCount(30);
        level.create();
        expect(Array.isArray(level.map)).to.be.true;

        console.log(JSON.stringify(level.map));
        RG.printMap(level.map);

    });
});
<commit_msg>Added new unit test.<commit_after>
const RG = require('../../../client/src/battles');
const expect = require('chai').expect;
const TemplLevel = require('../../../client/src/template.level');

const Castle = require('../../../client/data/tiles.castle');

describe('Template.Level', () => {
    it('creates a 2-d map of the level', () => {
        const level = new TemplLevel(10, 7);

        RG.RAND.setSeed(new Date().getTime());

        level.setGenParams([1, 2, 1, 1]);
        level.setRoomCount(30);
        level.create();
        expect(Array.isArray(level.map)).to.be.true;

        // console.log(JSON.stringify(level.map));
        RG.printMap(level.map);

    });

    /*
    it('can create 2-d castles', () => {
        const level = new TemplLevel(10, 7);
        RG.RAND.setSeed(new Date().getTime());

        level.setFiller(Castle.filler);
        level.setTemplates(Castle.templates);
        level.setConstraintFunc(Castle.constraintFunc);
        level.setGenParams([1, 2, 1, 1]);
        level.setRoomCount(30);
        level.create();

        RG.printMap(level.map);
    });
    */
});
<|endoftext|>