<commit_before>var CLIENT_ID =
  "840179112792-bhg3k1h0dcnp9ltelj21o6vibphjcufe.apps.googleusercontent.com";

// Array of API discovery doc URLs for APIs used
var DISCOVERY_DOCS = [
  "https://sheets.googleapis.com/$discovery/rest?version=v4"
];

// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = "https://www.googleapis.com/auth/spreadsheets";

// expense sheet id
var SPREADSHEET_ID = "1tAd4YjX8VgRkRG8-LXuYLhlUsyZgxLsRKqvbK74fetY";

var authorizeButton = document.getElementById("authorize-button");
var signoutButton = document.getElementById("signout-button");
var expenseForm = document.getElementById("expense-form");

var description = document.getElementById("description");
var date = document.getElementById("date");
var accountSelect = document.getElementById("account");
var categorySelect = document.getElementById("category");
var amount = document.getElementById("amount");
var income = document.getElementById("is-income");
var formLoader = document.getElementById("form-loader");
var snackbarContainer = document.getElementById("toast-container");

/**
 *  On load, called to load the auth2 library and API client library.
 */
function handleClientLoad() {
  gapi.load("client:auth2", initClient);
}

/**
 *  Initializes the API client library and sets up sign-in state
 *  listeners.
 */
function initClient() {
  gapi.client
    .init({
      discoveryDocs: DISCOVERY_DOCS,
      clientId: CLIENT_ID,
      scope: SCOPES
    })
    .then(function() {
      // Listen for sign-in state changes.
      gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

      // Handle the initial sign-in state.
      updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
      authorizeButton.onclick = handleAuthClick;
      signoutButton.onclick = handleSignoutClick;
    });
}

/**
 *  Called when the signed in status changes, to update the UI
 *  appropriately. After a sign-in, the API is called.
 */
function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    authorizeButton.style.display = "none";
    signoutButton.style.display = "block";
    expenseForm.style.display = "flex";
    formLoader.style.display = "none";
    updateAccounts();
    updateCategories();
  } else {
    authorizeButton.style.display = "block";
    signoutButton.style.display = "none";
    expenseForm.style.display = "none";
    formLoader.style.display = "none";
  }
}

/**
 *  Sign in the user upon button click.
 */
function handleAuthClick(event) {
  gapi.auth2.getAuthInstance().signIn();
}

/**
 *  Sign out the user upon button click.
 */
function handleSignoutClick(event) {
  gapi.auth2.getAuthInstance().signOut();
}

/**
 * Add expense to the sheet
 */
function addExpense(event) {
  if (!expenseForm.checkValidity()) {
    return;
  }

  event.preventDefault();
  formLoader.style.display = "block";
  expenseForm.style.display = "none";

  var epochDay = new Date(1899, 11, 31);
  var expenseDate = new Date(date.value);
  var oneDay = 24 * 60 * 60 * 1000;

  var days = Math.round(
    Math.abs(epochDay.getTime() - expenseDate.getTime()) / oneDay
  );
  var description = desc.value;
  var account = accountSelect.value;
  var category = categorySelect.value;
  var amountVal = amount.value;
  var isIncome = income.checked;

  var request = {
    // The ID of the spreadsheet to update.
    spreadsheetId: SPREADSHEET_ID,

    // The A1 notation of a range to search for a logical table of data.
    // Values will be appended after the last row of the table.
    range: "Expenses!A1",

    includeValuesInResponse: true,

    responseDateTimeRenderOption: "FORMATTED_STRING",

    responseValueRenderOption: "FORMATTED_VALUE",

    // How the input data should be interpreted.
    valueInputOption: "USER_ENTERED",

    // How the input data should be inserted.
    insertDataOption: "INSERT_ROWS",

    resource: {
      values: [
        [
          days,
          description,
          account,
          category,
          isIncome ? 0 : amountVal,
          isIncome ? amountVal : 0
        ]
      ]
    }
  };

  gapi.client.sheets.spreadsheets.values
    .append(request)
    .then(function(response) {
      if (response.status !== 200) {
        console.log(response);
        snackbarContainer.MaterialSnackbar.showSnackbar({
          message: "Sorry something went wrong!"
        });
        return;
      }

      date.value = "";
      desc.value = "";
      accountSelect.value = "";
      categorySelect.value = "";
      amount.value = "";
      income.checked = false;
      formLoader.style.display = "none";
      expenseForm.style.display = "flex";

      snackbarContainer.MaterialSnackbar.showSnackbar({
        message: "Expense added!"
      });
    });
  return false;
}

/**
 * Fetch all accounts from sheet and update the select dropdown
 */
function updateAccounts() {
  gapi.client.sheets.spreadsheets.values
    .get(getRequestObj("Data!A5:A50"))
    .then(function(response) {
      var accounts = "";
      var allValues = response.result.values[0];
      allValues.forEach(function(value) {
        accounts += wrapInOption(value);
      });

      accountSelect.innerHTML = accounts;
    });
}

/**
 * Fetch expense categories from sheet and update the select dropdown
 */
function updateCategories() {
  gapi.client.sheets.spreadsheets.values
    .get(getRequestObj("Data!E5:E50"))
    .then(function(response) {
      var categories = "";
      var allValues = response.result.values[0];
      allValues.forEach(function(value) {
        categories += wrapInOption(value);
      });

      categorySelect.innerHTML = categories;
    });
}

function getRequestObj(range) {
  return {
    spreadsheetId: SPREADSHEET_ID,
    range: range,
    dateTimeRenderOption: "FORMATTED_STRING",
    majorDimension: "COLUMNS",
    valueRenderOption: "FORMATTED_VALUE"
  };
}

function wrapInOption(option) {
  return `<option value='${option}'>${option}</option>`;
}

// register for service worker
if ("serviceWorker" in navigator) {
  window.addEventListener("load", function() {
    navigator.serviceWorker.register("sw.js").then(
      function(registration) {
        // Registration was successful
        console.log(
          "ServiceWorker registration successful with scope: ",
          registration.scope
        );
      },
      function(err) {
        // registration failed :(
        console.log("ServiceWorker registration failed: ", err);
      }
    );
  });
}
<commit_msg>update ranges<commit_after>var CLIENT_ID =
  "840179112792-bhg3k1h0dcnp9ltelj21o6vibphjcufe.apps.googleusercontent.com";

// Array of API discovery doc URLs for APIs used
var DISCOVERY_DOCS = [
  "https://sheets.googleapis.com/$discovery/rest?version=v4"
];

// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = "https://www.googleapis.com/auth/spreadsheets";

// expense sheet id
var SPREADSHEET_ID = "1tAd4YjX8VgRkRG8-LXuYLhlUsyZgxLsRKqvbK74fetY";

var authorizeButton = document.getElementById("authorize-button");
var signoutButton = document.getElementById("signout-button");
var expenseForm = document.getElementById("expense-form");

var description = document.getElementById("description");
var date = document.getElementById("date");
var accountSelect = document.getElementById("account");
var categorySelect = document.getElementById("category");
var amount = document.getElementById("amount");
var income = document.getElementById("is-income");
var formLoader = document.getElementById("form-loader");
var snackbarContainer = document.getElementById("toast-container");

/**
 *  On load, called to load the auth2 library and API client library.
 */
function handleClientLoad() {
  gapi.load("client:auth2", initClient);
}

/**
 *  Initializes the API client library and sets up sign-in state
 *  listeners.
 */
function initClient() {
  gapi.client
    .init({
      discoveryDocs: DISCOVERY_DOCS,
      clientId: CLIENT_ID,
      scope: SCOPES
    })
    .then(function() {
      // Listen for sign-in state changes.
      gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

      // Handle the initial sign-in state.
      updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
      authorizeButton.onclick = handleAuthClick;
      signoutButton.onclick = handleSignoutClick;
    });
}

/**
 *  Called when the signed in status changes, to update the UI
 *  appropriately. After a sign-in, the API is called.
 */
function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    authorizeButton.style.display = "none";
    signoutButton.style.display = "block";
    expenseForm.style.display = "flex";
    formLoader.style.display = "none";
    updateAccounts();
    updateCategories();
  } else {
    authorizeButton.style.display = "block";
    signoutButton.style.display = "none";
    expenseForm.style.display = "none";
    formLoader.style.display = "none";
  }
}

/**
 *  Sign in the user upon button click.
 */
function handleAuthClick(event) {
  gapi.auth2.getAuthInstance().signIn();
}

/**
 *  Sign out the user upon button click.
 */
function handleSignoutClick(event) {
  gapi.auth2.getAuthInstance().signOut();
}

/**
 * Add expense to the sheet
 */
function addExpense(event) {
  if (!expenseForm.checkValidity()) {
    return;
  }

  event.preventDefault();
  formLoader.style.display = "block";
  expenseForm.style.display = "none";

  var epochDay = new Date(1899, 11, 31);
  var expenseDate = new Date(date.value);
  var oneDay = 24 * 60 * 60 * 1000;

  var days = Math.round(
    Math.abs(epochDay.getTime() - expenseDate.getTime()) / oneDay
  );
  var description = desc.value;
  var account = accountSelect.value;
  var category = categorySelect.value;
  var amountVal = amount.value;
  var isIncome = income.checked;

  var request = {
    // The ID of the spreadsheet to update.
    spreadsheetId: SPREADSHEET_ID,

    // The A1 notation of a range to search for a logical table of data.
    // Values will be appended after the last row of the table.
    range: "Expenses!A1",

    includeValuesInResponse: true,

    responseDateTimeRenderOption: "FORMATTED_STRING",

    responseValueRenderOption: "FORMATTED_VALUE",

    // How the input data should be interpreted.
    valueInputOption: "USER_ENTERED",

    // How the input data should be inserted.
    insertDataOption: "INSERT_ROWS",

    resource: {
      values: [
        [
          days,
          description,
          account,
          category,
          isIncome ? 0 : amountVal,
          isIncome ? amountVal : 0
        ]
      ]
    }
  };

  gapi.client.sheets.spreadsheets.values
    .append(request)
    .then(function(response) {
      if (response.status !== 200) {
        console.log(response);
        snackbarContainer.MaterialSnackbar.showSnackbar({
          message: "Sorry something went wrong!"
        });
        return;
      }

      date.value = "";
      desc.value = "";
      accountSelect.value = "";
      categorySelect.value = "";
      amount.value = "";
      income.checked = false;
      formLoader.style.display = "none";
      expenseForm.style.display = "flex";

      snackbarContainer.MaterialSnackbar.showSnackbar({
        message: "Expense added!"
      });
    });
  return false;
}

/**
 * Fetch all accounts from sheet and update the select dropdown
 */
function updateAccounts() {
  gapi.client.sheets.spreadsheets.values
    .get(getRequestObj("Data!A2:A50"))
    .then(function(response) {
      var accounts = "";
      var allValues = response.result.values[0];
      allValues.forEach(function(value) {
        accounts += wrapInOption(value);
      });

      accountSelect.innerHTML = accounts;
    });
}

/**
 * Fetch expense categories from sheet and update the select dropdown
 */
function updateCategories() {
  gapi.client.sheets.spreadsheets.values
    .get(getRequestObj("Data!E2:E50"))
    .then(function(response) {
      var categories = "";
      var allValues = response.result.values[0];
      allValues.forEach(function(value) {
        categories += wrapInOption(value);
      });

      categorySelect.innerHTML = categories;
    });
}

function getRequestObj(range) {
  return {
    spreadsheetId: SPREADSHEET_ID,
    range: range,
    dateTimeRenderOption: "FORMATTED_STRING",
    majorDimension: "COLUMNS",
    valueRenderOption: "FORMATTED_VALUE"
  };
}

function wrapInOption(option) {
  return `<option value='${option}'>${option}</option>`;
}

// register for service worker
if ("serviceWorker" in navigator) {
  window.addEventListener("load", function() {
    navigator.serviceWorker.register("sw.js").then(
      function(registration) {
        // Registration was successful
        console.log(
          "ServiceWorker registration successful with scope: ",
          registration.scope
        );
      },
      function(err) {
        // registration failed :(
        console.log("ServiceWorker registration failed: ", err);
      }
    );
  });
}
<|endoftext|>


<commit_before>$('#close-upload').on('click', function(){
    $('#fileForm').foundation('reveal', 'close')
});

var filesuploaded = 0;
var filesprocessed = 0;
$( function() {
    'use strict';

    /*
        Initialize the jQuery File Upload widget.

        Default options are defined by the package,
        however users may extend and define their
        own options.
    */

    var formData = $('#fileupload').serializeArray();
    formData.push(
        {name:"redirect",value:""},
        {name:"max_file_size",value:"{{ max_file_size }}"},
        {name:"max_file_count",value:"{{ max_file_count }}"},
        {name:"expires",value:"{{ expires }}"},
        {name:"signature",value:"{{ signature }}"}
    );

    $('#fileupload').fileupload({
        formData: formData,
        url: '{{ swift_url }}',
        method:'POST',
        dataType:'text',
        sequentialUploads: true,
        recalculateProgress: false,
        previewMaxWidth:100,
        previewMaxHeight:100
    })

    .bind('fileuploadprocessstart', function (e) {
        $('#preloadmsg').hide();
        $('.fileupload-progress').show();
        $('#start-upload').removeClass('disabled');
        $('#cancel-upload').removeClass('disabled');
    })

    .bind('fileuploadprocessdone', function (e, data) {
        filesprocessed = filesprocessed + 1;
    })

    .bind('fileuploadsend', function (e, data) {
        Foundation.libs.reveal.settings.close_on_background_click = false;
        $('#close-upload').off().addClass('disabled');

        $.each(data.files, function (index, file) {

            $('#fileForm').foundation({reveal : {close_on_background_click: false,close_on_esc:false}});
        });
    })

    .bind('fileuploadfail', function (e, data) {
        closeForm();
    })

    .bind('fileuploadcompleted', function (e, data) {
        filesuploaded = filesuploaded + 1;
        if (filesprocessed == filesuploaded) {
            closeForm();
        }
    })
    .addClass('fileupload-processing');

});

function closeForm() {
    $('#fileForm').foundation({reveal : {close_on_background_click: true,close_on_esc:true}});
    setTimeout(function(){
        $('#fileForm').foundation('reveal', 'close');
        setTimeout(function(){
            $('#preloadmsg').show();
            $('.fileupload-progress').hide();
            $('#start-upload').addClass('disabled');
            $('#cancel-upload').addClass('disabled');
            $('#close-upload').on('click', function(){
                $('#fileForm').foundation('reveal', 'close');
            }).removeClass('disabled');
        }, 250);
    }, 250);
    if(filesuploaded > 0) {
        $('#messages').html(
            '
' +
                '
' +
                    '
' +
                        'Success. ' + filesuploaded +
                        ' files were added. ×' +
                    '
' +
                '
' +
            '
'
        );
    }
}

/*
    Modify jquery fileupload's onAdd method. This method recreates
    the file object pointer and changes the name. The name change allows
    users to drag and drop directories and those directories are
    recreated on swift.

*/
$.blueimp.fileupload.prototype._onAdd = function (e, data) {
    var that = this,
        result = true,
        options = $.extend({}, this.options, data),
        files = data.files,
        filesLength = files.length,
        limit = options.limitMultiFileUploads,
        limitSize = options.limitMultiFileUploadSize,
        overhead = options.limitMultiFileUploadSizeOverhead,
        batchSize = 0,
        paramName = this._getParamName(options),
        paramNameSet,
        paramNameSlice,
        fileSet,
        i,
        j = 0;
    if (limitSize && (!filesLength || files[0].size === undefined)) {
        limitSize = undefined;
    }
    if (!(options.singleFileUploads || limit || limitSize) ||
            !this._isXHRUpload(options)) {
        fileSet = [files];
        paramNameSet = [paramName];
    } else if (!(options.singleFileUploads || limitSize) && limit) {
        fileSet = [];
        paramNameSet = [];
        for (i = 0; i < filesLength; i += limit) {
            fileSet.push(files.slice(i, i + limit));
            paramNameSlice = paramName.slice(i, i + limit);
            if (!paramNameSlice.length) {
                paramNameSlice = paramName;
            }
            paramNameSet.push(paramNameSlice);
        }
    } else if (!options.singleFileUploads && limitSize) {
        fileSet = [];
        paramNameSet = [];
        for (i = 0; i < filesLength; i = i + 1) {
            batchSize += files[i].size + overhead;
            if (i + 1 === filesLength ||
                    ((batchSize + files[i + 1].size + overhead) > limitSize) ||
                    (limit && i + 1 - j >= limit)) {
                fileSet.push(files.slice(j, i + 1));
                paramNameSlice = paramName.slice(j, i + 1);
                if (!paramNameSlice.length) {
                    paramNameSlice = paramName;
                }
                paramNameSet.push(paramNameSlice);
                j = i + 1;
                batchSize = 0;
            }
        }
    } else {
        paramNameSet = paramName;
    }
    data.originalFiles = files;
    $.each(fileSet || files, function (index, element) {

        /****************** Swift browser edits here ******************/
        /*
            A new File object is created using "element". This new file
            has a different ".name". This new name allows swift to
            create pseudo folders. The end result is the file structure
            that is dragged and dropped in swiftbrowser is preserved on
            swift.
        */

        if (element.relativePath) {
            var element = new File([element], element.relativePath + element.name, {type: "text/plain"});

        } else if (element.webkitRelativePath){
            console.log(typeof element.webkitRelativePath);
            var element = new File([element], element.webkitRelativePath + element.name, {type: "text/plain"});

        }
        var newData = $.extend({}, data);
        newData.files = fileSet ? element : [element];
        newData.paramName = paramNameSet[index];
        that._initResponseObject(newData);
        that._initProgressObject(newData);
        that._addConvenienceMethods(e, newData);
        result = that._trigger(
            'add',
            $.Event('add', {delegatedEvent: e}),
            newData
        );
        return result;
    });
    return result;
}
<commit_msg>Close modal on upload complete.<commit_after>$('#close-upload').on('click', function(){
    $('#fileForm').foundation('reveal', 'close');
});

var files_added = 0; /* Track files added to the upload. */
var files_processed = 0; /* Track files that are processed.*/
var files_uploaded = 0; /* Track successful uploads. */
$( function() {
    'use strict';

    /*
        Initialize the jQuery File Upload widget.

        Default options are defined by the package,
        however users may extend and define their
        own options.
    */

    var formData = $('#fileupload').serializeArray();
    formData.push(
        {name:"redirect",value:""},
        {name:"max_file_size",value:"{{ max_file_size }}"},
        {name:"max_file_count",value:"{{ max_file_count }}"},
        {name:"expires",value:"{{ expires }}"},
        {name:"signature",value:"{{ signature }}"}
    );

    $('#fileupload').fileupload({
        formData: formData,
        url: '{{ swift_url }}',
        method:'POST',
        dataType:'text',
        sequentialUploads: true,
        recalculateProgress: false,
        previewMaxWidth:100,
        previewMaxHeight:100
    })

    // Keep a counter of files as they are added.
    .bind('fileuploadadd', function (e, data) {
        files_added += 1;
    })

    .bind('fileuploaddone', function (e, data) {
        files_uploaded += 1;
    })

    .bind('fileuploadprocessstart', function (e) {
        $('#preloadmsg').hide();
        $('.fileupload-progress').show();
        $('#start-upload').removeClass('disabled');
        $('#cancel-upload').removeClass('disabled');
    })

    .bind('fileuploadsend', function (e, data) {
        Foundation.libs.reveal.settings.close_on_background_click = false;
        $('#close-upload').off().addClass('disabled');

        $.each(data.files, function (index, file) {

            $('#fileForm').foundation({reveal : {close_on_background_click: false,close_on_esc:false}});
        });
    })

    // Keep a counter of files as they are processed.
    .bind('fileuploadalways', function (e, data) {
        files_processed += 1;

        // If all fiels have been processed, close the form.
        if (files_processed == files_added) {
            closeForm();
        }
    })
    .addClass('fileupload-processing');

});

function closeForm() {
    $('#fileForm').foundation({reveal : {close_on_background_click: true,close_on_esc:true}});
    setTimeout(function(){
        $('#fileForm').foundation('reveal', 'close');
        setTimeout(function(){
            $('#preloadmsg').show();
            $('.fileupload-progress').hide();
            $('#start-upload').addClass('disabled');
            $('#cancel-upload').addClass('disabled');
            $('#close-upload').on('click', function(){
                $('#fileForm').foundation('reveal', 'close');
            }).removeClass('disabled');
        }, 250);
    }, 250);
    if(files_uploaded > 0) {
        $('#messages').html(
            '
' +
                '
' +
                    '
' +
                        'Success. ' + files_uploaded +
                        ' files were added. ×' +
                    '
' +
                '
' +
            '
'
        );
    }
}

/*
    Modify jquery fileupload's onAdd method. This method recreates
    the file object pointer and changes the name. The name change allows
    users to drag and drop directories and those directories are
    recreated on swift.

*/
$.blueimp.fileupload.prototype._onAdd = function (e, data) {
    var that = this,
        result = true,
        options = $.extend({}, this.options, data),
        files = data.files,
        filesLength = files.length,
        limit = options.limitMultiFileUploads,
        limitSize = options.limitMultiFileUploadSize,
        overhead = options.limitMultiFileUploadSizeOverhead,
        batchSize = 0,
        paramName = this._getParamName(options),
        paramNameSet,
        paramNameSlice,
        fileSet,
        i,
        j = 0;
    if (limitSize && (!filesLength || files[0].size === undefined)) {
        limitSize = undefined;
    }
    if (!(options.singleFileUploads || limit || limitSize) ||
            !this._isXHRUpload(options)) {
        fileSet = [files];
        paramNameSet = [paramName];
    } else if (!(options.singleFileUploads || limitSize) && limit) {
        fileSet = [];
        paramNameSet = [];
        for (i = 0; i < filesLength; i += limit) {
            fileSet.push(files.slice(i, i + limit));
            paramNameSlice = paramName.slice(i, i + limit);
            if (!paramNameSlice.length) {
                paramNameSlice = paramName;
            }
            paramNameSet.push(paramNameSlice);
        }
    } else if (!options.singleFileUploads && limitSize) {
        fileSet = [];
        paramNameSet = [];
        for (i = 0; i < filesLength; i = i + 1) {
            batchSize += files[i].size + overhead;
            if (i + 1 === filesLength ||
                    ((batchSize + files[i + 1].size + overhead) > limitSize) ||
                    (limit && i + 1 - j >= limit)) {
                fileSet.push(files.slice(j, i + 1));
                paramNameSlice = paramName.slice(j, i + 1);
                if (!paramNameSlice.length) {
                    paramNameSlice = paramName;
                }
                paramNameSet.push(paramNameSlice);
                j = i + 1;
                batchSize = 0;
            }
        }
    } else {
        paramNameSet = paramName;
    }
    data.originalFiles = files;
    $.each(fileSet || files, function (index, element) {

        /****************** Swift browser edits here ******************/
        /*
            A new File object is created using "element". This new file
            has a different ".name". This new name allows swift to
            create pseudo folders. The end result is the file structure
            that is dragged and dropped in swiftbrowser is preserved on
            swift.
        */

        if (element.relativePath) {
            var element = new File([element], element.relativePath + element.name, {type: "text/plain"});

        } else if (element.webkitRelativePath){
            console.log(typeof element.webkitRelativePath);
            var element = new File([element], element.webkitRelativePath + element.name, {type: "text/plain"});

        }
        var newData = $.extend({}, data);
        newData.files = fileSet ? element : [element];
        newData.paramName = paramNameSet[index];
        that._initResponseObject(newData);
        that._initProgressObject(newData);
        that._addConvenienceMethods(e, newData);
        result = that._trigger(
            'add',
            $.Event('add', {delegatedEvent: e}),
            newData
        );
        return result;
    });
    return result;
}
<|endoftext|>


<commit_before>'use strict';

const smoochBot = require('smooch-bot');
const MemoryStore = smoochBot.MemoryStore;
const MemoryLock = smoochBot.MemoryLock;
const Bot = smoochBot.Bot;
const Script = smoochBot.Script;
const StateMachine = smoochBot.StateMachine;

class ConsoleBot extends Bot {
    constructor(options) {
        super(options);
    }

    say(text) {
        return new Promise((resolve) => {
            console.log(text);
            resolve();
        });
    }
}

const script = new Script({

  // processing: {
  // prompt: (bot) => bot.say(`![](http://www.bieg.nl/beeld/speechbubble.gif)`),
  // receive: () => 'processing'
  // },

  start: {
      receive: (bot) => {
            return bot.say(`${groet}... Wat voor soort hypotheek zoek je? `)
            .then(() => bot.say(`![](http://www.bieg.nl/beeld/woningen.jpg)`))
            .then(() => bot.say(`%[Starters Hypotheek](postback:hypotheektype_starter)`))
            .then(() => bot.say (`%[Nieuwe hypotheek](postback:hypotheektype_nieuw) `))
            .then(() => bot.say (`%[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`))
            .then(() => 'processing');
      }
  },

    askName: {
        prompt: (bot) => bot.say('What\'s your name'),
        receive: (bot, message) => {
            const name = message.text.trim();
            bot.setProp('name', name);
            return bot.say(`I'll call you ${name}! Great!`)
                .then(() => 'finish');
        }
    },

    finish: {
        receive: (bot, message) => {
            return bot.getProp('name')
                .then((name) => bot.say(`Sorry ${name}, my creator didn't ` +
                        'teach me how to do anything else!'))
                .then(() => 'finish');
        }
    }
});

const userId = 'testUserId';
const store = new MemoryStore();
const lock = new MemoryLock();
const bot = new ConsoleBot({
    store,
    lock,
    userId
});

const stateMachine = new StateMachine({
    script,
    bot,
    userId
});

process.stdin.on('data', function(data) {
    stateMachine.receiveMessage({
        text: data.toString().trim()
    })
        .catch((err) => {
            console.error(err);
            console.error(err.stack);
        });
});
<commit_msg>script<commit_after>'use strict';

const smoochBot = require('smooch-bot');
const MemoryStore = smoochBot.MemoryStore;
const MemoryLock = smoochBot.MemoryLock;
const Bot = smoochBot.Bot;
//const Script = smoochBot.Script;
const StateMachine = smoochBot.StateMachine;

const _ = require('lodash');
const Script = require('smooch-bot').Script;
const scriptRules = require('./script.json');

class ConsoleBot extends Bot {
    constructor(options) {
        super(options);
    }

    say(text) {
        return new Promise((resolve) => {
            console.log(text);
            resolve();
        });
    }
}

const script = new Script({

  // processing: {
  // prompt: (bot) => bot.say(`![](http://www.bieg.nl/beeld/speechbubble.gif)`),
  // receive: () => 'processing'
  // },

  start: {
      receive: (bot) => {
            return bot.say(`${groet}... Wat voor soort hypotheek zoek je? `)
            .then(() => bot.say(`![](http://www.bieg.nl/beeld/woningen.jpg)`))
            .then(() => bot.say(`%[Starters Hypotheek](postback:hypotheektype_starter)`))
            .then(() => bot.say (`%[Nieuwe hypotheek](postback:hypotheektype_nieuw) `))
            .then(() => bot.say (`%[Hypotheek oversluiten](postback:hypotheektype_oversluiten)`))
            .then(() => 'processing');
      }
  },

    askName: {
        prompt: (bot) => bot.say('What\'s your name'),
        receive: (bot, message) => {
            const name = message.text.trim();
            bot.setProp('name', name);
            return bot.say(`I'll call you ${name}! Great!`)
                .then(() => 'finish');
        }
    },

    finish: {
        receive: (bot, message) => {
            return bot.getProp('name')
                .then((name) => bot.say(`Sorry ${name}, my creator didn't ` +
                        'teach me how to do anything else!'))
                .then(() => 'finish');
        }
    }
});

const userId = 666;
const store = new MemoryStore();
const lock = new MemoryLock();
const bot = new ConsoleBot({
    store,
    lock,
    userId
});

const stateMachine = new StateMachine({
    script,
    bot,
    userId
});

process.stdin.on('data', function(data) {
    stateMachine.receiveMessage({
        text: data.toString().trim()
    })
        .catch((err) => {
            console.error(err);
            console.error(err.stack);
        });
});
<|endoftext|>


<commit_before>// Substitutes

var chars = {
	'o': ['0'],
	'e': ['3'],
	'i': ['1']
}

// this is matched using regex (case-insensitive)
// the following match anywhere in the text
var words = {
	'tha': 'da',
	'wha': 'wa',
	'this': 'dis'
}
// the follwing should match at word end (or they should be complete words)
var endWords = {
	'ith': 'id',
	'es': 'ezz',
	'my': 'mah'
}
// the following should match whole words
var completeWords = {
	'is': 'izz',
	'you': 'u',
	'are': 'r',
	'the': 'da'
}

// join to words
for (var key in endWords){
	words[key + '(?=[^a-z])'] = endWords[key]
}
for (var key in completeWords){
	words['([^a-z]|^)' + key + '(?=[^a-z])'] = '$1' + completeWords[key]
}

function convertChars(text){
	var text = String(text)
	var probab = 0.5

	for (var key in words) {
		reg = new RegExp(key, "gi")
		var bracketCount = (key.match(/\(/g) || []).length

		if (reg.test(text)){
			// replace
			text = text.replace(reg, (match, p1, p2) => {
				chance = Math.random()
				if (chance <= probab){
					if (bracketCount < 2){
						return words[key]
					} else if (bracketCount == 2){  // ([ae])s: $1zz, complete words
						return words[key].replace("$1", p1)
					}
				} else {
					return match
				}
			})
			// end replace
		}
	}

	return text
}

function loadSubstitutes(orig, newCh){
	list = [newCh]
	orig = orig.toLowerCase()
	if (orig in chars) {
		Array.prototype.push.apply(list, chars[orig]);
	}
	return list
}

function convertSingleChar(text){
	var probab = 0.5
	len = text.length
	var newText = ""

	for (var i=0; i < len; i++){
		charCode = text[i].charCodeAt()
		chance = Math.random()

		if (chance <= probab){
			if (charCode >= 65 && charCode <= 90){
				subs = loadSubstitutes(text[i], String.fromCharCode(charCode + 32))
				newText += subs[Math.floor(Math.random() * subs.length)]; // random from list
			} else if (charCode >= 97 && charCode <= 122){
				subs = loadSubstitutes(text[i], String.fromCharCode(charCode - 32))
				newText += subs[Math.floor(Math.random() * subs.length)];
			} else {
				newText += text[i]
			}
		} else {
			newText += text[i]
		}
	}

	return newText
}

function inputChangeEvent(){
	val = $("#input").val()
	newVal = convertChars(val)
	console.log(newVal)
	newVal = convertSingleChar(newVal)
	console.log(newVal)
	$("#output").text(newVal)
}

$(document).ready(function(){
	$("#input").bind('input propertychange', inputChangeEvent)
})
<commit_msg>improve lower to upper and v.v. replacement logic<commit_after>// Substitutes

var chars = {
	'o': ['0'],
	'e': ['3'],
	'i': ['1']
}

// this is matched using regex (case-insensitive)
// the following match anywhere in the text
var words = {
	'tha': 'da',
	'wha': 'wa',
	'this': 'dis'
}
// the follwing should match at word end (or they should be complete words)
var endWords = {
	'ith': 'id',
	'es': 'ezz',
	'my': 'mah'
}
// the following should match whole words
var completeWords = {
	'is': 'izz',
	'you': 'u',
	'are': 'r',
	'the': 'da'
}

// join to words
for (var key in endWords){
	words[key + '(?=[^a-z])'] = endWords[key]
}
for (var key in completeWords){
	words['([^a-z]|^)' + key + '(?=[^a-z])'] = '$1' + completeWords[key]
}

function convertChars(text){
	var text = String(text)
	var probab = 0.6

	for (var key in words) {
		reg = new RegExp(key, "gi")
		var bracketCount = (key.match(/\(/g) || []).length

		if (reg.test(text)){
			// replace
			text = text.replace(reg, (match, p1, p2) => {
				chance = Math.random()
				if (chance <= probab){
					if (bracketCount < 2){
						return words[key]
					} else if (bracketCount == 2){  // ([ae])s: $1zz, complete words
						return words[key].replace("$1", p1)
					}
				} else {
					return match
				}
			})
			// end replace
		}
	}

	return text
}

function loadSubstitutes(orig, newCh){
	list = [newCh]
	orig = orig.toLowerCase()
	if (orig in chars) {
		Array.prototype.push.apply(list, chars[orig]);
	}
	return list
}

function convertSingleChar(text){
	var upProbab = 0.5
	var downProbab = 0.7
	len = text.length
	var newText = ""

	for (var i=0; i < len; i++){
		charCode = text[i].charCodeAt()
		chance = Math.random()

		if (charCode >= 65 && charCode <= 90 && chance <= downProbab){
			subs = loadSubstitutes(text[i], String.fromCharCode(charCode + 32))
			newText += subs[Math.floor(Math.random() * subs.length)]; // random from list
		} else if (charCode >= 97 && charCode <= 122 && chance <= upProbab){
			subs = loadSubstitutes(text[i], String.fromCharCode(charCode - 32))
			newText += subs[Math.floor(Math.random() * subs.length)];
		} else {
			newText += text[i]
		}
	}

	return newText
}

function inputChangeEvent(){
	val = $("#input").val()
	newVal = convertChars(val)
	console.log(newVal)
	newVal = convertSingleChar(newVal)
	console.log(newVal)
	$("#output").text(newVal)
}

$(document).ready(function(){
	$("#input").bind('input propertychange', inputChangeEvent)
})
<|endoftext|>


<commit_before>/*
  Random Word Maker
  ==============
  Irvel Nduva
  irvel.com
  Marzo 2015
*/

function cambiardP(){
  var xmlHttp = null;
  xmlHttp = new XMLHttpRequest();
  xmlHttp.open( "GET", "http://randomword.setgetgo.com/get.php", true );
  xmlHttp.send();
  document.getElementById("palabraInventada").innerHTML = xmlHttp.responseText;
};

 function cambiarP() {
        var requestStr = "http://randomword.setgetgo.com/get.php";

        $.ajax({
            type: "GET",
            url: requestStr,
            dataType: "jsonp",
            jsonpCallback: 'RandomWordComplete'
        });
    };

    function RandomWordComplete(data) {
        document.getElementById("palabraInventada").innerHTML = data.Word;
    };
<commit_msg>Added changes to script.js from gh-pages<commit_after>/*
  Random Word Maker
  ==============
  Irvel Nduva
  irvel.com
  Marzo 2015
*/

function cambiarP() {
  var word1;
  var word2;
  var word3;
  var requestStr = "http://randomword.setgetgo.com/get.php";
    $.ajax({
      type: "GET",
      url: requestStr,
      dataType: "jsonp",
      jsonpCallback: 'RandomWordComplete'
  });
};

function RandomWordComplete(data) {
  document.getElementById("palabraInventada").innerHTML = data.Word;
};
<|endoftext|>


<commit_before>var vger =  angular.module('vger', []);

vger.run(['$rootScope', function ($rootScope) {
    // set visibility state for elements
    $rootScope.loading = true;
    $rootScope.messageVisible = false;
    $rootScope.mapVisible = true;
    $rootScope.spreadMenu = false;

    // set map on screen
    $rootScope.screenMap = L.map('map', {zoomControl: false}).locate({setView: true, maxZoom: 15});
    L.control.zoom({position: 'bottomleft'}).addTo($rootScope.screenMap);
    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap contributors'
    }).addTo($rootScope.screenMap);

    // check if running as phonegap app
    var phonegapApp = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1;
    if (phonegapApp) {
        document.addEventListener("deviceready", onDeviceReady, false);

        function onDeviceReady() {
            document.addEventListener("menubutton", onMenuKeyDown, false);
        }

        function onMenuKeyDown() {
            $rootScope.spreadMenu = !$rootScope.spreadMenu;
        }
    }
}]);

vger.controller('ListCtrl', ['$rootScope', '$scope', '$http', function ($rootScope, $scope, $http) {

    var markIcon = L.icon({
        iconUrl: 'icon.svg',
        iconSize:     [32, 48], // size of the icon
        shadowSize:   [40, 48], // size of the shadow
        iconAnchor:   [16, 48], // point of the icon which will correspond to marker's location
        popupAnchor:  [0, -52] // point from which the popup should open relative to the iconAnchor
    });

    $scope.currentLocationMarkers = new Array();

	// get wikipedia entries for given position
	var getWikipediaEntries = function(lat, lng) {
        // store bound limits to zoom the map and show all entries
        var southWestBound = [0, 0],
            northEastBound = [0, 0];

        $rootScope.loading = true;
        angular.forEach($scope.entries, function(value, index) {
            value.marker.closePopup().unbindPopup().setOpacity(0);
        });
        $scope.entries = [];
        //get list of closer entries
        $http.jsonp('http://en.wikipedia.org/w/api.php?format=json&action=query&list=geosearch&gsradius=10000&gscoord=' + lat + '|' + lng + '&gslimit=20&callback=JSON_CALLBACK').success(function(data) {
            $scope.entries = data.query.geosearch;
            var ids = "";
            angular.forEach($scope.entries, function(value, index) {
                ids += value.pageid + "|";
                value.popUp = L.popup().setContent('
' + value.title + '
');
                value.marker = L.marker([value.lat, value.lon], {icon: markIcon});
                value.marker.addTo($rootScope.screenMap).bindPopup(value.popUp);
                // update bound limits
                if (index == 0) {
                    southWestBound[0] = value.lat;
                    southWestBound[1] = value.lon;
                    northEastBound[0] = value.lat;
                    northEastBound[1] = value.lon;
                } else {
                    southWestBound[0] = value.lat < southWestBound[0] ? value.lat : southWestBound[0];
                    southWestBound[1] = value.lon < southWestBound[1] ? value.lon : southWestBound[1];
                    northEastBound[0] = value.lat > northEastBound[0] ? value.lat : northEastBound[0];
                    northEastBound[1] = value.lon > northEastBound[1] ? value.lon : northEastBound[1];
                }
            });
            ids = ids.slice(0, - 1);
            // get thumbnails
            $http.jsonp('http://en.wikipedia.org/w/api.php?action=query&prop=pageimages&format=json&piprop=thumbnail&pithumbsize=60&pilimit=20&pageids=' + ids + '&callback=JSON_CALLBACK').success(function(data) {
                angular.forEach($scope.entries, function(value, index) {
                    value.thumbnail = data.query.pages[value.pageid].thumbnail;
                });
                //get excerpts
                $http.jsonp('http://en.wikipedia.org/w/api.php?action=query&prop=extracts&format=json&exchars=250&exlimit=20&exintro=&pageids=' + ids + '&callback=JSON_CALLBACK').success(function(data) {
                    angular.forEach($scope.entries, function(entry, index) {
                        var content = '
' + entry.title + '
'
                                      + data.query.pages[entry.pageid].extract + '
'
                                      + 'Read more';
                        if (entry.thumbnail) {
                            content = '' + content;
                        }
                        entry.popUp.setContent(content);
                    });
                    $rootScope.loading = false;
                });
            });
            // set inital zoom to show all entries
            $rootScope.screenMap.fitBounds([southWestBound, northEastBound], {padding: [16, 24]});
        });
    };

    // load wikipedia entries for current location
    $scope.reload = function() {
        $rootScope.localization = $rootScope.screenMap.getCenter();
        getWikipediaEntries($rootScope.localization.lat, $rootScope.localization.lng);
    };

    // set map to current location
    $scope.currentLocation = function() {
        $rootScope.screenMap.locate({setView: true, zoom: 14, maxZoom: 15});
    };

    // open pop-up of a selected entry
    $scope.openPopUp = function(index) {
        $scope.entries[index].marker.openPopup();
        $scope.showMap();
    };

    // locations to visit if current location not available
    var visitLocations = [
        { name: 'La Habana', position: [23.13986, -82.38445] },
        { name: 'Pompeii', position: [40.7512, 14.4869] },
        { name: 'Tiananmen Square', position: [39.9021, 116.3917] },
    ];

    // set the map to any of the visitLocations
    $scope.visitLocation = function() {
        $scope.location = visitLocations[Math.floor(Math.random() * visitLocations.length)];
        $scope.messages.redirect = true;
        $rootScope.screenMap.setView($scope.location.position, 14);
        $rootScope.localization = $rootScope.screenMap.getCenter();
        getWikipediaEntries($rootScope.localization.lat, $rootScope.localization.lng);
        $rootScope.messageVisible = true;
    }
    $rootScope.screenMap.on('locationerror', function() {
        $scope.visitLocation();
    });

    // set the current location on the map
    var personIcon = L.icon({
        iconUrl: 'person.svg',
        iconSize:     [32, 48], // size of the icon
        iconAnchor:   [16, 48], // point of the icon which will correspond to marker's location
        popupAnchor:  [0, -52] // point from which the popup should open relative to the iconAnchor
    });
    $rootScope.screenMap.on('locationfound', function() {
        $rootScope.localization = $rootScope.screenMap.getCenter();
        // make the previous markers invisible
        if ($scope.currentLocationMarkers.length > 0) {
            $scope.currentLocationMarkers[$scope.currentLocationMarkers.length - 1].setOpacity(0);
        }
        var currentLocationMark = L.marker([$rootScope.localization.lat, $rootScope.localization.lng], {icon: personIcon});
        currentLocationMark.addTo($rootScope.screenMap);
        $scope.currentLocationMarkers.push(currentLocationMark);
        getWikipediaEntries($rootScope.localization.lat, $rootScope.localization.lng);
    });

    $scope.showMap = function() {
        window.scrollTo(0,0);
        $rootScope.mapVisible = true;
    }

    $scope.showList = function() {
        window.scrollTo(0,0);
        $rootScope.mapVisible = false;
    }

    $scope.logo = function() {
        $scope.messages.about = true;
        $rootScope.messageVisible = true;
    }

    // user facing messages
    $scope.messages = {
        redirect: false,
        about: false
    };

    $scope.clearMessage = function() {
        $rootScope.messageVisible = false;
        angular.forEach($scope.messages, function(message){
            message = false;
        });
    }

}]);<commit_msg>update phonegap menu var on angular<commit_after>var vger =  angular.module('vger', []);

vger.run(['$rootScope', function ($rootScope) {
    // set visibility state for elements
    $rootScope.loading = true;
    $rootScope.messageVisible = false;
    $rootScope.mapVisible = true;
    $rootScope.spreadMenu = false;

    // set map on screen
    $rootScope.screenMap = L.map('map', {zoomControl: false}).locate({setView: true, maxZoom: 15});
    L.control.zoom({position: 'bottomleft'}).addTo($rootScope.screenMap);
    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap contributors'
    }).addTo($rootScope.screenMap);

    // check if running as phonegap app
    var phonegapApp = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1;
    if (phonegapApp) {
        document.addEventListener("deviceready", onDeviceReady, false);

        function onDeviceReady() {
            document.addEventListener("menubutton", onMenuKeyDown, false);
        }

        function onMenuKeyDown() {
            $rootScope.$apply(function(){
                $rootScope.spreadMenu = !$rootScope.spreadMenu;
            });
        }
    }
}]);

vger.controller('ListCtrl', ['$rootScope', '$scope', '$http', function ($rootScope, $scope, $http) {

    var markIcon = L.icon({
        iconUrl: 'icon.svg',
        iconSize:     [32, 48], // size of the icon
        shadowSize:   [40, 48], // size of the shadow
        iconAnchor:   [16, 48], // point of the icon which will correspond to marker's location
        popupAnchor:  [0, -52] // point from which the popup should open relative to the iconAnchor
    });

    $scope.currentLocationMarkers = new Array();

	// get wikipedia entries for given position
	var getWikipediaEntries = function(lat, lng) {
        // store bound limits to zoom the map and show all entries
        var southWestBound = [0, 0],
            northEastBound = [0, 0];

        $rootScope.loading = true;
        angular.forEach($scope.entries, function(value, index) {
            value.marker.closePopup().unbindPopup().setOpacity(0);
        });
        $scope.entries = [];
        //get list of closer entries
        $http.jsonp('http://en.wikipedia.org/w/api.php?format=json&action=query&list=geosearch&gsradius=10000&gscoord=' + lat + '|' + lng + '&gslimit=20&callback=JSON_CALLBACK').success(function(data) {
            $scope.entries = data.query.geosearch;
            var ids = "";
            angular.forEach($scope.entries, function(value, index) {
                ids += value.pageid + "|";
                value.popUp = L.popup().setContent('
' + value.title + '
');
                value.marker = L.marker([value.lat, value.lon], {icon: markIcon});
                value.marker.addTo($rootScope.screenMap).bindPopup(value.popUp);
                // update bound limits
                if (index == 0) {
                    southWestBound[0] = value.lat;
                    southWestBound[1] = value.lon;
                    northEastBound[0] = value.lat;
                    northEastBound[1] = value.lon;
                } else {
                    southWestBound[0] = value.lat < southWestBound[0] ? value.lat : southWestBound[0];
                    southWestBound[1] = value.lon < southWestBound[1] ? value.lon : southWestBound[1];
                    northEastBound[0] = value.lat > northEastBound[0] ? value.lat : northEastBound[0];
                    northEastBound[1] = value.lon > northEastBound[1] ? value.lon : northEastBound[1];
                }
            });
            ids = ids.slice(0, - 1);
            // get thumbnails
            $http.jsonp('http://en.wikipedia.org/w/api.php?action=query&prop=pageimages&format=json&piprop=thumbnail&pithumbsize=60&pilimit=20&pageids=' + ids + '&callback=JSON_CALLBACK').success(function(data) {
                angular.forEach($scope.entries, function(value, index) {
                    value.thumbnail = data.query.pages[value.pageid].thumbnail;
                });
                //get excerpts
                $http.jsonp('http://en.wikipedia.org/w/api.php?action=query&prop=extracts&format=json&exchars=250&exlimit=20&exintro=&pageids=' + ids + '&callback=JSON_CALLBACK').success(function(data) {
                    angular.forEach($scope.entries, function(entry, index) {
                        var content = '
' + entry.title + '
'
                                      + data.query.pages[entry.pageid].extract + '
'
                                      + 'Read more';
                        if (entry.thumbnail) {
                            content = '' + content;
                        }
                        entry.popUp.setContent(content);
                    });
                    $rootScope.loading = false;
                });
            });
            // set inital zoom to show all entries
            $rootScope.screenMap.fitBounds([southWestBound, northEastBound], {padding: [16, 24]});
        });
    };

    // load wikipedia entries for current location
    $scope.reload = function() {
        $rootScope.localization = $rootScope.screenMap.getCenter();
        getWikipediaEntries($rootScope.localization.lat, $rootScope.localization.lng);
    };

    // set map to current location
    $scope.currentLocation = function() {
        $rootScope.screenMap.locate({setView: true, zoom: 14, maxZoom: 15});
    };

    // open pop-up of a selected entry
    $scope.openPopUp = function(index) {
        $scope.entries[index].marker.openPopup();
        $scope.showMap();
    };

    // locations to visit if current location not available
    var visitLocations = [
        { name: 'La Habana', position: [23.13986, -82.38445] },
        { name: 'Pompeii', position: [40.7512, 14.4869] },
        { name: 'Tiananmen Square', position: [39.9021, 116.3917] },
    ];

    // set the map to any of the visitLocations
    $scope.visitLocation = function() {
        $scope.location = visitLocations[Math.floor(Math.random() * visitLocations.length)];
        $scope.messages.redirect = true;
        $rootScope.screenMap.setView($scope.location.position, 14);
        $rootScope.localization = $rootScope.screenMap.getCenter();
        getWikipediaEntries($rootScope.localization.lat, $rootScope.localization.lng);
        $rootScope.messageVisible = true;
    }
    $rootScope.screenMap.on('locationerror', function() {
        $scope.visitLocation();
    });

    // set the current location on the map
    var personIcon = L.icon({
        iconUrl: 'person.svg',
        iconSize:     [32, 48], // size of the icon
        iconAnchor:   [16, 48], // point of the icon which will correspond to marker's location
        popupAnchor:  [0, -52] // point from which the popup should open relative to the iconAnchor
    });
    $rootScope.screenMap.on('locationfound', function() {
        $rootScope.localization = $rootScope.screenMap.getCenter();
        // make the previous markers invisible
        if ($scope.currentLocationMarkers.length > 0) {
            $scope.currentLocationMarkers[$scope.currentLocationMarkers.length - 1].setOpacity(0);
        }
        var currentLocationMark = L.marker([$rootScope.localization.lat, $rootScope.localization.lng], {icon: personIcon});
        currentLocationMark.addTo($rootScope.screenMap);
        $scope.currentLocationMarkers.push(currentLocationMark);
        getWikipediaEntries($rootScope.localization.lat, $rootScope.localization.lng);
    });

    $scope.showMap = function() {
        window.scrollTo(0,0);
        $rootScope.mapVisible = true;
    }

    $scope.showList = function() {
        window.scrollTo(0,0);
        $rootScope.mapVisible = false;
    }

    $scope.logo = function() {
        $scope.messages.about = true;
        $rootScope.messageVisible = true;
    }

    // user facing messages
    $scope.messages = {
        redirect: false,
        about: false
    };

    $scope.clearMessage = function() {
        $rootScope.messageVisible = false;
        angular.forEach($scope.messages, function(message){
            message = false;
        });
    }

}]);<|endoftext|>


<commit_before>// BEGIN-SNIPPET components-ui-calendar-moment
import { inject as service } from '@ember/service';

import { computed } from '@ember/object';
import { merge } from '@ember/polyfills';
import moment from 'moment';
import UiCalendarComponent from 'ember-semantic-ui-calendar/components/ui-calendar';

const UiCalendarMoment = UiCalendarComponent.extend({
  // See below
});

export default UiCalendarMoment;
// END-SNIPPET components-ui-calendar-moment

// BEGIN-SNIPPET components-ui-calendar-moment-binding
UiCalendarMoment.reopen({
  // Store the moment object for the selected date
  momentValue: null,

  // Provide the Date object that is used by ui-calendar
  date: computed('momentValue', function() {
    let momentValue = this.get('momentValue');
    return momentValue ? momentValue.toDate() : null;
  }).readOnly(),

  willInitSemantic(settings) {
    this._super(...arguments);

    merge(settings, {
      onChange(date) {
        // Wraps the Date in a moment object an triggers the onChange action
        this.get('onChange')(date ? moment(date) : null);
      }
    });
  }
});
// END-SNIPPET components-ui-calendar-moment-binding

// BEGIN-SNIPPET components-ui-calendar-moment-locale
UiCalendarMoment.reopen({
  moment: service('moment'),

  init() {
    this._super(...arguments);

    this.get('moment').on('localeChanged', () => this.momentLocaleChanged());
  },

  localizedText: computed(function() {
    return {
      days: moment.weekdaysMin(),
      months: moment.months(),
      monthsShort: moment.monthsShort()
      // You can also add translations for `today` and `now` here, using an
      // addon like ember-i18n or ember-intl.
    };
  }).volatile(),

  momentLocaleChanged() {
    // Update translations
    this.execute('setting', 'text', this.get('localizedText'));

    // Refresh the calendar in popup
    this.execute('refresh');

    // Refresh the input
    this.execute('set date', this.get('date'), true, false);
  },

  willInitSemantic(settings) {
    this._super(...arguments);
    merge(settings, {
      text: this.get('localizedText'),
      formatter: {
        date(date) {
          return date ? moment(date).format('L') : '';
        },
        time(date) {
          return date ? moment(date).format('LT') : '';
        }
      }
    });
  }
});
// END-SNIPPET components-ui-calendar-moment-locale
<commit_msg>Fix eslint warnings<commit_after>// BEGIN-SNIPPET components-ui-calendar-moment
import { inject as service } from '@ember/service';

import { computed } from '@ember/object';
import { merge } from '@ember/polyfills';
import moment from 'moment';
import UiCalendarComponent from 'ember-semantic-ui-calendar/components/ui-calendar';

const UiCalendarMoment = UiCalendarComponent.extend({
  // See below
});

export default UiCalendarMoment;
// END-SNIPPET components-ui-calendar-moment

// BEGIN-SNIPPET components-ui-calendar-moment-binding
UiCalendarMoment.reopen({
  // Store the moment object for the selected date
  momentValue: null,

  // Provide the Date object that is used by ui-calendar
  date: computed('momentValue', function() {
    let momentValue = this.get('momentValue');
    return momentValue ? momentValue.toDate() : null;
  }).readOnly(),

  willInitSemantic(settings) {
    this._super(...arguments);

    merge(settings, {
      onChange(date) {
        // Wraps the Date in a moment object an triggers the onChange action
        this.get('onChange')(date ? moment(date) : null);
      }
    });
  }
});
// END-SNIPPET components-ui-calendar-moment-binding

// BEGIN-SNIPPET components-ui-calendar-moment-locale
UiCalendarMoment.reopen({
  moment: service('moment'),

  init() {
    this._super(...arguments);

    this.get('moment').on('localeChanged', () => this.momentLocaleChanged());
  },

  localizedText: computed('moment.locale', function() {
    return {
      days: moment.weekdaysMin(),
      months: moment.months(),
      monthsShort: moment.monthsShort()
      // You can also add translations for `today` and `now` here, using an
      // addon like ember-i18n or ember-intl.
    };
  }),

  momentLocaleChanged() {
    // Update translations
    this.execute('setting', 'text', this.get('localizedText'));

    // Refresh the calendar in popup
    this.execute('refresh');

    // Refresh the input
    this.execute('set date', this.get('date'), true, false);
  },

  willInitSemantic(settings) {
    this._super(...arguments);
    merge(settings, {
      text: this.get('localizedText'),
      formatter: {
        date(date) {
          return date ? moment(date).format('L') : '';
        },
        time(date) {
          return date ? moment(date).format('LT') : '';
        }
      }
    });
  }
});
// END-SNIPPET components-ui-calendar-moment-locale
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview Parses Mali DDK/kernel events in the Linux event trace format.
 */
base.require('linux_perf_parser');
base.exportTo('tracing', function() {

  var LinuxPerfParser = tracing.LinuxPerfParser;

  /**
   * Parses Mali DDK/kernel trace events.
   * @constructor
   */
  function LinuxPerfMaliParser(importer) {
    LinuxPerfParser.call(this, importer);

    // kernel events
    importer.registerEventHandler('mali_dvfs_event',
        LinuxPerfMaliParser.prototype.dvfsEventEvent.bind(this));
    importer.registerEventHandler('mali_dvfs_set_clock',
        LinuxPerfMaliParser.prototype.dvfsSetClockEvent.bind(this));
    importer.registerEventHandler('mali_dvfs_set_voltage',
        LinuxPerfMaliParser.prototype.dvfsSetVoltageEvent.bind(this));

    // DDK events (from X server)
    importer.registerEventHandler('tracing_mark_write:mali_driver',
        LinuxPerfMaliParser.prototype.maliDDKEvent.bind(this));
  }

  LinuxPerfMaliParser.prototype = {
    __proto__: LinuxPerfParser.prototype,

    maliDDKOpenSlice: function(pid, ts, func, blockinfo) {
      var kthread = this.importer.getOrCreateKernelThread('mali_ddk', pid,
                                                          'mali_ddk');
      kthread.thread.beginSlice(func, '', ts, { 'blockinfo': blockinfo });
    },

    maliDDKCloseSlice: function(pid, ts, args, blockinfo) {
      var kthread = this.importer.getOrCreateKernelThread('mali_ddk', pid,
                                                          'mali_ddk');
      var thread = kthread.thread;
      if (!thread.openSliceCount) {
        this.importer.importError('maliDDKCloseSlice w/o matching OpenSlice');
        return;
      }
      thread.endSlice(ts);
    },

    /**
     * Parses maliDDK events and sets up state in the importer.
     * events will come in pairs with a cros_trace_print_enter
     * like this:
     *
     * tracing_mark_write: mali_driver: cros_trace_print_enter:
     * gles/src/texture/mali_gles_texture_slave.c1505:
     * gles2_texturep_upload_2d
     *
     * and a cros_trace_print_exit like this:
     *
     * tracing_mark_write: mali_driver: cros_trace_print_exit:
     * gles/src/texture/mali_gles_texture_slave.c1505:
     */
    maliDDKEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var maliEvent =
          /^s*(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/.exec(eventBase[2]);
      switch (maliEvent[1]) {
        case 'cros_trace_print_enter':
          this.maliDDKOpenSlice(pid, ts, maliEvent[3], maliEvent[2]);
          break;
        case 'cros_trace_print_exit':
          this.maliDDKCloseSlice(pid, ts, [], maliEvent[2]);
      }
      return true;
    },

    /*
     * Kernel event support.
     */

    dvfsSample: function(counterName, seriesName, ts, value) {
      // NB: record all data on cpu 0; cpuNumber is not meaningful
      var targetCpu = this.importer.getOrCreateCpuState(0);
      var counter = targetCpu.cpu.getOrCreateCounter('', counterName);
      if (counter.numSeries == 0) {
        counter.seriesNames.push(seriesName);
        counter.seriesColors.push(tracing.getStringColorId(counter.name));
      }
      counter.timestamps.push(ts);
      counter.samples.push(value);
    },

    dvfsEventEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var event = /utilization=(\d+)/.exec(eventBase[5]);
      if (!event)
        return false;

      this.dvfsSample('DVFS Utilization', 'utilization', ts, event[1]);
      return true;
    },

    dvfsSetClockEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var event = /frequency=(\d+)/.exec(eventBase[5]);
      if (!event)
        return false;

      this.dvfsSample('DVFS Frequency', 'frequency', ts, event[1]);
      return true;
    },

    dvfsSetVoltageEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var event = /voltage=(\d+)/.exec(eventBase[5]);
      if (!event)
        return false;

      this.dvfsSample('DVFS Voltage', 'voltage', ts, event[1]);
      return true;
    }
  };

  LinuxPerfParser.registerSubtype(LinuxPerfMaliParser);

  return {
    LinuxPerfMaliParser: LinuxPerfMaliParser
  };
});
<commit_msg>Add Mali perf events to "gpu-driver" category<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview Parses Mali DDK/kernel events in the Linux event trace format.
 */
base.require('linux_perf_parser');
base.exportTo('tracing', function() {

  var LinuxPerfParser = tracing.LinuxPerfParser;

  /**
   * Parses Mali DDK/kernel trace events.
   * @constructor
   */
  function LinuxPerfMaliParser(importer) {
    LinuxPerfParser.call(this, importer);

    // kernel events
    importer.registerEventHandler('mali_dvfs_event',
        LinuxPerfMaliParser.prototype.dvfsEventEvent.bind(this));
    importer.registerEventHandler('mali_dvfs_set_clock',
        LinuxPerfMaliParser.prototype.dvfsSetClockEvent.bind(this));
    importer.registerEventHandler('mali_dvfs_set_voltage',
        LinuxPerfMaliParser.prototype.dvfsSetVoltageEvent.bind(this));

    // DDK events (from X server)
    importer.registerEventHandler('tracing_mark_write:mali_driver',
        LinuxPerfMaliParser.prototype.maliDDKEvent.bind(this));
  }

  LinuxPerfMaliParser.prototype = {
    __proto__: LinuxPerfParser.prototype,

    maliDDKOpenSlice: function(pid, ts, func, blockinfo) {
      var kthread = this.importer.getOrCreateKernelThread('mali_ddk', pid,
                                                          'mali_ddk');
      kthread.thread.beginSlice('gpu-driver', func, ts,
                                { 'blockinfo': blockinfo });
    },

    maliDDKCloseSlice: function(pid, ts, args, blockinfo) {
      var kthread = this.importer.getOrCreateKernelThread('mali_ddk', pid,
                                                          'mali_ddk');
      var thread = kthread.thread;
      if (!thread.openSliceCount) {
        this.importer.importError('maliDDKCloseSlice w/o matching OpenSlice');
        return;
      }
      thread.endSlice(ts);
    },

    /**
     * Parses maliDDK events and sets up state in the importer.
     * events will come in pairs with a cros_trace_print_enter
     * like this:
     *
     * tracing_mark_write: mali_driver: cros_trace_print_enter:
     * gles/src/texture/mali_gles_texture_slave.c1505:
     * gles2_texturep_upload_2d
     *
     * and a cros_trace_print_exit like this:
     *
     * tracing_mark_write: mali_driver: cros_trace_print_exit:
     * gles/src/texture/mali_gles_texture_slave.c1505:
     */
    maliDDKEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var maliEvent =
          /^s*(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/.exec(eventBase[2]);
      switch (maliEvent[1]) {
        case 'cros_trace_print_enter':
          this.maliDDKOpenSlice(pid, ts, maliEvent[3], maliEvent[2]);
          break;
        case 'cros_trace_print_exit':
          this.maliDDKCloseSlice(pid, ts, [], maliEvent[2]);
      }
      return true;
    },

    /*
     * Kernel event support.
     */

    dvfsSample: function(counterName, seriesName, ts, value) {
      // NB: record all data on cpu 0; cpuNumber is not meaningful
      var targetCpu = this.importer.getOrCreateCpuState(0);
      var counter = targetCpu.cpu.getOrCreateCounter('', counterName);
      if (counter.numSeries == 0) {
        counter.seriesNames.push(seriesName);
        counter.seriesColors.push(tracing.getStringColorId(counter.name));
      }
      counter.timestamps.push(ts);
      counter.samples.push(value);
    },

    dvfsEventEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var event = /utilization=(\d+)/.exec(eventBase[5]);
      if (!event)
        return false;

      this.dvfsSample('DVFS Utilization', 'utilization', ts, event[1]);
      return true;
    },

    dvfsSetClockEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var event = /frequency=(\d+)/.exec(eventBase[5]);
      if (!event)
        return false;

      this.dvfsSample('DVFS Frequency', 'frequency', ts, event[1]);
      return true;
    },

    dvfsSetVoltageEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var event = /voltage=(\d+)/.exec(eventBase[5]);
      if (!event)
        return false;

      this.dvfsSample('DVFS Voltage', 'voltage', ts, event[1]);
      return true;
    }
  };

  LinuxPerfParser.registerSubtype(LinuxPerfMaliParser);

  return {
    LinuxPerfMaliParser: LinuxPerfMaliParser
  };
});
<|endoftext|>


<commit_before>var storage = function(key, value) {
  if (_.isUndefined(value)) {
    try {
      return JSON.parse(window.localStorage.getItem(key));
    } catch (e) {
      return void(0);
    }
  } else {
    window.localStorage.setItem(key, JSON.stringify(value));
  }
};

var displayTime = function(seconds) {
  var s = parseFloat(seconds);
  if (s > 0) {
    return (Math.floor(s / 60).toString() + 'm ' +
            (s % 60).toString() + 's');
  } else {
    return '...';
  }
};
var displayUnixTimeOfArrival = function(time) {
  return displayTime(time - Math.round(Date.now() / 1000));
};

// epochTime is in milliseconds
var formatPredictionRow = function(prediction) {
  var $li = $('
');
  var $route = $('');
  $route.text(prediction.route);
  var $dir = $('');
  $dir.text(prediction.direction);
  var $time = $('');
  $time.attr('data-occurs', prediction.unixTimeOfArrival);
  $time.text(displayUnixTimeOfArrival(prediction.unixTimeOfArrival));
  $li.append(' ', $route, $dir, $time);
  return $li;
};

var parsePredictions = function(xhrResult) {
  var ret = [];
  $(xhrResult).find('predictions').each(function() {
    var route = $(this).attr('routeTitle');
    $(this).find('direction').each(function() {
      var direction = $(this).attr('title');
      $(this).find('prediction').each(function() {
        ret.push({
          route: route,
          direction: direction,
          unixTimeOfArrival: Math.round($(this).attr('epochTime') / 1000),
          affectedByLayover: $(this).attr('affectedByLayover')
        });
      });
    });
  });
  return _.sortBy(ret, function(p) {
    return parseFloat(p.seconds);
  });
};

var closeMenus = function() {
  $('#menu-nav').find('li').removeClass('active');
  $('.menu').hide();
};

var setupFavorites = function() {
  var $menu = $('.menu.favorites');
  var $list = $menu.find('.list-group');
  var favorites = storage('favorites');
  $list.empty();
  _.each(favorites, function(stopId) {
    var stop = _.findWhere(stops, {id: stopId});
    $list.append('
' + stop.title + '
');
  });
  $list.find('.list-group-item').click(function() {
    stop = $(this).data();
    setLocation(stop.lat, stop.lon, 17);
    window.currentStop = stop;
    loadStop(stop);
    closeMenus();
  });
};

var toggleFavorite = function(stop) {
  var favorites = storage('favorites') || [];
  var index = favorites.indexOf(stop.id);
  if (index !== -1) {
    favorites.splice(index, 1);
  } else {
    favorites.push(stop.id);
  }
  storage('favorites', favorites);
  checkFavorite(stop);
  setupFavorites();
};

var checkFavorite = function(stop) {
  var favorites = storage('favorites') || [];
  if (favorites.indexOf(stop.id) !== -1) {
    $('.favorite').find('span')
      .removeClass('glyphicon-star-empty')
      .addClass('glyphicon-star')
      .css({color: '#d90'});
  } else {
    $('.favorite').find('span')
      .addClass('glyphicon-star-empty')
      .removeClass('glyphicon-star')
      .css({color: '#000'});
  }
};

var openStop = function(stop, xhrResult) {
  var $box = $('#predictions');
  var $head = $box.find('.panel-heading');
  var predictions = parsePredictions(xhrResult);
  var p;
  checkFavorite(stop);
  $head.find('.title').html(stop.title);
  $box.find('.list-group').html('');
  for (var i = 0; i < predictions.length; i++) {
    $box.find('.list-group').append(formatPredictionRow(predictions[i]));
  }
  $('#map').css('width', '70%');
  $box.show();
};

var loadStop = function(stop) {
  $('#predictions').find('.loading').css({ display: 'block' });
  $('#predictions').find('.refresh').hide();
  $.ajax({
    type: 'GET',
    url: 'http://webservices.nextbus.com/service/publicXMLFeed' +
      '?command=predictions&a=mbta&stopId=' + stop.id,
    dataType: 'xml',
    success: function(data) {
      $('#predictions').find('.loading').css({ display: 'none' });
      $('#predictions').find('.refresh').show();
      openStop(stop, data);
    },
    error: function() {
      $('#predictions').find('.loading').css({ display: 'none' });
      $('#predictions').find('.refresh').show();
      console.log('An Error occurred');
    }
  });
};

var autoReload = function() {
  if (currentStop) {
    loadStop(currentStop);
  }
  setTimeout(autoReload, 60 * 1000);
};

var currentStop;
var initialLocation;
var boston = { lat: 42.38, lng: -71.1, zoom: 12 };
var browserSupportFlag;
var map;
function setLocation(lat, lng, zoom) {
  map.setCenter(new google.maps.LatLng(lat, lng));
  map.setZoom(zoom);
}

function setLocationToNonGeolocatedDefault() {
  if (storage('zoom') && storage('lat') && storage('lng')) {
    setLocation(storage('lat'), storage('lng'), storage('zoom'));
  } else {
    setLocation(boston.lat, boston.lng, boston.zoom);
  }
}

var geolocate = function() {
  // Try W3C Geolocation (Preferred)
  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      setLocation(position.coords.latitude, position.coords.longitude, 17);
    }, function() {
    }, {
      timeout: 7000
    });
  }
};

function initialize() {
  var myOptions = {
    zoom: 12,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById("map"), myOptions);
  setLocationToNonGeolocatedDefault();
  geolocate();

  google.maps.event.addListener(map, 'bounds_changed', function() {
    storage('zoom', map.getZoom());
    storage('lat', map.getCenter().lat());
    storage('lng', map.getCenter().lng());
  });

  for (var i = 0; i < stops.length; i++) {
    (function(stop) {
      var pos =  new google.maps.LatLng(stop.lat, stop.lon);
      var marker = new google.maps.Marker({
        position: pos,
        map: map,
        title: stop.title
      });
      google.maps.event.addListener(marker, 'click', function() {
        currentStop = stop;
        loadStop(stop);
      });
    }).call(this, stops[i]);
  }

  $('#predictions').find('.close-predictions').click(function() {
    $('#map').css('width', '100%');
    $('#predictions').hide();
  });

  $('.menu').find('.close-menu').click(function() {
    $('#map').css('width', '100%');
    closeMenus();
  });

  $('#predictions').find('.refresh').click(function() {
    if (currentStop) {
      loadStop(currentStop);
    }
  });

  $('#predictions').find('.favorite').click(function() {
    if (currentStop) {
      toggleFavorite(currentStop);
    }
  });

  $('#menu-nav').find('a.geolocate').click(function(){
    geolocate();
    closeMenus();
  });

  $('#menu-nav').find('a.favorites').click(function() {
    setupFavorites();
    closeMenus();
    $('#menu-nav li.favorites').addClass('active');
    $('.menu.favorites').show();
  });

  $('#menu-nav').find('a.search').click(function() {
    closeMenus();
    $('#menu-nav li.search').addClass('active');
    $('.menu.search').show();
  });

  $('#menu-nav').find('a.settings').click(function() {
    closeMenus();
    $('#menu-nav li.settings').addClass('active');
    $('.menu.settings').show();
  });

  $('.menu.settings').find('.clear-data').click(function() {
    window.localStorage.clear();
  });

  autoReload();
}

google.maps.event.addDomListener(window, 'load', initialize);

var countDownTimer;
var countDown = function() {
  $('.time').each(function() {
    var time = $(this).attr('data-occurs');
    $(this).text(displayUnixTimeOfArrival(time));
  });
  countDownTimer = setTimeout(countDown, 1000);
};
countDown();
<commit_msg>minor ux fix<commit_after>var storage = function(key, value) {
  if (_.isUndefined(value)) {
    try {
      return JSON.parse(window.localStorage.getItem(key));
    } catch (e) {
      return void(0);
    }
  } else {
    window.localStorage.setItem(key, JSON.stringify(value));
  }
};

var displayTime = function(seconds) {
  var s = parseFloat(seconds);
  if (s > 0) {
    return (Math.floor(s / 60).toString() + 'm ' +
            (s % 60).toString() + 's');
  } else {
    return '...';
  }
};
var displayUnixTimeOfArrival = function(time) {
  return displayTime(time - Math.round(Date.now() / 1000));
};

// epochTime is in milliseconds
var formatPredictionRow = function(prediction) {
  var $li = $('
');
  var $route = $('');
  $route.text(prediction.route);
  var $dir = $('');
  $dir.text(prediction.direction);
  var $time = $('');
  $time.attr('data-occurs', prediction.unixTimeOfArrival);
  $time.text(displayUnixTimeOfArrival(prediction.unixTimeOfArrival));
  $li.append(' ', $route, $dir, $time);
  return $li;
};

var parsePredictions = function(xhrResult) {
  var ret = [];
  $(xhrResult).find('predictions').each(function() {
    var route = $(this).attr('routeTitle');
    $(this).find('direction').each(function() {
      var direction = $(this).attr('title');
      $(this).find('prediction').each(function() {
        ret.push({
          route: route,
          direction: direction,
          unixTimeOfArrival: Math.round($(this).attr('epochTime') / 1000),
          affectedByLayover: $(this).attr('affectedByLayover')
        });
      });
    });
  });
  return _.sortBy(ret, function(p) {
    return parseFloat(p.seconds);
  });
};

var closeMenus = function() {
  $('#menu-nav').find('li').removeClass('active');
  $('.menu').hide();
};

var setupFavorites = function() {
  var $menu = $('.menu.favorites');
  var $list = $menu.find('.list-group');
  var favorites = storage('favorites');
  $list.empty();
  _.each(favorites, function(stopId) {
    var stop = _.findWhere(stops, {id: stopId});
    $list.append('
' + stop.title + '
');
  });
  $list.find('.list-group-item').click(function() {
    stop = $(this).data();
    setLocation(stop.lat, stop.lon, 17);
    window.currentStop = stop;
    loadStop(stop);
    closeMenus();
  });
};

var toggleFavorite = function(stop) {
  $('.favorite').blur();
  var favorites = storage('favorites') || [];
  var index = favorites.indexOf(stop.id);
  if (index !== -1) {
    favorites.splice(index, 1);
  } else {
    favorites.push(stop.id);
  }
  storage('favorites', favorites);
  checkFavorite(stop);
  setupFavorites();
};

var checkFavorite = function(stop) {
  var favorites = storage('favorites') || [];
  if (favorites.indexOf(stop.id) !== -1) {
    $('.favorite').find('span')
      .removeClass('glyphicon-star-empty')
      .addClass('glyphicon-star')
      .css({color: '#d90'});
  } else {
    $('.favorite').find('span')
      .addClass('glyphicon-star-empty')
      .removeClass('glyphicon-star')
      .css({color: '#000'});
  }
};

var openStop = function(stop, xhrResult) {
  var $box = $('#predictions');
  var $head = $box.find('.panel-heading');
  var predictions = parsePredictions(xhrResult);
  var p;
  checkFavorite(stop);
  $head.find('.title').html(stop.title);
  $box.find('.list-group').html('');
  for (var i = 0; i < predictions.length; i++) {
    $box.find('.list-group').append(formatPredictionRow(predictions[i]));
  }
  $('#map').css('width', '70%');
  $box.show();
};

var loadStop = function(stop) {
  $('#predictions').find('.loading').css({ display: 'block' });
  $('#predictions').find('.refresh').hide();
  $.ajax({
    type: 'GET',
    url: 'http://webservices.nextbus.com/service/publicXMLFeed' +
      '?command=predictions&a=mbta&stopId=' + stop.id,
    dataType: 'xml',
    success: function(data) {
      $('#predictions').find('.loading').css({ display: 'none' });
      $('#predictions').find('.refresh').show();
      openStop(stop, data);
    },
    error: function() {
      $('#predictions').find('.loading').css({ display: 'none' });
      $('#predictions').find('.refresh').show();
      console.log('An Error occurred');
    }
  });
};

var autoReload = function() {
  if (currentStop) {
    loadStop(currentStop);
  }
  setTimeout(autoReload, 60 * 1000);
};

var currentStop;
var initialLocation;
var boston = { lat: 42.38, lng: -71.1, zoom: 12 };
var browserSupportFlag;
var map;
function setLocation(lat, lng, zoom) {
  map.setCenter(new google.maps.LatLng(lat, lng));
  map.setZoom(zoom);
}

function setLocationToNonGeolocatedDefault() {
  if (storage('zoom') && storage('lat') && storage('lng')) {
    setLocation(storage('lat'), storage('lng'), storage('zoom'));
  } else {
    setLocation(boston.lat, boston.lng, boston.zoom);
  }
}

var geolocate = function() {
  // Try W3C Geolocation (Preferred)
  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      setLocation(position.coords.latitude, position.coords.longitude, 17);
    }, function() {
    }, {
      timeout: 7000
    });
  }
};

function initialize() {
  var myOptions = {
    zoom: 12,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById("map"), myOptions);
  setLocationToNonGeolocatedDefault();
  geolocate();

  google.maps.event.addListener(map, 'bounds_changed', function() {
    storage('zoom', map.getZoom());
    storage('lat', map.getCenter().lat());
    storage('lng', map.getCenter().lng());
  });

  for (var i = 0; i < stops.length; i++) {
    (function(stop) {
      var pos =  new google.maps.LatLng(stop.lat, stop.lon);
      var marker = new google.maps.Marker({
        position: pos,
        map: map,
        title: stop.title
      });
      google.maps.event.addListener(marker, 'click', function() {
        currentStop = stop;
        loadStop(stop);
      });
    }).call(this, stops[i]);
  }

  $('#predictions').find('.close-predictions').click(function() {
    $('#map').css('width', '100%');
    $('#predictions').hide();
  });

  $('.menu').find('.close-menu').click(function() {
    $('#map').css('width', '100%');
    closeMenus();
  });

  $('#predictions').find('.refresh').click(function() {
    if (currentStop) {
      loadStop(currentStop);
    }
  });

  $('#predictions').find('.favorite').click(function() {
    if (currentStop) {
      toggleFavorite(currentStop);
    }
  });

  $('#menu-nav').find('a.geolocate').click(function(){
    geolocate();
    closeMenus();
  });

  $('#menu-nav').find('a.favorites').click(function() {
    setupFavorites();
    closeMenus();
    $('#menu-nav li.favorites').addClass('active');
    $('.menu.favorites').show();
  });

  $('#menu-nav').find('a.search').click(function() {
    closeMenus();
    $('#menu-nav li.search').addClass('active');
    $('.menu.search').show();
  });

  $('#menu-nav').find('a.settings').click(function() {
    closeMenus();
    $('#menu-nav li.settings').addClass('active');
    $('.menu.settings').show();
  });

  $('.menu.settings').find('.clear-data').click(function() {
    window.localStorage.clear();
  });

  autoReload();
}

google.maps.event.addDomListener(window, 'load', initialize);

var countDownTimer;
var countDown = function() {
  $('.time').each(function() {
    var time = $(this).attr('data-occurs');
    $(this).text(displayUnixTimeOfArrival(time));
  });
  countDownTimer = setTimeout(countDown, 1000);
};
countDown();
<|endoftext|>


<commit_before>import { moduleForComponent } from 'ember-qunit';
import { test, testBS3, testBS4 } from '../../../helpers/bootstrap-test';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('bs-tab/pane', 'Integration | Component | bs-tab/pane', {
  integration: true
});

const transitionTimeout = 150;

testBS3('it has correct markup', function(assert) {
  this.render(hbs`
    {{#bs-tab/pane fade=true activeId="pane1" elementId="pane1"}}
      template block text
    {{/bs-tab/pane}}
  `);

  assert.equal(this.$().text().trim(), 'template block text', 'Shows block content');
  assert.equal(this.$('div.tab-pane').length, 1, 'has tab-pane class');
  assert.equal(this.$('div.tab-pane').hasClass('active'), true, 'tab-pane has active class');
  assert.equal(this.$('div.tab-pane').hasClass('in'), true, 'tab-pane has in class');
});

testBS4('it has correct markup', function(assert) {
  this.render(hbs`
    {{#bs-tab/pane fade=true activeId="pane1" elementId="pane1"}}
      template block text
    {{/bs-tab/pane}}
  `);

  assert.equal(this.$().text().trim(), 'template block text', 'Shows block content');
  assert.equal(this.$('div.tab-pane').length, 1, 'has tab-pane class');
  assert.equal(this.$('div.tab-pane').hasClass('active'), true, 'tab-pane has active class');
  assert.equal(this.$('div.tab-pane').hasClass('show'), true, 'tab-pane has show class');
});

test('it has correct markup when switching active pane and fade=false', function(assert) {
  this.set('activeId', null);
  this.render(hbs`
    {{#bs-tab/pane fade=false activeId=activeId elementId="pane1"}}
      template block text
    {{/bs-tab/pane}}
  `);

  assert.equal(this.$('div.tab-pane').hasClass('fade'), false, 'tab-pane does not have fade class');

  assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
  assert.equal(this.$('div.tab-pane').hasClass('in'), false, 'tab-pane does not have in class');

  this.set('activeId', 'pane1');
  assert.equal(this.$('div.tab-pane').hasClass('active'), true, 'tab-pane has active class');
  assert.equal(this.$('div.tab-pane').hasClass('in'), false, 'tab-pane does not have in class');

  this.set('activeId', null);
  assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
  assert.equal(this.$('div.tab-pane').hasClass('in'), false, 'tab-pane does not have in class');
});

testBS3('it has correct markup when switching active pane and fade=true', function(assert) {
  this.set('activeId', null);
  this.render(hbs`
    {{#bs-tab/pane fade=true activeId=activeId elementId="pane1"}}
      template block text
    {{/bs-tab/pane}}
  `);

  assert.equal(this.$('div.tab-pane').hasClass('fade'), true, 'tab-pane has fade class');
  assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
  assert.equal(this.$('div.tab-pane').hasClass('in'), false, 'tab-pane does not have in class');

  this.set('activeId', 'pane1');
  assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
  assert.equal(this.$('div.tab-pane').hasClass('in'), false, 'tab-pane does not have in class');

  let done = assert.async();
  // wait for fade animation
  setTimeout(() => {
    assert.equal(this.$('div.tab-pane').hasClass('active'), true, 'tab-pane has active class');
    assert.equal(this.$('div.tab-pane').hasClass('in'), true, 'tab-pane has in class');

    this.set('activeId', null);
    assert.equal(this.$('div.tab-pane').hasClass('active'), true, 'tab-pane has active class');
    assert.equal(this.$('div.tab-pane').hasClass('in'), false, 'tab-pane does not have in class');

    // wait for fade animation
    setTimeout(() => {
      assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
      assert.equal(this.$('div.tab-pane').hasClass('in'), false, 'tab-pane does not have in class');

      done();
    }, transitionTimeout);

  }, transitionTimeout);
});

testBS4('it has correct markup when switching active pane and fade=true', function(assert) {
  this.set('activeId', null);
  this.render(hbs`
    {{#bs-tab/pane fade=true activeId=activeId elementId="pane1"}}
      template block text
    {{/bs-tab/pane}}
  `);

  assert.equal(this.$('div.tab-pane').hasClass('fade'), true, 'tab-pane has fade class');
  assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
  assert.equal(this.$('div.tab-pane').hasClass('show'), false, 'tab-pane does not have show class');

  this.set('activeId', 'pane1');
  assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
  assert.equal(this.$('div.tab-pane').hasClass('show'), false, 'tab-pane does not have show class');

  let done = assert.async();
  // wait for fade animation
  setTimeout(() => {
    assert.equal(this.$('div.tab-pane').hasClass('active'), true, 'tab-pane has active class');
    assert.equal(this.$('div.tab-pane').hasClass('show'), true, 'tab-pane has show class');

    this.set('activeId', null);
    assert.equal(this.$('div.tab-pane').hasClass('active'), true, 'tab-pane has active class');
    assert.equal(this.$('div.tab-pane').hasClass('show'), false, 'tab-pane does not have show class');

    // wait for fade animation
    setTimeout(() => {
      assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
      assert.equal(this.$('div.tab-pane').hasClass('show'), false, 'tab-pane does not have show class');

      done();
    }, transitionTimeout);

  }, transitionTimeout);
});
<commit_msg>Apply test helpers to tab pane tests.<commit_after>import { moduleForComponent } from 'ember-qunit';
import { test, visibilityClass } from '../../../helpers/bootstrap-test';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('bs-tab/pane', 'Integration | Component | bs-tab/pane', {
  integration: true
});

const transitionTimeout = 150;

test('it has correct markup', function(assert) {
  this.render(hbs`
    {{#bs-tab/pane fade=true activeId="pane1" elementId="pane1"}}
      template block text
    {{/bs-tab/pane}}
  `);

  assert.equal(this.$().text().trim(), 'template block text', 'Shows block content');
  assert.equal(this.$('div.tab-pane').length, 1, 'has tab-pane class');
  assert.equal(this.$('div.tab-pane').hasClass('active'), true, 'tab-pane has active class');
  assert.equal(this.$('div.tab-pane').hasClass(visibilityClass()), true, 'tab-pane has visibility class');
});

test('it has correct markup when switching active pane and fade=false', function(assert) {
  this.set('activeId', null);
  this.render(hbs`
    {{#bs-tab/pane fade=false activeId=activeId elementId="pane1"}}
      template block text
    {{/bs-tab/pane}}
  `);

  assert.equal(this.$('div.tab-pane').hasClass('fade'), false, 'tab-pane does not have fade class');

  assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
  assert.equal(this.$('div.tab-pane').hasClass(visibilityClass()), false, 'tab-pane does not have visibility class');

  this.set('activeId', 'pane1');
  assert.equal(this.$('div.tab-pane').hasClass('active'), true, 'tab-pane has active class');
  assert.equal(this.$('div.tab-pane').hasClass(visibilityClass()), false, 'tab-pane does not have visibility class');

  this.set('activeId', null);
  assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
  assert.equal(this.$('div.tab-pane').hasClass(visibilityClass()), false, 'tab-pane does not have visibility class');
});

test('it has correct markup when switching active pane and fade=true', function(assert) {
  this.set('activeId', null);
  this.render(hbs`
    {{#bs-tab/pane fade=true activeId=activeId elementId="pane1"}}
      template block text
    {{/bs-tab/pane}}
  `);

  assert.equal(this.$('div.tab-pane').hasClass('fade'), true, 'tab-pane has fade class');
  assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
  assert.equal(this.$('div.tab-pane').hasClass(visibilityClass()), false, 'tab-pane does not have visibility class');

  this.set('activeId', 'pane1');
  assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
  assert.equal(this.$('div.tab-pane').hasClass(visibilityClass()), false, 'tab-pane does not have visibility class');

  let done = assert.async();
  // wait for fade animation
  setTimeout(() => {
    assert.equal(this.$('div.tab-pane').hasClass('active'), true, 'tab-pane has active class');
    assert.equal(this.$('div.tab-pane').hasClass(visibilityClass()), true, 'tab-pane has visibility class');

    this.set('activeId', null);
    assert.equal(this.$('div.tab-pane').hasClass('active'), true, 'tab-pane has active class');
    assert.equal(this.$('div.tab-pane').hasClass(visibilityClass()), false, 'tab-pane does not have visibility class');

    // wait for fade animation
    setTimeout(() => {
      assert.equal(this.$('div.tab-pane').hasClass('active'), false, 'tab-pane does not have active class');
      assert.equal(this.$('div.tab-pane').hasClass(visibilityClass()), false, 'tab-pane does not have visibility class');

      done();
    }, transitionTimeout);

  }, transitionTimeout);
});
<|endoftext|>


<commit_before>var colors = require('colors');

var config;
var activeLevels = {};
var levelColors = {
    INFO: colors.white,
    DEBUG: colors.green,
    WARN: colors.yellow,
    ERROR: colors.magenta,
    FATAL: colors.red
};

var canLog = function (logLevel) {
    return activeLevels[logLevel];
}

var init = function (cfg) {
    config = cfg || {};

    if (config.levels) {
        config.levels.forEach(function (logLevel) {
            activeLevels[logLevel] = true;
        });
    }

    if (config.colors) {
        config.colors.forEach(function (levelColor) {
            levelColors[levelColor.level] = colors[levelColor.color.toLowerCase()];
        });
    }
};

var log = function (logLevel, message) {
    console.log(levelColors[logLevel](message));
};

exports.init = init;
exports.log = log;
exports.canLog = canLog;<commit_msg>Case enforcement and error checking<commit_after>var colors = require('colors');

var config;
var activeLevels = {};
var levelColors = {
    INFO: colors.white,
    DEBUG: colors.green,
    WARN: colors.yellow,
    ERROR: colors.magenta,
    FATAL: colors.red
};

var canLog = function (logLevel) {
    return activeLevels[logLevel];
}

var init = function (cfg) {
    config = cfg || {};

    if (config.levels) {
        config.levels.forEach(function (logLevel) {
            activeLevels[logLevel.toUpperCase()] = true;
        });
    }

    if (config.colors) {
        config.colors.forEach(function (levelColor) {
            if (!colors[levelColor.color.toLowerCase()]) {
                throw new Error('Console color [' + levelColor.color.toLowerCase() + '] is not available.');
            } else {
                levelColors[levelColor.level.toUpperCase()] = colors[levelColor.color.toLowerCase()];
            }
        });
    }
};

var log = function (logLevel, message) {
    console.log(levelColors[logLevel](message));
};

exports.init = init;
exports.log = log;
exports.canLog = canLog;<|endoftext|>