<commit_before>// ==UserScript==
// @name         Stack Overflow Extras (SOX)
// @namespace    https://github.com/soscripted/sox
// @version      1.0.3 DEV
// @description  Adds a bunch of optional features to sites in the Stack Overflow Network.
// @contributor  ᴉʞuǝ (stackoverflow.com/users/1454538/)
// @contributor  ᔕᖺᘎᕊ (stackexchange.com/users/4337810/)
// @updateURL    https://rawgit.com/soscripted/sox/master/sox.user.js
// @match        *://*.stackoverflow.com/*
// @match        *://*.stackexchange.com/*
// @match        *://*.superuser.com/*
// @match        *://*.serverfault.com/*
// @match        *://*.askubuntu.com/*
// @match        *://*.stackapps.com/*
// @match        *://*.mathoverflow.net/*
// @match        *://github.com/soscripted/*
// @require      https://code.jquery.com/jquery-2.1.4.min.js
// @require      https://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js
// @require      https://cdn.rawgit.com/timdown/rangyinputs/master/rangyinputs-jquery-src.js
// @require      https://cdn.rawgit.com/jeresig/jquery.hotkeys/master/jquery.hotkeys.js
// @require      https://cdn.rawgit.com/camagu/jquery-feeds/master/jquery.feeds.js
// @require      https://rawgit.com/soscripted/sox/dev/sox.helpers.js?v=1.0.2g
// @require      https://rawgit.com/soscripted/sox/dev/sox.enhanced_editor.js?v=1.0.2g
// @require      https://rawgit.com/soscripted/sox/dev/sox.features.js?v=1.0.2g
// @require      https://api.stackexchange.com/js/2.0/all.js
// @resource     settingsDialog https://rawgit.com/soscripted/sox/5b3a497ac02d2b927415226d009ea08c7eba4a4f/sox.dialog.html
// @resource     featuresJSON https://rawgit.com/soscripted/sox/dev/sox.features.info.json?v=1.0.2g
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_getResourceText
// @grant        GM_info
// ==/UserScript==
/*jshint multistr: true */
(function(sox, $, undefined) {
    var SOX_SETTINGS = 'SOXSETTINGS';
    var SOX_VERSION = (typeof GM_info !== "undefined" ? GM_info.script.version : "??");
    var SOX_MANAGER = (typeof GM_info == "undefined" ? "??" : GM_info.scriptHandler + "/Chrome" ||  "Greasemonkey" + "/Firefox");

    // auto-inject version number and environment information into GitHub issues
    // setInterval, because on GitHub, when you change page, the URL changes but the page itself is actually the same. So this will check every 2 seconds for whether the issue texatarea exists
    setInterval(function() {
        if (location.hostname.indexOf('github.com') > -1) {
            if($('#issue_body').length) {
                var $issue = $('#issue_body'),
                    issueText = $issue.text();

                issueText = issueText.replace('1.X.X', SOX_VERSION); //inject the SOX version by replacing the issue template's placeholder '1.X.X'
                issueText = issueText.replace('Chrome/Tampermonkey', SOX_MANAGER); //inject the SOX userscript manager+platfirm by replacing the issue template's placeholder 'Chrome/Tampermonkey'
                $issue.text(issueText);
            }
            // on GitHub, stop execution of the rest of the script.
            return;
        }
    }, 2000);

    var $settingsDialog = $(GM_getResourceText('settingsDialog')),
        featuresJSON = JSON.parse(GM_getResourceText('featuresJSON')),
        $soxSettingsDialog,
        $soxSettingsDialogFeatures,
        $soxSettingsDialogVersion,
        $soxSettingsSave,
        $soxSettingsReset,
        $soxSettingsToggleAccessTokensDiv,
        $soxSettingsToggle,
        $soxSettingsClose;

    function isAvailable() {
        return GM_getValue(SOX_SETTINGS, -1) != -1;
    }

    function getSettings() {
        return JSON.parse(GM_getValue(SOX_SETTINGS));
    }

    function reset() {
        GM_deleteValue(SOX_SETTINGS);
    }

    function save(options) {
        GM_setValue(SOX_SETTINGS, JSON.stringify(options));
        console.log('SOX settings saved: ' + JSON.stringify(options));
    }

    function isDeprecated() { //checks whether the saved settings contain a deprecated feature
        var settings = getSettings(),
            deprecatedFeatures = [
                'answerCountSidebar',
                'highlightClosedQuestions',
                'unHideAnswer',
                'flaggingPercentages'
            ];
        return (new RegExp('(' + deprecatedFeatures.join('|') + ')')).test(settings);
    }

    function addFeature(category, feature, desc) {
        var $div = $('
'),
            $label = $(''),
            $input = $('<input/>', {
                id: feature,
                type: 'checkbox',
                style: 'margin-right: 5px;'
            });
        $div.append($label);
        $label.append($input);
        $input.after(desc);
        $soxSettingsDialogFeatures.find('#' + category).append($div);
    }

    function addCategory(name) {
        var $div = $('
', {
                id: name,
                'class': 'feature-header'
            }),
            $h3 = $('
', {
                text: name
            });
        $div.append($h3);
        $soxSettingsDialogFeatures.find('#sox-settings-dialog-access-tokens').before($div);
    }

    //initialize sox
    (function() {

        // add sox CSS file and font-awesome CSS file
        $('head').append('<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">')
            .append('<link rel="stylesheet" type="text/css" href="https://rawgit.com/soscripted/sox/dev/sox.css?v=1.0.2d" />');
        $('body').append($settingsDialog);

        $soxSettingsDialog = $('#sox-settings-dialog');
        $soxSettingsDialogFeatures = $soxSettingsDialog.find('#sox-settings-dialog-features');
        $soxSettingsDialogVersion = $soxSettingsDialog.find('#sox-settings-dialog-version');
        $soxSettingsSave = $soxSettingsDialog.find('#sox-settings-dialog-save');
        $soxSettingsReset = $soxSettingsDialog.find('#sox-settings-dialog-reset');
        $soxSettingsToggleAccessTokensDiv = $soxSettingsDialog.find('#sox-settings-dialog-access-tokens');
        $soxSettingsToggle = $soxSettingsDialog.find('#sox-settings-dialog-check-toggle');
        $soxSettingsClose = $soxSettingsDialog.find('#sox-settings-dialog-close');

        $soxSettingsDialogVersion.text('v' + SOX_VERSION + ' ');

        for (var category in featuresJSON) { //load all the features in the settings dialog
            addCategory(category);
            for (var feature in featuresJSON[category]) {
                addFeature(category, feature, featuresJSON[category][feature].desc);
            }
        }

        // add settings icon to navbar
        var $soxSettingsButton = $('', {
                id: 'soxSettingsButton',
                class: 'topbar-icon yes-hover sox-settings-button',
                title: 'Change SOX Settings',
                style: 'color: #A1A1A1',
                click: function(e) {
                    e.preventDefault();
                    $('#sox-settings-dialog').toggle();
                }
            }),
            $icon = $('', {
                class: 'fa fa-cogs'
            });
        $soxSettingsButton.append($icon).appendTo('div.network-items');

        // add click handlers for the buttons in the settings dialog
        $soxSettingsClose.on('click', function() {
            $soxSettingsDialog.hide();
        });
        $soxSettingsReset.on('click', function() {
            reset();
            location.reload(); // reload page to reflect changed settings
        });
        $soxSettingsToggleAccessTokensDiv.find('#toggle-access-token-links').on('click', function() {
            $links = $(this).parent().find('#sox-settings-dialog-access-tokens-links');
            if ($links.is(':visible')) {
                $links.hide();
                $soxSettingsToggleAccessTokensDiv.find('#toggle-access-token-links').removeClass('expander-arrow-small-show').addClass('expander-arrow-small-hide')
            } else {
                $links.show();
                $soxSettingsToggleAccessTokensDiv.find('#toggle-access-token-links').removeClass('expander-arrow-small-hide').addClass('expander-arrow-small-show')
            }
        });
        $soxSettingsToggle.on('click', function() {
            var $icon = $(this).find('i'),
                checked = $icon.hasClass('fa-check-square-o') ? true : false;

            if (checked) {
                $icon.removeClass('fa-check-square-o').addClass('fa-square-o');
                $soxSettingsDialogFeatures.find('input').prop('checked', false);
            } else {
                $icon.removeClass('fa-square-o').addClass('fa-check-square-o');
                $soxSettingsDialogFeatures.find('input').prop('checked', true);
            }
        });
        $soxSettingsSave.on('click', function() {
            var extras = [];
            $soxSettingsDialogFeatures.find('input[type=checkbox]:checked').each(function() {
                var x = $(this).parents('.feature-header').attr('id') + '-' + $(this).attr('id');
                console.log(x);
                extras.push(x); //Add the function's ID (also the checkbox's ID) to the array
            });
            save(extras);
            location.reload(); // reload page to reflect changed settings
        });

        $(document).on('click', 'a.getAccessToken', function() {
            $that = $(this);
            var client_id = $(this).attr('data-client-id');
            var key = $(this).attr('data-key');
            var featureId = $(this).attr('data-feature-id');
            SE.init({
                clientId: client_id,
                key: key,
                channelUrl: 'http://meta.stackexchange.com/blank',
                complete: function(d) {
                    console.log('SE init');
                }
            });
            SE.authenticate({
                success: function(data) {
                    accessToken = data.accessToken;
                    console.log(accessToken);
                    var accessTokens = JSON.parse(GM_getValue('SOX-accessTokens', "{}"));
                    accessTokens[featureId] = accessToken;
                    GM_setValue('SOX-accessTokens', JSON.stringify(accessTokens));
                    $that.before(accessToken);
                    $that.text(" New access token?");
                }
            });
        });

        // check if settings exist and execute desired functions
        if (isAvailable()) {
            var extras = getSettings();
            if (isDeprecated()) { //if the setting is set but a deprecated, non-existent feature exists, then delete the setting and act as if it is new
                reset();
            } else {
                for (var i = 0; i < extras.length; ++i) {
                    $soxSettingsDialogFeatures.find('#' + extras[i].split('-')[1]).prop('checked', true);
                    try {
                        var featureHeader = extras[i].split('-')[0];
                        var featureId = extras[i].split('-')[1];
                        var feature = featuresJSON[featureHeader][featureId];
                        if (feature['accessToken']) {
                            var accessTokens = JSON.parse(GM_getValue('SOX-accessTokens', "{}"));
                            if (!accessTokens[featureId]) {
                                $soxSettingsToggleAccessTokensDiv.find('#sox-settings-dialog-access-tokens-links').append(feature['desc'] + ': Get access token?');
                            } else if (accessTokens[featureId]) {
                                $soxSettingsToggleAccessTokensDiv.find('#sox-settings-dialog-access-tokens-links').append(feature['desc'] + ': ' + accessTokens[featureId] + ' New access token?');
                            }
                        }
                        if (feature['enableOnSites']) {
                            var sites = feature['enableOnSites'].split(',');
                            if (sites.indexOf(SOHelper.getAPISiteName()) > -1) { //if current site is in list, run feature
                                features[featureId]();
                            }
                        } else if (feature['disableOnSites']) {
                            var sites = feature['disableOnSites'].split(',');
                            if (sites.indexOf(SOHelper.getAPISiteName()) == -1) { //if current site is in list, don't run feature
                                features[featureId]();
                            }
                        } else { //if neither enableOnSites nor disableOnSites is given, run the feature (features that run on all sites)
                            features[featureId]();
                        }
                    } catch (err) {
                        $soxSettingsDialogFeatures.find('#' + extras[i]).parent().css('color', 'red').attr('title', 'There was an error loading this feature. Please raise an issue on GitHub.');
                        console.log('SOX error: There was an error loading the feature "' + extras[i] + '". Please raise an issue on GitHub, and copy the following error log.');
                        console.log('Error details:');
                        console.log(err);
                        i++;
                    }
                }
            }
        } else {
            // no settings found, mark all inputs as checked and display settings dialog
            $soxSettingsDialogFeatures.find('input').prop('checked', true);

            setTimeout(function() {
                $soxSettingsDialog.show();
            }, 500);
        }

    })();
}(window.sox = window.sox || {}, jQuery));
<commit_msg>Update sox.user.js<commit_after>// ==UserScript==
// @name         Stack Overflow Extras (SOX)
// @namespace    https://github.com/soscripted/sox
// @version      1.0.3 DEV
// @description  Adds a bunch of optional features to sites in the Stack Overflow Network.
// @contributor  ᴉʞuǝ (stackoverflow.com/users/1454538/)
// @contributor  ᔕᖺᘎᕊ (stackexchange.com/users/4337810/)
// @updateURL    https://rawgit.com/soscripted/sox/master/sox.user.js
// @match        *://*.stackoverflow.com/*
// @match        *://*.stackexchange.com/*
// @match        *://*.superuser.com/*
// @match        *://*.serverfault.com/*
// @match        *://*.askubuntu.com/*
// @match        *://*.stackapps.com/*
// @match        *://*.mathoverflow.net/*
// @match        *://github.com/soscripted/*
// @require      https://code.jquery.com/jquery-2.1.4.min.js
// @require      https://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js
// @require      https://cdn.rawgit.com/timdown/rangyinputs/master/rangyinputs-jquery-src.js
// @require      https://cdn.rawgit.com/jeresig/jquery.hotkeys/master/jquery.hotkeys.js
// @require      https://cdn.rawgit.com/camagu/jquery-feeds/master/jquery.feeds.js
// @require      https://rawgit.com/soscripted/sox/dev/sox.helpers.js?v=1.0.2g
// @require      https://rawgit.com/soscripted/sox/dev/sox.enhanced_editor.js?v=1.0.2g
// @require      https://rawgit.com/soscripted/sox/dev/sox.features.js?v=1.0.2g
// @require      https://api.stackexchange.com/js/2.0/all.js
// @resource     settingsDialog https://rawgit.com/soscripted/sox/5b3a497ac02d2b927415226d009ea08c7eba4a4f/sox.dialog.html
// @resource     featuresJSON https://rawgit.com/soscripted/sox/dev/sox.features.info.json?v=1.0.2g
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_getResourceText
// @grant        GM_info
// ==/UserScript==
/*jshint multistr: true */
(function(sox, $, undefined) {
    var SOX_SETTINGS = 'SOXSETTINGS';
    var SOX_VERSION = (typeof GM_info !== "undefined" ? GM_info.script.version : "??");
    var SOX_MANAGER = (typeof GM_info == "undefined" ? "??" : GM_info.scriptHandler + "/Chrome" ||  "Greasemonkey" + "/Firefox");

    // auto-inject version number and environment information into GitHub issues
    // setInterval, because on GitHub, when you change page, the URL changes but the page itself is actually the same. So this will check every 2 seconds for whether the issue texatarea exists
    if (location.hostname.indexOf('github.com') > -1) {
        setInterval(function() {
            if($('#issue_body').length) {
                var $issue = $('#issue_body'),
                    issueText = $issue.text();

                issueText = issueText.replace('1.X.X', SOX_VERSION); //inject the SOX version by replacing the issue template's placeholder '1.X.X'
                issueText = issueText.replace('Chrome/Tampermonkey', SOX_MANAGER); //inject the SOX userscript manager+platfirm by replacing the issue template's placeholder 'Chrome/Tampermonkey'
                $issue.text(issueText);
            }
            // on GitHub, stop execution of the rest of the script.
            return;
        }, 2000);
     } else {

         var $settingsDialog = $(GM_getResourceText('settingsDialog')),
             featuresJSON = JSON.parse(GM_getResourceText('featuresJSON')),
             $soxSettingsDialog,
             $soxSettingsDialogFeatures,
             $soxSettingsDialogVersion,
             $soxSettingsSave,
             $soxSettingsReset,
             $soxSettingsToggleAccessTokensDiv,
             $soxSettingsToggle,
             $soxSettingsClose;

         function isAvailable() {
             return GM_getValue(SOX_SETTINGS, -1) != -1;
         }

         function getSettings() {
             return JSON.parse(GM_getValue(SOX_SETTINGS));
         }

         function reset() {
             GM_deleteValue(SOX_SETTINGS);
         }

         function save(options) {
             GM_setValue(SOX_SETTINGS, JSON.stringify(options));
             console.log('SOX settings saved: ' + JSON.stringify(options));
         }

         function isDeprecated() { //checks whether the saved settings contain a deprecated feature
             var settings = getSettings(),
                 deprecatedFeatures = [
                     'answerCountSidebar',
                     'highlightClosedQuestions',
                     'unHideAnswer',
                     'flaggingPercentages'
                 ];
             return (new RegExp('(' + deprecatedFeatures.join('|') + ')')).test(settings);
         }

         function addFeature(category, feature, desc) {
             var $div = $('
'),
                 $label = $(''),
                 $input = $('<input/>', {
                     id: feature,
                     type: 'checkbox',
                     style: 'margin-right: 5px;'
                 });
             $div.append($label);
             $label.append($input);
             $input.after(desc);
             $soxSettingsDialogFeatures.find('#' + category).append($div);
         }

         function addCategory(name) {
             var $div = $('
', {
                 id: name,
                 'class': 'feature-header'
             }),
                 $h3 = $('
', {
                     text: name
                 });
             $div.append($h3);
             $soxSettingsDialogFeatures.find('#sox-settings-dialog-access-tokens').before($div);
         }

         //initialize sox
         (function() {

             // add sox CSS file and font-awesome CSS file
             $('head').append('<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">')
                 .append('<link rel="stylesheet" type="text/css" href="https://rawgit.com/soscripted/sox/dev/sox.css?v=1.0.2d" />');
             $('body').append($settingsDialog);

             $soxSettingsDialog = $('#sox-settings-dialog');
             $soxSettingsDialogFeatures = $soxSettingsDialog.find('#sox-settings-dialog-features');
             $soxSettingsDialogVersion = $soxSettingsDialog.find('#sox-settings-dialog-version');
             $soxSettingsSave = $soxSettingsDialog.find('#sox-settings-dialog-save');
             $soxSettingsReset = $soxSettingsDialog.find('#sox-settings-dialog-reset');
             $soxSettingsToggleAccessTokensDiv = $soxSettingsDialog.find('#sox-settings-dialog-access-tokens');
             $soxSettingsToggle = $soxSettingsDialog.find('#sox-settings-dialog-check-toggle');
             $soxSettingsClose = $soxSettingsDialog.find('#sox-settings-dialog-close');

             $soxSettingsDialogVersion.text('v' + SOX_VERSION + ' ');

             for (var category in featuresJSON) { //load all the features in the settings dialog
                 addCategory(category);
                 for (var feature in featuresJSON[category]) {
                     addFeature(category, feature, featuresJSON[category][feature].desc);
                 }
             }

             // add settings icon to navbar
             var $soxSettingsButton = $('', {
                 id: 'soxSettingsButton',
                 class: 'topbar-icon yes-hover sox-settings-button',
                 title: 'Change SOX Settings',
                 style: 'color: #A1A1A1',
                 click: function(e) {
                     e.preventDefault();
                     $('#sox-settings-dialog').toggle();
                 }
             }),
                 $icon = $('', {
                     class: 'fa fa-cogs'
                 });
             $soxSettingsButton.append($icon).appendTo('div.network-items');

             // add click handlers for the buttons in the settings dialog
             $soxSettingsClose.on('click', function() {
                 $soxSettingsDialog.hide();
             });
             $soxSettingsReset.on('click', function() {
                 reset();
                 location.reload(); // reload page to reflect changed settings
             });
             $soxSettingsToggleAccessTokensDiv.find('#toggle-access-token-links').on('click', function() {
                 $links = $(this).parent().find('#sox-settings-dialog-access-tokens-links');
                 if ($links.is(':visible')) {
                     $links.hide();
                     $soxSettingsToggleAccessTokensDiv.find('#toggle-access-token-links').removeClass('expander-arrow-small-show').addClass('expander-arrow-small-hide')
                 } else {
                     $links.show();
                     $soxSettingsToggleAccessTokensDiv.find('#toggle-access-token-links').removeClass('expander-arrow-small-hide').addClass('expander-arrow-small-show')
                 }
             });
             $soxSettingsToggle.on('click', function() {
                 var $icon = $(this).find('i'),
                     checked = $icon.hasClass('fa-check-square-o') ? true : false;

                 if (checked) {
                     $icon.removeClass('fa-check-square-o').addClass('fa-square-o');
                     $soxSettingsDialogFeatures.find('input').prop('checked', false);
                 } else {
                     $icon.removeClass('fa-square-o').addClass('fa-check-square-o');
                     $soxSettingsDialogFeatures.find('input').prop('checked', true);
                 }
             });
             $soxSettingsSave.on('click', function() {
                 var extras = [];
                 $soxSettingsDialogFeatures.find('input[type=checkbox]:checked').each(function() {
                     var x = $(this).parents('.feature-header').attr('id') + '-' + $(this).attr('id');
                     console.log(x);
                     extras.push(x); //Add the function's ID (also the checkbox's ID) to the array
                 });
                 save(extras);
                 location.reload(); // reload page to reflect changed settings
             });

             $(document).on('click', 'a.getAccessToken', function() {
                 $that = $(this);
                 var client_id = $(this).attr('data-client-id');
                 var key = $(this).attr('data-key');
                 var featureId = $(this).attr('data-feature-id');
                 SE.init({
                     clientId: client_id,
                     key: key,
                     channelUrl: 'http://meta.stackexchange.com/blank',
                     complete: function(d) {
                         console.log('SE init');
                     }
                 });
                 SE.authenticate({
                     success: function(data) {
                         accessToken = data.accessToken;
                         console.log(accessToken);
                         var accessTokens = JSON.parse(GM_getValue('SOX-accessTokens', "{}"));
                         accessTokens[featureId] = accessToken;
                         GM_setValue('SOX-accessTokens', JSON.stringify(accessTokens));
                         $that.before(accessToken);
                         $that.text(" New access token?");
                     }
                 });
             });

             // check if settings exist and execute desired functions
             if (isAvailable()) {
                 var extras = getSettings();
                 if (isDeprecated()) { //if the setting is set but a deprecated, non-existent feature exists, then delete the setting and act as if it is new
                     reset();
                 } else {
                     for (var i = 0; i < extras.length; ++i) {
                         $soxSettingsDialogFeatures.find('#' + extras[i].split('-')[1]).prop('checked', true);
                         try {
                             var featureHeader = extras[i].split('-')[0];
                             var featureId = extras[i].split('-')[1];
                             var feature = featuresJSON[featureHeader][featureId];
                             if (feature['accessToken']) {
                                 var accessTokens = JSON.parse(GM_getValue('SOX-accessTokens', "{}"));
                                 if (!accessTokens[featureId]) {
                                     $soxSettingsToggleAccessTokensDiv.find('#sox-settings-dialog-access-tokens-links').append(feature['desc'] + ': Get access token?');
                                 } else if (accessTokens[featureId]) {
                                     $soxSettingsToggleAccessTokensDiv.find('#sox-settings-dialog-access-tokens-links').append(feature['desc'] + ': ' + accessTokens[featureId] + ' New access token?');
                                 }
                             }
                             if (feature['enableOnSites']) {
                                 var sites = feature['enableOnSites'].split(',');
                                 if (sites.indexOf(SOHelper.getAPISiteName()) > -1) { //if current site is in list, run feature
                                     features[featureId]();
                                 }
                             } else if (feature['disableOnSites']) {
                                 var sites = feature['disableOnSites'].split(',');
                                 if (sites.indexOf(SOHelper.getAPISiteName()) == -1) { //if current site is in list, don't run feature
                                     features[featureId]();
                                 }
                             } else { //if neither enableOnSites nor disableOnSites is given, run the feature (features that run on all sites)
                                 features[featureId]();
                             }
                         } catch (err) {
                             $soxSettingsDialogFeatures.find('#' + extras[i]).parent().css('color', 'red').attr('title', 'There was an error loading this feature. Please raise an issue on GitHub.');
                             console.log('SOX error: There was an error loading the feature "' + extras[i] + '". Please raise an issue on GitHub, and copy the following error log.');
                             console.log('Error details:');
                             console.log(err);
                             i++;
                         }
                     }
                 }
             } else {
                 // no settings found, mark all inputs as checked and display settings dialog
                 $soxSettingsDialogFeatures.find('input').prop('checked', true);

                 setTimeout(function() {
                     $soxSettingsDialog.show();
                 }, 500);
             }

         })();
     } //end for else not being on GitHub
}(window.sox = window.sox || {}, jQuery));
<|endoftext|>


<commit_before><commit_msg>feat(shape): Implement positioning elements in percents<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
 * Please see distribution for license.
 */
$.register_module({
    name: 'og.analytics.Data',
    dependencies: ['og.api.rest'],
    obj: function () {
        var module = this, counter = 1, connections = {};
        $(window).on('unload', function () {
            Object.keys(connections).forEach(function (key) {try {connections[key].kill();} catch (error) {}});
        });
        var constructor = function (source, config, label) {
            var data = this, api = og.api.rest.views, id = 'data_' + counter++ + '_' + +new Date, meta,
                viewport = null, viewport_id, viewport_cache, prefix, view_id = config.view_id, viewport_version,
                graph_id = config.graph_id, subscribed = false, ROOT = 'rootNode', SETS = 'columnSets',
                ROWS = 'rowCount', grid_type = null, depgraph = !!source.depgraph, loading_viewport_id = false,
                fixed_set = {portfolio: 'Portfolio', primitives: 'Primitives'},
                autoconnect = typeof config.autoconnect !== 'undefined' ? config.autoconnect : true,
                label = config.label ? config.label + '-' : '';
            var data_handler = (function () {
                var timeout = null, rate = 500, last = +new Date, current, delta;
                var handler = function (result) {
                    if (!result || result.error) // do not kill connection even if there is an error, just warn
                        return og.dev.warn(data.prefix + (result && result.message || 'reset connection'));
                    if (result.data && result.data.version === viewport_version) fire('data', result.data.data);
                };
                return function (result) {
                    clearTimeout(timeout);
                    if (!view_id) return; // connection is dead
                    if ((delta = (current = +new Date) - last) >= rate) return (last = current), handler(result);
                    timeout = setTimeout(data_handler.partial(result), rate - delta);
                };
            })();
            var data_setup = function () {
                if (!view_id || !viewport) return;
                var promise, viewports = (depgraph ? api.grid.depgraphs : api.grid).viewports;
                subscribed = true;
                (viewport_id ? viewports.get({
                    view_id: view_id, grid_type: grid_type, graph_id: graph_id,
                    viewport_id: viewport_id, update: data_setup
                }) : (promise = viewports.put({
                        view_id: view_id, grid_type: grid_type, graph_id: graph_id,
                        loading: function () {loading_viewport_id = true;},
                        rows: viewport.rows, columns: viewport.cols, format: viewport.format
                    })).pipe(function (result) {
                        loading_viewport_id = false;
                        if (result.error) return (data.prefix = module.name + ' (' + label + view_id + '-dead):\n'),
                            (view_id = graph_id = viewport_id = subscribed = null), result; // goes to data_setup
                        viewport_id = result.meta.id; viewport_version = promise.id;
                        return viewports.get({
                            view_id: view_id, grid_type: grid_type, graph_id: graph_id, dry: true,
                            viewport_id: viewport_id, update: data_setup
                        });
                    })
                ).pipe(data_handler);
            };
            var disconnect_handler = function () {fire('disconnect'), data.disconnect(data.prefix + 'disconnected');};
            var fire = (function () {
                var fatal_fired = false, connect_fired = null;
                return function (type) {
                    var args = Array.prototype.slice.call(arguments);
                    try {
                        if (type === 'fatal' && !fatal_fired) // fire only once ever
                            return (fatal_fired = true), og.common.events.fire.apply(data, args);
                        if (type === 'connect' && connect_fired !== view_id) // fire once per new view_id
                            return (connect_fired = view_id), og.common.events.fire.apply(data, args);
                        og.common.events.fire.apply(data, args);
                    } catch (error) {og.dev.warn(data.prefix + 'a ' + type + ' handler threw ', error);}
                }
            })();
            var initialize = function () {
                var message, put_options = ['viewdefinition', 'aggregators', 'providers']
                    .reduce(function (acc, val) {return (acc[val] = source[val]), acc;}, {});
                if (depgraph || config.bypass) grid_type = source.type; // don't bother with type_setup
                if (view_id && grid_type) return structure_setup().pipe(structure_handler);
                if (grid_type) return api.put(put_options).pipe(view_handler).pipe(structure_handler);
                try {api.put(put_options).pipe(view_handler);} // initial request params come from outside so try/catch
                catch (error) {fire('fatal', data.prefix + error.message);}
            };
            var reconnect_handler = function () {initialize();};
            var structure_handler = function (result) {
                if (!grid_type || (depgraph && !graph_id)) return;
                if (result.error) return fire('fatal', data.prefix + result.message);
                fire('connect', {view_id: view_id, graph_id: graph_id});
                if (!result.data[SETS].length) return;
                meta.data_rows = result.data[ROOT] ? result.data[ROOT][1] + 1 : result.data[ROWS];
                meta.structure = result.data[ROOT] || [];
                meta.columns.fixed = [{name: fixed_set[grid_type], columns: result.data[SETS][0].columns}];
                meta.columns.scroll = result.data[SETS].slice(1);
                fire('meta', meta);
                if (!subscribed) return data_setup();
            };
            var same_viewport = function (one, two) {
                if ((!one || !two) && one !== two) return false; // if either viewport is null
                return one.rows.join('|') === two.rows.join('|') && one.cols.join('|') === two.cols.join('|') &&
                    one.format === two.format;
            };
            var structure_setup = function () {
                if (!view_id) return null; // goes to structure_handler
                if (!depgraph)
                    return api.grid.structure.get({view_id: view_id, grid_type: grid_type, update: initialize});
                return api.grid.structure
                    .get({view_id: view_id, grid_type: grid_type, update: initialize}).pipe(function (result) {
                        if (result.error || !result.data[SETS].length) return result; // goes to structure_handler
                        if (graph_id) return api.grid.depgraphs.structure
                            .get({view_id: view_id, grid_type: grid_type, graph_id: graph_id, update: initialize});
                        return api.grid.depgraphs.put({
                            view_id: view_id, grid_type: grid_type, row: source.row, col: source.col
                        }).pipe(function (result) {
                            if (result.error) return fire('fatal', data.prefix + result.message);
                            return api.grid.depgraphs.structure.get({
                                view_id: view_id, grid_type: grid_type,
                                graph_id: (graph_id = result.meta.id), update: initialize
                            });
                        })
                    });
            };
            var type_setup = function (update) {
                var port_request, prim_request, initial = grid_type === null;
                grid_type = source.type;
                port_request = api.grid.structure
                    .get({dry: initial, view_id: view_id, update: initial ? type_setup : null, grid_type: 'portfolio'});
                if (initial) return /* just register interest and bail*/; else prim_request = api.grid.structure
                    .get({view_id: view_id, grid_type: 'primitives'});
                $.when(port_request, prim_request).then(function (port_struct, prim_struct) {
                    var portfolio = port_struct.data &&
                            !!(port_struct.data[ROOT] ? port_struct.data[ROOT][1] : port_struct.data[ROWS]),
                        primitives = prim_struct.data &&
                            !!(prim_struct.data[ROOT] ? prim_struct.data[ROOT][1] : prim_struct.data[ROWS]);
                    if (!grid_type)
                        grid_type = source.type = portfolio ? 'portfolio' : primitives ? 'primitives' : grid_type;
                    structure_handler(grid_type === 'portfolio' ? port_struct : prim_struct);
                    fire('types', {portfolio: portfolio, primitives: primitives});
                });
            };
            var view_handler = function (result) {
                if (result.error) return fire('fatal', data.prefix + result.message);
                data.prefix = module.name + ' (' + label + (view_id = result.meta.id) + '):\n';
                return grid_type ? structure_setup() : type_setup();
            };
            data.disconnect = function () {
                if (arguments.length) og.dev.warn.apply(null, Array.prototype.slice.call(arguments));
                if (view_id) api.del({view_id: view_id});
                data.prefix = module.name + ' (' + label + view_id + '-dead' + '):\n';
                view_id = graph_id = viewport_id = subscribed = null;
            };
            data.id = id;
            data.kill = function () {
                data.disconnect.apply(data, Array.prototype.slice.call(arguments));
                delete connections[data.id];
                if (autoconnect) og.api.rest.off('disconnect', disconnect_handler).off('reconnect', reconnect_handler);
            };
            data.meta = meta = {columns: {}};
            data.prefix = prefix = module.name + ' (' + label + 'undefined' + '):\n';
            data.reconnect = function (connection) {
                view_id = connection.view_id; graph_id = connection.graph_id;
                initialize();
            };
            data.viewport = function (new_viewport) {
                var promise, viewports = (depgraph ? api.grid.depgraphs : api.grid).viewports;
                if (new_viewport === null) {
                    if (viewport_id) viewports
                        .del({view_id: view_id, grid_type: grid_type, graph_id: graph_id, viewport_id: viewport_id});
                    viewport = viewport_cache = viewport_id = null;
                    if (meta.viewport) (meta.viewport.cols = []), (meta.viewport.rows = []);
                    return data;
                }
                if (!new_viewport.rows.length || !new_viewport.cols.length)
                    return og.dev.warn(data.prefix + 'nonsensical viewport, ', new_viewport), data;
                if (same_viewport(viewport_cache, new_viewport)) return data; // duplicate viewport, do nothing
                viewport_cache = JSON.parse(JSON.stringify(data.meta.viewport = viewport = new_viewport));
                if (!viewport_id) return loading_viewport_id ? data : data_setup(), data;
                try { // viewport definitions come from outside, so try/catch
                    (promise = viewports.put({
                        view_id: view_id, grid_type: grid_type, graph_id: graph_id, viewport_id: viewport_id,
                        rows: viewport.rows, columns: viewport.cols, format: viewport.format
                    })).pipe(function (result) {if (result.error) return; else viewport_version = promise.id;});
                } catch (error) {fire('fatal', data.prefix + error.message);}
                return data;
            };
            connections[data.id] = data;
            if (autoconnect) og.api.rest.on('disconnect', disconnect_handler).on('reconnect', reconnect_handler);
            data.on('fatal', function (message) {data.kill(message);});
            setTimeout(initialize); // allow events to be attached
        };
        constructor.prototype.off = og.common.events.off;
        constructor.prototype.on = og.common.events.on;
        return constructor;
    }
});<commit_msg>bugfix for depgraphs dealing with the new API<commit_after>/*
 * Copyright 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
 * Please see distribution for license.
 */
$.register_module({
    name: 'og.analytics.Data',
    dependencies: ['og.api.rest'],
    obj: function () {
        var module = this, counter = 1, connections = {};
        $(window).on('unload', function () {
            Object.keys(connections).forEach(function (key) {try {connections[key].kill();} catch (error) {}});
        });
        var constructor = function (source, config, label) {
            var data = this, api = og.api.rest.views, id = 'data_' + counter++ + '_' + +new Date, meta,
                viewport = null, viewport_id, viewport_cache, prefix, view_id = config.view_id, viewport_version,
                graph_id = config.graph_id, subscribed = false, ROOT = 'rootNode', SETS = 'columnSets',
                ROWS = 'rowCount', grid_type = null, depgraph = !!source.depgraph, loading_viewport_id = false,
                fixed_set = {portfolio: 'Portfolio', primitives: 'Primitives'},
                autoconnect = typeof config.autoconnect !== 'undefined' ? config.autoconnect : true,
                label = config.label ? config.label + '-' : '';
            var data_handler = (function () {
                var timeout = null, rate = 500, last = +new Date, current, delta;
                var handler = function (result) {
                    if (!result || result.error) // do not kill connection even if there is an error, just warn
                        return og.dev.warn(data.prefix + (result && result.message || 'reset connection'));
                    if (result.data && result.data.version === viewport_version) fire('data', result.data.data);
                };
                return function (result) {
                    clearTimeout(timeout);
                    if (!view_id) return; // connection is dead
                    if ((delta = (current = +new Date) - last) >= rate) return (last = current), handler(result);
                    timeout = setTimeout(data_handler.partial(result), rate - delta);
                };
            })();
            var data_setup = function () {
                if (!view_id || !viewport) return;
                var promise, viewports = (depgraph ? api.grid.depgraphs : api.grid).viewports;
                subscribed = true;
                (viewport_id ? viewports.get({
                    view_id: view_id, grid_type: grid_type, graph_id: graph_id,
                    viewport_id: viewport_id, update: data_setup
                }) : (promise = viewports.put({
                        view_id: view_id, grid_type: grid_type, graph_id: graph_id,
                        loading: function () {loading_viewport_id = true;},
                        rows: viewport.rows, columns: viewport.cols, format: viewport.format
                    })).pipe(function (result) {
                        loading_viewport_id = false;
                        if (result.error) return (data.prefix = module.name + ' (' + label + view_id + '-dead):\n'),
                            (view_id = graph_id = viewport_id = subscribed = null), result; // goes to data_setup
                        viewport_id = result.meta.id; viewport_version = promise.id;
                        return viewports.get({
                            view_id: view_id, grid_type: grid_type, graph_id: graph_id, dry: true,
                            viewport_id: viewport_id, update: data_setup
                        });
                    })
                ).pipe(data_handler);
            };
            var disconnect_handler = function () {fire('disconnect'), data.disconnect(data.prefix + 'disconnected');};
            var fire = (function () {
                var fatal_fired = false, connect_fired = null;
                return function (type) {
                    var args = Array.prototype.slice.call(arguments);
                    try {
                        if (type === 'fatal' && !fatal_fired) // fire only once ever
                            return (fatal_fired = true), og.common.events.fire.apply(data, args);
                        if (type === 'connect' && connect_fired !== view_id) // fire once per new view_id
                            return (connect_fired = view_id), og.common.events.fire.apply(data, args);
                        og.common.events.fire.apply(data, args);
                    } catch (error) {og.dev.warn(data.prefix + 'a ' + type + ' handler threw ', error);}
                }
            })();
            var initialize = function () {
                var message, put_options = ['viewdefinition', 'aggregators', 'providers']
                    .reduce(function (acc, val) {return (acc[val] = source[val]), acc;}, {});
                if (depgraph || config.bypass) grid_type = source.type; // don't bother with type_setup
                if (view_id && grid_type) return structure_setup();
                if (grid_type) return api.put(put_options).pipe(view_handler).pipe(structure_handler);
                try {api.put(put_options).pipe(view_handler);} // initial request params come from outside so try/catch
                catch (error) {fire('fatal', data.prefix + error.message);}
            };
            var reconnect_handler = function () {initialize();};
            var structure_handler = function (result) {
                if (!grid_type || (depgraph && !graph_id)) return;
                if (result.error) return fire('fatal', data.prefix + result.message);
                fire('connect', {view_id: view_id, graph_id: graph_id});
                if (!result.data[SETS].length) return;
                meta.data_rows = result.data[ROOT] ? result.data[ROOT][1] + 1 : result.data[ROWS];
                meta.structure = result.data[ROOT] || [];
                meta.columns.fixed = [{name: fixed_set[grid_type], columns: result.data[SETS][0].columns}];
                meta.columns.scroll = result.data[SETS].slice(1);
                fire('meta', meta);
                if (!subscribed) return data_setup();
            };
            var same_viewport = function (one, two) {
                if ((!one || !two) && one !== two) return false; // if either viewport is null
                return one.rows.join('|') === two.rows.join('|') && one.cols.join('|') === two.cols.join('|') &&
                    one.format === two.format;
            };
            var structure_setup = function (update) {
                var initial = !update;
                if (initial) return api.grid.structure
                    .get({view_id: view_id, grid_type: grid_type, update: structure_setup, initial: initial});
                api.grid.structure.get({view_id: view_id, grid_type: grid_type, update: structure_handler})
                    .pipe(function (result) {
                        if (result.error) return fire('fatal', data.prefix + result.message);
                        return !depgraph ? structure_handler(result) : api.grid.depgraphs.put({
                            view_id: view_id, grid_type: grid_type, row: source.row, col: source.col
                        }).pipe(function (result) {
                            if (result.error) return fire('fatal', data.prefix + result.message);
                            return api.grid.depgraphs.structure
                                .get({view_id: view_id, grid_type: grid_type, graph_id: (graph_id = result.meta.id)})
                                .pipe(structure_handler);
                        })
                    });
            };
            var type_setup = function (update) {
                var port_request, prim_request, initial = grid_type === null;
                grid_type = source.type;
                port_request = api.grid.structure
                    .get({dry: initial, view_id: view_id, update: initial ? type_setup : null, grid_type: 'portfolio'});
                if (initial) return /* just register interest and bail*/; else prim_request = api.grid.structure
                    .get({view_id: view_id, grid_type: 'primitives'});
                $.when(port_request, prim_request).then(function (port_struct, prim_struct) {
                    var portfolio = port_struct.data &&
                            !!(port_struct.data[ROOT] ? port_struct.data[ROOT][1] : port_struct.data[ROWS]),
                        primitives = prim_struct.data &&
                            !!(prim_struct.data[ROOT] ? prim_struct.data[ROOT][1] : prim_struct.data[ROWS]);
                    if (!grid_type)
                        grid_type = source.type = portfolio ? 'portfolio' : primitives ? 'primitives' : grid_type;
                    structure_handler(grid_type === 'portfolio' ? port_struct : prim_struct);
                    fire('types', {portfolio: portfolio, primitives: primitives});
                });
            };
            var view_handler = function (result) {
                if (result.error) return fire('fatal', data.prefix + result.message);
                data.prefix = module.name + ' (' + label + (view_id = result.meta.id) + '):\n';
                return grid_type ? structure_setup() : type_setup();
            };
            data.disconnect = function () {
                if (arguments.length) og.dev.warn.apply(null, Array.prototype.slice.call(arguments));
                if (view_id) api.del({view_id: view_id});
                data.prefix = module.name + ' (' + label + view_id + '-dead' + '):\n';
                view_id = graph_id = viewport_id = subscribed = null;
            };
            data.id = id;
            data.kill = function () {
                data.disconnect.apply(data, Array.prototype.slice.call(arguments));
                delete connections[data.id];
                if (autoconnect) og.api.rest.off('disconnect', disconnect_handler).off('reconnect', reconnect_handler);
            };
            data.meta = meta = {columns: {}};
            data.prefix = prefix = module.name + ' (' + label + 'undefined' + '):\n';
            data.reconnect = function (connection) {
                view_id = connection.view_id; graph_id = connection.graph_id;
                initialize();
            };
            data.viewport = function (new_viewport) {
                var promise, viewports = (depgraph ? api.grid.depgraphs : api.grid).viewports;
                if (new_viewport === null) {
                    if (viewport_id) viewports
                        .del({view_id: view_id, grid_type: grid_type, graph_id: graph_id, viewport_id: viewport_id});
                    viewport = viewport_cache = viewport_id = null;
                    if (meta.viewport) (meta.viewport.cols = []), (meta.viewport.rows = []);
                    return data;
                }
                if (!new_viewport.rows.length || !new_viewport.cols.length)
                    return og.dev.warn(data.prefix + 'nonsensical viewport, ', new_viewport), data;
                if (same_viewport(viewport_cache, new_viewport)) return data; // duplicate viewport, do nothing
                viewport_cache = JSON.parse(JSON.stringify(data.meta.viewport = viewport = new_viewport));
                if (!viewport_id) return loading_viewport_id ? data : data_setup(), data;
                try { // viewport definitions come from outside, so try/catch
                    (promise = viewports.put({
                        view_id: view_id, grid_type: grid_type, graph_id: graph_id, viewport_id: viewport_id,
                        rows: viewport.rows, columns: viewport.cols, format: viewport.format
                    })).pipe(function (result) {if (result.error) return; else viewport_version = promise.id;});
                } catch (error) {fire('fatal', data.prefix + error.message);}
                return data;
            };
            connections[data.id] = data;
            if (autoconnect) og.api.rest.on('disconnect', disconnect_handler).on('reconnect', reconnect_handler);
            data.on('fatal', function (message) {data.kill(message);});
            setTimeout(initialize); // allow events to be attached
        };
        constructor.prototype.off = og.common.events.off;
        constructor.prototype.on = og.common.events.on;
        return constructor;
    }
});<|endoftext|>


<commit_before>'use strict';
/* eslint-disable no-unused-vars */

/** Initialize the Map View */
function initMap() {
  // Example: trip.html?locations=48.13237830000001,11.5865944*48.14127879999999,11.5652331*48.1472299,11.5737519*48.1376098,11.5799253*48.17315919999999,11.5466036*48.13237830000001,11.5865944
  const urlParameters = getFromUrl();
  // Select the center of map using first destination.
  const centerPoint = urlParameters.locations.split('*')[0];

  const centerLat = parseFloat(centerPoint.split(',')[0]);
  const centerLong = parseFloat(centerPoint.split(',')[1]);

  const directionsService = new google.maps.DirectionsService();
  const directionsRenderer = new google.maps.DirectionsRenderer();
  const map = new google.maps.Map(document.getElementById('map'), {
    zoom: 13,
    center: {
      lat: centerLat,
      lng: centerLong,
    },
  });
  directionsRenderer.setMap(map);
  const body = document.getElementsByTagName('body')[0];
  body.addEventListener('load',
    calculateAndDisplayRoute(directionsService, directionsRenderer), false);
}

/** Calculate and display the itinerary
* @param {directionsService} directionsService Direction API parameter.
* @param {directionsRenderer} directionsRenderer Direction API parameter.
*/
function calculateAndDisplayRoute(directionsService, directionsRenderer) {
  const urlParameters = getFromUrl();
  const locations = urlParameters.locations.split('*');
  let waypts = [];

  const start = locations[0];
  const finish = locations[locations.length - 1];

  for (let i = 1; i < locations.length - 1; i++) {
    waypts.push({
      location: locations[i],
      stopover: true,
    });
  }

  directionsService.route(
    {
      origin: start,
      destination: finish,
      waypoints: waypts,
      optimizeWaypoints: true,
      travelMode: google.maps.TravelMode.DRIVING,
    },
    (response, status) => {
      if (status === 'OK') {
        directionsRenderer.setDirections(response);
        const route = response.routes[0];
        const summaryPanel = document.getElementById('directions-panel');
        summaryPanel.innerHTML = '';

        for (let i = 0; i < route.legs.length; i++) {
          const routeSegment = i + 1;
          summaryPanel.innerHTML +=
            'Route Segment: ' + routeSegment + '
';
          summaryPanel.innerHTML += route.legs[i].start_address + ' to ';
          summaryPanel.innerHTML += route.legs[i].end_address + '
';
          summaryPanel.innerHTML +=
            route.legs[i].distance.text + '

';
        }
      } else {
        window.alert('Directions request failed due to ' + status);
      }
    },
  );
}

/** Parse the url query for getting parameters
* @param {String} query URL query after the question mark.
*/
function parse_query_string(query) {
  const vars = query.split("&");
  let query_string = {};

  for (var i = 0; i < vars.length; i++) {

    const pair = vars[i].split("=");
    const key = decodeURIComponent(pair[0]);
    const value = decodeURIComponent(pair[1]);
    query_string[key] = value;
  }
  return query_string;
}

/** Look url and get locations for itinerary*/
function getFromUrl() {
  // URL query after the question mark.
  const query = window.location.search.substring(1);

  // Parsed Query
  const parsedQuery = parse_query_string(query);

  return parsedQuery;
}
<commit_msg>test commit<commit_after>'use strict';
/* eslint-disable no-unused-vars */

/** Initialize the Map View */
function initMap() {
  // Example: trip.html?locations=48.13237830000001,11.5865944*48.14127879999999,11.5652331*48.1472299,11.5737519*48.1376098,11.5799253*48.17315919999999,11.5466036*48.13237830000001,11.5865944
  const urlParameters = getFromUrl();
  // Select the center of map using first destination.
  const centerPoint = urlParameters.locations.split('*')[0];

  const centerLat = parseFloat(centerPoint.split(',')[0]);
  const centerLong = parseFloat(centerPoint.split(',')[1]);

  const directionsService = new google.maps.DirectionsService();
  const directionsRenderer = new google.maps.DirectionsRenderer();
  const map = new google.maps.Map(document.getElementById('map'), {
    zoom: 13,
    center: {
      lat: centerLat,
      lng: centerLong,
    },
  });
  directionsRenderer.setMap(map);
  const body = document.getElementsByTagName('body')[0];
  body.addEventListener('load',
    calculateAndDisplayRoute(directionsService, directionsRenderer), false);
}

/** Calculate and display the itinerary
* @param {directionsService} directionsService Direction API parameter.
* @param {directionsRenderer} directionsRenderer Direction API parameter.
*/
function calculateAndDisplayRoute(directionsService, directionsRenderer) {
  const urlParameters = getFromUrl();
  const locations = urlParameters.locations.split('*');
  let waypts = [];

  const start = locations[0];
  const finish = locations[locations.length - 1];

  for (let i = 1; i < locations.length - 1; i++) {
    waypts.push({
      location: locations[i],
      stopover: true,
    });
  }

  directionsService.route(
    {
      origin: start,
      destination: finish,
      waypoints: waypts,
      optimizeWaypoints: true,
      travelMode: google.maps.TravelMode.DRIVING,
    },
    (response, status) => {
      if (status === 'OK') {
        directionsRenderer.setDirections(response);
        const route = response.routes[0];
        const summaryPanel = document.getElementById('directions-panel');
        summaryPanel.innerHTML = '';

        for (let i = 0; i < route.legs.length; i++) {
          const routeSegment = i + 1;
          summaryPanel.innerHTML +=
            'Route Segment: ' + routeSegment + '
';
          summaryPanel.innerHTML += route.legs[i].start_address + ' to ';
          summaryPanel.innerHTML += route.legs[i].end_address + '
';
          summaryPanel.innerHTML +=
            route.legs[i].distance.text + '

';
        }
      } else {
        window.alert('Directions request failed due to ' + status);
      }
    },
  );
}

/** Parse the url query for getting parameters
* @param {String} query URL query after the question mark.
*/
function parse_query_string(query) {
  const vars = query.split("&");
  let query_string = {};

  for (var i = 0; i < vars.length; i++) {

    const pair = vars[i].split("=");
    const key = decodeURIComponent(pair[0]);
    const value = decodeURIComponent(pair[1]);
    query_string[key] = value;
  }
  return query_string;
}

/** Look url and get locations for itinerary*/
function getFromUrl() {
  // URL query after the question mark.
  const query = window.location.search.substring(1);

  // Parsed Query
  const parsedQuery = parse_query_string(query);
  return parsedQuery;
}
<|endoftext|>


<commit_before>import insertElement from '../../common/insertElement';
import insertHtmlBeforeEnd from '../../common/insertHtmlBeforeEnd';
import {now} from '../../support/now';
import {coolTime, cooldownText, seen, titan} from './constants';
import {createTBody, createTable} from '../../common/cElement';

function reformat(el) {
  return [el[0], el[1].cooldownText, el[1].coolTime, el[1].seen];
}

function onCd(el) {return el[coolTime] > now;}

function int(a, b) {return a[coolTime] - b[coolTime];}

function makeRow(el) {
  return '
' + el[titan] +
    '	' + el[cooldownText] +
    '	' + el[seen] + '
';
}

function makeHtml(theTitans) {
  return Object.entries(theTitans).map(reformat).filter(onCd).sort(int)
    .map(makeRow).join('');
}

function makeTrackerTable(theTitans) {
  var trackerTable = createTable({className: 'fshTTracker'});
  var tBody = createTBody({
    innerHTML: '
Titan	' +
      'Cooldown	' +
      'Visible
'
  });
  insertElement(trackerTable, tBody);
  insertHtmlBeforeEnd(tBody, makeHtml(theTitans));
  return trackerTable;
}

export default function displayTracker(parentTable, theTitans) {
  var trackerTable = makeTrackerTable(theTitans);
  var newRow = parentTable.insertRow(5);
  var newCell = newRow.insertCell(-1);
  newCell.colSpan = 3;
  insertElement(newCell, trackerTable);
}
<commit_msg>guard<commit_after>import insertElement from '../../common/insertElement';
import insertHtmlBeforeEnd from '../../common/insertHtmlBeforeEnd';
import {now} from '../../support/now';
import {coolTime, cooldownText, seen, titan} from './constants';
import {createTBody, createTable} from '../../common/cElement';

function reformat(el) {
  return [el[0], el[1].cooldownText, el[1].coolTime, el[1].seen];
}

function onCd(el) {return el[coolTime] > now;}

function int(a, b) {return a[coolTime] - b[coolTime];}

function makeRow(el) {
  return '
' + el[titan] +
    '	' + el[cooldownText] +
    '	' + el[seen] + '
';
}

function makeHtml(theTitans) {
  return Object.entries(theTitans).map(reformat).filter(onCd).sort(int)
    .map(makeRow).join('');
}

function makeTrackerTable(theTitans) {
  var trackerTable = createTable({className: 'fshTTracker'});
  var tBody = createTBody({
    innerHTML: '
Titan	' +
      'Cooldown	' +
      'Visible
'
  });
  insertElement(trackerTable, tBody);
  insertHtmlBeforeEnd(tBody, makeHtml(theTitans));
  return trackerTable;
}

export default function displayTracker(parentTable, theTitans) {
  if (parentTable.rows.length > 5) {
    var trackerTable = makeTrackerTable(theTitans);
    var newRow = parentTable.insertRow(5);
    var newCell = newRow.insertCell(-1);
    newCell.colSpan = 3;
    insertElement(newCell, trackerTable);
  }
}
<|endoftext|>


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

    const controller = function (Base, $scope, $element) {

        class HelpIconController extends Base {

            constructor() {
                super();
                this.hovered = false;
            }

            hoverIn() {
                this.hovered = true;
                clearTimeout(this.timer);
                this.timer = setTimeout(() => {
                    this.hovered = false;
                    $scope.$apply();
                }, Number(this.delay) || 1000);
                $scope.$apply();
            }

            $postLink() {
                $element.on('mouseover', () => this.hoverIn());
            }

        }

        return new HelpIconController();
    };

    controller.$inject = ['Base', '$scope', '$element'];

    angular.module('app.ui').component('wHelpIcon', {
        templateUrl: 'modules/ui/directives/helpIcon/helpIcon.html',
        transclude: true,
        bindings: {
            delay: '='
        },
        controller
    });

})();
<commit_msg>CLIENT-1132: fix help interval<commit_after>(function () {
    'use strict';

    const controller = function (Base, $scope, $element) {

        class HelpIconController extends Base {

            constructor() {
                super();
                this.hovered = false;
            }

            hoverIn() {
                this.hovered = true;
                clearTimeout(this.timer);
                $scope.$apply();
            }

            hoverOut() {
                clearTimeout(this.timer);
                this.timer = setTimeout(() => {
                    this.hovered = false;
                    $scope.$apply();
                }, Number(this.delay) || 1000);
            }

            $postLink() {
                $element.on('mouseover', () => this.hoverIn());
                $element.on('mouseout', () => this.hoverOut());
            }

        }

        return new HelpIconController();
    };

    controller.$inject = ['Base', '$scope', '$element'];

    angular.module('app.ui').component('wHelpIcon', {
        templateUrl: 'modules/ui/directives/helpIcon/helpIcon.html',
        transclude: true,
        bindings: {
            delay: '='
        },
        controller
    });

})();
<|endoftext|>


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

    /**
     * @param Base
     * @param $scope
     * @param $state
     * @param user
     * @param modalManager
     * @param ChartFactory
     * @param {app.utils} angularUtils
     * @param {JQuery} $element
     * @param {Waves} waves
     * @return {WelcomeCtrl}
     */
    const controller = function (Base,
                                 $scope,
                                 $state,
                                 user,
                                 modalManager,
                                 angularUtils,
                                 waves,
                                 $element,
                                 ChartFactory) {

        const ds = require('data-service');
        const { utils } = require('@waves/signature-generator');
        const { Money } = require('@waves/data-entities');
        const { flatten } = require('ramda');

        const WCT_ID = WavesApp.network.code === 'T' ?
            WavesApp.defaultAssets.TRY :
            'DHgwrRvVyqJsepd32YbBqUeDH4GJ1N984X8QoekjgH8J';

        const PAIRS_IN_SLIDER = [
            {
                amount: WavesApp.defaultAssets.VST,
                price: 'WAVES'
            },
            {
                amount: WavesApp.defaultAssets.BTC,
                price: 'WAVES'
            },
            {
                amount: WCT_ID,
                price: 'WAVES'
            },
            {
                amount: WavesApp.defaultAssets.DASH,
                price: WavesApp.defaultAssets.BTC
            },
            {
                amount: WavesApp.defaultAssets.ETH,
                price: WavesApp.defaultAssets.BTC
            },
            {
                amount: WavesApp.defaultAssets.BCH,
                price: WavesApp.defaultAssets.BTC
            },
            {
                amount: WavesApp.defaultAssets.ETH,
                price: 'WAVES'
            },
            {
                amount: 'WAVES',
                price: WavesApp.defaultAssets.USD
            },
            {
                amount: WavesApp.defaultAssets.ZEC,
                price: 'WAVES'
            },
            {
                amount: WavesApp.defaultAssets.XMR,
                price: WavesApp.defaultAssets.BTC
            }
        ];

        const chartOptions = {
            red: {
                charts: [
                    {
                        axisX: 'timestamp',
                        axisY: 'rate',
                        lineColor: '#ef4829',
                        fillColor: '#FFF',
                        gradientColor: ['#FEEFEC', '#FFF'],
                        lineWidth: 4
                    }
                ]
            },
            blue: {
                charts: [
                    {
                        axisX: 'timestamp',
                        axisY: 'rate',
                        lineColor: '#1f5af6',
                        fillColor: '#FFF',
                        gradientColor: ['#EAF0FE', '#FFF'],
                        lineWidth: 4
                    }
                ]
            }
        };

        const whenHeaderGetFix = 60;

        class WelcomeCtrl extends Base {

            /**
             * @type {Array}
             * @public
             */
            pairsInfoList = [];

            constructor() {
                super($scope);

                this._initUserList();
                this._initPairs();
            }

            /**
             * @private
             */
            _addScrollHandler() {
                const scrolledView = $element.find('.scrolled-view');
                const header = $element.find('w-site-header');
                scrolledView.on('scroll', () => {
                    header.toggleClass('fixed', scrolledView.scrollTop() > whenHeaderGetFix);
                    header.toggleClass('unfixed', scrolledView.scrollTop() <= whenHeaderGetFix);
                });
            }

            /**
             * @public
             */
            showTutorialModals() {
                return modalManager.showTutorialModals();
            }

            /**
             * @public
             */
            goToDexDemo(pairAssets) {
                angularUtils.openDex(pairAssets.assetId1, pairAssets.assetId2, 'dex-demo');
            }

            /**
             * @private
             */
            _initPairs() {
                const startDate = angularUtils.moment().add().day(-7);
                Promise.all(PAIRS_IN_SLIDER.map(pair => ds.api.pairs.get(pair.amount, pair.price)))
                    .then(pairs => Promise.all(pairs.map(pair => ds.api.pairs.info(pair))))
                    .then(infoList => {
                        const tempInfoList = flatten(infoList);
                        Promise.all(tempInfoList.map(info => {
                            return waves.utils.getRateHistory(info.amountAsset.id, info.priceAsset.id, startDate);
                        })).then(rateHistory => {
                            this.pairsInfoList = tempInfoList.map((info, i) => {
                                return {
                                    volumeBigNum: info.volume.getTokens(),
                                    rateHistory: rateHistory[i],
                                    ...info
                                };
                            });
                        })
                            .catch(() => {
                                this.pairsInfoList = tempInfoList.map(this._fakeValues);
                            })
                            .then(() => {
                                angularUtils.safeApply($scope);
                                this._insertCharts();
                                this._addScrollHandler();
                            });
                    });
            }

            /**
             * @param info
             * @private
             */
            _fakeValues(info) {
                return {
                    rateHistory: [{
                        rate: new BigNumber(0),
                        timestamp: ds.utils.normalizeTime(Date.now())
                    }],
                    ticker: info.displayName,
                    amountAsset: info.amountAsset,
                    priceAsset: info.priceAsset,
                    change24: new BigNumber(0),
                    high: new Money(0, info.priceAsset),
                    id: info.id,
                    lastPrice: new Money(0, info.priceAsset),
                    low: new Money(0, info.priceAsset),
                    volume: new Money(0, info.priceAsset)
                };
            }

            /**
             * @private
             */
            _insertCharts() {
                const marketRows = $element.find('.table-markets .row-content');
                PAIRS_IN_SLIDER.forEach((pair, i) => {
                    const options = this.pairsInfoList[i].change24.gt(0) ? chartOptions.blue : chartOptions.red;
                    new ChartFactory(
                        marketRows.eq(i).find('.graph'),
                        options,
                        this.pairsInfoList[i].rateHistory
                    );
                });
            }

            /**
             * @private
             */
            _initUserList() {
                user.getUserList()
                    .then((list) => {
                        this.userList = list.filter(user => utils.crypto.isValidAddress(user.address));
                        this.pendingRestore = false;
                        setTimeout(() => {
                            $scope.$apply(); // TODO FIX!
                        }, 100);
                    });
            }

        }

        return new WelcomeCtrl();
    };

    controller.$inject = [
        'Base',
        '$scope',
        '$state',
        'user',
        'modalManager',
        'utils',
        'waves',
        '$element',
        'ChartFactory'
    ];

    angular.module('app.welcome')
        .controller('WelcomeCtrl', controller);
})();
<commit_msg>DEXW-1713: progress save<commit_after>(function () {
    'use strict';

    /**
     * @param Base
     * @param $scope
     * @param $state
     * @param user
     * @param modalManager
     * @param ChartFactory
     * @param {app.utils} angularUtils
     * @param {JQuery} $element
     * @param {Waves} waves
     * @return {WelcomeCtrl}
     */
    const controller = function (Base,
                                 $scope,
                                 $state,
                                 user,
                                 modalManager,
                                 angularUtils,
                                 waves,
                                 $element,
                                 ChartFactory) {

        const ds = require('data-service');
        const { utils } = require('@waves/signature-generator');
        const { Money } = require('@waves/data-entities');
        const { flatten } = require('ramda');

        const WCT_ID = WavesApp.network.code === 'T' ?
            WavesApp.defaultAssets.TRY :
            'DHgwrRvVyqJsepd32YbBqUeDH4GJ1N984X8QoekjgH8J';

        const PAIRS_IN_SLIDER = [
            {
                amount: WavesApp.defaultAssets.VST,
                price: 'WAVES'
            },
            {
                amount: WavesApp.defaultAssets.BTC,
                price: 'WAVES'
            },
            {
                amount: WCT_ID,
                price: 'WAVES'
            },
            {
                amount: WavesApp.defaultAssets.DASH,
                price: WavesApp.defaultAssets.BTC
            },
            {
                amount: WavesApp.defaultAssets.ETH,
                price: WavesApp.defaultAssets.BTC
            },
            {
                amount: WavesApp.defaultAssets.BCH,
                price: WavesApp.defaultAssets.BTC
            },
            {
                amount: WavesApp.defaultAssets.ETH,
                price: 'WAVES'
            },
            {
                amount: 'WAVES',
                price: WavesApp.defaultAssets.USD
            },
            {
                amount: WavesApp.defaultAssets.ZEC,
                price: 'WAVES'
            },
            {
                amount: WavesApp.defaultAssets.XMR,
                price: WavesApp.defaultAssets.BTC
            }
        ];

        const chartOptions = {
            red: {
                charts: [
                    {
                        axisX: 'timestamp',
                        axisY: 'rate',
                        lineColor: '#ef4829',
                        fillColor: '#FFF',
                        gradientColor: ['#FEEFEC', '#FFF'],
                        lineWidth: 4
                    }
                ]
            },
            blue: {
                charts: [
                    {
                        axisX: 'timestamp',
                        axisY: 'rate',
                        lineColor: '#1f5af6',
                        fillColor: '#FFF',
                        gradientColor: ['#EAF0FE', '#FFF'],
                        lineWidth: 4
                    }
                ]
            }
        };

        const whenHeaderGetFix = 60;

        class WelcomeCtrl extends Base {

            /**
             * @type {Array}
             * @public
             */
            pairsInfoList = [];

            constructor() {
                super($scope);

                this._initUserList();
                this._initPairs();
            }

            /**
             * @private
             */
            _addScrollHandler() {
                const scrolledView = $element.find('.scrolled-view');
                const header = $element.find('w-site-header');

                const contestLink = $element.find('.contect-link');
                const bodyHeight = document.body.offsetHeight;

                scrolledView.on('scroll', () => {
                    header.toggleClass('fixed', scrolledView.scrollTop() > whenHeaderGetFix);
                    header.toggleClass('unfixed', scrolledView.scrollTop() <= whenHeaderGetFix);

                    if (scrolledView.scrollTop() > bodyHeight) {
                        contestLink.removeClass('show');
                    }
                });
            }

            /**
             * @public
             */
            showTutorialModals() {
                return modalManager.showTutorialModals();
            }

            /**
             * @public
             */
            goToDexDemo(pairAssets) {
                angularUtils.openDex(pairAssets.assetId1, pairAssets.assetId2, 'dex-demo');
            }

            /**
             * @private
             */
            _initPairs() {
                const startDate = angularUtils.moment().add().day(-7);
                Promise.all(PAIRS_IN_SLIDER.map(pair => ds.api.pairs.get(pair.amount, pair.price)))
                    .then(pairs => Promise.all(pairs.map(pair => ds.api.pairs.info(pair))))
                    .then(infoList => {
                        const tempInfoList = flatten(infoList);
                        Promise.all(tempInfoList.map(info => {
                            return waves.utils.getRateHistory(info.amountAsset.id, info.priceAsset.id, startDate);
                        })).then(rateHistory => {
                            this.pairsInfoList = tempInfoList.map((info, i) => {
                                return {
                                    volumeBigNum: info.volume.getTokens(),
                                    rateHistory: rateHistory[i],
                                    ...info
                                };
                            });
                        })
                            .catch(() => {
                                this.pairsInfoList = tempInfoList.map(this._fakeValues);
                            })
                            .then(() => {
                                angularUtils.safeApply($scope);
                                this._insertCharts();
                                this._addScrollHandler();
                            });
                    });
            }

            /**
             * @param info
             * @private
             */
            _fakeValues(info) {
                return {
                    rateHistory: [{
                        rate: new BigNumber(0),
                        timestamp: ds.utils.normalizeTime(Date.now())
                    }],
                    ticker: info.displayName,
                    amountAsset: info.amountAsset,
                    priceAsset: info.priceAsset,
                    change24: new BigNumber(0),
                    high: new Money(0, info.priceAsset),
                    id: info.id,
                    lastPrice: new Money(0, info.priceAsset),
                    low: new Money(0, info.priceAsset),
                    volume: new Money(0, info.priceAsset)
                };
            }

            /**
             * @private
             */
            _insertCharts() {
                const marketRows = $element.find('.table-markets .row-content');
                PAIRS_IN_SLIDER.forEach((pair, i) => {
                    const options = this.pairsInfoList[i].change24.gt(0) ? chartOptions.blue : chartOptions.red;
                    new ChartFactory(
                        marketRows.eq(i).find('.graph'),
                        options,
                        this.pairsInfoList[i].rateHistory
                    );
                });
            }

            /**
             * @private
             */
            _initUserList() {
                user.getUserList()
                    .then((list) => {
                        this.userList = list.filter(user => utils.crypto.isValidAddress(user.address));
                        this.pendingRestore = false;
                        setTimeout(() => {
                            $scope.$apply(); // TODO FIX!
                        }, 100);
                    });
            }

        }

        return new WelcomeCtrl();
    };

    controller.$inject = [
        'Base',
        '$scope',
        '$state',
        'user',
        'modalManager',
        'utils',
        'waves',
        '$element',
        'ChartFactory'
    ];

    angular.module('app.welcome')
        .controller('WelcomeCtrl', controller);
})();
<|endoftext|>