<commit_before>#!/usr/bin/env node

var path = require('path');
var fs = require('fs');
var pkg = require(path.join(__dirname,'package.json'));
var program = require ('commander');
var xml2js = require('xml2js');
var util = require('util');
var ini = require('ini');

/// DECLARATIONS //////////////////////////////////////////////////////////////

var wd 			= process.cwd();	// working directory default
var SP 			= '   ';
var num_webloc 	= 0;
var num_url 	= 0;

/// EXECUTION /////////////////////////////////////////////////////////////////

program
	.version(pkg.version)
	.usage('[<dir>]')
	.description('Scan the specified or current directory for .webloc and .url files, extract title and url, and emit a list.');

program
	.arguments('<dir>')
	.action(function( dir ) {
		wd = path.resolve(dir);	// note resolve already checks for cwd
	});

// execute the parser
program.parse(process.argv);

// read files non-recursively from working directory wd
fs.readdir( wd, function( err,files ) {
	if (err) throw new Error(err);
	console.log('Reading',files.length,'files...');
	files.forEach(function(name){
		var filePath = path.join(wd,name);
		var stats = fs.statSync(filePath);
		var out = '';
		if (stats.isFile()) ProcessFile(filePath, stats);
		console.log(out);
	});
	console.log('Found',num_webloc,'.webloc files and',num_url,'.url files');
});

/// SUPPORT FUNCTIONS /////////////////////////////////////////////////////////
///	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*/ given a valid filePath, determine if it's a file to parse of one of two
	XML types based on extension
/*/	function ProcessFile ( filePath, stats ) {
		switch (path.extname( filePath )) {
			case '.webloc': 	ParseDotWebloc( filePath, stats );
								break;
			case '.url': 		ParseDotUrl( filePath, stats );
								break;
			default: 			return;
		}
	}
///	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*/	Parse XML file in Webloc Format
/*/	function ParseDotWebloc ( filePath, stats ) {
		var parser = new xml2js.Parser();
		var data = fs.readFileSync(filePath,'utf8');
		parser.parseString( data, function( err, result ) {
			if (err) {
				console.log(filePath,'error',err);
				return;
			}
			var url = result.plist.dict[0].string[0];
			var birth = stats.birthtime;
			var mm = ("0"+(birth.getMonth()+1)).slice(-2);
			var dd = ("0"+birth.getDate()).slice(-2);
			var yyyy = birth.getFullYear();
			var date = yyyy+'/'+mm+'/'+dd;
			var out = '* '+date+' ['+path.basename(filePath,'.webloc')+']('+url+')';
			console.log(SO,out);
		});
		num_webloc++;
	}
///	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*/	Parse XML file in URL format
/*/	function ParseDotUrl ( filePath, stats ) {
		var result = ini.parse(fs.readFileSync(filePath,'utf-8'));
		var url = result.InternetShortcut.URL;
		var birth = stats.birthtime;
		var mm = ("0"+(birth.getMonth()+1)).slice(-2);
		var dd = ("0"+birth.getDate()).slice(-2);
		var yyyy = birth.getFullYear();
		var date = yyyy+'/'+mm+'/'+dd;
		var out = '* '+date+' ['+path.basename(filePath,'.url')+']('+url+')';
		console.log(out);
		num_url++;
	}
<commit_msg>remove typo causing crash<commit_after>#!/usr/bin/env node

var path = require('path');
var fs = require('fs');
var pkg = require(path.join(__dirname,'package.json'));
var program = require ('commander');
var xml2js = require('xml2js');
var util = require('util');
var ini = require('ini');

/// DECLARATIONS //////////////////////////////////////////////////////////////

var wd 			= process.cwd();	// working directory default
var SP 			= '   ';
var num_webloc 	= 0;
var num_url 	= 0;

/// EXECUTION /////////////////////////////////////////////////////////////////

program
	.version(pkg.version)
	.usage('[<dir>]')
	.description('Scan the specified or current directory for .webloc and .url files, extract title and url, and emit a list.');

program
	.arguments('<dir>')
	.action(function( dir ) {
		wd = path.resolve(dir);	// note resolve already checks for cwd
	});

// execute the parser
program.parse(process.argv);

// read files non-recursively from working directory wd
fs.readdir( wd, function( err,files ) {
	if (err) throw new Error(err);
	console.log('Reading',files.length,'files...');
	files.forEach(function(name){
		var filePath = path.join(wd,name);
		var stats = fs.statSync(filePath);
		var out = '';
		if (stats.isFile()) ProcessFile(filePath, stats);
		console.log(out);
	});
	console.log('Found',num_webloc,'.webloc files and',num_url,'.url files');
});

/// SUPPORT FUNCTIONS /////////////////////////////////////////////////////////
///	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*/ given a valid filePath, determine if it's a file to parse of one of two
	XML types based on extension
/*/	function ProcessFile ( filePath, stats ) {
		switch (path.extname( filePath )) {
			case '.webloc': 	ParseDotWebloc( filePath, stats );
								break;
			case '.url': 		ParseDotUrl( filePath, stats );
								break;
			default: 			return;
		}
	}
///	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*/	Parse XML file in Webloc Format
/*/	function ParseDotWebloc ( filePath, stats ) {
		var parser = new xml2js.Parser();
		var data = fs.readFileSync(filePath,'utf8');
		parser.parseString( data, function( err, result ) {
			if (err) {
				console.log(filePath,'error',err);
				return;
			}
			var url = result.plist.dict[0].string[0];
			var birth = stats.birthtime;
			var mm = ("0"+(birth.getMonth()+1)).slice(-2);
			var dd = ("0"+birth.getDate()).slice(-2);
			var yyyy = birth.getFullYear();
			var date = yyyy+'/'+mm+'/'+dd;
			var out = '* '+date+' ['+path.basename(filePath,'.webloc')+']('+url+')';
			console.log(out);
		});
		num_webloc++;
	}
///	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*/	Parse XML file in URL format
/*/	function ParseDotUrl ( filePath, stats ) {
		var result = ini.parse(fs.readFileSync(filePath,'utf-8'));
		var url = result.InternetShortcut.URL;
		var birth = stats.birthtime;
		var mm = ("0"+(birth.getMonth()+1)).slice(-2);
		var dd = ("0"+birth.getDate()).slice(-2);
		var yyyy = birth.getFullYear();
		var date = yyyy+'/'+mm+'/'+dd;
		var out = '* '+date+' ['+path.basename(filePath,'.url')+']('+url+')';
		console.log(out);
		num_url++;
	}
<|endoftext|>


<commit_before>// ==UserScript==
// @name         GitHub 汉化插件
// @description  汉化 GitHub 界面的部分菜单及内容。
// @copyright    2016, 楼教主 (http://www.52cik.com/)
// @icon         https://assets-cdn.github.com/pinned-octocat.svg
// @version      1.1.2
// @author       楼教主
// @license      MIT
// @homepageURL  https://github.com/52cik/github-hans
// @match        http://*github.com/*
// @match        https://*github.com/*
// @require      http://www.52cik.com/github-hans/locals.js?v1.1.2
// @run-at       document-end
// @grant        none
// ==/UserScript==

(function (window, document, undefined) {
    'use strict';

    // 要翻译的页面正则
    var page = document.body.className.match(I18N.conf.rePage);
    page = page ? page[1] : false;

    walk(document.body); // 立即翻译
    timeElement(); // 时间节点翻译

    $(document).ajaxComplete(function () {
        walk(document.body); // ajax 请求后再次翻译
    });

    function walk(node) {
        var nodes = node.childNodes;

        var i = 0;
        var len = nodes.length;
        var el = null; // 遍历元素用
        var attr; // 元素属性

        for (; i < len; i++) {
            el = nodes[i];

            if (el.nodeType === 1) {
                if (el.tagName === "INPUT") { // 输入框 按钮 处理
                    if (el.type === "button" || el.type === "submit") {
                        el.value = translate(el.value);
                    } else {
                        el.placeholder = translate(el.placeholder);
                    }
                } else if (attr = el.getAttribute('aria-label')) { // 带提示的元素，类似 tooltip 效果的
                    el.setAttribute('aria-label', translate(attr));

                    if (attr = el.getAttribute('data-copied-hint')) { // 复制成功提示
                        el.setAttribute('data-copied-hint', translate(attr));
                    }
                }

                // todo 的跳过 readme, 文件列表, 代码显示
                if (el.id !== 'readme' && !I18N.conf.reIgnore.test(el.className)) {
                    walk(el);
                }
            } else if (el.nodeType === 3) { // 文本节点处理
                el.data = translate(el.data);
            }
        }
    }

    function translate(data) { // 翻译
        var str;
        var _key = data.trim();

        if (_key === '') { return data; } // 空字符返回原始数据

        str = transPage('pubilc', _key); // 公共翻译
        if (str !== _key) { return str; } // 已公共翻译

        if (page === false) { return data; } // 未知页面不翻译

        str = transPage(page, _key); // 翻译已知页面
        return str === _key ? data : str; // 未翻译返回原始数据
    }

    function transPage(page, key) {
        var str, res, len, i;

        // 静态翻译
        str = I18N['zh'][page]['static'][key];
        if (str) { return str; }

        // 正则翻译
        if (res = I18N['zh'][page]['regexp']) {
            for (i = 0, len = res.length; i < len; i++) {
                str = key.replace(res[i][0], res[i][1]);
                if (str !== key) { return str; }
            }
        }

        return key; // 没有翻译条目
    }

    function timeElement () { // 时间节点翻译
        var RelativeTimeElement$getFormattedDate = RelativeTimeElement.prototype.getFormattedDate;
        var TimeAgoElement$getFormattedDate = TimeAgoElement.prototype.getFormattedDate;
        var LocalTimeElement$getFormattedDate = LocalTimeElement.prototype.getFormattedDate;

        var RelativeTime = function(str, el) { // 相对时间解析
            if (/^on ([\w ]+)$/.test(str)) {
                return '于 ' + el.title.replace(/ .+$/, '');
            }

            return str.replace(/just now|(an?|\d+) (second|minute|hour|day|month|year)s? ago/, function(m, d, t) {
                if (m === 'just now') { return '刚刚'; }

                if (d[0] === 'a') { d = '1'; } // a, an 修改为 1

                var dt = {second: '秒', minute: '分钟', hour: '小时', day: '天', month: '个月', year: '年'};

                return d + ' ' + dt[t] + '之前';
            });
        };

        RelativeTimeElement.prototype.getFormattedDate = function() {
            var str = RelativeTimeElement$getFormattedDate.call(this);
            return RelativeTime(str, this);
        };

        TimeAgoElement.prototype.getFormattedDate = function() {
            var str = TimeAgoElement$getFormattedDate.call(this);
            return RelativeTime(str, this);
        };

        LocalTimeElement.prototype.getFormattedDate = function() {
            return this.title.replace(/ .+$/, '');
        };

        // 遍历 time 元素进行翻译
        $('time').each(function (i, el) {
            if (el.getFormattedDate) { // 跳过未注册的 time 元素
                el.textContent = el.getFormattedDate();
            }
        });
    }

})(window, document);
<commit_msg>贡献部分基于事件翻译<commit_after>// ==UserScript==
// @name         GitHub 汉化插件
// @description  汉化 GitHub 界面的部分菜单及内容。
// @copyright    2016, 楼教主 (http://www.52cik.com/)
// @icon         https://assets-cdn.github.com/pinned-octocat.svg
// @version      1.2.0
// @author       楼教主
// @license      MIT
// @homepageURL  https://github.com/52cik/github-hans
// @match        http://*github.com/*
// @match        https://*github.com/*
// @require      http://www.52cik.com/github-hans/locals.js?v1.2.0
// @run-at       document-end
// @grant        none
// ==/UserScript==

(function (window, document, undefined) {
    'use strict';

    // 要翻译的页面正则
    var page = document.body.className.match(I18N.conf.rePage);
    page = page ? page[1] : false;

    timeElement(); // 时间节点翻译
    walk(document.body); // 立即翻译
    contributions(); // // 贡献日历 基于事件翻译

    $(document).ajaxComplete(function () {
        walk(document.body); // ajax 请求后再次翻译
    });

    function walk(node) {
        var nodes = node.childNodes;

        var i = 0;
        var len = nodes.length;
        var el = null; // 遍历元素用
        var attr; // 元素属性

        for (; i < len; i++) {
            el = nodes[i];

            if (el.nodeType === 1) {
                if (el.tagName === "INPUT") { // 输入框 按钮 处理
                    if (el.type === "button" || el.type === "submit") {
                        el.value = translate(el.value);
                    } else {
                        el.placeholder = translate(el.placeholder);
                    }
                } else if (attr = el.getAttribute('aria-label')) { // 带提示的元素，类似 tooltip 效果的
                    el.setAttribute('aria-label', translate(attr));

                    if (attr = el.getAttribute('data-copied-hint')) { // 复制成功提示
                        el.setAttribute('data-copied-hint', translate(attr));
                    }
                }

                // todo 的跳过 readme, 文件列表, 代码显示
                if (el.id !== 'readme' && !I18N.conf.reIgnore.test(el.className)) {
                    walk(el);
                }
            } else if (el.nodeType === 3) { // 文本节点处理
                el.data = translate(el.data);
            }
        }
    }

    function translate(data) { // 翻译
        var str;
        var _key = data.trim();

        if (_key === '') { return data; } // 空字符返回原始数据

        str = transPage('pubilc', _key); // 公共翻译
        if (str !== _key) { return str; } // 已公共翻译

        if (page === false) { return data; } // 未知页面不翻译

        str = transPage(page, _key); // 翻译已知页面
        return str === _key ? data : str; // 未翻译返回原始数据
    }

    function transPage(page, key) {
        var str, res, len, i;

        // 静态翻译
        str = I18N['zh'][page]['static'][key];
        if (str) { return str; }

        // 正则翻译
        if (res = I18N['zh'][page]['regexp']) {
            for (i = 0, len = res.length; i < len; i++) {
                str = key.replace(res[i][0], res[i][1]);
                if (str !== key) { return str; }
            }
        }

        return key; // 没有翻译条目
    }

    function timeElement () { // 时间节点翻译
        var RelativeTimeElement$getFormattedDate = RelativeTimeElement.prototype.getFormattedDate;
        var TimeAgoElement$getFormattedDate = TimeAgoElement.prototype.getFormattedDate;
        var LocalTimeElement$getFormattedDate = LocalTimeElement.prototype.getFormattedDate;

        var RelativeTime = function(str, el) { // 相对时间解析
            if (/^on ([\w ]+)$/.test(str)) {
                return '于 ' + el.title.replace(/ .+$/, '');
            }

            return str.replace(/just now|(an?|\d+) (second|minute|hour|day|month|year)s? ago/, function(m, d, t) {
                if (m === 'just now') { return '刚刚'; }

                if (d[0] === 'a') { d = '1'; } // a, an 修改为 1

                var dt = {second: '秒', minute: '分钟', hour: '小时', day: '天', month: '个月', year: '年'};

                return d + ' ' + dt[t] + '之前';
            });
        };

        RelativeTimeElement.prototype.getFormattedDate = function() {
            var str = RelativeTimeElement$getFormattedDate.call(this);
            return RelativeTime(str, this);
        };

        TimeAgoElement.prototype.getFormattedDate = function() {
            var str = TimeAgoElement$getFormattedDate.call(this);
            return RelativeTime(str, this);
        };

        LocalTimeElement.prototype.getFormattedDate = function() {
            return this.title.replace(/ .+$/, '');
        };

        // 遍历 time 元素进行翻译
        $('time').each(function (i, el) {
            if (el.getFormattedDate) { // 跳过未注册的 time 元素
                el.textContent = el.getFormattedDate();
            }
        });
    }

    function contributions() { // 贡献日历 基于事件翻译
        var tip = document.getElementsByClassName('svg-tip-one-line');

        setTimeout(function () {
            $('.js-calendar-graph').on('mouseover', '.day', function() {
                var $tip = $(tip);

                var str = $tip.text().trim().replace(/^(No|\d+) contributions? on (.+)$/, function(m, i, d) {
                    var str = '<strong>';
                    str += i === 'No' ? '无贡献' : (i + ' 次贡献');
                    str += '</strong> ';

                    var dt = new Date(d);
                    dt.setHours(dt.getHours() + 8); // 为了获取 +8 时区的 ISO 时间。
                    str += dt.toISOString().split('T')[0]; // 得到 yyyy-mm-dd 这样的格式

                    return str;
                });

                $tip.html(str);
                $tip.css('left', $(this).offset().left - tip[0].offsetWidth / 2 + 5.5);
            });
        }, 99);
    }

})(window, document);
<|endoftext|>


<commit_before>(function (window, undefined) {
    "use strict";

    // declare variables awaiting values
    let WPRDC_BASE_URL,
        WPRDC_META_URL,
        WPRDC_DATA_SOURCES,
        WPRDC_QUERY_PREFIX,
        WPRDC_QUERY_SUFFIX,
        PITT_LABS;

    // await those values
    window.addEventListener("dataready", function handler(event) {
        // assign the received values
        ({
            WPRDC_BASE_URL,
            WPRDC_META_URL,
            WPRDC_DATA_SOURCES,
            WPRDC_QUERY_PREFIX,
            WPRDC_QUERY_SUFFIX,
            PITT_LABS
        } = event.detail);

        // wait for these values before fetching dependant data
        fetchAllData();

        // need only assign values once
        window.removeEventListener("dataready", handler);
    });

    // Oakland Coordinates: 40.4388 N, 79.9514 W (40.4388, -79.9514)
    // Cathy Coordinates: 40° 26′ 39″ N, 79° 57′ 11″ W (40.444167, -79.953056)
    const cathyLatLong = [40.444167, -79.953056];
    const map = L.map("mapid", {
        center: cathyLatLong,
        zoom: 15,
        minZoom: 12,
        maxBounds: L.latLngBounds([40.65, -80.25], [40.25, -79.70]),
        maxBoundsViscosity: 0.90
    });

    const sidebar = document.getElementById("sidebar");
    const sidebarToggle = document.getElementById("sidebarToggle");

    //Start with sidebar closed if mobile
    if (screen.width <= 800) {
        sidebarToggle.open = 0;
        sidebar.className = "hidden";
        sidebarToggle.className = "fa fa-chevron-right fa-3x";
    } else {
        sidebarToggle.open = 1;
        sidebar.className = "shown";
        sidebarToggle.className = "fa fa-chevron-left fa-3x";
    }

    L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
        attribution: "© OpenStreetMap contributors"
    }).addTo(map);

    // Array of markers
    const markers = [];

    // Create a new Date object for the current date
    const currentDate = new Date();

    // The following are functions that display records created within 1, 7, and
    // 30 days respectively (assuming all fetched data has been pruned to the last
    // 30 days already)
    function displayPastDay() {
        markers.forEach((marker, i) => {
            //Check if library or other non-dated pin
            if (!marker.incidentYear || !marker.isMapped) {
                return;
            }

            const recordDate = new Date(marker.incidentYear,
                marker.incidentMonth - 1,
                marker.incidentDay);

            if (getDateDifference(currentDate, recordDate) <= 1) {
                marker.inDate = true;
                if (!marker.filtered) {
                    marker.pin.addTo(map);
                }
            } else {
                map.removeLayer(marker.pin);
                marker.inDate = false;
            }
        });
    }

    function displayPastWeek() {
        markers.forEach((marker, i) => {
            if (!marker.incidentYear || !marker.isMapped) {
                return;
            }

            const recordDate = new Date(marker.incidentYear,
                marker.incidentMonth - 1,
                marker.incidentDay);

            if (getDateDifference(currentDate, recordDate) <= 7) {
                marker.inDate = true;
                if (!marker.filtered) {
                    marker.pin.addTo(map);
                }
            } else {
                map.removeLayer(marker.pin);
                marker.inDate = false;
            }
        });
    }

    function displayPastMonth() {
        markers.forEach((marker, i) => {
            if (!marker.isMapped) {
                return;
            }

            marker.inDate = true;

            if (!marker.filtered) {
                marker.pin.addTo(map);
            }
        });
    }

    function filterDisplay(e) {
        const elm = e.target;
        const type = /.+?(?=[A-Z])/.exec(elm.id)[0];

        if (elm.checked) {
            markers.forEach((marker) => {
                if (marker.type === type && marker.isMapped) {
                    if (marker.inDate) {
                        marker.pin.addTo(map);
                    }
                    marker.filtered = false;
                }
            });
        } else {
            markers.forEach((marker) => {
                if (marker.type === type && marker.isMapped) {
                    map.removeLayer(marker.pin);
                    marker.filtered = true;
                }
            });
        }
    }

    //Displays and hides the sidebar
    function toggleSidebar() {
        if (sidebarToggle.open == 1) {
            sidebarToggle.open = 0;
            sidebar.className = "hidden";
            sidebarToggle.className = "fa fa-chevron-right fa-3x";
        } else {
            sidebarToggle.open = 1;
            sidebar.className = "shown";
            sidebarToggle.className = "fa fa-chevron-left fa-3x";
        }
    }

    //Listeners for date buttons
    document.getElementById("radioDay").addEventListener("click", displayPastDay);
    document.getElementById("radioWeek").addEventListener("click", displayPastWeek);
    document.getElementById("radioMonth").addEventListener("click", displayPastMonth);

    //Listener for sidebar toggle
    document.getElementById("sidebarToggle").addEventListener("click", toggleSidebar);

    // Display a notification to the user.
    // Style is optional, can be "error", "warning", or "success"
    function displayNotification(messageText, style, customHTML) {
        const notificationArea = document.getElementById("notifications");
        const box = document.createElement("div");
        box.className = "notification";

        if (style) {
            box.classList.add(style);
        }

        const closeButton = document.createElement("button");
        closeButton.className = "close";
        closeButton.innerHTML = "x";
        closeButton.addEventListener("click", function() {
            box.style.display = "none";
        });

        box.appendChild(closeButton);

        const textarea = document.createTextNode(messageText);
        box.appendChild(textarea);

        if (customHTML) {
            const customDiv = document.createElement("div");
            customHTML(customDiv);
            box.appendChild(customDiv);
        }

        const topNotification = notificationArea.firstChild;
        notificationArea.insertBefore(box, topNotification);
    }

    // Fetch data from West Pennsylvania Regional Data Center using the SQL API
    // TODO: Prune to last 30 days in SQL
    function fetchWPRDCData(dataSourceName, options={}) {
        const dataSource = WPRDC_DATA_SOURCES[dataSourceName];
        let query = WPRDC_QUERY_PREFIX + dataSource.id + WPRDC_QUERY_SUFFIX + dataSource.primaryFiltering;

        if (options.limit) {
          query += " LIMIT " + options.limit;
        }

        return fetch(WPRDC_BASE_URL + query)
            .then((response) => {
                // Inspired by https://github.com/github/fetch#handling-http-error-statuses
                if (response.status >= 200 && response.status < 300) {
                    return response.json();
                } else {
                  throw new Error(`Could not retrieve the ${dataSourceName} dataset; bad response.`);
                }
            })
            .then((data) => {
                if (!data || !data.result || !data.result.records) {
                    displayNotification(`${dataSourceName} records not processed.`, "error", (retryDiv) => {
                        const retryButton = document.createElement("button");
                        retryButton.innerHTML = "
 Retry
";
                        retryButton.type = "button";
                        retryButton.className = "retry";
                        retryButton.addEventListener("click", function() {
                            retryDiv.parentNode.style.display = "none";
                            fetchWPRDCData(dataSourceName);
                        });
                        retryDiv.appendChild(retryButton);
                    });
                    return;
                }

                const records = data.result.records;

                const filterContainer = document.createElement("div");
                filterContainer.className = "typeBtn";

                const filter = document.createElement("input");
                filter.id = dataSourceName.toLowerCase() + "Check";
                filter.type = "checkbox";
                filter.checked = true;

                const filterLabel = document.createElement("label");
                filterLabel.htmlFor = dataSourceName.toLowerCase() + "Check";
                filterLabel.innerHTML = dataSource.icon.options.html + " - " +
                    dataSourceName;

                filter.addEventListener("click", filterDisplay);

                document.getElementById("typeSelection").appendChild(filterContainer);
                filterContainer.appendChild(filter);
                filterContainer.appendChild(filterLabel);

                records.forEach((record, i) => {
                    if (dataSource.processRecord) {
                        dataSource.processRecord(record, i);
                    }

                    //Prune to last 30 days
                    if (record.incidentYear) {
                        if (getDateDifference(currentDate, new Date(record.incidentYear,
                            record.incidentMonth - 1,
                            record.incidentDay)) > 30) {
                                return;
                        }
                    }

                    record.inDate = true;
                    record.type = dataSourceName.toLowerCase();

                    const latLong = dataSource.latLong.map((fieldName) => record[fieldName]);
                    const latLongNoNulls = latLong.some((field) => !!field);

                    if (latLongNoNulls) {
                        const title = dataSource.title(record);
                        record.pin = L.marker(latLong, {
                            title: title,
                            icon: dataSource.icon
                        });

                        record.pin.bindPopup(dataSource.popup(record));
                        record.pin.addTo(map);

                        record.isMapped = true;
                    } else {
                        record.isMapped = false;
                    }
                    markers.push(record);
                });
            })
            .catch((err) => displayNotification(`Error: Public dataset ${dataSourceName} could not be retrieved`, "error", (retryDiv) => {
                const retryButton = document.createElement("button");
                retryButton.innerHTML = "
 Retry
";
                retryButton.type = "button";
                retryButton.className = "retry";
                retryButton.addEventListener("click", function() {
                    retryDiv.parentNode.style.display = "none";
                    fetchWPRDCData(dataSourceName);
                });
                retryDiv.appendChild(retryButton);
            }))
            .then(() => {
                return fetch(WPRDC_META_URL + dataSource.id)
                .then((response) => {
                    //check response for data and data for date
                    if (response.status >= 200 && response.status < 300) {
                        return response.json();
                    }
                })
                .then((metadata) => {
                    // Parse json for last modified field
                    var parsedDate = Date.parse(metadata.result.last_modified);

                    // Display a notification if the dataset has been updated within .updateTime
                    var diff = Date.now() - parsedDate;
                    if (diff <= dataSource.updateTime) {
                        displayNotification("The " + dataSourceName + " dataset has been recently updated.");
                    }
                });
           });
    }

    //Fetch data from Pitt using Ritwik Gupta's PittAPI and associated wrapper
    //May not need the "options" parameter, as I can't see any data request from Pitt being overwhelmingly large
    function fetchPittData(dataSection, dataSourceName, filterCreated, options = {}){
        if (dataSection == "Labs"){
            return fetch("http://securitas.cs.pitt.edu/lab_status/" + dataSourceName.toUpperCase())
            .then((response) => {
                // Inspired by https://github.com/github/fetch#handling-http-error-statuses
                if (response.status >= 200 && response.status < 300) {
                    return response;
                } else {
                    throw new Error(`Could not retrieve the ${dataSourceName} dataset; bad response.`);
                }
            })
            .then((response) => response.json())
            .then((data) => {
                if (!data) {
                    displayNotification(`${dataSourceName} records not processed.`, "error", (retryDiv) => {
                        const retryButton = document.createElement("button");
                        retryButton.innerHTML = "
 Retry
";
                        retryButton.type = "button";
                        retryButton.className = "retry";
                        retryButton.addEventListener("click", function() {
                            retryDiv.parentNode.style.display = "none";
                            fetchPittData(dataSourceName);
                        });
                        retryDiv.appendChild(retryButton);
                    });
                    return;
                }

                //Grab dataSource object
                const dataSource = PITT_LABS[dataSourceName];

                //If the checkbox has yet to be built for filtering the pins (only executes for first lab fetch)
                if (!filterCreated){
                    var filterContainer = document.createElement("div");
                    filterContainer.className = "typeBtn";

                    var filter = document.createElement("input");
                    filter.id = dataSection.toLowerCase() + "Check";
                    filter.type = "checkbox";
                    filter.checked = true;

                    var filterLabel = document.createElement("label");
                    filterLabel.htmlFor = dataSourceName.toLowerCase() + "Check";
                    filterLabel.innerHTML = dataSource.icon.options.html + " - " + dataSection;

                    filter.addEventListener("click", filterDisplay);

                    document.getElementById("typeSelection").appendChild(filterContainer);
                    filterContainer.appendChild(filter);
                    filterContainer.appendChild(filterLabel);
                }

                //Create pin object
                const thePin = L.marker(PITT_LABS[dataSourceName].latLong, {
                    title: dataSourceName,
                    icon: dataSource.icon
                });

                //Create popup
                var pup = L.popup();
                    pup.setContent("
 " + dataSourceName + " Lab
Status: " + data.status
                                 + "
 Macs available: " + data.mac
                                + "
 Windows available: " + data.windows
                                + "
 Linux available: " + data.linux + "
");

                //labRecord.popup = pup;
                //Bind popup to pin
                thePin.bindPopup(pup);
                //Add pin to map
                thePin.addTo(map);
                pup.isMapped = true;
                //Push pin (haha, get it?)
                markers.push({ //Push the following object onto the markers array
                    numWindows: data.windows,
                    numMac: data.mac,
                    numLinux: data.linux,
                    labStatus: data.status,
                    pin: thePin,
                    isMapped: true,
                    inDate: true, //Date is not important, but necessary for filtering for now
                    type: "labs"
                });
            })
            .catch((err) => displayNotification(`Error: Pitt dataset ${dataSourceName} could not be retrieved`, "error", (retryDiv) => {
                const retryButton = document.createElement("button");
                retryButton.innerHTML = "
 Retry
";
                retryButton.type = "button";
                retryButton.className = "retry";
                retryButton.addEventListener("click", function() {
                    retryDiv.parentNode.style.display = "none";
                    fetchPittData(dataSourceName);
                });
                retryDiv.appendChild(retryButton);
            }));
        }
    }

    function fetchAllData() {
        Promise.all([
            fetchWPRDCData("Police", { limit: 250 }),
            fetchWPRDCData("311", { limit: 250 }),
            fetchWPRDCData("Arrest", { limit: 250 }),
            fetchWPRDCData("Code Violation", { limit: 250 }),
            fetchWPRDCData("Library"),
            fetchWPRDCData("Non-Traffic Violation", { limit: 250 }),

            fetchPittData('Labs', 'Alumni', false),
            fetchPittData('Labs', 'Benedum', true),
            fetchPittData('Labs', 'Cath_G62', true),
            fetchPittData('Labs', 'Cath_G27', true),
            fetchPittData('Labs', 'Lawrence', true),
            fetchPittData('Labs', 'Hillman', true),
            fetchPittData('Labs', 'Suth', true)

        ]).catch((err) => {
            displayNotification(err, "error", (retryDiv) => {
                var retryButton = document.createElement("button");
                retryButton.innerHTML = "
 Retry
";
                retryButton.type = "button";
                retryButton.className = "retry";
                retryButton.addEventListener("click", function() {
                    retryDiv.parentNode.style.display = "none";
                    fetchAllData();
                });
                retryDiv.appendChild(retryButton);
            });
        });
    }

    //Helper function that returns difference between two dates in days
    function getDateDifference(dateA, dateB) {
        return Math.floor(Math.abs(dateA.getTime() - dateB.getTime()) / 86400000);
    }

})(typeof window !== "undefined" ? window : {});
<commit_msg>TODO get full lab URL<commit_after>(function (window, undefined) {
    "use strict";

    // declare variables awaiting values
    let WPRDC_BASE_URL,
        WPRDC_META_URL,
        WPRDC_DATA_SOURCES,
        WPRDC_QUERY_PREFIX,
        WPRDC_QUERY_SUFFIX,
        PITT_LABS;

    // await those values
    window.addEventListener("dataready", function handler(event) {
        // assign the received values
        ({
            WPRDC_BASE_URL,
            WPRDC_META_URL,
            WPRDC_DATA_SOURCES,
            WPRDC_QUERY_PREFIX,
            WPRDC_QUERY_SUFFIX,
            PITT_LABS
        } = event.detail);

        // wait for these values before fetching dependant data
        fetchAllData();

        // need only assign values once
        window.removeEventListener("dataready", handler);
    });

    // Oakland Coordinates: 40.4388 N, 79.9514 W (40.4388, -79.9514)
    // Cathy Coordinates: 40° 26′ 39″ N, 79° 57′ 11″ W (40.444167, -79.953056)
    const cathyLatLong = [40.444167, -79.953056];
    const map = L.map("mapid", {
        center: cathyLatLong,
        zoom: 15,
        minZoom: 12,
        maxBounds: L.latLngBounds([40.65, -80.25], [40.25, -79.70]),
        maxBoundsViscosity: 0.90
    });

    const sidebar = document.getElementById("sidebar");
    const sidebarToggle = document.getElementById("sidebarToggle");

    //Start with sidebar closed if mobile
    if (screen.width <= 800) {
        sidebarToggle.open = 0;
        sidebar.className = "hidden";
        sidebarToggle.className = "fa fa-chevron-right fa-3x";
    } else {
        sidebarToggle.open = 1;
        sidebar.className = "shown";
        sidebarToggle.className = "fa fa-chevron-left fa-3x";
    }

    L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
        attribution: "© OpenStreetMap contributors"
    }).addTo(map);

    // Array of markers
    const markers = [];

    // Create a new Date object for the current date
    const currentDate = new Date();

    // The following are functions that display records created within 1, 7, and
    // 30 days respectively (assuming all fetched data has been pruned to the last
    // 30 days already)
    function displayPastDay() {
        markers.forEach((marker, i) => {
            //Check if library or other non-dated pin
            if (!marker.incidentYear || !marker.isMapped) {
                return;
            }

            const recordDate = new Date(marker.incidentYear,
                marker.incidentMonth - 1,
                marker.incidentDay);

            if (getDateDifference(currentDate, recordDate) <= 1) {
                marker.inDate = true;
                if (!marker.filtered) {
                    marker.pin.addTo(map);
                }
            } else {
                map.removeLayer(marker.pin);
                marker.inDate = false;
            }
        });
    }

    function displayPastWeek() {
        markers.forEach((marker, i) => {
            if (!marker.incidentYear || !marker.isMapped) {
                return;
            }

            const recordDate = new Date(marker.incidentYear,
                marker.incidentMonth - 1,
                marker.incidentDay);

            if (getDateDifference(currentDate, recordDate) <= 7) {
                marker.inDate = true;
                if (!marker.filtered) {
                    marker.pin.addTo(map);
                }
            } else {
                map.removeLayer(marker.pin);
                marker.inDate = false;
            }
        });
    }

    function displayPastMonth() {
        markers.forEach((marker, i) => {
            if (!marker.isMapped) {
                return;
            }

            marker.inDate = true;

            if (!marker.filtered) {
                marker.pin.addTo(map);
            }
        });
    }

    function filterDisplay(e) {
        const elm = e.target;
        const type = /.+?(?=[A-Z])/.exec(elm.id)[0];

        if (elm.checked) {
            markers.forEach((marker) => {
                if (marker.type === type && marker.isMapped) {
                    if (marker.inDate) {
                        marker.pin.addTo(map);
                    }
                    marker.filtered = false;
                }
            });
        } else {
            markers.forEach((marker) => {
                if (marker.type === type && marker.isMapped) {
                    map.removeLayer(marker.pin);
                    marker.filtered = true;
                }
            });
        }
    }

    //Displays and hides the sidebar
    function toggleSidebar() {
        if (sidebarToggle.open == 1) {
            sidebarToggle.open = 0;
            sidebar.className = "hidden";
            sidebarToggle.className = "fa fa-chevron-right fa-3x";
        } else {
            sidebarToggle.open = 1;
            sidebar.className = "shown";
            sidebarToggle.className = "fa fa-chevron-left fa-3x";
        }
    }

    //Listeners for date buttons
    document.getElementById("radioDay").addEventListener("click", displayPastDay);
    document.getElementById("radioWeek").addEventListener("click", displayPastWeek);
    document.getElementById("radioMonth").addEventListener("click", displayPastMonth);

    //Listener for sidebar toggle
    document.getElementById("sidebarToggle").addEventListener("click", toggleSidebar);

    // Display a notification to the user.
    // Style is optional, can be "error", "warning", or "success"
    function displayNotification(messageText, style, customHTML) {
        const notificationArea = document.getElementById("notifications");
        const box = document.createElement("div");
        box.className = "notification";

        if (style) {
            box.classList.add(style);
        }

        const closeButton = document.createElement("button");
        closeButton.className = "close";
        closeButton.innerHTML = "x";
        closeButton.addEventListener("click", function() {
            box.style.display = "none";
        });

        box.appendChild(closeButton);

        const textarea = document.createTextNode(messageText);
        box.appendChild(textarea);

        if (customHTML) {
            const customDiv = document.createElement("div");
            customHTML(customDiv);
            box.appendChild(customDiv);
        }

        const topNotification = notificationArea.firstChild;
        notificationArea.insertBefore(box, topNotification);
    }

    // Fetch data from West Pennsylvania Regional Data Center using the SQL API
    // TODO: Prune to last 30 days in SQL
    function fetchWPRDCData(dataSourceName, options={}) {
        const dataSource = WPRDC_DATA_SOURCES[dataSourceName];
        let query = WPRDC_QUERY_PREFIX + dataSource.id + WPRDC_QUERY_SUFFIX + dataSource.primaryFiltering;

        if (options.limit) {
          query += " LIMIT " + options.limit;
        }

        return fetch(WPRDC_BASE_URL + query)
            .then((response) => {
                // Inspired by https://github.com/github/fetch#handling-http-error-statuses
                if (response.status >= 200 && response.status < 300) {
                    return response.json();
                } else {
                  throw new Error(`Could not retrieve the ${dataSourceName} dataset; bad response.`);
                }
            })
            .then((data) => {
                if (!data || !data.result || !data.result.records) {
                    displayNotification(`${dataSourceName} records not processed.`, "error", (retryDiv) => {
                        const retryButton = document.createElement("button");
                        retryButton.innerHTML = "
 Retry
";
                        retryButton.type = "button";
                        retryButton.className = "retry";
                        retryButton.addEventListener("click", function() {
                            retryDiv.parentNode.style.display = "none";
                            fetchWPRDCData(dataSourceName);
                        });
                        retryDiv.appendChild(retryButton);
                    });
                    return;
                }

                const records = data.result.records;

                const filterContainer = document.createElement("div");
                filterContainer.className = "typeBtn";

                const filter = document.createElement("input");
                filter.id = dataSourceName.toLowerCase() + "Check";
                filter.type = "checkbox";
                filter.checked = true;

                const filterLabel = document.createElement("label");
                filterLabel.htmlFor = dataSourceName.toLowerCase() + "Check";
                filterLabel.innerHTML = dataSource.icon.options.html + " - " +
                    dataSourceName;

                filter.addEventListener("click", filterDisplay);

                document.getElementById("typeSelection").appendChild(filterContainer);
                filterContainer.appendChild(filter);
                filterContainer.appendChild(filterLabel);

                records.forEach((record, i) => {
                    if (dataSource.processRecord) {
                        dataSource.processRecord(record, i);
                    }

                    //Prune to last 30 days
                    if (record.incidentYear) {
                        if (getDateDifference(currentDate, new Date(record.incidentYear,
                            record.incidentMonth - 1,
                            record.incidentDay)) > 30) {
                                return;
                        }
                    }

                    record.inDate = true;
                    record.type = dataSourceName.toLowerCase();

                    const latLong = dataSource.latLong.map((fieldName) => record[fieldName]);
                    const latLongNoNulls = latLong.some((field) => !!field);

                    if (latLongNoNulls) {
                        const title = dataSource.title(record);
                        record.pin = L.marker(latLong, {
                            title: title,
                            icon: dataSource.icon
                        });

                        record.pin.bindPopup(dataSource.popup(record));
                        record.pin.addTo(map);

                        record.isMapped = true;
                    } else {
                        record.isMapped = false;
                    }
                    markers.push(record);
                });
            })
            .catch((err) => displayNotification(`Error: Public dataset ${dataSourceName} could not be retrieved`, "error", (retryDiv) => {
                const retryButton = document.createElement("button");
                retryButton.innerHTML = "
 Retry
";
                retryButton.type = "button";
                retryButton.className = "retry";
                retryButton.addEventListener("click", function() {
                    retryDiv.parentNode.style.display = "none";
                    fetchWPRDCData(dataSourceName);
                });
                retryDiv.appendChild(retryButton);
            }))
            .then(() => {
                return fetch(WPRDC_META_URL + dataSource.id)
                .then((response) => {
                    //check response for data and data for date
                    if (response.status >= 200 && response.status < 300) {
                        return response.json();
                    }
                })
                .then((metadata) => {
                    // Parse json for last modified field
                    var parsedDate = Date.parse(metadata.result.last_modified);

                    // Display a notification if the dataset has been updated within .updateTime
                    var diff = Date.now() - parsedDate;
                    if (diff <= dataSource.updateTime) {
                        displayNotification("The " + dataSourceName + " dataset has been recently updated.");
                    }
                });
           });
    }

    //Fetch data from Pitt using Ritwik Gupta's PittAPI and associated wrapper
    //May not need the "options" parameter, as I can't see any data request from Pitt being overwhelmingly large
    function fetchPittData(dataSection, dataSourceName, filterCreated, options = {}){
        if (dataSection == "Labs"){

            //TODO: GET THE FULL URL WHEN THE SERVER IS UP |
            //                                             V
            return fetch("http://securitas.cs.pitt.edu/something/lab_status/" + dataSourceName.toUpperCase())
            .then((response) => {
                // Inspired by https://github.com/github/fetch#handling-http-error-statuses
                if (response.status >= 200 && response.status < 300) {
                    return response;
                } else {
                    throw new Error(`Could not retrieve the ${dataSourceName} dataset; bad response.`);
                }
            })
            .then((response) => response.json())
            .then((data) => {
                if (!data) {
                    displayNotification(`${dataSourceName} records not processed.`, "error", (retryDiv) => {
                        const retryButton = document.createElement("button");
                        retryButton.innerHTML = "
 Retry
";
                        retryButton.type = "button";
                        retryButton.className = "retry";
                        retryButton.addEventListener("click", function() {
                            retryDiv.parentNode.style.display = "none";
                            fetchPittData(dataSourceName);
                        });
                        retryDiv.appendChild(retryButton);
                    });
                    return;
                }

                //Grab dataSource object
                const dataSource = PITT_LABS[dataSourceName];

                //If the checkbox has yet to be built for filtering the pins (only executes for first lab fetch)
                if (!filterCreated){
                    var filterContainer = document.createElement("div");
                    filterContainer.className = "typeBtn";

                    var filter = document.createElement("input");
                    filter.id = dataSection.toLowerCase() + "Check";
                    filter.type = "checkbox";
                    filter.checked = true;

                    var filterLabel = document.createElement("label");
                    filterLabel.htmlFor = dataSourceName.toLowerCase() + "Check";
                    filterLabel.innerHTML = dataSource.icon.options.html + " - " + dataSection;

                    filter.addEventListener("click", filterDisplay);

                    document.getElementById("typeSelection").appendChild(filterContainer);
                    filterContainer.appendChild(filter);
                    filterContainer.appendChild(filterLabel);
                }

                //Create pin object
                const thePin = L.marker(PITT_LABS[dataSourceName].latLong, {
                    title: dataSourceName,
                    icon: dataSource.icon
                });

                //Create popup
                var pup = L.popup();
                    pup.setContent("
 " + dataSourceName + " Lab
Status: " + data.status
                                 + "
 Macs available: " + data.mac
                                + "
 Windows available: " + data.windows
                                + "
 Linux available: " + data.linux + "
");

                //labRecord.popup = pup;
                //Bind popup to pin
                thePin.bindPopup(pup);
                //Add pin to map
                thePin.addTo(map);
                pup.isMapped = true;
                //Push pin (haha, get it?)
                markers.push({ //Push the following object onto the markers array
                    numWindows: data.windows,
                    numMac: data.mac,
                    numLinux: data.linux,
                    labStatus: data.status,
                    pin: thePin,
                    isMapped: true,
                    inDate: true, //Date is not important, but necessary for filtering for now
                    type: "labs"
                });
            })
            .catch((err) => displayNotification(`Error: Pitt dataset ${dataSourceName} could not be retrieved`, "error", (retryDiv) => {
                const retryButton = document.createElement("button");
                retryButton.innerHTML = "
 Retry
";
                retryButton.type = "button";
                retryButton.className = "retry";
                retryButton.addEventListener("click", function() {
                    retryDiv.parentNode.style.display = "none";
                    fetchPittData(dataSourceName);
                });
                retryDiv.appendChild(retryButton);
            }));
        }
    }

    function fetchAllData() {
        Promise.all([
            fetchWPRDCData("Police", { limit: 250 }),
            fetchWPRDCData("311", { limit: 250 }),
            fetchWPRDCData("Arrest", { limit: 250 }),
            fetchWPRDCData("Code Violation", { limit: 250 }),
            fetchWPRDCData("Library"),
            fetchWPRDCData("Non-Traffic Violation", { limit: 250 }),

            fetchPittData('Labs', 'Alumni', false),
            fetchPittData('Labs', 'Benedum', true),
            fetchPittData('Labs', 'Cath_G62', true),
            fetchPittData('Labs', 'Cath_G27', true),
            fetchPittData('Labs', 'Lawrence', true),
            fetchPittData('Labs', 'Hillman', true),
            fetchPittData('Labs', 'Suth', true)

        ]).catch((err) => {
            displayNotification(err, "error", (retryDiv) => {
                var retryButton = document.createElement("button");
                retryButton.innerHTML = "
 Retry
";
                retryButton.type = "button";
                retryButton.className = "retry";
                retryButton.addEventListener("click", function() {
                    retryDiv.parentNode.style.display = "none";
                    fetchAllData();
                });
                retryDiv.appendChild(retryButton);
            });
        });
    }

    //Helper function that returns difference between two dates in days
    function getDateDifference(dateA, dateB) {
        return Math.floor(Math.abs(dateA.getTime() - dateB.getTime()) / 86400000);
    }

})(typeof window !== "undefined" ? window : {});
<|endoftext|>


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

    // cache DOM elements
    var errorListNode = document.getElementById('error-list');
    var outputNode;
    var iframeWindow;

    /**
     * The `getJSON` success callback.
     *
     * @callback xhrCallback
     * @param {Object} The JSON response.
     */

    /**
     * Gets JSON from url.
     *
     * @param {String} url - The url.
     * @param {xhrCallback} callback - The callback that handles the response.
     */
    function getJSON(url, callback) {
        // http://youmightnotneedjquery.com/#json
        var request = new XMLHttpRequest();
        request.open('GET', url, true);

        request.onreadystatechange = function() {
            if (this.readyState === 4) {
                if (this.status >= 200 && this.status < 400) {
                    callback(JSON.parse(this.responseText));
                } else {
                    // todo: handle error
                }
            }
        };

        request.send();
        request = null;
    }

    /**
     * Initializes iframe window and document for level output.
     *
     * @param {HTMLElement} node - The DOM node, which can be an iframe.
     * @param {Array} dependencies - The script dependencies for the iframe head.
     * @return {Window} - The iframe window object.
     */
    function initializeIframe(node, dependencies) {
        var iframe = node;

        // use iframe node or create and append an iframe into node
        if (iframe.nodeName !== 'IFRAME') {
            iframe = document.createElement('iframe');
            node.appendChild(iframe);
        }

        // get iframe window
        iframeWindow = iframe.contentWindow || iframe;

        // construct iframe document
        iframeWindow.document.open();
        var url, extension;
        var html = [''];
        for (var i = 0, l = dependencies.length; i < l; i++) {
            url = dependencies[i];
            extension = url.split('.').pop().toLowerCase();
            if (extension === 'js') {
                html.push('');
            } else if (extension === 'css') {
                html.push('<link rel="stylesheet" href="' + url + '" />');
            }
        }
        html.push('');
        iframeWindow.document.write(html.join(''));
        iframeWindow.document.close();

        return iframeWindow;
    }

    // todo: get script dependencies from JSON
    var dependencies = [
        '//cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js',
        '//cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js',
        '//cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js'
    ];

    iframeWindow = initializeIframe(
        document.getElementById('output'),
        dependencies
    );

    // iframe onload
    iframeWindow.onload = function() {
        outputNode = iframeWindow.document.body;
        renderOutput(editor.getValue(), outputNode, errorListNode);
    };

    // initialize editor
    var ace = window.ace;
    var Range = ace.require('ace/range').Range;
    var editor = ace.edit('editor');
    var session  = editor.getSession();
    // todo: get allowed lines from JSON
    var allowedLines = [3];

    editor.setTheme('ace/theme/monokai');
    session.setMode('ace/mode/jsx');

    // todo: get code from JSON
    var code = (
        'var Component = React.createClass({\n\t' +
        'render: function() {\n\t\treturn;\n\t}\n});' +
        '\n\nReactDOM.render(<Component />, document.body);'
    );

    editor.insert(code);

    var range = new Range();
    range.setStart(allowedLines[0] - 1, 0);
    range.setEnd(allowedLines[0] - 1, 80);
    session.addMarker(range, "editable-highlight");

    // prevent passing event key if the cursor line does not meet our criteria
    editor.keyBinding.addKeyboardHandler({
        handleKeyboard: function(data, hash, keyString, keyCode, event) {
            if (hash === -1 || (keyCode <= 40 && keyCode >= 37)) {
                return false;
            }

            if (!intersects(editor, range)) {
                return {
                    command: 'null',
                    passEvent: false
                };
            }
        }
    });

    // refresh on change
    // todo: get expected output from JSON
    editor.on('change', window._.debounce(function() {
         onEditorChange(editor.getValue(), 'Hello World!', outputNode, errorListNode);
    }, 500));

    /**
     * Refreshes Ace editor on change.
     *
     * @param {String} editorValue - The editor value.
     * @param {String} expectedOutput - The expected output.
     * @param {HTMLElement} outputNode - The output DOM element.
     * @param {HTMLElement} errorListNode - The error list DOM element.
     */
    function onEditorChange(editorValue, expectedOutput, outputNode, errorListNode) {
        var errorContainerNode = errorListNode.parentNode;
        errorListNode.innerHTML = '';
        renderOutput(editorValue, outputNode, errorListNode);
        // todo: hardcode expected output for now
        validateOutput(editorValue, outputNode.innerHTML, expectedOutput);
        console.log(errorListNode.innerHTML.length);

        if (errorListNode.innerHTML.length < 1) {
            errorContainerNode.classList.remove('hide');
            errorContainerNode.classList.add('hide');
        } else {
            errorContainerNode.classList.remove('hide');
        }
    }

    /**
     * Checks to see if current selection matches range.
     *
     * @param {Object} editor - The Ace editor.
     * @param {Object} range - The Ace range.
     * @return {Boolean}
     */
    function intersects(editor, range) {
        return editor.getSelectionRange().intersects(range);
    }

    /**
     * Renders the editor output.
     *
     * @param {String} editorValue - The editor value.
     * @param {HTMLElement} outputNode - The output DOM element.
     * @param {HTMLElement} errorListNode - The error list DOM element.
     */
    function renderOutput(editorValue, outputNode, errorListNode) {
        try {
            // todo: use test case from JSON
            var transpiledCode = iframeWindow.babel.transform(editorValue).code;

            // run the transpiled code
            iframeWindow.eval(transpiledCode);

        } catch (e) {
            var errorElement = document.createElement('li');
            errorElement.innerHTML = '' + ' ' + e + '';
            errorListNode.appendChild(errorElement);
        }
    }

    /**
     * Validates the editor output.
     *
     * @param {String} editorValue - The editor value.
     * @param {String} outputHTML - The inner HTML of the output DOM element.
     * @param {String} expectedOutput - The expected output.
     */
     function validateOutput(editorValue, outputHTML, expectedOutput) {
        // if answer is correct alert us
        if (outputHTML.indexOf(expectedOutput) >= 0) {
            alert('You got it!');
        }
     }
})();
<commit_msg>Begin refactoring main to use level.json config<commit_after>(function(){
    'use strict';

    // cache DOM elements
    var errorListNode = document.getElementById('error-list');
    var outputNode;
    var iframeWindow;

    /**
     * The `getJSON` success callback.
     *
     * @callback xhrCallback
     * @param {Object} The JSON response.
     */

    /**
     * Gets JSON from url.
     *
     * @param {String} url - The url.
     * @param {xhrCallback} callback - The callback that handles the response.
     */
    function getJSON(url, callback) {
        // http://youmightnotneedjquery.com/#json
        var request = new XMLHttpRequest();
        request.open('GET', url, true);

        request.onreadystatechange = function() {
            if (this.readyState === 4) {
                if (this.status >= 200 && this.status < 400) {
                    callback(JSON.parse(this.responseText));
                } else {
                    // todo: handle error
                }
            }
        };

        request.send();
        request = null;
    }

    /**
     * Initializes iframe window and document for level output.
     *
     * @param {HTMLElement} node - The DOM node, which can be an iframe.
     * @param {Array} dependencies - The script dependencies for the iframe head.
     * @return {Window} - The iframe window object.
     */
    function initializeIframe(node, dependencies) {
        var iframe = node;

        // use iframe node or create and append an iframe into node
        if (iframe.nodeName !== 'IFRAME') {
            iframe = document.createElement('iframe');
            node.appendChild(iframe);
        }

        // get iframe window
        iframeWindow = iframe.contentWindow || iframe;

        // construct iframe document
        iframeWindow.document.open();
        var url, extension;
        var html = [''];
        for (var i = 0, l = dependencies.length; i < l; i++) {
            url = dependencies[i];
            extension = url.split('.').pop().toLowerCase();
            if (extension === 'js') {
                html.push('');
            } else if (extension === 'css') {
                html.push('<link rel="stylesheet" href="' + url + '" />');
            }
        }
        html.push('');
        iframeWindow.document.write(html.join(''));
        iframeWindow.document.close();

        return iframeWindow;
    }

    // initialize editor
    var ace = window.ace;
    var Range = ace.require('ace/range').Range;
    var editor = ace.edit('editor');
    var session  = editor.getSession();
    editor.setTheme('ace/theme/monokai');

    // get level JSON
    getJSON('./level.json', function(res) {
        session.setMode('ace/mode/' + res.editor_mode);

        var iframeWindow = initializeIframe(
            document.getElementById('output'),
            res.dependencies || []
        );

        // iframe onload
        iframeWindow.onload = function() {
            outputNode = iframeWindow.document.body;
            renderOutput(editor.getValue(), outputNode, errorListNode);
        };

        // editor range
        var range = new Range();
        // todo: update for more than one allowed line
        range.setStart(res.editor_allowed_lines[0] - 1, 0);
        range.setEnd(res.editor_allowed_lines[0] - 1, 80);
        session.addMarker(range, 'editable-highlight');

        // prevent passing event key if the cursor line does not meet our criteria
        editor.keyBinding.addKeyboardHandler({
            handleKeyboard: function(data, hash, keyString, keyCode, event) {
                if (hash === -1 || (keyCode <= 40 && keyCode >= 37)) {
                    return false;
                }

                if (!intersects(editor, range)) {
                    return {
                        command: 'null',
                        passEvent: false
                    };
                }
            }
        });

        // insert level code into editor
        editor.insert(res.code);

        // refresh on change
        editor.on('change', window._.debounce(function() {
             onEditorChange(editor.getValue(), 'Hello World!', outputNode, errorListNode);
        }, 500));

    });

    /**
     * Refreshes Ace editor on change.
     *
     * @param {String} editorValue - The editor value.
     * @param {String} expectedOutput - The expected output.
     * @param {HTMLElement} outputNode - The output DOM element.
     * @param {HTMLElement} errorListNode - The error list DOM element.
     */
    function onEditorChange(editorValue, expectedOutput, outputNode, errorListNode) {
        var errorContainerNode = errorListNode.parentNode;
        errorListNode.innerHTML = '';
        renderOutput(editorValue, outputNode, errorListNode);
        // todo: hardcode expected output for now
        validateOutput(editorValue, outputNode.innerHTML, expectedOutput);

        if (errorListNode.innerHTML.length < 1) {
            errorContainerNode.classList.remove('hide');
            errorContainerNode.classList.add('hide');
        } else {
            errorContainerNode.classList.remove('hide');
        }
    }

    /**
     * Checks to see if current selection matches range.
     *
     * @param {Object} editor - The Ace editor.
     * @param {Object} range - The Ace range.
     * @return {Boolean}
     */
    function intersects(editor, range) {
        return editor.getSelectionRange().intersects(range);
    }

    /**
     * Renders the editor output.
     *
     * @param {String} editorValue - The editor value.
     * @param {HTMLElement} outputNode - The output DOM element.
     * @param {HTMLElement} errorListNode - The error list DOM element.
     */
    function renderOutput(editorValue, outputNode, errorListNode) {
        try {
            // todo: use test case from JSON
            var transpiledCode = iframeWindow.babel.transform(editorValue).code;

            // run the transpiled code
            iframeWindow.eval(transpiledCode);

        } catch (e) {
            var errorElement = document.createElement('li');
            errorElement.innerHTML = '' + ' ' + e + '';
            errorListNode.appendChild(errorElement);
        }
    }

    /**
     * Validates the editor output.
     *
     * @param {String} editorValue - The editor value.
     * @param {String} outputHTML - The inner HTML of the output DOM element.
     * @param {String} expectedOutput - The expected output.
     */
     function validateOutput(editorValue, outputHTML, expectedOutput) {
        // if answer is correct alert us
        if (outputHTML.indexOf(expectedOutput) >= 0) {
            alert('You got it!');
        }
     }
})();
<|endoftext|>


<commit_before>/**
 * Your eyes will thank me
 * Sleepy mode.
 */

var d = document.documentElement,
    t = document.querySelectorAll(".js-toggle-lights")[0],
    l = document.querySelectorAll(".site-description")[0],
    m = localStorage.getItem("nightmode"),
    l1 = "Ubuntu experience.",
    l2 = "Ubuntu experience. Sleep mode.";

if(m == "true") {
  d.classList.add("night-mode");
  l.textContent = l2;
}

t.addEventListener("click", function(){
  if(d.classList.contains("night-mode")) {
    d.classList.remove("night-mode");
    localStorage.setItem("nightmode", "false");
    l.textContent = l1;
  } else {
    d.classList.add("night-mode");
    localStorage.setItem("nightmode", "true");
    l.textContent = l2;
  }
});

/**
 * Timing is everything
 */

function timeAgo(time){
    var units = [
    { name: "second", limit: 60, in_seconds: 1 },
    { name: "minute", limit: 3600, in_seconds: 60 },
    { name: "hour", limit: 86400, in_seconds: 3600 },
    { name: "day", limit: 604800, in_seconds: 86400 },
    { name: "week", limit: 2629743, in_seconds: 604800 },
    { name: "month", limit: 31556926, in_seconds: 2629743 },
    { name: "year", limit: null, in_seconds: 31556926 }
    ];
    var diff = (new Date() - new Date(time*1000)) / 1000;
    if (diff < 5) return "now";
    var i = 0;
    var unit = null;

    while ((unit = units[i++]) !== null) {
      if (diff < unit.limit || !unit.limit){
        diff = Math.floor(diff / unit.in_seconds);
        return diff + " " + unit.name + (diff>1 ? "s" : "") + " old";
      }
    }
}

function toTimestamp(dateString){
  dateString = dateString.split('-').join('/');

  var date = new Date(dateString);
  valid = !isNaN(date.valueOf());

  if(valid === true){
      date = (date.getTime() / 1000).toFixed(0);
      date = timeAgo(date);
  }else{
      date = dateString;
  }
  return date;
}

/**
 * In Real Life
 * Quantified Self
 */

if (sessionStorage.irl) {
        document.getElementById('irl').innerHTML = sessionStorage.irl;
} else {
      var al = function(data) {
            var activity = parseInt(data.googlefit.steps);
            if(activity > 10) activity = "I've made " + activity.toLocaleString() + " steps today and"; else activity = "I'm either sleeping or working. Most likely <s>working</s> sleeping.";
            var irl = activity + " I spent over " + data.health.age.days.toLocaleString() + " days on Earth, my heart beat rate is " + data.googlefit.heartRate.bpm + " bpm measured " + timeAgo(data.googlefit.heartRate.timestamp) + ".";
            document.getElementById('irl').innerHTML = irl;
            sessionStorage.irl = irl;
      };

        var alt = document.createElement('script'); alt.type = 'text/javascript'; alt.async = true;
        alt.src = "http://track.andreiluca.com/api/?callback=al";
        var s = document.getElementsByTagName('script')[0];
        // s.parentNode.insertBefore(alt, s);
        document.body.appendChild(alt);
};

/**
 * Jekyll Search
 * https://github.com/christian-fei/Simple-Jekyll-Search
 */

!function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){module.exports=function(){function receivedResponse(xhr){return 200==xhr.status&&4==xhr.readyState}function handleResponse(xhr,callback){xhr.onreadystatechange=function(){if(receivedResponse(xhr))try{callback(null,JSON.parse(xhr.responseText))}catch(err){callback(err,null)}}}var self=this;self.load=function(location,callback){var xhr=window.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP");xhr.open("GET",location,!0),handleResponse(xhr,callback),xhr.send()}}},{}],2:[function(require,module,exports){function FuzzySearchStrategy(){function createFuzzyRegExpFromString(string){return new RegExp(string.split("").join(".*?"),"gi")}var self=this;self.matches=function(string,crit){return"string"!=typeof string?!1:(string=string.trim(),!!string.match(createFuzzyRegExpFromString(crit)))}}module.exports=new FuzzySearchStrategy},{}],3:[function(require,module,exports){function LiteralSearchStrategy(){function doMatch(string,crit){return string.toLowerCase().indexOf(crit.toLowerCase())>=0}var self=this;self.matches=function(string,crit){return"string"!=typeof string?!1:(string=string.trim(),doMatch(string,crit))}}module.exports=new LiteralSearchStrategy},{}],4:[function(require,module,exports){module.exports=function(){function findMatches(store,crit,strategy){for(var data=store.get(),i=0;i<data.length&&matches.length<limit;i++)findMatchesInObject(data[i],crit,strategy);return matches}function findMatchesInObject(obj,crit,strategy){for(var key in obj)if(strategy.matches(obj[key],crit)){matches.push(obj);break}}function getSearchStrategy(){return fuzzy?fuzzySearchStrategy:literalSearchStrategy}var self=this,matches=[],fuzzy=!1,limit=10,fuzzySearchStrategy=require("./SearchStrategies/fuzzy"),literalSearchStrategy=require("./SearchStrategies/literal");self.setFuzzy=function(_fuzzy){fuzzy=!!_fuzzy},self.setLimit=function(_limit){limit=parseInt(_limit,10)||limit},self.search=function(data,crit){return crit?(matches.length=0,findMatches(data,crit,getSearchStrategy())):[]}}},{"./SearchStrategies/fuzzy":2,"./SearchStrategies/literal":3}],5:[function(require,module,exports){module.exports=function(_store){function isObject(obj){return!!obj&&"[object Object]"==Object.prototype.toString.call(obj)}function isArray(obj){return!!obj&&"[object Array]"==Object.prototype.toString.call(obj)}function addObject(data){return store.push(data),data}function addArray(data){for(var added=[],i=0;i<data.length;i++)isObject(data[i])&&added.push(addObject(data[i]));return added}var self=this,store=[];isArray(_store)&&addArray(_store),self.clear=function(){return store.length=0,store},self.get=function(){return store},self.put=function(data){return isObject(data)?addObject(data):isArray(data)?addArray(data):void 0}}},{}],6:[function(require,module,exports){module.exports=function(){var self=this,templatePattern=/\{(.*?)\}/g;self.setTemplatePattern=function(newTemplatePattern){templatePattern=newTemplatePattern},self.render=function(t,data){return t.replace(templatePattern,function(match,prop){return data[prop]||match})}}},{}],7:[function(require,module,exports){!function(window,document,undefined){"use strict";function initWithJSON(json){store.put(opt.json),registerInput()}function initWithURL(url){jsonLoader.load(url,function(err,json){err?throwError("failed to get JSON ("+url+")"):(store.put(json),registerInput())})}function throwError(message){throw new Error("SimpleJekyllSearch --- "+message)}function validateOptions(_opt){for(var i=0;i<requiredOptions.length;i++){var req=requiredOptions[i];_opt[req]||throwError("You must specify a "+req)}}function assignOptions(_opt){for(var option in opt)opt[option]=_opt[option]||opt[option]}function isJSON(json){try{return json instanceof Object&&JSON.parse(JSON.stringify(json))}catch(e){return!1}}function emptyResultsContainer(){opt.resultsContainer.innerHTML=""}function appendToResultsContainer(text){opt.resultsContainer.innerHTML+=text}function registerInput(){opt.searchInput.addEventListener("keyup",function(e){return 0==e.target.value.length?void emptyResultsContainer():void render(searcher.search(store,e.target.value))})}function render(results){if(emptyResultsContainer(),0==results.length)return appendToResultsContainer(opt.noResultsText);for(var i=0;i<results.length;i++){results[i]['date'] = toTimestamp(results[i]['date']);appendToResultsContainer(templater.render(opt.searchResultTemplate,results[i]))}}var Searcher=require("./Searcher"),Templater=require("./Templater"),Store=require("./Store"),JSONLoader=require("./JSONLoader"),searcher=new Searcher,templater=new Templater,store=new Store,jsonLoader=new JSONLoader,requiredOptions=["searchInput","resultsContainer","json"],opt={searchInput:null,resultsContainer:null,json:[],searchResultTemplate:'
{title}
',noResultsText:"No results found",limit:5,fuzzy:1};window.SimpleJekyllSearch=function(_opt){validateOptions(_opt),assignOptions(_opt),isJSON(opt.json)?initWithJSON(opt.json):initWithURL(opt.json)}}(window,document)},{"./JSONLoader":1,"./Searcher":4,"./Store":5,"./Templater":6}]},{},[7]);

SimpleJekyllSearch({
        searchInput: document.getElementById('search-input'),
        resultsContainer: document.getElementById('search-results'),
        json: '/search.json',
        searchResultTemplate: '
{title} {date}
',
        noResultsText: '

',
        limit: 10,
        fuzzy: true,
});

// var s1 = document.getElementById("search-input");
// s1.focus();

/**
 * Toggles
 */

function toggl(id) {
       var e = document.getElementById(id);
       if(e.style.display == 'block') e.style.display = 'none';
       else e.style.display = 'block';
}

/**
 * Easter egg
 */

if( typeof console === 'object' ) {
        console.log(
            '\n' +
            'I\'m watching you.\n' +
            '\n' +
            '@andreiluca\n'
        );
}<commit_msg>Easter egg<commit_after>/**
 * Your eyes will thank me
 * Sleepy mode.
 */

var d = document.documentElement,
    t = document.querySelectorAll(".js-toggle-lights")[0],
    l = document.querySelectorAll(".site-description")[0],
    m = localStorage.getItem("nightmode"),
    l1 = "Ubuntu experience.",
    l2 = "Ubuntu experience. Sleep mode.";

if(m == "true") {
  d.classList.add("night-mode");
  l.textContent = l2;
}

t.addEventListener("click", function(){
  if(d.classList.contains("night-mode")) {
    d.classList.remove("night-mode");
    localStorage.setItem("nightmode", "false");
    l.textContent = l1;
  } else {
    d.classList.add("night-mode");
    localStorage.setItem("nightmode", "true");
    l.textContent = l2;
  }
});

/**
 * Timing is everything
 */

function timeAgo(time){
    var units = [
    { name: "second", limit: 60, in_seconds: 1 },
    { name: "minute", limit: 3600, in_seconds: 60 },
    { name: "hour", limit: 86400, in_seconds: 3600 },
    { name: "day", limit: 604800, in_seconds: 86400 },
    { name: "week", limit: 2629743, in_seconds: 604800 },
    { name: "month", limit: 31556926, in_seconds: 2629743 },
    { name: "year", limit: null, in_seconds: 31556926 }
    ];
    var diff = (new Date() - new Date(time*1000)) / 1000;
    if (diff < 5) return "now";
    var i = 0;
    var unit = null;

    while ((unit = units[i++]) !== null) {
      if (diff < unit.limit || !unit.limit){
        diff = Math.floor(diff / unit.in_seconds);
        return diff + " " + unit.name + (diff>1 ? "s" : "") + " old";
      }
    }
}

function toTimestamp(dateString){
  dateString = dateString.split('-').join('/');

  var date = new Date(dateString);
  valid = !isNaN(date.valueOf());

  if(valid === true){
      date = (date.getTime() / 1000).toFixed(0);
      date = timeAgo(date);
  }else{
      date = dateString;
  }
  return date;
}

/**
 * In Real Life
 * Quantified Self
 */

if (sessionStorage.irl) {
        document.getElementById('irl').innerHTML = sessionStorage.irl;
} else {
      var al = function(data) {
            var activity = parseInt(data.googlefit.steps);
            if(activity > 10) activity = "I've made " + activity.toLocaleString() + " steps today and"; else activity = "I'm either sleeping or working. Most likely <s>working</s> sleeping.";
            var irl = activity + " I spent over " + data.health.age.days.toLocaleString() + " days on Earth, my heart beat rate is " + data.googlefit.heartRate.bpm + " bpm measured " + timeAgo(data.googlefit.heartRate.timestamp) + ".";
            document.getElementById('irl').innerHTML = irl;
            sessionStorage.irl = irl;
      };

        var alt = document.createElement('script'); alt.type = 'text/javascript'; alt.async = true;
        alt.src = "http://track.andreiluca.com/api/?callback=al";
        var s = document.getElementsByTagName('script')[0];
        // s.parentNode.insertBefore(alt, s);
        document.body.appendChild(alt);
};

/**
 * Jekyll Search
 * https://github.com/christian-fei/Simple-Jekyll-Search
 */

!function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){module.exports=function(){function receivedResponse(xhr){return 200==xhr.status&&4==xhr.readyState}function handleResponse(xhr,callback){xhr.onreadystatechange=function(){if(receivedResponse(xhr))try{callback(null,JSON.parse(xhr.responseText))}catch(err){callback(err,null)}}}var self=this;self.load=function(location,callback){var xhr=window.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP");xhr.open("GET",location,!0),handleResponse(xhr,callback),xhr.send()}}},{}],2:[function(require,module,exports){function FuzzySearchStrategy(){function createFuzzyRegExpFromString(string){return new RegExp(string.split("").join(".*?"),"gi")}var self=this;self.matches=function(string,crit){return"string"!=typeof string?!1:(string=string.trim(),!!string.match(createFuzzyRegExpFromString(crit)))}}module.exports=new FuzzySearchStrategy},{}],3:[function(require,module,exports){function LiteralSearchStrategy(){function doMatch(string,crit){return string.toLowerCase().indexOf(crit.toLowerCase())>=0}var self=this;self.matches=function(string,crit){return"string"!=typeof string?!1:(string=string.trim(),doMatch(string,crit))}}module.exports=new LiteralSearchStrategy},{}],4:[function(require,module,exports){module.exports=function(){function findMatches(store,crit,strategy){for(var data=store.get(),i=0;i<data.length&&matches.length<limit;i++)findMatchesInObject(data[i],crit,strategy);return matches}function findMatchesInObject(obj,crit,strategy){for(var key in obj)if(strategy.matches(obj[key],crit)){matches.push(obj);break}}function getSearchStrategy(){return fuzzy?fuzzySearchStrategy:literalSearchStrategy}var self=this,matches=[],fuzzy=!1,limit=10,fuzzySearchStrategy=require("./SearchStrategies/fuzzy"),literalSearchStrategy=require("./SearchStrategies/literal");self.setFuzzy=function(_fuzzy){fuzzy=!!_fuzzy},self.setLimit=function(_limit){limit=parseInt(_limit,10)||limit},self.search=function(data,crit){return crit?(matches.length=0,findMatches(data,crit,getSearchStrategy())):[]}}},{"./SearchStrategies/fuzzy":2,"./SearchStrategies/literal":3}],5:[function(require,module,exports){module.exports=function(_store){function isObject(obj){return!!obj&&"[object Object]"==Object.prototype.toString.call(obj)}function isArray(obj){return!!obj&&"[object Array]"==Object.prototype.toString.call(obj)}function addObject(data){return store.push(data),data}function addArray(data){for(var added=[],i=0;i<data.length;i++)isObject(data[i])&&added.push(addObject(data[i]));return added}var self=this,store=[];isArray(_store)&&addArray(_store),self.clear=function(){return store.length=0,store},self.get=function(){return store},self.put=function(data){return isObject(data)?addObject(data):isArray(data)?addArray(data):void 0}}},{}],6:[function(require,module,exports){module.exports=function(){var self=this,templatePattern=/\{(.*?)\}/g;self.setTemplatePattern=function(newTemplatePattern){templatePattern=newTemplatePattern},self.render=function(t,data){return t.replace(templatePattern,function(match,prop){return data[prop]||match})}}},{}],7:[function(require,module,exports){!function(window,document,undefined){"use strict";function initWithJSON(json){store.put(opt.json),registerInput()}function initWithURL(url){jsonLoader.load(url,function(err,json){err?throwError("failed to get JSON ("+url+")"):(store.put(json),registerInput())})}function throwError(message){throw new Error("SimpleJekyllSearch --- "+message)}function validateOptions(_opt){for(var i=0;i<requiredOptions.length;i++){var req=requiredOptions[i];_opt[req]||throwError("You must specify a "+req)}}function assignOptions(_opt){for(var option in opt)opt[option]=_opt[option]||opt[option]}function isJSON(json){try{return json instanceof Object&&JSON.parse(JSON.stringify(json))}catch(e){return!1}}function emptyResultsContainer(){opt.resultsContainer.innerHTML=""}function appendToResultsContainer(text){opt.resultsContainer.innerHTML+=text}function registerInput(){opt.searchInput.addEventListener("keyup",function(e){return 0==e.target.value.length?void emptyResultsContainer():void render(searcher.search(store,e.target.value))})}function render(results){if(emptyResultsContainer(),0==results.length)return appendToResultsContainer(opt.noResultsText);for(var i=0;i<results.length;i++){results[i]['date'] = toTimestamp(results[i]['date']);appendToResultsContainer(templater.render(opt.searchResultTemplate,results[i]))}}var Searcher=require("./Searcher"),Templater=require("./Templater"),Store=require("./Store"),JSONLoader=require("./JSONLoader"),searcher=new Searcher,templater=new Templater,store=new Store,jsonLoader=new JSONLoader,requiredOptions=["searchInput","resultsContainer","json"],opt={searchInput:null,resultsContainer:null,json:[],searchResultTemplate:'
{title}
',noResultsText:"No results found",limit:5,fuzzy:1};window.SimpleJekyllSearch=function(_opt){validateOptions(_opt),assignOptions(_opt),isJSON(opt.json)?initWithJSON(opt.json):initWithURL(opt.json)}}(window,document)},{"./JSONLoader":1,"./Searcher":4,"./Store":5,"./Templater":6}]},{},[7]);

SimpleJekyllSearch({
        searchInput: document.getElementById('search-input'),
        resultsContainer: document.getElementById('search-results'),
        json: '/search.json',
        searchResultTemplate: '
{title} {date}
',
        noResultsText: '

',
        limit: 10,
        fuzzy: true,
});

// var s1 = document.getElementById("search-input");
// s1.focus();

/**
 * Toggles
 */

function toggl(id) {
       var e = document.getElementById(id);
       if(e.style.display == 'block') e.style.display = 'none';
       else e.style.display = 'block';
}

/**
 * Easter egg
 */

if( typeof console === 'object' ) {
        console.log(
            '\n' +
            'I’m watching you.\n' +
            '\n' +
            '@andreiluca\n'
        );
}<|endoftext|>


<commit_before>var chess = require('chess'),
    twilio = require('twilio'),
    express = require('express'),
    qs = require('querystring');

var renderBoard = require('./lib/chess-renderer.js').renderBoard;

twilioClient = twilio('AC7bb2f43a783c6c974a8571d786605fa2', process.env.AUTH_TOKEN);

var app = express();

// create a game client
var gc = chess.create(),
    m = null,
    status = null;

// look at the valid moves
status = gc.getStatus();

console.log(renderBoard(status));

// make a move
m = gc.move('a4');

// look at the status again after the move to see
// the opposing side's available moves
status = gc.getStatus();

/*
twilio.sendMessage({

  to:'+16515556677', // Any number Twilio can deliver to
  from: '+14506667788', // A number you bought from Twilio and can use for outbound communication
  body: 'word to your mother.' // body of the SMS message

}, function(err, responseData) { //this function is executed when a response is received from Twilio

  if (!err) { // "err" is an error received during the request, if any

    "responseData" is a JavaScript object containing data received from Twilio.
      // A sample response from sending an SMS message is here (click "JSON" to see how the data appears in JavaScript):
      // http://www.twilio.com/docs/api/rest/sending-sms#example-1

      console.log(responseData.from); // outputs "+14506667788"
    console.log(responseData.body); // outputs "word to your mother."

  }
});
*/
var phoneNumbers = {};
app.post('/sms/reply/', function (req, res) {
  var body = '';

  req.on('data', function (data) {
    body += data;
  });

  req.on('end', function () {

    var POST = qs.parse(body);

    console.log('text body', POST);

    //validate incoming request is from twilio using your auth token and the header from Twilio
    var token = process.env.AUTH_TOKEN,
    header = req.headers['x-twilio-signature'];

    //validateRequest returns true if the request originated from Twilio
    if (twilio.validateRequest(token, header, 'http://nicki.fn.lc:8183/sms/reply/', POST)) {

      if(phoneNumbers.hasOwnProperty(POST.To)){
        phoneNumbers[POST.To].gc = chess.create();
      }else{
        var curr_gc = phoneNumbers[POST.To].gc;

        var smsBody = POST.Body.replace(/^\s+|\s+$/g, '');

        if(board.isCheckmate){
          res.send('Checkmate. Game Over');
          delete phoneNumbers[POST.To];
          res.send('Start again?');

        }else if(board.isStalemate){
          res.send('Stalemate. Game Over');
          delete phoneNumbers[POST.To];
          res.send('Start again?');
        }

        //generate a TwiML response
        var resp = new twilio.TwimlResponse();

        //if we have a valid message
        if(smsBody === 6){

          //If we have a move command
          if(smsBody.slice(2,3) === 'to'){
            var piece_pos = smsBody.slice(0,1);

            var move_pos = smsBody.reverse().slice(0,1);

            //Error message
            try{
              curr_gc.move(piece_pos, move_pos);
            }catch(err){
              resp.message('Error'+err.message);
            }else{
              resp.message('Piece moved from '+piece_pos+' to '+move_pos);
            }

          }else if(smsBody.slice(0,3) === 'undo'){
            curr_gc.undo();
            resp.message('Successful undo');
          }

        }else{
          resp.message('Board\n' + renderBoard(gc.getStatus()));
        }
      }

      //Write headers
      res.writeHead(200, { 'Content-Type':'text/xml' });
      res.end(resp.toString());

    }
    else {
      res.writeHead(403, { 'Content-Type':'text/plain' });
      res.end('you are not twilio - take a hike.');
    }
  });
});

var server = app.listen(8183, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('CheSMS listening at http://%s:%s', host, port);
});
<commit_msg>Fixed syntax error<commit_after>var chess = require('chess'),
    twilio = require('twilio'),
    express = require('express'),
    qs = require('querystring');

var renderBoard = require('./lib/chess-renderer.js').renderBoard;

twilioClient = twilio('AC7bb2f43a783c6c974a8571d786605fa2', process.env.AUTH_TOKEN);

var app = express();

// create a game client
var gc = chess.create(),
    m = null,
    status = null;

// look at the valid moves
status = gc.getStatus();

console.log(renderBoard(status));

// make a move
m = gc.move('a4');

// look at the status again after the move to see
// the opposing side's available moves
status = gc.getStatus();

/*
twilio.sendMessage({

  to:'+16515556677', // Any number Twilio can deliver to
  from: '+14506667788', // A number you bought from Twilio and can use for outbound communication
  body: 'word to your mother.' // body of the SMS message

}, function(err, responseData) { //this function is executed when a response is received from Twilio

  if (!err) { // "err" is an error received during the request, if any

    "responseData" is a JavaScript object containing data received from Twilio.
      // A sample response from sending an SMS message is here (click "JSON" to see how the data appears in JavaScript):
      // http://www.twilio.com/docs/api/rest/sending-sms#example-1

      console.log(responseData.from); // outputs "+14506667788"
    console.log(responseData.body); // outputs "word to your mother."

  }
});
*/
var phoneNumbers = {};
app.post('/sms/reply/', function (req, res) {
  var body = '';

  req.on('data', function (data) {
    body += data;
  });

  req.on('end', function () {

    var POST = qs.parse(body);

    console.log('text body', POST);

    //validate incoming request is from twilio using your auth token and the header from Twilio
    var token = process.env.AUTH_TOKEN,
    header = req.headers['x-twilio-signature'];

    //validateRequest returns true if the request originated from Twilio
    if (twilio.validateRequest(token, header, 'http://nicki.fn.lc:8183/sms/reply/', POST)) {

      if(phoneNumbers.hasOwnProperty(POST.To)){
        phoneNumbers[POST.To].gc = chess.create();
      }else{
        var curr_gc = phoneNumbers[POST.To].gc;

        var smsBody = POST.Body.replace(/^\s+|\s+$/g, '');

        if(board.isCheckmate){
          res.send('Checkmate. Game Over');
          delete phoneNumbers[POST.To];
          res.send('Start again?');

        }else if(board.isStalemate){
          res.send('Stalemate. Game Over');
          delete phoneNumbers[POST.To];
          res.send('Start again?');
        }

        //generate a TwiML response
        var resp = new twilio.TwimlResponse();

        //if we have a valid message
        if(smsBody === 6){

          //If we have a move command
          if(smsBody.slice(2,3) === 'to'){
            var piece_pos = smsBody.slice(0,1);

            var move_pos = smsBody.reverse().slice(0,1);

            //Error message
            try{
              curr_gc.move(piece_pos, move_pos);
            }catch(err){
              resp.message('Error'+err.message);
              return;
            }

          resp.message('Piece moved from '+piece_pos+' to '+move_pos);

          }else if(smsBody.slice(0,3) === 'undo'){
            curr_gc.undo();
            resp.message('Successful undo');
          }

        }else{
          resp.message('Board\n' + renderBoard(gc.getStatus()));
        }
      }

      //Write headers
      res.writeHead(200, { 'Content-Type':'text/xml' });
      res.end(resp.toString());

    }
    else {
      res.writeHead(403, { 'Content-Type':'text/plain' });
      res.end('you are not twilio - take a hike.');
    }
  });
});

var server = app.listen(8183, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('CheSMS listening at http://%s:%s', host, port);
});
<|endoftext|>


<commit_before>var l = localStorage, _ = document;

var fs = (function (){
  var obj = {};
  BrowserFS.install(obj);
  var lsfs = new BrowserFS.FileSystem.LocalStorage();
  BrowserFS.initialize(lsfs);
  return obj.require('fs');
})();

var saving = _.getElementById('saving');
var theme = 'chrome';

var editors = {
  create(type, theme, onDel) {
    var obj = Object.create(this);
    obj.elm = _.createElement('div');
    this.elm.appendChild(obj.elm);
    var x = _.createElement('button');
    var elm = _.createElement('div');
    obj.elm.appendChild(elm);
    obj.elm.appendChild(x);
    x.classList.add('x');
    obj.elm.classList.add('editor');
    x.innerHTML = '×';
    x.onclick = onDel;
    obj.editor = ace.edit(elm);
    obj.editor.getSession().setMode('ace/mode/' + type);
    obj.editor.setTheme('ace/theme/' + theme);
    this.editors.push(obj);
    return obj;
  },
  editors: [],
  elm: _.getElementById('editors'),
  editorsByName: Object.create(null)
};

var extToType = {
  'js': 'javascript',
  'md': 'markdown',
  'html': 'html',
  'css': 'css'
};

function add(fileName) {
  var type = extToType[fileName.split('.').pop()];
  var editor = editors.create(type, theme, () => {
    del(fileName);
    editors.elm.removeChild(editor.elm);
  });
  editors.editorsByName[fileName] = editor;
  try {
    editor.editor.setValue(fs.readFileSync(fileName, 'utf-8'));
  } catch (e) {
    console.debug(e);
    fs.writeFileSync(fileName, '');
  }
}

function save() {
  var ps = [];
  for (var i in editors.editorsByName) {
    ps.push(new Promise((resolve, reject) => fs.writeFile(
      i,
      editors.editorsByName[i].editor.getValue(),
      (err, res) => err ? reject(err) : resolve(res))
    ));
  }
  return Promise.all(ps);
}

function saveWithUI() {
  saving.innerHTML = "Saving...";
  return save().then(() => saving.innerHTML = "All changes saved").catch(err => {
    console.error(err);
    saving.innerHTML = "Error saving: " + err.message
  });
}

function compile() {

}

function bundle(main) {
  return rollup.rollup({
    entry: main,
    plugins: [{
      load(id){
        return fs.readFileSync(id, 'utf-8')
      },
      resolveId(importee, importer){
        return importee + '.js';
      }
    }]
  }).then(bundle => bundle.generate({
    format: 'iife',
    moduleName: "mian"
  }), er => {throw er}).then(res => _.getElementById('output').innerHTML = res.code);
}

function del(file) {
  return new Promise((resolve, reject) => fs.unlink(
    file,
    (err, res) => err ? reject(err) : resolve(res)
  ));
}

function changeTheme(newTheme) {
  theme = newTheme;
  editors.editors.forEach((v) => v.editor.setTheme(theme));
}

document.getElementById('theme').oninput = function () {
  for (var i = 0, arr = document.getElementById('theme').children, choice = ''; i < arr.length; i ++) {
    arr[i].selected&&(choice=arr[i].id)
  }
  changeTheme(choice);
}
<commit_msg>Fux big<commit_after>var l = localStorage, _ = document;

var fs = (function (){
  var obj = {};
  BrowserFS.install(obj);
  var lsfs = new BrowserFS.FileSystem.LocalStorage();
  BrowserFS.initialize(lsfs);
  return obj.require('fs');
})();

var saving = _.getElementById('saving');
var theme = 'chrome';

var editors = {
  create(type, theme, onDel) {
    var obj = Object.create(this);
    obj.elm = _.createElement('div');
    this.elm.appendChild(obj.elm);
    var x = _.createElement('button');
    var elm = _.createElement('div');
    obj.elm.appendChild(elm);
    obj.elm.appendChild(x);
    x.classList.add('x');
    obj.elm.classList.add('editor');
    x.innerHTML = '×';
    x.onclick = onDel;
    obj.editor = ace.edit(elm);
    obj.editor.getSession().setMode('ace/mode/' + type);
    obj.editor.setTheme('ace/theme/' + theme);
    this.editors.push(obj);
    return obj;
  },
  editors: [],
  elm: _.getElementById('editors'),
  editorsByName: Object.create(null)
};

var extToType = {
  'js': 'javascript',
  'md': 'markdown',
  'html': 'html',
  'css': 'css'
};

function add(fileName) {
  var type = extToType[fileName.split('.').pop()];
  var editor = editors.create(type, theme, () => {
    del(fileName);
    editors.elm.removeChild(editor.elm);
  });
  editors.editorsByName[fileName] = editor;
  try {
    editor.editor.setValue(fs.readFileSync(fileName, 'utf-8'));
  } catch (e) {
    console.debug(e);
    fs.writeFileSync(fileName, '');
  }
}

function save() {
  var ps = [];
  for (var i in editors.editorsByName) {
    ps.push(new Promise((resolve, reject) => fs.writeFile(
      i,
      editors.editorsByName[i].editor.getValue(),
      (err, res) => err ? reject(err) : resolve(res))
    ));
  }
  return Promise.all(ps);
}

function saveWithUI() {
  saving.innerHTML = "Saving...";
  return save().then(() => saving.innerHTML = "All changes saved").catch(err => {
    console.error(err);
    saving.innerHTML = "Error saving: " + err.message
  });
}

function compile() {

}

function bundle(main) {
  return rollup.rollup({
    entry: main,
    plugins: [{
      load(id){
        return fs.readFileSync(id, 'utf-8')
      },
      resolveId(importee, importer){
        return importee + '.js';
      }
    }]
  }).then(bundle => bundle.generate({
    format: 'iife',
    moduleName: "mian"
  }), er => {throw er}).then(res => _.getElementById('output').innerHTML = res.code);
}

function del(file) {
  return new Promise((resolve, reject) => fs.unlink(
    file,
    (err, res) => err ? reject(err) : resolve(res)
  ));
}

function changeTheme(newTheme) {
  theme = newTheme;
  editors.editors.forEach((v) => v.editor.setTheme('ace/theme/' + theme));
}

document.getElementById('theme').oninput = function () {
  for (var i = 0, arr = document.getElementById('theme').children, choice = ''; i < arr.length; i ++) {
    arr[i].selected&&(choice=arr[i].id)
  }
  changeTheme(choice);
}
<|endoftext|>