<commit_before>'use strict';

import _ from 'lodash';

let angular = require('angular');

module.exports = angular.module('spinnaker.core.delivery.executions.service', [
  require('../../cache/deckCacheFactory.js'),
  require('../../utils/appendTransform.js'),
  require('../../config/settings.js'),
  require('../filter/executionFilter.model.js'),
  require('./executions.transformer.service.js')
])
  .factory('executionService', function($http, $timeout, $q, $log, ExecutionFilterModel, $state,
                                        settings, appendTransform, executionsTransformer) {

    const activeStatuses = ['RUNNING', 'SUSPENDED', 'PAUSED', 'NOT_STARTED'];
    const runningLimit = 30;

    function getRunningExecutions(applicationName) {
      return getFilteredExecutions(applicationName, {statuses: activeStatuses, limit: runningLimit});
    }

    function getFilteredExecutions(applicationName, {statuses = Object.keys(_.pickBy(ExecutionFilterModel.sortFilter.status || {}, _.identity)), limit = ExecutionFilterModel.sortFilter.count} = {}) {
      let url = [ settings.gateUrl, 'applications', applicationName, `pipelines?limit=${limit}`].join('/');
      if (statuses.length) {
        url += '&statuses=' + statuses.map((status) => status.toUpperCase()).join(',');
      }
      return $http({
        method: 'GET',
        url: url,
        timeout: settings.pollSchedule * 2 + 5000, // TODO: replace with apiHost call
      })
        .then((resp) => resp.data);
    }

    function getExecutions(applicationName) {
      return getFilteredExecutions(applicationName);
    }

    function getExecution(executionId) {
      const url = [ settings.gateUrl, 'pipelines', executionId].join('/');
      return $http({
        method: 'GET',
        url: url,
        timeout: settings.pollSchedule * 2 + 5000, // TODO: replace with apiHost call
      }).then((resp) => resp.data);
    }

    function transformExecution(application, execution) {
      return executionsTransformer.transformExecution(application, execution);
    }

    function transformExecutions(application, executions) {
      if (!executions || !executions.length) {
        return;
      }
      executions.forEach((execution) => {
        (execution.stages || []).forEach(removeInstances);
        if (execution.trigger && execution.trigger.parentExecution) {
          (execution.trigger.parentExecution.stages || []).forEach(removeInstances);
        }
        let stringVal = JSON.stringify(execution, jsonReplacer);
        // do not transform if it hasn't changed
        let match = (application.executions.data || []).filter((test) => test.id === execution.id);
        if (!match.length || !match[0].stringVal || match[0].stringVal !== stringVal) {
          execution.stringVal = stringVal;
          executionsTransformer.transformExecution(application, execution);
        }
      });
    }

    // these fields are never displayed in the UI, so don't retain references to them, as they consume a lot of memory
    // on very large deployments
    function removeInstances(stage) {
      if (stage.context) {
        delete stage.context.instances;
        delete stage.context.asg;
        if (stage.context.targetReferences) {
          stage.context.targetReferences.forEach(tr => {
            delete tr.instances;
            delete tr.asg;
          });
        }
      }
    }

    // remove these fields - they are not of interest when determining if the pipeline has changed
    function jsonReplacer(key, value) {
      var val = value;

      if (key === 'instances' || key === 'asg' || key === 'commits' || key === 'history') {
        val = undefined;
      }

      return val;
    }

    function waitUntilNewTriggeredPipelineAppears(application, pipelineName, triggeredPipelineId) {

      return getRunningExecutions(application.name).then(function(executions) {
        let match = executions.find(function(execution) {
          return execution.id === triggeredPipelineId;
        });
        var deferred = $q.defer();
        if (match) {
          application.executions.refresh().then(deferred.resolve);
          return deferred.promise;
        } else {
          return $timeout(function() {
            return waitUntilNewTriggeredPipelineAppears(application, pipelineName, triggeredPipelineId);
          }, 1000);
        }
      });
    }

    function waitUntilPipelineIsCancelled(application, executionId) {
      return waitUntilExecutionMatches(executionId, (execution) => execution.status === 'CANCELED')
        .then(() => application.executions.refresh());
    }

    function waitUntilPipelineIsDeleted(application, executionId) {
      let deferred = $q.defer();
      getExecution(executionId).then(
        () => $timeout(() => waitUntilPipelineIsDeleted(application, executionId).then(deferred.resolve), 1000),
        deferred.resolve
      );
      deferred.promise.then(() => application.executions.refresh());
      return deferred.promise;
    }

    function cancelExecution(application, executionId) {
      var deferred = $q.defer();
      $http({
        method: 'PUT',
        url: [
          settings.gateUrl,
          'applications',
          application.name,
          'pipelines',
          executionId,
          'cancel',
        ].join('/')
      }).then(
        () => waitUntilPipelineIsCancelled(application, executionId).then(deferred.resolve),
        (exception) => deferred.reject(exception && exception.data ? exception.message : null)
      );
      return deferred.promise;
    }

    function pauseExecution(application, executionId) {
      var deferred = $q.defer();
      var matcher = (execution) => {
        return execution.status === 'PAUSED';
      };

      $http({
        method: 'PUT',
        url: [
          settings.gateUrl,
          'pipelines',
          executionId,
          'pause',
        ].join('/')
      }).then(
        () => waitUntilExecutionMatches(executionId, matcher).then(() => application.executions.refresh()).then(deferred.resolve),
        (exception) => deferred.reject(exception && exception.data ? exception.message : null)
    );
      return deferred.promise;
    }

    function resumeExecution(application, executionId) {
      var deferred = $q.defer();
      var matcher = (execution) => {
        return execution.status === 'RUNNING';
      };

      $http({
        method: 'PUT',
        url: [
          settings.gateUrl,
          'pipelines',
          executionId,
          'resume',
        ].join('/')
      }).then(
        () => waitUntilExecutionMatches(executionId, matcher).then(() => application.executions.refresh()).then(deferred.resolve),
        (exception) => deferred.reject(exception && exception.data ? exception.message : null)
    );
      return deferred.promise;
    }

    function deleteExecution(application, executionId) {
      var deferred = $q.defer();
      $http({
        method: 'DELETE',
        url: [
          settings.gateUrl,
          'pipelines',
          executionId,
        ].join('/')
      }).then(
        () => waitUntilPipelineIsDeleted(application, executionId).then(deferred.resolve),
        (exception) => deferred.reject(exception && exception.data ? exception.data.message : null)
      );
      return deferred.promise;
    }

    function waitUntilExecutionMatches(executionId, closure) {
      return getExecution(executionId).then(
        (execution) => {
          if (closure(execution)) {
            return execution;
          }
          return $timeout(() => waitUntilExecutionMatches(executionId, closure), 1000);
        }
      );
    }

    function getSectionCacheKey(groupBy, application, heading) {
      return ['pipeline', groupBy, application, heading].join('#');
    }

    function getProjectExecutions(project, limit = 1) {
      return $http({
        method: 'GET',
        transformResponse: appendTransform(function(executions) {
          if (!executions || !executions.length) {
            return [];
          }
          executions.forEach(function(execution) {
            executionsTransformer.transformExecution({}, execution);
          });
          return executions;
        }),
        url: [
          settings.gateUrl,
          'projects',
          project,
          'pipelines'
        ].join('/') + '?limit=' + limit
      }).then((resp) => {
        return resp.data.sort((a, b) => b.startTime - (a.startTime || new Date().getTime()));
      });
    }

    function addExecutionsToApplication(application, executions = []) {
      // only add executions if we actually got some executions back
      // this will fail if there was just one execution and someone just deleted it
      // but that is much less likely at this point than orca falling over under load,
      // resulting in an empty list of executions coming back
      if (application.executions.data && application.executions.data.length && executions.length) {
        let existingData = application.executions.data;
        // remove any that have dropped off, update any that have changed
        let toRemove = [];
        existingData.forEach((execution, idx) => {
          let matches = executions.filter((test) => test.id === execution.id);
          if (!matches.length) {
            toRemove.push(idx);
          } else {
            if (execution.stringVal && matches[0].stringVal && execution.stringVal !== matches[0].stringVal) {
              existingData[idx] = matches[0];
            }
          }
        });

        toRemove.reverse().forEach((idx) => existingData.splice(idx, 1));

        // add any new ones
        executions.forEach((execution) => {
          if (!existingData.filter((test) => test.id === execution.id).length) {
            existingData.push(execution);
          }
        });
        return existingData;
      } else {
        return executions;
      }
    }

    function updateExecution(application, execution) {
      if (application.executions.data && application.executions.data.length) {
        application.executions.data.forEach((t, idx) => {
          if (execution.id === t.id) {
            execution.stringVal = JSON.stringify(execution);
            if (t.stringVal !== execution.stringVal) {
              transformExecution(application, execution);
              application.executions.data[idx] = execution;
              application.executions.dataUpdated();
            }
          }
        });
      }
    }

    function getLastExecutionForApplicationByConfigId(appName, configId) {
      return getFilteredExecutions(appName, {}, 1 )
        .then((executions) => {
          return executions.filter((execution) => {
            return execution.pipelineConfigId === configId;
          });
        })
        .then((executionsByConfigId) => {
          return executionsByConfigId[0];
        });
    }

    function patchExecution(executionId, stageId, data) {
      var targetUrl = [settings.gateUrl, 'pipelines', executionId, 'stages', stageId].join('/');
      var request = {
        method: 'PATCH',
        url: targetUrl,
        data: data,
        timeout: settings.pollSchedule * 2 + 5000
      };
      return $http(request).then(resp => resp.data);
    }

    return {
      getExecutions: getExecutions,
      getExecution: getExecution,
      getRunningExecutions: getRunningExecutions,
      transformExecutions: transformExecutions,
      transformExecution: transformExecution,
      cancelExecution: cancelExecution,
      resumeExecution: resumeExecution,
      pauseExecution: pauseExecution,
      deleteExecution: deleteExecution,
      waitUntilNewTriggeredPipelineAppears: waitUntilNewTriggeredPipelineAppears,
      waitUntilExecutionMatches: waitUntilExecutionMatches,
      getSectionCacheKey: getSectionCacheKey,
      getProjectExecutions: getProjectExecutions,
      addExecutionsToApplication: addExecutionsToApplication,
      updateExecution: updateExecution,
      getLastExecutionForApplicationByConfigId: getLastExecutionForApplicationByConfigId,
      patchExecution: patchExecution,
    };
  });
<commit_msg>(core) clean single execution before adding to application (#2834)<commit_after>'use strict';

import _ from 'lodash';

let angular = require('angular');

module.exports = angular.module('spinnaker.core.delivery.executions.service', [
  require('../../cache/deckCacheFactory.js'),
  require('../../utils/appendTransform.js'),
  require('../../config/settings.js'),
  require('../filter/executionFilter.model.js'),
  require('./executions.transformer.service.js')
])
  .factory('executionService', function($http, $timeout, $q, $log, ExecutionFilterModel, $state,
                                        settings, appendTransform, executionsTransformer) {

    const activeStatuses = ['RUNNING', 'SUSPENDED', 'PAUSED', 'NOT_STARTED'];
    const runningLimit = 30;

    function getRunningExecutions(applicationName) {
      return getFilteredExecutions(applicationName, {statuses: activeStatuses, limit: runningLimit});
    }

    function getFilteredExecutions(applicationName, {statuses = Object.keys(_.pickBy(ExecutionFilterModel.sortFilter.status || {}, _.identity)), limit = ExecutionFilterModel.sortFilter.count} = {}) {
      let url = [ settings.gateUrl, 'applications', applicationName, `pipelines?limit=${limit}`].join('/');
      if (statuses.length) {
        url += '&statuses=' + statuses.map((status) => status.toUpperCase()).join(',');
      }
      return $http({
        method: 'GET',
        url: url,
        timeout: settings.pollSchedule * 2 + 5000, // TODO: replace with apiHost call
      })
        .then((resp) => {
          resp.data.forEach(cleanExecutionForDiffing);
          return resp.data;
        });
    }

    function getExecutions(applicationName) {
      return getFilteredExecutions(applicationName);
    }

    function getExecution(executionId) {
      const url = [ settings.gateUrl, 'pipelines', executionId].join('/');
      return $http({
        method: 'GET',
        url: url,
        timeout: settings.pollSchedule * 2 + 5000, // TODO: replace with apiHost call
      }).then((resp) => {
        cleanExecutionForDiffing(resp.data);
        return resp.data;
      });
    }

    function transformExecution(application, execution) {
      return executionsTransformer.transformExecution(application, execution);
    }

    function transformExecutions(application, executions) {
      if (!executions || !executions.length) {
        return;
      }
      executions.forEach((execution) => {
        let stringVal = JSON.stringify(execution, jsonReplacer);
        // do not transform if it hasn't changed
        let match = (application.executions.data || []).find((test) => test.id === execution.id);
        if (!match || !match.stringVal || match.stringVal !== stringVal) {
          execution.stringVal = stringVal;
          executionsTransformer.transformExecution(application, execution);
        }
      });
    }

    function cleanExecutionForDiffing(execution) {
      (execution.stages || []).forEach(removeInstances);
      if (execution.trigger && execution.trigger.parentExecution) {
        (execution.trigger.parentExecution.stages || []).forEach(removeInstances);
      }
    }

    // these fields are never displayed in the UI, so don't retain references to them, as they consume a lot of memory
    // on very large deployments
    function removeInstances(stage) {
      if (stage.context) {
        delete stage.context.instances;
        delete stage.context.asg;
        if (stage.context.targetReferences) {
          stage.context.targetReferences.forEach(tr => {
            delete tr.instances;
            delete tr.asg;
          });
        }
      }
    }

    // remove these fields - they are not of interest when determining if the pipeline has changed
    function jsonReplacer(key, value) {
      var val = value;

      if (key === 'instances' || key === 'asg' || key === 'commits' || key === 'history') {
        val = undefined;
      }

      return val;
    }

    function waitUntilNewTriggeredPipelineAppears(application, pipelineName, triggeredPipelineId) {

      return getRunningExecutions(application.name).then(function(executions) {
        let match = executions.find(function(execution) {
          return execution.id === triggeredPipelineId;
        });
        var deferred = $q.defer();
        if (match) {
          application.executions.refresh().then(deferred.resolve);
          return deferred.promise;
        } else {
          return $timeout(function() {
            return waitUntilNewTriggeredPipelineAppears(application, pipelineName, triggeredPipelineId);
          }, 1000);
        }
      });
    }

    function waitUntilPipelineIsCancelled(application, executionId) {
      return waitUntilExecutionMatches(executionId, (execution) => execution.status === 'CANCELED')
        .then(() => application.executions.refresh());
    }

    function waitUntilPipelineIsDeleted(application, executionId) {
      let deferred = $q.defer();
      getExecution(executionId).then(
        () => $timeout(() => waitUntilPipelineIsDeleted(application, executionId).then(deferred.resolve), 1000),
        deferred.resolve
      );
      deferred.promise.then(() => application.executions.refresh());
      return deferred.promise;
    }

    function cancelExecution(application, executionId) {
      var deferred = $q.defer();
      $http({
        method: 'PUT',
        url: [
          settings.gateUrl,
          'applications',
          application.name,
          'pipelines',
          executionId,
          'cancel',
        ].join('/')
      }).then(
        () => waitUntilPipelineIsCancelled(application, executionId).then(deferred.resolve),
        (exception) => deferred.reject(exception && exception.data ? exception.message : null)
      );
      return deferred.promise;
    }

    function pauseExecution(application, executionId) {
      var deferred = $q.defer();
      var matcher = (execution) => {
        return execution.status === 'PAUSED';
      };

      $http({
        method: 'PUT',
        url: [
          settings.gateUrl,
          'pipelines',
          executionId,
          'pause',
        ].join('/')
      }).then(
        () => waitUntilExecutionMatches(executionId, matcher).then(() => application.executions.refresh()).then(deferred.resolve),
        (exception) => deferred.reject(exception && exception.data ? exception.message : null)
    );
      return deferred.promise;
    }

    function resumeExecution(application, executionId) {
      var deferred = $q.defer();
      var matcher = (execution) => {
        return execution.status === 'RUNNING';
      };

      $http({
        method: 'PUT',
        url: [
          settings.gateUrl,
          'pipelines',
          executionId,
          'resume',
        ].join('/')
      }).then(
        () => waitUntilExecutionMatches(executionId, matcher).then(() => application.executions.refresh()).then(deferred.resolve),
        (exception) => deferred.reject(exception && exception.data ? exception.message : null)
    );
      return deferred.promise;
    }

    function deleteExecution(application, executionId) {
      var deferred = $q.defer();
      $http({
        method: 'DELETE',
        url: [
          settings.gateUrl,
          'pipelines',
          executionId,
        ].join('/')
      }).then(
        () => waitUntilPipelineIsDeleted(application, executionId).then(deferred.resolve),
        (exception) => deferred.reject(exception && exception.data ? exception.data.message : null)
      );
      return deferred.promise;
    }

    function waitUntilExecutionMatches(executionId, closure) {
      return getExecution(executionId).then(
        (execution) => {
          if (closure(execution)) {
            return execution;
          }
          return $timeout(() => waitUntilExecutionMatches(executionId, closure), 1000);
        }
      );
    }

    function getSectionCacheKey(groupBy, application, heading) {
      return ['pipeline', groupBy, application, heading].join('#');
    }

    function getProjectExecutions(project, limit = 1) {
      return $http({
        method: 'GET',
        transformResponse: appendTransform(function(executions) {
          if (!executions || !executions.length) {
            return [];
          }
          executions.forEach(function(execution) {
            executionsTransformer.transformExecution({}, execution);
          });
          return executions;
        }),
        url: [
          settings.gateUrl,
          'projects',
          project,
          'pipelines'
        ].join('/') + '?limit=' + limit
      }).then((resp) => {
        return resp.data.sort((a, b) => b.startTime - (a.startTime || new Date().getTime()));
      });
    }

    function addExecutionsToApplication(application, executions = []) {
      // only add executions if we actually got some executions back
      // this will fail if there was just one execution and someone just deleted it
      // but that is much less likely at this point than orca falling over under load,
      // resulting in an empty list of executions coming back
      if (application.executions.data && application.executions.data.length && executions.length) {
        let existingData = application.executions.data;
        // remove any that have dropped off, update any that have changed
        let toRemove = [];
        existingData.forEach((execution, idx) => {
          let matches = executions.filter((test) => test.id === execution.id);
          if (!matches.length) {
            toRemove.push(idx);
          } else {
            if (execution.stringVal && matches[0].stringVal && execution.stringVal !== matches[0].stringVal) {
              existingData[idx] = matches[0];
            }
          }
        });

        toRemove.reverse().forEach((idx) => existingData.splice(idx, 1));

        // add any new ones
        executions.forEach((execution) => {
          if (!existingData.filter((test) => test.id === execution.id).length) {
            existingData.push(execution);
          }
        });
        return existingData;
      } else {
        return executions;
      }
    }

    function updateExecution(application, execution) {
      if (application.executions.data && application.executions.data.length) {
        application.executions.data.forEach((t, idx) => {
          if (execution.id === t.id) {
            execution.stringVal = JSON.stringify(execution, jsonReplacer);
            if (t.stringVal !== execution.stringVal) {
              transformExecution(application, execution);
              application.executions.data[idx] = execution;
              application.executions.dataUpdated();
            }
          }
        });
      }
    }

    function getLastExecutionForApplicationByConfigId(appName, configId) {
      return getFilteredExecutions(appName, {}, 1 )
        .then((executions) => {
          return executions.filter((execution) => {
            return execution.pipelineConfigId === configId;
          });
        })
        .then((executionsByConfigId) => {
          return executionsByConfigId[0];
        });
    }

    function patchExecution(executionId, stageId, data) {
      var targetUrl = [settings.gateUrl, 'pipelines', executionId, 'stages', stageId].join('/');
      var request = {
        method: 'PATCH',
        url: targetUrl,
        data: data,
        timeout: settings.pollSchedule * 2 + 5000
      };
      return $http(request).then(resp => resp.data);
    }

    return {
      getExecutions: getExecutions,
      getExecution: getExecution,
      getRunningExecutions: getRunningExecutions,
      transformExecutions: transformExecutions,
      transformExecution: transformExecution,
      cancelExecution: cancelExecution,
      resumeExecution: resumeExecution,
      pauseExecution: pauseExecution,
      deleteExecution: deleteExecution,
      waitUntilNewTriggeredPipelineAppears: waitUntilNewTriggeredPipelineAppears,
      waitUntilExecutionMatches: waitUntilExecutionMatches,
      getSectionCacheKey: getSectionCacheKey,
      getProjectExecutions: getProjectExecutions,
      addExecutionsToApplication: addExecutionsToApplication,
      updateExecution: updateExecution,
      getLastExecutionForApplicationByConfigId: getLastExecutionForApplicationByConfigId,
      patchExecution: patchExecution,
    };
  });
<|endoftext|>


<commit_before>(function ($){
var app = $.app;
var prevDegree = 0;
var currentPlaying = null;

function player () {}

function updateSongInfo(muFile){
  var songInfo = $('#player_column #player_controls #song_info');
  var yt = '';
  var wiki = '';
  var amzn = '';
  var lyrics = '';
  $('#title_info .title', songInfo).text(muFile.title).attr('title', muFile.title);
  $('#artist_info .title', songInfo).text(muFile.artist).attr('title', muFile.artist);
  $('#album_info .title', songInfo).text(muFile.album).attr('title', muFile.album);
  $('#title_info .extern', songInfo).html(yt+lyrics);
  $('#artist_info .extern', songInfo).html(wiki+amzn);
}

function animateSeeker() {
  var player = $('#player').get(0);
  var degree = (player.currentTime/player.duration)*360;

  if(player.currentTime == 0){ prevDegree = 0; }

  if((degree-prevDegree)>1){
    $.app.ctx.beginPath();
    $.app.ctx.clearRect(0,0,$.app.canvas.width,$.app.canvas.height);
    $.app.ctx.strokeStyle = 'rgba(00, 194, 256, 0.9)';
    $.app.ctx.lineWidth = 14;
    $.app.ctx.arc(75,75,65,Math.PI*(270/180),Math.PI*(degree+270)/180);
    $.app.ctx.shadowOffsetX = 0;
    $.app.ctx.shadowOffsetY = 0;
    $.app.ctx.shadowBlur = 5;
    $.app.ctx.shadowColor = 'rgba(170,170,170,0.7)';
    $.app.ctx.stroke();

    $.app.ctx.closePath();
    prevDegree = degree;
  }
  window.webkitRequestAnimationFrame(animateSeeker);
}

player.prevSong = function () {
  var prevDiv = currentPlaying.prev();
  if(prevDiv.length == 0) {
    prevDiv = currentPlaying.parent().children().last();
  }
  player.playMedia(prevDiv);
}

player.nextSong = function () {
  var nextDiv = currentPlaying.next();
  if(nextDiv.length == 0) {
    nextDiv = currentPlaying.parent().children().first();
  }
  player.playMedia(nextDiv);
}

player.pauseMedia = function () {
  $('#player').get(0).pause();
}

player.playMedia = function (div, resumeFlag) {

  if(!div){
    if($('#playlist', '#playlist_wrapper').is(':empty')){
      alert('No selction made.');
      return;
    } else {
      div = $('.entry', '#playlist').first();
      resumeFlag = false;
    }
  }
  var muFile = div.find('.entry_action').data('muFile');
  app.utils.getPlayableURL(muFile.path, function (url) {
    if(url) {
      if(!resumeFlag) { $('#player').get(0).src = url; }

      var wrapper_height = $('#player_wrapper').height()-30;
      var wrapper_width = $('#player_wrapper').width()-30;

      $('#player', player.jqelem).get(0).play();
      currentPlaying = div;
      currentPlaying.parent().children().removeClass('active_entry');
      currentPlaying.addClass('active_entry');
      app.utils.searchImage(muFile.album,muFile.artist,function (tbUrl) {
        $('#album_artwork', player.jqelem).attr('src',tbUrl);
        var height = $('#album_artwork', player.jqelem).height();
        var width = $('#album_artwork', player.jqelem).width();

        if(height > wrapper_height || width > wrapper_width){
          var ratio, new_height, new_width;
          if(height > wrapper_height){
            ratio = width/height;
            new_height = wrapper_height;
            new_width = ratio*new_height;
          } else {
            ratio = height/width;
            new_width = wrapper_width;
            new_height = ratio*new_width;
          }
          $('#player_wrapper img', player.jqelem)
            .css({ 'height': new_height,'width': new_width });
        }

      });
      updateSongInfo(muFile);
    } else {
      alert('Add music again');
    }
  });

}

player.saveVolume = function () {
  window.localStorage.setItem('__volume__', $('#player').get(0).volume);
}

player.loadVolume = function () {
  var localVolume = window.localStorage.getItem('__volume__');
  localVolume = localVolume == null ? 0.3 : JSON.parse(localVolume);
  $('#player').get(0).volume = localVolume;
  return localVolume*100;
}

player.init = function (jqelem) {
  player.jqelem = jqelem;
  player.action = 'play';
  $('#album_artwork', player.jqelem).attr('src', '/images/nothumb.png');

  $('#play', player.jqelem)
    .hover(
      function () {
        $('img', this)
          .attr('src', '/images/'+player.action+'_hover.png');
      },
      function () {
        $('img', this)
          .attr('src', '/images/'+player.action+'.png');
      }
    )
    .click(function () {
      if(player.action == 'play'){
        player.playMedia(currentPlaying, true);
      } else {
        player.pauseMedia();
      }
    });

  $('#prev', player.jqelem)
    .hover(
      function (){
        $('img', this).attr('src', '/images/previous_hover.png');
      },
      function (){
        $('img', this).attr('src', '/images/previous.png');
      }
    )
    .click(function (){
      player.prevSong();
    });

  $('#next', player.jqelem)
    .hover(
      function (){
        $('img', this).attr('src', '/images/next_hover.png');
      },
      function (){
        $('img', this).attr('src', '/images/next.png');
      }
    )
    .click(function (){
      player.nextSong();
    });

  $('#player', player.jqelem)
    .bind('ended', function (e){
      $.app.player.nextSong();
    })
    .bind('play', function () {
      player.action = 'pause';
      $('img', '#play').attr('src', '/images/pause.png');
      animateSeeker();
    })
    .bind('pause', function () {
      player.action = 'play';
      $('img', '#play').attr('src', '/images/play.png');
    });

  $('#player_volume', player.jqelem).slider({
    'range' : 'min',
    'value' : player.loadVolume(),
    'min' : 0.0,
    'max' : 100,
    'slide' : function (e, ui){
      $('#player', player.jqelem).get(0).volume = (ui.value)/100;
    }
  });
};

app.player = player;

})(jQuery)
<commit_msg>Fixes the error after files are minified<commit_after>(function ($){
var app = $.app;
var prevDegree = 0;
var currentPlaying = null;

function player () {}

function updateSongInfo(muFile){
  var songInfo = $('#player_column #player_controls #song_info');
  var yt = '';
  var wiki = '';
  var amzn = '';
  var lyrics = '';
  $('#title_info .title', songInfo).text(muFile.title).attr('title', muFile.title);
  $('#artist_info .title', songInfo).text(muFile.artist).attr('title', muFile.artist);
  $('#album_info .title', songInfo).text(muFile.album).attr('title', muFile.album);
  $('#title_info .extern', songInfo).html(yt+lyrics);
  $('#artist_info .extern', songInfo).html(wiki+amzn);
}

function animateSeeker() {
  var player = $('#player').get(0);
  var degree = (player.currentTime/player.duration)*360;

  if(player.currentTime == 0){ prevDegree = 0; }

  if((degree-prevDegree)>1){
    $.app.ctx.beginPath();
    $.app.ctx.clearRect(0,0,$.app.canvas.width,$.app.canvas.height);
    $.app.ctx.strokeStyle = 'rgba(00, 194, 256, 0.9)';
    $.app.ctx.lineWidth = 14;
    $.app.ctx.arc(75,75,65,Math.PI*(270/180),Math.PI*(degree+270)/180);
    $.app.ctx.shadowOffsetX = 0;
    $.app.ctx.shadowOffsetY = 0;
    $.app.ctx.shadowBlur = 5;
    $.app.ctx.shadowColor = 'rgba(170,170,170,0.7)';
    $.app.ctx.stroke();

    $.app.ctx.closePath();
    prevDegree = degree;
  }
  window.webkitRequestAnimationFrame(animateSeeker);
}

player.prevSong = function () {
  var prevDiv = currentPlaying.prev();
  if(prevDiv.length == 0) {
    prevDiv = currentPlaying.parent().children().last();
  }
  player.playMedia(prevDiv);
}

player.nextSong = function () {
  var nextDiv = currentPlaying.next();
  if(nextDiv.length == 0) {
    nextDiv = currentPlaying.parent().children().first();
  }
  player.playMedia(nextDiv);
}

player.pauseMedia = function () {
  $('#player').get(0).pause();
}

player.playMedia = function (div, resumeFlag) {

  if(!div){
    if($('#playlist', '#playlist_wrapper').is(':empty')){
      alert('No selction made.');
      return;
    } else {
      div = $('.entry', '#playlist').first();
      resumeFlag = false;
    }
  }
  var muFile = div.find('.entry_action').data('muFile');
  app.utils.getPlayableURL(muFile.path, function (url) {
    if(url) {
      if(!resumeFlag) { $('#player').get(0).src = url; }

      var wrapper_height = $('#player_wrapper').height()-30;
      var wrapper_width = $('#player_wrapper').width()-30;

      $('#player', player.jqelem).get(0).play();
      currentPlaying = div;
      currentPlaying.parent().children().removeClass('active_entry');
      currentPlaying.addClass('active_entry');
      app.utils.searchImage(muFile.album,muFile.artist,function (tbUrl) {
        $('#album_artwork', player.jqelem).attr('src',tbUrl);
        var height = $('#album_artwork', player.jqelem).height();
        var width = $('#album_artwork', player.jqelem).width();

        if(height > wrapper_height || width > wrapper_width){
          var ratio, new_height, new_width;
          if(height > wrapper_height){
            ratio = width/height;
            new_height = wrapper_height;
            new_width = ratio*new_height;
          } else {
            ratio = height/width;
            new_width = wrapper_width;
            new_height = ratio*new_width;
          }
          $('#player_wrapper img', player.jqelem)
            .css({ 'height': new_height,'width': new_width });
        }

      });
      updateSongInfo(muFile);
    } else {
      alert('Add music again');
    }
  });

}

player.saveVolume = function () {
  window.localStorage.setItem('__volume__', $('#player').get(0).volume);
}

player.loadVolume = function () {
  var localVolume = window.localStorage.getItem('__volume__');
  localVolume = localVolume == null ? 0.3 : JSON.parse(localVolume);
  $('#player').get(0).volume = localVolume;
  return localVolume*100;
}

player.init = function (jqelem) {
  player.jqelem = jqelem;
  player.action = 'play';
  $('#album_artwork', player.jqelem).attr('src', '/images/nothumb.png');

  $('#play', player.jqelem)
    .hover(
      function () {
        $('img', this)
          .attr('src', '/images/'+player.action+'_hover.png');
      },
      function () {
        $('img', this)
          .attr('src', '/images/'+player.action+'.png');
      }
    )
    .click(function () {
      if(player.action == 'play'){
        player.playMedia(currentPlaying, true);
      } else {
        player.pauseMedia();
      }
    });

  $('#prev', player.jqelem)
    .hover(
      function (){
        $('img', this).attr('src', '/images/previous_hover.png');
      },
      function (){
        $('img', this).attr('src', '/images/previous.png');
      }
    )
    .click(function (){
      player.prevSong();
    });

  $('#next', player.jqelem)
    .hover(
      function (){
        $('img', this).attr('src', '/images/next_hover.png');
      },
      function (){
        $('img', this).attr('src', '/images/next.png');
      }
    )
    .click(function (){
      player.nextSong();
    });

  $('#player', player.jqelem)
    .bind('ended', function (e){
      $.app.player.nextSong();
    })
    .bind('play', function () {
      player.action = 'pause';
      $('img', '#play').attr('src', '/images/pause.png');
      animateSeeker();
    })
    .bind('pause', function () {
      player.action = 'play';
      $('img', '#play').attr('src', '/images/play.png');
    });

  $('#player_volume', player.jqelem).slider({
    'range' : 'min',
    'value' : player.loadVolume(),
    'min' : 0.0,
    'max' : 100,
    'slide' : function (e, ui){
      $('#player', player.jqelem).get(0).volume = (ui.value)/100;
    }
  });
};

app.player = player;

})(jQuery);
<|endoftext|>


<commit_before>var popup_function = function(rows, package_info){
    if (!document.getElementById('CompanyInfo')) {
	var content = "
"
	    + "

"
	    + "
"
	    + "×
"
	    + "

";
	document.body.innerHTML = content + document.body.innerHTML;
	var close = document.getElementById('CompanyInfoClose');

	close.addEventListener('click',function() {
	    document.getElementById('CompanyInfo').style.display = 'none';
	});
    } else {
	document.getElementById('CompanyInfo').style.display = 'block';
    }

    var htmlspecialchars = function(str){
	var span_dom = document.createElement('span');
	span_dom.innerText = str;
	str = span_dom.innerHTML;
	delete(span_dom);
	return str;
    };

    var info_dom = document.getElementById('CompanyInfo');
    info_dom.style.background = 'yellow';
    info_dom.style.color = 'black';
    document.getElementById('CompanyInfoMessage').innerHTML += '
'
	+ htmlspecialchars(rows[1]) + '. ' + htmlspecialchars(rows[2])
	+ '[' + htmlspecialchars(package_info.name) + ']'
	+ '
';
};

function onRequest(request, sender, sendResponse) {
    if (request.method== 'page') {
        // 顯示設定求職小幫手的 page action
        chrome.pageAction.show(sender.tab.id);
    }

    if (request.method == 'add_match') {
        chrome.tabs.executeScript(sender.tab.id, {code: "(" + popup_function + ')(' + JSON.stringify(request.rows) + ',' + JSON.stringify(request.package_info) + ')'});
    }

    // Return nothing to let the connection be cleaned up.
    sendResponse({});
};

// Listen for the content script to send a message to the background page.
chrome.extension.onRequest.addListener(onRequest);
<commit_msg>文字換成關閉<commit_after>var popup_function = function(rows, package_info){
    if (!document.getElementById('CompanyInfo')) {
	var content = "
"
	    + "

"
	    + "
"
	    + "關閉
"
	    + "

";
	document.body.innerHTML = content + document.body.innerHTML;
	var close = document.getElementById('CompanyInfoClose');

	close.addEventListener('click',function() {
	    document.getElementById('CompanyInfo').style.display = 'none';
	});
    } else {
	document.getElementById('CompanyInfo').style.display = 'block';
    }

    var htmlspecialchars = function(str){
	var span_dom = document.createElement('span');
	span_dom.innerText = str;
	str = span_dom.innerHTML;
	delete(span_dom);
	return str;
    };

    var info_dom = document.getElementById('CompanyInfo');
    info_dom.style.background = 'yellow';
    info_dom.style.color = 'black';
    document.getElementById('CompanyInfoMessage').innerHTML += '
'
	+ htmlspecialchars(rows[1]) + '. ' + htmlspecialchars(rows[2])
	+ '[' + htmlspecialchars(package_info.name) + ']'
	+ '
';
};

function onRequest(request, sender, sendResponse) {
    if (request.method== 'page') {
        // 顯示設定求職小幫手的 page action
        chrome.pageAction.show(sender.tab.id);
    }

    if (request.method == 'add_match') {
        chrome.tabs.executeScript(sender.tab.id, {code: "(" + popup_function + ')(' + JSON.stringify(request.rows) + ',' + JSON.stringify(request.package_info) + ')'});
    }

    // Return nothing to let the connection be cleaned up.
    sendResponse({});
};

// Listen for the content script to send a message to the background page.
chrome.extension.onRequest.addListener(onRequest);
<|endoftext|>


<commit_before>/** Service professional service
**/
'use strict';

var ServiceProfessionalService = require('../models/ServiceProfessionalService'),
    GroupListRemoteModel = require('../utils/GroupListRemoteModel');

exports.create = function create(appModel) {

    var api = new GroupListRemoteModel({
        // Conservative cache, just 1 minute
        listTtl: { minutes: 1 },
        groupIdField: 'jobTitleID',
        itemIdField: 'serviceProfessionalServiceID',
        Model: ServiceProfessionalService
    });

    var restUrlPrefix = 'me/service-professional-services/';

    api.addLocalforageSupport('service-professional-services/');
    api.addRestSupport(appModel.rest, restUrlPrefix);

    appModel.on('clearLocalData', function() {
        api.clearCache();
    });

    // Override GroupListRemoteModel's implementation until it
    // supports actual individual fetch. Bypasses local cache.
    api.getItem = function(jobTitleID, serviceID) {
        api.state.isLoading(true);

        // Returns plain data
        return appModel.rest.get(restUrlPrefix + jobTitleID + '/' + serviceID)
             .then(function(data) {
                  api.state.isLoading(false);
                  return data;
             })
             .catch(function(err) {
                  api.state.isLoading(false);
                  throw err;
             });
    };

    var baseSetItem = api.setItem.bind(api);

    // GroupListRemoteModel cache only works for one services API call: ...-services/{jobTitleID}
    // Updates to service objects may change which calls they are returned by. Rather
    // than implement fine-grained control on which cached items are adjusted on object
    // update, clear the cache whenever an item is updated.
    api.setItem = function(item) {
        return baseSetItem(item)
            .then(function(serverObject) {
                api.clearCache();
                return serverObject;
            });
    };

    api.getClientSpecificServices = function(clientID) {
        return appModel.rest.get(restUrlPrefix + 'client/' + clientID);
    };

    api.getClientSpecificServicesForJobTitle = function(clientID, jobTitleID) {
        return api.getClientSpecificServices(clientID).then(function(services) {
            return services.filter(function(service) {
                return service.jobTitleID == jobTitleID;
            });
        });
    };

    return api;
};
<commit_msg>services app api model implements call to fetch services bookable by provider #309<commit_after>/** Service professional service
**/
'use strict';

var ServiceProfessionalService = require('../models/ServiceProfessionalService'),
    GroupListRemoteModel = require('../utils/GroupListRemoteModel');

exports.create = function create(appModel) {

    var api = new GroupListRemoteModel({
        // Conservative cache, just 1 minute
        listTtl: { minutes: 1 },
        groupIdField: 'jobTitleID',
        itemIdField: 'serviceProfessionalServiceID',
        Model: ServiceProfessionalService
    });

    var restUrlPrefix = 'me/service-professional-services/';

    api.addLocalforageSupport('service-professional-services/');
    api.addRestSupport(appModel.rest, restUrlPrefix);

    appModel.on('clearLocalData', function() {
        api.clearCache();
    });

    // Override GroupListRemoteModel's implementation until it
    // supports actual individual fetch. Bypasses local cache.
    api.getItem = function(jobTitleID, serviceID) {
        api.state.isLoading(true);

        // Returns plain data
        return appModel.rest.get(restUrlPrefix + jobTitleID + '/' + serviceID)
             .then(function(data) {
                  api.state.isLoading(false);
                  return data;
             })
             .catch(function(err) {
                  api.state.isLoading(false);
                  throw err;
             });
    };

    var baseSetItem = api.setItem.bind(api);

    // GroupListRemoteModel cache only works for one services API call: ...-services/{jobTitleID}
    // Updates to service objects may change which calls they are returned by. Rather
    // than implement fine-grained control on which cached items are adjusted on object
    // update, clear the cache whenever an item is updated.
    api.setItem = function(item) {
        return baseSetItem(item)
            .then(function(serverObject) {
                api.clearCache();
                return serverObject;
            });
    };

    api.getClientSpecificServices = function(clientID) {
        return appModel.rest.get(restUrlPrefix + 'client/' + clientID);
    };

    api.getClientSpecificServicesForJobTitle = function(clientID, jobTitleID) {
        return api.getClientSpecificServices(clientID).then(function(services) {
            return services.filter(function(service) {
                return service.jobTitleID == jobTitleID;
            });
        });
    };

    api.getServicesBookableByProvider = function(clientID, jobTitleID) {
        return appModel.rest.get(restUrlPrefix + jobTitleID + '/client/' + clientID);
    };

    return api;
};
<|endoftext|>


<commit_before>if (!Array.prototype.last) {
  Array.prototype.last = function () {
    return this[this.length - 1];
  };
}

var jsPlayerUtils = {
  exception: function (type, m) {
    var ex = new Error();
    ex.name = type;
    //for Firefox
    ex.value = type;
    ex.message = m;
    throw (ex);
  },
  addClass: function(e, klass) {
    e.className = e.className + " " + klass;
  },
  removeClass: function(e, klass) {
    var retval, classString;
    if (e.className === "" || e.className === " ") {
      return;
    }
    classes = e.className.split(" ");
    console.log(classes);
    classString = classes.filter(function(member, i, a) {
      if (!(member === klass)){
       return member;
      }
    }).join(" ");
    console.log(classString);
    e.className = classString;
  }
};

var jsPlayerEngine = function (engineElement, params) {

  var outObject = {};
  params = params || {};

  if (!engineElement) {
    jsPlayerUtils.exception("ArgumentError", "Engine element not provided");
  } else {
    outObject.engineElement = engineElement;
  }

  outObject.status = function () {
    return outObject.engineElement.paused;
  };

  outObject.play = function () {
    outObject.engineElement.play();
  };

  outObject.pause = function () {
    outObject.engineElement.pause();
  };

  outObject.isPlaying = function () {
    return outObject.engineElement.paused;
  };

  return outObject;
};

var jsPlayer = function (sourceURL, params) {
  var outObject = {},
      helpers = {};

  if (!sourceURL) {
    jsPlayerUtils.exception("ArgumentError", "URL of audio not provided");
  }

  params = params || {};
  outObject.source = sourceURL;
  outObject.elementID = params.elementID || "jsPlayer";
  outObject.controls = {};
  outObject.mimeType = (function () {
    var audioTypes = { mp3: "audio/mpeg", mpeg: "audio/mpeg", mpeg3: "audio/mpeg",
                         ogg: "audio/ogg" },
        retval, match;
    match = outObject.source.split(".").last();
    if (match && audioTypes[match]) {
      retval = audioTypes[match];
    } else if (params.format && audioTypes[params.format]) {
      retval = audioTypes[params.format];
    } else {
      jsPlayerUtils.exception("ArgumentError",
        "Can not find audio type.  Provide a format member in the parameters object");
    }
    return retval;
  }());

  // detect audio engine
  (function () {
    var node = document.getElementById(outObject.elementID),
        el = document.createElement("audio");
    if (!node) {
      jsPlayerUtils.exception("RuntimeError",
        "Unable to find player element " + outObject.elementID);
    }
    if (!el.canPlayType || !el.canPlayType(outObject.mimeType)) {
      // build flash elements
      outObject.engineType = "Flash";
    } else {
      el.setAttribute("src", outObject.source);
      el.setAttribute("controls", "controls");
      node.appendChild(el);
      outObject.engineType =  "Native";
      outObject.engine = jsPlayerEngine(el);
    }
  }());

  // construct player controls
  (function () {
    var node = document.getElementById(outObject.elementID),
        e = document.createElement("div");
    e.setAttribute("class", "startStop");
    node.appendChild(e);
    outObject.controls.startStop = e;
  }());

  helpers.playPause = function () {
    if (outObject.engine.isPlaying()) {
      outObject.engine.play();
      jsPlayerUtils.removeClass(outObject.controls.startStop, "playerStopped");
      jsPlayerUtils.addClass(outObject.controls.startStop, "playerStarted");
    } else {
      outObject.engine.pause();
      jsPlayerUtils.removeClass(outObject.controls.startStop, "playerStarted");
      jsPlayerUtils.addClass(outObject.controls.startStop, "playerStopped");
    }
  };

  //event binding should be absolute last thing
  if (document.getElementsByTagName("body")[0].addEventListener) {
    outObject.controls.startStop.addEventListener("click",
      function () {
        helpers.playPause();
      }, false);
  } else {
    //Hello IE.  We meet again.
  }
  return outObject;
};
<commit_msg>Autostart things<commit_after>if (!Array.prototype.last) {
  Array.prototype.last = function () {
    return this[this.length - 1];
  };
}

var jsPlayerUtils = {
  exception: function (type, m) {
    var ex = new Error();
    ex.name = type;
    //for Firefox
    ex.value = type;
    ex.message = m;
    throw (ex);
  },
  addClass: function(e, klass) {
    e.className = e.className + " " + klass;
  },
  removeClass: function(e, klass) {
    var retval, classString;
    if (e.className === "" || e.className === " ") {
      return;
    }
    classes = e.className.split(" ");
    console.log(classes);
    classString = classes.filter(function(member, i, a) {
      if (!(member === klass)){
       return member;
      }
    }).join(" ");
    console.log(classString);
    e.className = classString;
  }
};

var jsPlayerEngine = function (engineElement, params) {

  var outObject = {};
  params = params || {};

  if (!engineElement) {
    jsPlayerUtils.exception("ArgumentError", "Engine element not provided");
  } else {
    outObject.engineElement = engineElement;
  }

  outObject.status = function () {
    return outObject.engineElement.paused;
  };

  outObject.play = function () {
    outObject.engineElement.play();
  };

  outObject.pause = function () {
    outObject.engineElement.pause();
  };

  outObject.isPlaying = function () {
    return outObject.engineElement.paused;
  };

  return outObject;
};

var jsPlayer = function (sourceURL, params) {
  var outObject = {},
      helpers = {};

  if (!sourceURL) {
    jsPlayerUtils.exception("ArgumentError", "URL of audio not provided");
  }

  params = params || {};
  outObject.source = sourceURL;
  outObject.elementID = params.elementID || "jsPlayer";
  outObject.controls = {};
  outObject.mimeType = (function () {
    var audioTypes = { mp3: "audio/mpeg", mpeg: "audio/mpeg", mpeg3: "audio/mpeg",
                         ogg: "audio/ogg" },
        retval, match;
    match = outObject.source.split(".").last();
    if (match && audioTypes[match]) {
      retval = audioTypes[match];
    } else if (params.format && audioTypes[params.format]) {
      retval = audioTypes[params.format];
    } else {
      jsPlayerUtils.exception("ArgumentError",
        "Can not find audio type.  Provide a format member in the parameters object");
    }
    return retval;
  }());

  // detect audio engine
  (function () {
    var node = document.getElementById(outObject.elementID),
        el = document.createElement("audio");
    if (!node) {
      jsPlayerUtils.exception("RuntimeError",
        "Unable to find player element " + outObject.elementID);
    }
    if (!el.canPlayType || !el.canPlayType(outObject.mimeType)) {
      // build flash elements
      outObject.engineType = "Flash";
    } else {
      el.setAttribute("src", outObject.source);
      el.setAttribute("controls", "controls");
      node.appendChild(el);
      outObject.engineType =  "Native";
      outObject.engine = jsPlayerEngine(el);
    }
  }());

  // construct player controls
  (function () {
    var node = document.getElementById(outObject.elementID),
        e = document.createElement("div");
    e.setAttribute("class", "startStop");
    node.appendChild(e);
    outObject.controls.startStop = e;
  }());

  helpers.playPause = function () {
    if (outObject.engine.isPlaying()) {
      outObject.engine.play();
      jsPlayerUtils.removeClass(outObject.controls.startStop, "playerStopped");
      jsPlayerUtils.addClass(outObject.controls.startStop, "playerStarted");
    } else {
      outObject.engine.pause();
      jsPlayerUtils.removeClass(outObject.controls.startStop, "playerStarted");
      jsPlayerUtils.addClass(outObject.controls.startStop, "playerStopped");
    }
  };

  if(params.autoStart) {
    helpers.playPause();
  } else {
    jsPlayerUtils.addClass(outObject.controls.startStop, "playerStopped");
  }
  //event binding should be absolute last thing
  if (document.getElementsByTagName("body")[0].addEventListener) {
    outObject.controls.startStop.addEventListener("click",
      function () {
        helpers.playPause();
      }, false);
  } else {
    //Hello IE.  We meet again.
  }
  return outObject;
};
<|endoftext|>


<commit_before>var ACTIVATED = false;

var myTabId = -1;

var LIMIT = 39;

function navigate(request, sender, callback) {
	alert(request.url);
	if (request.newTab) {
			chrome.tabs.create({url:request.url, active:true}, function(tab){myTabId = tab.id;});
			chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
				myTabId = -1;
			});
	} else {
		chrome.tabs.update(myTabId, {url: request.url});
	}
}

chrome.runtime.onMessage.addListener(navigate);

chrome.browserAction.onClicked.addListener(function(tab) {
	alert(myTabId);

	// In case our extension failed to track the event that our tab is closed,
	// this will check if our recommendation page exists.
	if (myTabId != -1) {
		chrome.tabs.get(myTabId, function(t) {
			if (chrome.runtime.lastError) {
				// tab does not exist
				myTabId = -1;
				chrome.tabs.sendMessage(tab.id, {"activated": false});
			}

			chrome.storage.local.get("doc_id", function(obj) {
				if (obj == null) {
					return;
				}
				id = obj["doc_id"].substr(0,15);
				url = 'http://www3.nhk.or.jp/news/easy/' + id + '/' + id + '.html'

				if (url != t.url) {
					myTabId = -1;
					navigate({"url": url, "newTab":true});
				}

			});
		});
	}

    if (myTabId != -1) {
		// Unselect currently selected tab
		chrome.tabs.query({ active: true }, function(tabs) {
			if (tabs.length > 0) {
				chrome.tabs.update(tabs[0].id, {highlighted: false});
			}
		});
		// select the recommendation tab
		chrome.tabs.update(myTabId, {highlighted: true});
	} else {

		chrome.storage.local.get(["doc_id", "sequence_id"], function(obj) {
				myTabId = tab.id;
				if (obj == null) {
					navigate({"url": "http://www3.nhk.or.jp/news/easy/", "newTab":true});
				}

				var needsInit = !('sequence_id' in obj) || obj['sequence_id'] == 0 || obj['sequence_id'] >= LIMIT;

				id = obj["doc_id"].substr(0,15);
				url = 'http://www3.nhk.or.jp/news/easy/' + id + '/' + id + '.html'

				if (needsInit) {
					url = chrome.extension.getURL('welcome_page.htm');
				}

				if (url != tab.url) {
					navigate({"url": url, "newTab":true});
				}

			});
	}

});
<commit_msg>fix bug with myTabId<commit_after>var ACTIVATED = false;

var myTabId = -1;

var LIMIT = 39;

function navigate(request, sender, callback) {
	if (request.newTab) {
			chrome.tabs.create(
				{
					url:request.url,
					active:true
				},
				function(tab){
					myTabId = tab.id;
				}
			);
			chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
				myTabId = -1;
			});
	} else {
		if (myTabId == -1) {
			myTabId = null;
		}
		chrome.tabs.update(myTabId, {url: request.url}, function(t) {
			myTabId = t.id;
		});
	}
}

chrome.runtime.onMessage.addListener(navigate);

chrome.browserAction.onClicked.addListener(function(tab) {

	// In case our extension failed to track the event that our tab is closed,
	// this will check if our recommendation page exists.
	if (myTabId != -1) {
		chrome.tabs.get(myTabId, function(t) {
			if (chrome.runtime.lastError) {
				// tab does not exist
				myTabId = -1;
				chrome.tabs.sendMessage(tab.id, {"activated": false});
			}

			chrome.storage.local.get("doc_id", function(obj) {
				if (obj == null) {
					return;
				}
				id = obj["doc_id"].substr(0,15);
				url = 'http://www3.nhk.or.jp/news/easy/' + id + '/' + id + '.html'

				if (url != t.url) {
					myTabId = -1;
					navigate({"url": url, "newTab":true});
				}

			});
		});
	}

    if (myTabId != -1) {
		// Unselect currently selected tab
		chrome.tabs.query({ active: true }, function(tabs) {
			if (tabs.length > 0) {
				chrome.tabs.update(tabs[0].id, {highlighted: false});
			}
		});
		// select the recommendation tab
		chrome.tabs.update(myTabId, {highlighted: true});
	} else {

		chrome.storage.local.get(["doc_id", "sequence_id"], function(obj) {
				myTabId = tab.id;
				if (obj == null) {
					navigate({"url": "http://www3.nhk.or.jp/news/easy/", "newTab":true});
				}

				var needsInit = !('sequence_id' in obj) || obj['sequence_id'] == 0 || obj['sequence_id'] >= LIMIT;

				id = obj["doc_id"].substr(0,15);
				url = 'http://www3.nhk.or.jp/news/easy/' + id + '/' + id + '.html'

				if (needsInit) {
					url = chrome.extension.getURL('welcome_page.htm');
				}

				if (url != tab.url) {
					navigate({"url": url, "newTab":true});
				}

			});
	}

});
<|endoftext|>


<commit_before>'use strict';

function random_boolean(chance){
    chance = chance !== void 0
      ? chance
      : .5;

    return Math.random() <= chance;
}

function random_hex(hash){
    hash = hash !== void 0
      ? false
      : true;
    var color = random_rgb();

    var blue = '0' + color['blue'].toString(16);
    var green = '0' + color['green'].toString(16);
    var red = '0' + color['red'].toString(16);

    var hex = hash ? '#' : '';
    hex += red.slice(-2) + green.slice(-2) + blue.slice(-2);

    return hex;
}

function random_rgb(){
  return {
    'blue': random_integer(256),
    'green': random_integer(256),
    'red': random_integer(256),
  };
}

function random_integer(max, todo){
    todo = todo || 'floor';
    return Math[todo](Math.random() * max);
}

function random_string(length, characters){
    var string = '';
    for(var loopCounter = 0; loopCounter < length; loopCounter++){
        string += characters[random_integer(characters.length - 1)];
    }
    return string;
}
<commit_msg>fixed random_boolean() chance<commit_after>'use strict';

function random_boolean(chance){
    chance = chance !== void 0
      ? chance
      : .5;

    return Math.random() < chance;
}

function random_hex(hash){
    hash = hash !== void 0
      ? false
      : true;
    var color = random_rgb();

    var blue = '0' + color['blue'].toString(16);
    var green = '0' + color['green'].toString(16);
    var red = '0' + color['red'].toString(16);

    var hex = hash ? '#' : '';
    hex += red.slice(-2) + green.slice(-2) + blue.slice(-2);

    return hex;
}

function random_rgb(){
  return {
    'blue': random_integer(256),
    'green': random_integer(256),
    'red': random_integer(256),
  };
}

function random_integer(max, todo){
    todo = todo || 'floor';
    return Math[todo](Math.random() * max);
}

function random_string(length, characters){
    var string = '';
    for(var loopCounter = 0; loopCounter < length; loopCounter++){
        string += characters[random_integer(characters.length - 1)];
    }
    return string;
}
<|endoftext|>


<commit_before>chrome.app.runtime.onLaunched.addListener(function(launchData) {
  chrome.app.window.create(
    'index.html',
    {
      id: 'mainWindow',
      bounds: {width: 900, height: 600}
    }
  );
});

chrome.runtime.onInstalled.addListener(function(){
  chrome.contextMenus.create({
    title: 'Stay on Top',
    id: 'stayontop',
    contexts: ['all']
  });
});

chrome.contextMenus.onClicked.addListener(function(itemData){
  if (itemData.menuItemId == "stayontop"){
    chrome.app.window.get("mainWindow").setAlwaysOnTop(true);
  }
});<commit_msg>completed "stay on top" feature.<commit_after>chrome.app.runtime.onLaunched.addListener(function(launchData) {
  chrome.app.window.create(
    'index.html',
    {
      id: 'mainWindow',
      bounds: {width: 900, height: 600}
    }
  );
});

chrome.runtime.onInstalled.addListener(function(){
  chrome.contextMenus.create({
    title: 'Stay on Top',
    id: 'stayontop',
    contexts: ['all']
  });
});

chrome.contextMenus.onClicked.addListener(function(itemData){
  if (itemData.menuItemId == "stayontop"){
    if (chrome.app.window.get("mainWindow").isAlwaysOnTop() == false){
      chrome.app.window.get("mainWindow").setAlwaysOnTop(true);
    }else{
      chrome.app.window.get("mainWindow").setAlwaysOnTop(false);
    }
  }
});<|endoftext|>


<commit_before>chrome.browserAction.onClicked.addListener(function(tab) {

  chrome.tabs.executeScript({
    file: 'highlight.js'
  });

  chrome.tabs.executeScript({
    code: 'var iconOn;'
  });

  chrome.tabs.executeScript({
    code: 'if (iconOn == true) { revert(window); } else { highlighter(window); }'
  });

});

var toggle;

chrome.browserAction.onClicked.addListener(function (tab) {

  if (toggle == "on") {
      chrome.browserAction.setIcon ({
        path : "images/icon19darktick.png"
      });
      toggle = "off";
  }
  else {
      chrome.browserAction.setIcon({
      path : "images/icon19dark.png"
      });
      toggle = "on";
  }

});
<commit_msg>Toggle Image code was backwards :)<commit_after>chrome.browserAction.onClicked.addListener(function(tab) {

  chrome.tabs.executeScript({
    file: 'highlight.js'
  });

  chrome.tabs.executeScript({
    code: 'var iconOn;'
  });

  chrome.tabs.executeScript({
    code: 'if (iconOn == true) { revert(window); } else { highlighter(window); }'
  });

});

var toggle;

chrome.browserAction.onClicked.addListener(function (tab) {

  if (toggle == "on") {
      chrome.browserAction.setIcon ({
        path : "images/icon19dark.png"
      });
      toggle = "off";
  }
  else {
      chrome.browserAction.setIcon({
      path : "images/icon19darktick.png"
      });
      toggle = "on";
  }

});
<|endoftext|>


<commit_before>// var $ = require('jquery');
// window.$ = $

window.jQuery = $ = require('jquery');
require('bootstrap/dist/js/bootstrap');
require('./js/jquery.easing.min');
require('./js/avatarSection');
var SnackBar = require('node-snackbar/dist/snackbar');

// WOW cloned from 'amd' branch of wowjs
var WOW = require('./js/wow.min');

$(document).ready(function(){
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: ($($anchor.attr('href')).offset().top - 50)
        }, 1250, 'easeInOutExpo');
        event.preventDefault();
    });

    $('body').scrollspy({
        target: '.navbar-fixed-top',
        offset: 51
    });

    $('.navbar-collapse ul li a').click(function() {
        $('.navbar-toggle:visible').click();
    });

    $('#mainNav').affix({
        offset: {
            top: 100
        }
    });

    new WOW().init();

    $('.contact-form').on('submit', function(event){
        event.preventDefault();
        $.ajax({
            url: "/contact_email",
            type: "POST",
            data: {
                contact_name: $('.contact-name').val(),
                contact_email: $('.contact-email').val(),
                contact_message: $('.contact-message').val()
            }
        }).done(function (data, textStatus, jqXHR){
            console.log("success! : " + textStatus + ' ' + data.message);

            // WRITE SUCCESSFUL EMAIL LOGIC
            document.getElementById("contact-form").reset();

            SnackBar.show({
                text: data.message,
                textColor: "#f05f40",
                pos: "bottom-right",
                actionText: "Thanks!",
                actionTextColor: "#f05f40",
                backgroundColor: "#333",
                duration: 1100
             });

            console.log("Success finished!");

        }).fail(function (jqXHR, textStatus, errorThrown) {
            console.log(`Failed! At : ${textStatus}, ${errorThrown}, ${jqXHR}`);

            SnackBar.show({
                text: `${textStatus.toUpperCase()}! ${errorThrown}! Please try again later!`,
                textColor: "#f05f40",
                pos: "bottom-right",
                actionText: "Thanks!",
                actionTextColor: "#f05f40",
                backgroundColor: "#333",
                duration: 1500
             });
        });
    });

    $('.social-hide-a').on('click', function(e){
        e.preventDefault();
        // $('.roro').css({'transform': 'rotate(180deg)'});
        $('ul.social-icons').toggle({
            duration: 800,
            easing: 'easeInOutExpo',
            complete: function(){
                if($('.roro').css('transform') == 'none'){
                    $('.roro').css({'transform': 'rotate(180deg)'});
                } else {
                    $('.roro').css({'transform': ''});
                }
            }
        })
    })

});

// {
//     animation: true,
//     container: '.contact-submit',
//     content: data.message,
//     delay: { "show": 800, "hide": 200 },
//     html: false,
//     placement: 'right',
//     title: 'Thank you!'
// }
<commit_msg>update WOWjs path in app-client<commit_after>// var $ = require('jquery');
// window.$ = $

window.jQuery = $ = require('jquery');
require('bootstrap/dist/js/bootstrap');
require('./js/jquery.easing.min');
require('./js/avatarSection');
var SnackBar = require('node-snackbar/dist/snackbar');

// WOW cloned from 'amd' branch of wowjs
var WOW = require('./node_modules/WOW/dist/wow.js');

$(document).ready(function(){
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: ($($anchor.attr('href')).offset().top - 50)
        }, 1250, 'easeInOutExpo');
        event.preventDefault();
    });

    $('body').scrollspy({
        target: '.navbar-fixed-top',
        offset: 51
    });

    $('.navbar-collapse ul li a').click(function() {
        $('.navbar-toggle:visible').click();
    });

    $('#mainNav').affix({
        offset: {
            top: 100
        }
    });

    new WOW().init();

    $('.contact-form').on('submit', function(event){
        event.preventDefault();
        $.ajax({
            url: "/contact_email",
            type: "POST",
            data: {
                contact_name: $('.contact-name').val(),
                contact_email: $('.contact-email').val(),
                contact_message: $('.contact-message').val()
            }
        }).done(function (data, textStatus, jqXHR){
            console.log("success! : " + textStatus + ' ' + data.message);

            // WRITE SUCCESSFUL EMAIL LOGIC
            document.getElementById("contact-form").reset();

            SnackBar.show({
                text: data.message,
                textColor: "#f05f40",
                pos: "bottom-right",
                actionText: "Thanks!",
                actionTextColor: "#f05f40",
                backgroundColor: "#333",
                duration: 1100
             });

            console.log("Success finished!");

        }).fail(function (jqXHR, textStatus, errorThrown) {
            console.log(`Failed! At : ${textStatus}, ${errorThrown}, ${jqXHR}`);

            SnackBar.show({
                text: `${textStatus.toUpperCase()}! ${errorThrown}! Please try again later!`,
                textColor: "#f05f40",
                pos: "bottom-right",
                actionText: "Thanks!",
                actionTextColor: "#f05f40",
                backgroundColor: "#333",
                duration: 1500
             });
        });
    });

    $('.social-hide-a').on('click', function(e){
        e.preventDefault();
        // $('.roro').css({'transform': 'rotate(180deg)'});
        $('ul.social-icons').toggle({
            duration: 800,
            easing: 'easeInOutExpo',
            complete: function(){
                if($('.roro').css('transform') == 'none'){
                    $('.roro').css({'transform': 'rotate(180deg)'});
                } else {
                    $('.roro').css({'transform': ''});
                }
            }
        })
    })

});

// {
//     animation: true,
//     container: '.contact-submit',
//     content: data.message,
//     delay: { "show": 800, "hide": 200 },
//     html: false,
//     placement: 'right',
//     title: 'Thank you!'
// }
<|endoftext|>


<commit_before>var DEPTH_LIMIT = 10;
var DEPTH = 0;
var IMAGES = false;

var Node = function(url, icon_url) {
    this.parent = null;
    this.depth = 0;
    this.max_depth = 0;
    this.url = url;
    this.icon_url = icon_url;
    this.image = null;
    this.children = [];
    this.insert = function(url, icon_url) {
        var node = new Node(url, icon_url);
        node.depth = this.depth + 1;
        node.parent = this;
        this.children.push(node);
        return node;
    };
};

var tabs = {};

chrome.runtime.onMessage.addListener(function(message, sender) {
    if (message.key == 'ctrl') exitNavigation(sender.tab.id);
});

chrome.commands.onCommand.addListener(function(command) {
    var fun;
    if (command == 'move-up') fun = up;
    else if (command == 'move-down') fun = down;
    else if (command == 'move-left') fun = left;
    else if (command == 'move-right') fun = right;
    chrome.tabs.query({active:true,windowType:"normal",currentWindow:true},function(d){
        navigate(d[0].id, fun);
    });
});

chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
    delete tabs[tabId];
});

chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) {
    navigateTo(removedTabId, tabs[addedTabId].url);

    tabs[addedTabId] = tabs[removedTabId];

    delete tabs[removedTabId];
    printTab(addedTabId);
});

chrome.webNavigation.onCommitted.addListener(function(details) {
    var type = details.transitionType;
    switch (type) {
        case 'link':
            break;
        case 'typed':
            break;
        case 'auto_bookmark':
            break;
        case 'auto_subframe':
            // do nothing
            return;
        case 'manual_subframe':
            break;
        case 'generated':
            break;
        case 'auto_toplevel':
            return;
        case 'form_submit':
            // do nothing? ????????????????????
            return;
        case 'reload':
            // do nothing
            return;
        case 'keyword':
            // do nothing? ????????????????????
            return;
        case 'keyword_generated':
            // do nothing? ????????????????????
            return;
    }
    if (tabs[details.tabId] && tabs[details.tabId].override) tabs[details.tabId].override = false;
    else {
        navigateTo(details.tabId, details.url);
    }
});

chrome.webNavigation.onCompleted.addListener(function(details) {
    if (tabs[details.tabId]) {
        if (tabs[details.tabId].current.url == details.url) {
            chrome.tabs.get(details.tabId, function(tab) {
                if (chrome.runtime.lastError) {
                    console.log(chrome.runtime.lastError.message);
                } else {
                    tabs[details.tabId].current.icon_url = tab.favIconUrl;
                    tabs[details.tabId].current.title = tab.title;
                    console.log(tab.title);
                }
            });
            //takeScreenshot(tabs[details.tabId].current);
        }
    }
});

function navigateTo(tabId, url, icon_url) {
    if (tabs[tabId]) {
        // tabId in tabs
        tabs[tabId].current = tabs[tabId].current.insert(url, icon_url);
        tabs[tabId].max_depth = Math.max(tabs[tabId].max_depth, tabs[tabId].current.depth);
    }
    else {
        // tabId not in tabs
        var node = new Node(url, icon_url);
        node.current = node;
        tabs[tabId] = node;
    }
    printTab(tabId);
}

function takeScreenshot(node) {
    chrome.tabs.captureVisibleTab(null, {format: 'png'}, function (dataUrl) {
        if (dataUrl) {
            node.image = dataUrl;
            console.log(dataUrl);
            //saveImage(dataUrl);
        }
    });
}

function up(tab) {
    if (tabs[tab] && tabs[tab].current.parent)
        tabs[tab].current = tabs[tab].current.parent;
    printTab(tab);
    return 'up';
}

function down(tab) {
    if (tabs[tab] && tabs[tab].current.children.length > 0)
        tabs[tab].current = tabs[tab].current.children[tabs[tab].current.children.length - 1];
    printTab(tab);
    return 'down';
}

function left(tab) {
    if (tabs[tab] && tabs[tab].current.parent && tabs[tab].current.parent.children.length > 1) {
        var index = tabs[tab].current.parent.children.indexOf(tabs[tab].current);
        if (index > 0)
            tabs[tab].current = tabs[tab].current.parent.children[index - 1];
    }
    printTab(tab);
    return 'left';
}

function right(tab) {
    if (tabs[tab] && tabs[tab].current.parent && tabs[tab].current.parent.children.length > 1) {
        var index = tabs[tab].current.parent.children.indexOf(tabs[tab].current);
        if (index > -1 && index < tabs[tab].current.parent.children.length - 1)
            tabs[tab].current = tabs[tab].current.parent.children[index + 1];
    }
    printTab(tab);
    return 'right';
}

function navigate(tabId, move) {
    move = move(tabId);
    var tree = getTree(tabs[tabId], tabs[tabId].current);
    var depth_of_current = tabs[tabId].current.depth;
    var max_depth = tabs[tabId].max_depth;
    chrome.tabs.sendMessage(tabId, {move: move, tree: tree, depth_of_current: depth_of_current, max_depth: max_depth}, function() {});
}

function getTree(node, current) {
    var tree = {
        name: node.title.substr(0, 30) + '... ',
        url: node.url.substr(0, 30) + '... ',
        icon: node.icon_url ? node.icon_url : "https://www.bookmanbookstore.com/wp-content/uploads/2012/07/placeholder_2.jpg",
        current: node == current,
        children: []
    };
    for (var i = 0; i < node.children.length; i++) tree.children.push(getTree(node.children[i], current));
    return tree;
}

function exitNavigation(tabId) {
    chrome.tabs.get(tabId, function(tab) {
        if (tab.url != tabs[tab.id].current.url) {
            tabs[tab.id].override = true;
            chrome.tabs.update(tab.id, {url: tabs[tab.id].current.url});
        }
    });
}

function printTab(tab) {
    formatTab(tabs[tab], 2, tabs[tab].current);
    console.log('');
}

function formatTab(tab, indent, current) {
    var base, fill;
    if (tab == current) {
        base = '1';
        fill = Array(indent - 1).join(' ');
    }
    else {
        base = '';
        fill = Array(indent).join(' ');
    }
    console.log(base + fill + tab.url);
    for (var i = 0; i < tab.children.length; i++) {
        formatTab(tab.children[i], indent + 4, current);
    }
}

function saveImage(dataUrl) {
    var BASE64_MARKER = ';base64,';
    var base64Index = dataUrl.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
    var base64 = dataUrl.substring(base64Index);
    var raw = window.atob(base64);
    var rawLength = raw.length;
    var array = new Uint8Array(new ArrayBuffer(rawLength));

    for (i = 0; i < rawLength; ++i) {
        array[i] = raw.charCodeAt(i);
    }
    blob = new Blob([array]);

    var reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onload = function (event) {
        var save = document.createElement('a');
        save.href = event.target.result;
        save.target = '_blank';
        save.download = 'pic.png' || 'unknown';

        var e = document.createEvent('Event');
        e.initEvent('click', true, true);
        save.dispatchEvent(e);
        (window.URL || window.webkitURL).revokeObjectURL(save.href);
    };

    fileWriter.write(blob);
}
<commit_msg>screenshot support!<commit_after>var DEPTH_LIMIT = 10;
var DEPTH = 0;
var IMAGES = false;

var Node = function(url, icon_url) {
    this.parent = null;
    this.depth = 0;
    this.max_depth = 0;
    this.url = url;
    this.icon_url = icon_url;
    this.image = null;
    this.children = [];
    this.insert = function(url, icon_url) {
        var node = new Node(url, icon_url);
        node.depth = this.depth + 1;
        node.parent = this;
        this.children.push(node);
        return node;
    };
};

var tabs = {};

chrome.runtime.onMessage.addListener(function(message, sender) {
    if (message.key == 'ctrl') exitNavigation(sender.tab.id);
});

chrome.commands.onCommand.addListener(function(command) {
    var fun;
    if (command == 'move-up') fun = up;
    else if (command == 'move-down') fun = down;
    else if (command == 'move-left') fun = left;
    else if (command == 'move-right') fun = right;
    chrome.tabs.query({active:true,windowType:"normal",currentWindow:true},function(d){
        navigate(d[0].id, fun);
    });
});

chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
    delete tabs[tabId];
});

chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) {
    navigateTo(removedTabId, tabs[addedTabId].url);

    tabs[addedTabId] = tabs[removedTabId];

    delete tabs[removedTabId];
    printTab(addedTabId);
});

chrome.webNavigation.onCommitted.addListener(function(details) {
    var type = details.transitionType;
    switch (type) {
        case 'link':
            break;
        case 'typed':
            break;
        case 'auto_bookmark':
            break;
        case 'auto_subframe':
            // do nothing
            return;
        case 'manual_subframe':
            break;
        case 'generated':
            break;
        case 'auto_toplevel':
            return;
        case 'form_submit':
            // do nothing? ????????????????????
            return;
        case 'reload':
            // do nothing
            return;
        case 'keyword':
            // do nothing? ????????????????????
            return;
        case 'keyword_generated':
            // do nothing? ????????????????????
            return;
    }
    if (tabs[details.tabId] && tabs[details.tabId].override) tabs[details.tabId].override = false;
    else {
        navigateTo(details.tabId, details.url);
    }
});

chrome.webNavigation.onCompleted.addListener(function(details) {
    if (tabs[details.tabId]) {
        if (tabs[details.tabId].current.url == details.url) {
            chrome.tabs.get(details.tabId, function(tab) {
                if (chrome.runtime.lastError) {
                    console.log(chrome.runtime.lastError.message);
                } else {
                    tabs[details.tabId].current.icon_url = tab.favIconUrl;
                    tabs[details.tabId].current.title = tab.title;
                    takeScreenshot(tabs[details.tabId].current);
                    console.log(tab.title);
                }
            });
        }
    }
});

function navigateTo(tabId, url, icon_url) {
    if (tabs[tabId]) {
        // tabId in tabs
        tabs[tabId].current = tabs[tabId].current.insert(url, icon_url);
        tabs[tabId].max_depth = Math.max(tabs[tabId].max_depth, tabs[tabId].current.depth);
    }
    else {
        // tabId not in tabs
        var node = new Node(url, icon_url);
        node.current = node;
        tabs[tabId] = node;
    }
    printTab(tabId);
}

function takeScreenshot(node) {
    chrome.tabs.captureVisibleTab(null, {format: 'png'}, function (dataUrl) {
        if (dataUrl) {
            node.image = dataUrl;
            console.log(dataUrl);
            //saveImage(dataUrl);
        }
    });
}

function up(tab) {
    if (tabs[tab] && tabs[tab].current.parent)
        tabs[tab].current = tabs[tab].current.parent;
    printTab(tab);
    return 'up';
}

function down(tab) {
    if (tabs[tab] && tabs[tab].current.children.length > 0)
        tabs[tab].current = tabs[tab].current.children[tabs[tab].current.children.length - 1];
    printTab(tab);
    return 'down';
}

function left(tab) {
    if (tabs[tab] && tabs[tab].current.parent && tabs[tab].current.parent.children.length > 1) {
        var index = tabs[tab].current.parent.children.indexOf(tabs[tab].current);
        if (index > 0)
            tabs[tab].current = tabs[tab].current.parent.children[index - 1];
    }
    printTab(tab);
    return 'left';
}

function right(tab) {
    if (tabs[tab] && tabs[tab].current.parent && tabs[tab].current.parent.children.length > 1) {
        var index = tabs[tab].current.parent.children.indexOf(tabs[tab].current);
        if (index > -1 && index < tabs[tab].current.parent.children.length - 1)
            tabs[tab].current = tabs[tab].current.parent.children[index + 1];
    }
    printTab(tab);
    return 'right';
}

function navigate(tabId, move) {
    move = move(tabId);
    var tree = getTree(tabs[tabId], tabs[tabId].current);
    var depth_of_current = tabs[tabId].current.depth;
    var max_depth = tabs[tabId].max_depth;
    chrome.tabs.sendMessage(tabId, {move: move, tree: tree, depth_of_current: depth_of_current, max_depth: max_depth}, function() {});
}

function getTree(node, current) {
    var tree = {
        name: node.title.substr(0, 30) + '... ',
        url: node.url.substr(0, 30) + '... ',
        icon: node.icon_url ? node.icon_url : "https://www.bookmanbookstore.com/wp-content/uploads/2012/07/placeholder_2.jpg",
        current: node == current,
        children: []
    };
    if (node.image) tree.icon = node.image;
    for (var i = 0; i < node.children.length; i++) tree.children.push(getTree(node.children[i], current));
    return tree;
}

function exitNavigation(tabId) {
    chrome.tabs.get(tabId, function(tab) {
        if (tab.url != tabs[tab.id].current.url) {
            tabs[tab.id].override = true;
            chrome.tabs.update(tab.id, {url: tabs[tab.id].current.url});
        }
    });
}

function printTab(tab) {
    formatTab(tabs[tab], 2, tabs[tab].current);
    console.log('');
}

function formatTab(tab, indent, current) {
    var base, fill;
    if (tab == current) {
        base = '1';
        fill = Array(indent - 1).join(' ');
    }
    else {
        base = '';
        fill = Array(indent).join(' ');
    }
    console.log(base + fill + tab.url);
    for (var i = 0; i < tab.children.length; i++) {
        formatTab(tab.children[i], indent + 4, current);
    }
}

function saveImage(dataUrl) {
    var BASE64_MARKER = ';base64,';
    var base64Index = dataUrl.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
    var base64 = dataUrl.substring(base64Index);
    var raw = window.atob(base64);
    var rawLength = raw.length;
    var array = new Uint8Array(new ArrayBuffer(rawLength));

    for (i = 0; i < rawLength; ++i) {
        array[i] = raw.charCodeAt(i);
    }
    blob = new Blob([array]);

    var reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onload = function (event) {
        var save = document.createElement('a');
        save.href = event.target.result;
        save.target = '_blank';
        save.download = 'pic.png' || 'unknown';

        var e = document.createEvent('Event');
        e.initEvent('click', true, true);
        save.dispatchEvent(e);
        (window.URL || window.webkitURL).revokeObjectURL(save.href);
    };

    fileWriter.write(blob);
}
<|endoftext|>


<commit_before>/*
Copyright 2020 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// app.yaml reference: https://cloud.google.com/appengine/docs/standard/nodejs/config/appref
// service.yaml reference: https://github.com/knative/docs/blob/master/docs/serving/spec/knative-api-specification-1.0.md

/**
 * @param {Object} gaeService - Information about the App Engine service, should at minimum contain {"app.yaml" : {}}
 */
function appToRun(gaeService) {
  let runService = {
    'service.yaml': {
      'apiVersion': 'serving.knative.dev/v1',
      'kind': 'Service',
      'metadata': {
        'name' : 'default'
      },
      'spec': {
        'template': {
          'metadata': {
            'annotations': {}
          },
          'spec': {
            'containers': [
              {
                'image': 'gcr.io/YOUR-PROJECT/image'
              }
            ]
          }
        }
      }
    }
  };

  const extractFunctions = [
    extractName,
    extractImageURL,
    extractEnvVars,
    extractProjectIDEnvVar,
    extractMaxInstances,
    extractConcurrency,
    extractMemory,
    extractMigrateToSecondGen,
    extractDockerfile,
    extractVPCAccess,
    extractCloudSQL,
  ]

  for (const extractFunction of extractFunctions) {
    extractFunction(gaeService, runService);
  }

  return runService;
}

const runtimeToDockerfile = {
'nodejs':
`FROM node:slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
CMD [ "npm", "start" ]`,

'nodejs8':
`FROM node:8-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
CMD [ "npm", "start" ]`,

'nodejs10':
`FROM node:10-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
CMD [ "npm", "start" ]`,

'nodejs12':
`FROM node:12-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
CMD [ "npm", "start" ]`,
}

  const firstGenRuntimes = ['python27', 'php55', 'go111'];

const firstGenMigrationGuides = {
'go111': 'https://cloud.google.com/appengine/docs/standard/go/go-differences',
'python27': 'https://cloud.google.com/appengine/docs/standard/python/',
'php55': 'https://cloud.google.com/appengine/docs/standard/php7/php-differences',
// (Java does not use an app.yaml): 'https://cloud.google.com/appengine/docs/standard/java11/java-differences',
}

function extractName(gae, run) {
  if(gae['app.yaml']['service']) {
    run['service.yaml']['metadata']['name'] = gae['app.yaml']['service'];
   }
}

function extractEnvVars(gae, run) {
  if(gae['app.yaml']['env_variables']) {
    const container = run['service.yaml']['spec']['template']['spec']['containers'][0];
    container['env'] = container['env'] || [];
    for (const key of Object.keys(gae['app.yaml']['env_variables'])) {
      container['env'].push({
        'name': key,
        'value': gae['app.yaml']['env_variables'][key]
      })
    }
   }
}

function extractProjectIDEnvVar(gae, run) {
  if(gae['project-id']) {
    const container = run['service.yaml']['spec']['template']['spec']['containers'][0];
    container['env'] = container['env'] || [];
    container['env'].push({
      'name': 'GOOGLE_CLOUD_PROJECT',
      'value': gae['project-id']
    })
   }
}

function extractMaxInstances(gae, run) {
  if(gae['app.yaml']['automatic_scaling'] && gae['app.yaml']['automatic_scaling']['max_instances']) {
    run['service.yaml']['spec']['template']['metadata']['annotations']['autoscaling.knative.dev/maxScale'] = gae['app.yaml']['automatic_scaling']['max_instances'].toString();
   }
}

function extractConcurrency(gae, run) {
  if(gae['app.yaml']['automatic_scaling'] && gae['app.yaml']['automatic_scaling']['max_concurrent_requests']) {
    run['service.yaml']['spec']['template']['spec']['containerConcurrency'] = gae['app.yaml']['automatic_scaling']['max_concurrent_requests'];
   }
}

function extractMemory(gae, run) {
  // see https://cloud.google.com/appengine/docs/standard/#instance_classes

  const instanceClassMemory = {
    'F1': '256Mi',
    'F2': '512Mi',
    'F4': '1Gi',
    'F4_HIGHMEM': '2Gi',
  }

  if(gae['app.yaml']['instance_class']) {
    const container = run['service.yaml']['spec']['template']['spec']['containers'][0];

    container['resources'] = container['resources'] || {'limits': {}};

    container['resources']['limits']['memory'] = instanceClassMemory[gae['app.yaml']['instance_class']];
   }
}

function extractMigrateToSecondGen(gae, run) {
  const runtime = gae['app.yaml']['runtime'];
  // "api_version" was deprecated for secnd gen runtimes
  if(gae['app.yaml']['api_version'] || firstGenRuntimes.includes(runtime)) {
    run['migrate-to-second-gen'] = true;
    run['migration-guide'] = firstGenMigrationGuides[runtime];
  }
}

function extractDockerfile(gae, run) {
  run['Dockerfile'] = runtimeToDockerfile[gae['app.yaml']['runtime']]
}

function extractVPCAccess(gae, run){
  if(gae['app.yaml']['vpc_access_connector']) {
    // TODO
  }
}

function extractCloudSQL(gae, run) {
  if(gae['cloudsql-instance']) {
    run['service.yaml']['spec']['template']['metadata']['annotations']['run.googleapis.com/cloudsql-instances'] = [gae['project-id'], gae['region'], gae['cloudsql-instance']].join(':');
  }
}

function extractImageURL(gae, run) {
  let imageName = gae['app.yaml']['service'] || 'image';
  let projectName = gae['project-id'] || '<YOUR-PROJECT>';

  run['service.yaml']['spec']['template']['spec']['containers'][0]['image'] = `gcr.io/${projectName}/${imageName}`;
}

export {appToRun}<commit_msg>Min instances + VPC access<commit_after>/*
Copyright 2020 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// app.yaml reference: https://cloud.google.com/appengine/docs/standard/nodejs/config/appref
// service.yaml reference: https://github.com/knative/docs/blob/master/docs/serving/spec/knative-api-specification-1.0.md

/**
 * @param {Object} gaeService - Information about the App Engine service, should at minimum contain {"app.yaml" : {}}
 */
function appToRun(gaeService) {
  let runService = {
    'service.yaml': {
      'apiVersion': 'serving.knative.dev/v1',
      'kind': 'Service',
      'metadata': {
        'name' : 'default'
      },
      'spec': {
        'template': {
          'metadata': {
            'annotations': {}
          },
          'spec': {
            'containers': [
              {
                'image': 'gcr.io/YOUR-PROJECT/image'
              }
            ]
          }
        }
      }
    }
  };

  const extractFunctions = [
    extractName,
    extractImageURL,
    extractEnvVars,
    extractProjectIDEnvVar,
    extractMaxInstances,
    extractMinInstances,
    extractConcurrency,
    extractMemory,
    extractMigrateToSecondGen,
    extractDockerfile,
    extractVPCAccess,
    extractCloudSQL,
  ]

  for (const extractFunction of extractFunctions) {
    extractFunction(gaeService, runService);
  }

  return runService;
}

const runtimeToDockerfile = {
'nodejs':
`FROM node:slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
CMD [ "npm", "start" ]`,

'nodejs8':
`FROM node:8-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
CMD [ "npm", "start" ]`,

'nodejs10':
`FROM node:10-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
CMD [ "npm", "start" ]`,

'nodejs12':
`FROM node:12-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
CMD [ "npm", "start" ]`,
}

const firstGenRuntimes = ['python27', 'php55', 'go111'];

const firstGenMigrationGuides = {
'go111': 'https://cloud.google.com/appengine/docs/standard/go/go-differences',
'python27': 'https://cloud.google.com/appengine/docs/standard/python/',
'php55': 'https://cloud.google.com/appengine/docs/standard/php7/php-differences',
// (Java does not use an app.yaml): 'https://cloud.google.com/appengine/docs/standard/java11/java-differences',
}

function extractName(gae, run) {
  if(gae['app.yaml']['service']) {
    run['service.yaml']['metadata']['name'] = gae['app.yaml']['service'];
   }
}

function extractEnvVars(gae, run) {
  if(gae['app.yaml']['env_variables']) {
    const container = run['service.yaml']['spec']['template']['spec']['containers'][0];
    container['env'] = container['env'] || [];
    for (const key of Object.keys(gae['app.yaml']['env_variables'])) {
      container['env'].push({
        'name': key,
        'value': gae['app.yaml']['env_variables'][key]
      })
    }
   }
}

function extractProjectIDEnvVar(gae, run) {
  if(gae['project-id']) {
    const container = run['service.yaml']['spec']['template']['spec']['containers'][0];
    container['env'] = container['env'] || [];
    container['env'].push({
      'name': 'GOOGLE_CLOUD_PROJECT',
      'value': gae['project-id']
    })
   }
}

function extractMaxInstances(gae, run) {
  if(gae['app.yaml']['automatic_scaling']?.['max_instances']) {
    run['service.yaml']['spec']['template']['metadata']['annotations']['autoscaling.knative.dev/maxScale'] = gae['app.yaml']['automatic_scaling']['max_instances'].toString();
   }
}

function extractMinInstances(gae, run) {
  if(gae['app.yaml']['automatic_scaling']?.['min_instances']) {
    run['service.yaml']['spec']['template']['metadata']['annotations']['autoscaling.knative.dev/minScale'] = gae['app.yaml']['automatic_scaling']['inx_instances'].toString();
   }
}

function extractConcurrency(gae, run) {
  if(gae['app.yaml']['automatic_scaling']?.['max_concurrent_requests']) {
    run['service.yaml']['spec']['template']['spec']['containerConcurrency'] = gae['app.yaml']['automatic_scaling']['max_concurrent_requests'];
   }
}

function extractMemory(gae, run) {
  // see https://cloud.google.com/appengine/docs/standard/#instance_classes

  const instanceClassMemory = {
    'F1': '256Mi',
    'F2': '512Mi',
    'F4': '1Gi',
    'F4_HIGHMEM': '2Gi',
  }

  if(gae['app.yaml']['instance_class']) {
    const container = run['service.yaml']['spec']['template']['spec']['containers'][0];

    container['resources'] = container['resources'] || {'limits': {}};

    container['resources']['limits']['memory'] = instanceClassMemory[gae['app.yaml']['instance_class']];
   }
}

function extractMigrateToSecondGen(gae, run) {
  const runtime = gae['app.yaml']['runtime'];
  // "api_version" was deprecated for secnd gen runtimes
  if(gae['app.yaml']['api_version'] || firstGenRuntimes.includes(runtime)) {
    run['migrate-to-second-gen'] = true;
    run['migration-guide'] = firstGenMigrationGuides[runtime];
  }
}

function extractDockerfile(gae, run) {
  run['Dockerfile'] = runtimeToDockerfile[gae['app.yaml']['runtime']]
}

function extractVPCAccess(gae, run){
  if(gae['app.yaml']['vpc_access_connector']?.['name']) {
    run['service.yaml']['spec']['template']['metadata']['annotations']['run.googleapis.com/vpc-access-connector'] = gae['app.yaml']['vpc_access_connector']['name'];
  }
}

function extractCloudSQL(gae, run) {
  if(gae['cloudsql-instance']) {
    run['service.yaml']['spec']['template']['metadata']['annotations']['run.googleapis.com/cloudsql-instances'] = [gae['project-id'], gae['region'], gae['cloudsql-instance']].join(':');
  }
}

function extractImageURL(gae, run) {
  let imageName = gae['app.yaml']['service'] || 'image';
  let projectName = gae['project-id'] || '<YOUR-PROJECT>';

  run['service.yaml']['spec']['template']['spec']['containers'][0]['image'] = `gcr.io/${projectName}/${imageName}`;
}

export {appToRun}
<|endoftext|>


<commit_before>// interface for interacting with Firepad

FirepadAPI = {

  // getting whether the host is in production or development

  setup: function(dev) {
    var prodFB = "https://project-3627267568762325747.firebaseio.com/"
    var devFB = "https://gitsync-test.firebaseio.com/"
    this.host = (dev ? devFB : prodFB);
  },

  /////////////////////
  // CLIENT METHODS - for file manipulation
  /////////////////////

  getText: function(id) {
  },

  getFirepad: function(id) { // give live editor copy, v and snapshot
    if (!id) return null;
    var content = "";
    var headless = Firepad.Headless(Session.get("firepadRef"));

    headless.onReady(function(){
      headless.getText(function(txt){ content = txt; });
      headless.dispose();
    });

    console.log(content)
    return content;
  },

  getAllFirepad: function() { // update file.content from firepad
    //Files.find({
    //repo:  Meteor.user().profile.repo,
    //branch: Meteor.user().profile.repoBranch,
    //}).fetch().filter(function typeCheck(file) { // remove imgs
    //return file.type === "file";
    //}).map(function readSJS(file) {
    //var sjs = Meteor.call("getFirepad", file);
    //Files.update(
    //file._id,
    //{$set: {
    //content: sjs.snapshot
    //}});
    //});
  },

  postFirepad: function(file) { // update files with their ids
    //var sjs = Meteor.call("getFirepad", file); // get doc and version
    //if (!sjs) return null; // if file id broke, don"t propagate error
    //Firepad.model.applyOp( file._id, {
    //op: [
    //{ p:0, d: sjs.snapshot }, // delete old content
    //{ p:0, i: file.content } // insert new blob content
    //],
    //meta: null,
    //v: sjs.v // apply it to last seen version
    //});
  },

  postAllFirepad: function(file) { // update all project sjs files
    //ufiles().map(function setSJS(file) {
    //Meteor.call("postFirepad", file);
    //});
  },

};

<commit_msg>client gettext working<commit_after>// interface for interacting with Firepad

FirepadAPI = {

  // getting whether the host is in production or development

  setup: function(dev) {
    var prodFB = "https://project-3627267568762325747.firebaseio.com/"
    var devFB = "https://gitsync-test.firebaseio.com/"
    this.host = (dev ? devFB : prodFB);
  },

  /////////////////////
  // CLIENT METHODS - for file manipulation
  /////////////////////

  getText: function(id, cb) {
    var headless = Firepad.Headless(Session.get("fb") + id);
    headless.getText(function(txt) {
      headless.dispose();
      cb(txt);
    });
  },

  getAllText: function(cb) { // update file.content from firepad
    Files.find({
      repo:  Meteor.user().profile.repo,
      branch: Meteor.user().profile.repoBranch,
    })

    .fetch().filter(function typeCheck(file) { // remove imgs
      return file.type === "file";
    }).map(function(file) { // using document ids
      return file._id

    }).map(function(id) {

      this.getText(id, function(txt){
        console.log(id, txt);
        Files.update( id, {$set: { content: txt }});
      });
    });
  },

  setText: function(file) { // update files with their ids
    //var sjs = Meteor.call("getFirepad", file); // get doc and version
    //if (!sjs) return null; // if file id broke, don"t propagate error
    //Firepad.model.applyOp( file._id, {
    //op: [
    //{ p:0, d: sjs.snapshot }, // delete old content
    //{ p:0, i: file.content } // insert new blob content
    //],
    //meta: null,
    //v: sjs.v // apply it to last seen version
    //});
  },

  setAllText: function() { // update all project sjs files
    ufiles().map(function(file) {
      this.setText(file)
    });
  },

};

<|endoftext|>