<commit_before>// Copyright 2015 Endless Mobile, Inc.

/* exported ThematicModule */

const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;

const Actions = imports.app.actions;
const CardContainer = imports.app.interfaces.cardContainer;
const Dispatcher = imports.app.dispatcher;
const Engine = imports.search.engine;
const Module = imports.app.interfaces.module;
const QueryObject = imports.search.queryObject;
const Scrollable = imports.app.interfaces.scrollable;
const ThemeableImage = imports.app.widgets.themeableImage;

/**
 * Class: ThematicModule
 * Module for showing themes from one main category
 *
 * This module is designed for apps that have both featured and non-featured
 * sets, where the non-featured sets act as "themes" which unite articles across
 * the featured sets.
 *
 * This module shows a few arrangements consecutively.
 * We recommend placing it in a <ScrollingArrangement> or another module that
 * can allow it to scroll.
 *
 * In contrast to the <HighlightsModule> this module shows articles from one
 * set, subdivided into several arrangements.
 * Each arrangement shows either one theme from the selected featured set,
 * or one featured set that has cards from the selected theme.
 *
 * Clicking on a card in the arrangement takes you directly to that article.
 * Above each arrangement is a card ("header") showing the title of the set
 * which can also be clicked to show more information about that set.
 *
 * Slots:
 *   arrangement - arrangement to display cards in
 *   card-type - type of cards to create for articles
 *   header-card-type - type of cards to create for sets
 */
const ThematicModule = new Lang.Class({
    Name: 'ThematicModule',
    GTypeName: 'EknThematicModule',
    Extends: Gtk.Grid,
    Implements: [ Module.Module, Scrollable.Scrollable,
        CardContainer.CardContainer ],

    Properties: {
        'factory': GObject.ParamSpec.override('factory', Module.Module),
        'factory-name': GObject.ParamSpec.override('factory-name', Module.Module),
        'scroll-server': GObject.ParamSpec.override('scroll-server', Scrollable.Scrollable),
        'fade-cards': GObject.ParamSpec.override('fade-cards',
            CardContainer.CardContainer),
    },

    _init: function (props={}) {
        props.orientation = Gtk.Orientation.VERTICAL;
        this.parent(props);
        this._arrangements = [];
        this._featured_arrangements = [];
        this._non_featured_arrangements = [];
        this._sets = [];

        this.scrollable_init();

        Dispatcher.get_default().register((payload) => {
            switch (payload.action_type) {
                case Actions.SHOW_SET:
                    this._show_set(payload.model);
                    break;
                case Actions.CLEAR_SETS:
                    this._clear_all();
                    break;
                case Actions.CLEAR_ITEMS:
                    this._clear_items();
                    break;
                case Actions.APPEND_SETS:
                    payload.models.forEach(this._add_set, this);
                    break;
            }
        });
    },

    // Module override
    get_slot_names: function () {
        return ['arrangement', 'card-type', 'header-card-type'];
    },

    show_more_content: function () {
        if (this._current_index >= this._current_arrangements.length)
            return;
        let arrangement = this._current_arrangements[this._current_index];
        let query = new QueryObject.QueryObject({
            limit: -1,
            tags: this._current_model.child_tags.concat(arrangement.accepted_child_tags),
            tag_match: QueryObject.QueryObjectTagMatch.ALL,
        });
        Engine.get_default().get_objects_by_query(query, null, (engine, task) => {
            let results;
            try {
                [results] = engine.get_objects_by_query_finish(task);
            } catch (e) {
                logError(e, 'Failed to load objects from set');
                return;
            }

            this._current_index += 1;
            // If we got no results for this arrangement, move onto the next one
            if (results.length === 0) {
                this.show_more_content();
            } else {
                results.forEach((model) => this._add_article_card(model, arrangement));
                arrangement.visible = true;
                Dispatcher.get_default().dispatch({
                    action_type: Actions.CONTENT_ADDED,
                    scroll_server: this.scroll_server,
                });
            }
        });
    },

    _show_set: function (model) {
        this._clear_items();

        this._current_arrangements = model.featured ?
            this._non_featured_arrangements : this._featured_arrangements;
        this._current_index = 0;
        this._current_model = model;
        this.show_more_content();

        Dispatcher.get_default().dispatch({
            action_type: Actions.SET_READY,
            model: model,
        });
    },

    _create_set_card: function (model) {
        let card = this.create_submodule('header-card-type', {
            model: model,
            visible: true,
            halign: Gtk.Align.START,
        });
        card.connect('clicked', () => {
            Dispatcher.get_default().dispatch({
                action_type: Actions.SET_CLICKED,
                model: model,
                context: this._sets,
            });
        });
        return card;
    },

    _add_article_card: function (model, arrangement) {
        let card = this.create_submodule('card-type', {
            model: model,
        });
        card.connect('clicked', () => {
            Dispatcher.get_default().dispatch({
                action_type: Actions.ITEM_CLICKED,
                model: model,
                context: arrangement.get_cards().map((card) => card.model),
                context_label: arrangement.set_title,
            });
        });
        arrangement.add_card(card);
    },

    _add_set: function (model) {
        this._sets.push(model);
        let header = this._create_set_card(model);

        let separator = new ThemeableImage.ThemeableImage({
            visible: true,
            halign: Gtk.Align.FILL,
            valign: Gtk.Align.CENTER,
        });
        separator.get_style_context().add_class(Gtk.STYLE_CLASS_SEPARATOR);

        let arrangement = this.create_submodule('arrangement', {
            vexpand: true,
            visible: false,
            no_show_all: true,
        });
        arrangement.accepted_child_tags = model.child_tags.slice();
        arrangement.set_title = model.title;
        this._arrangements.push(arrangement);

        if (model.featured) {
            this._featured_arrangements.push(arrangement);
        } else {
            this._non_featured_arrangements.push(arrangement);
        }

        let set_grid = new Gtk.Grid({
            orientation: Gtk.Orientation.VERTICAL,
            no_show_all: true,
        });
        set_grid.add(header);
        set_grid.add(separator);
        set_grid.add(arrangement);

        this.add(set_grid);

        arrangement.bind_property('visible', set_grid, 'visible',
            GObject.BindingFlags.SYNC_CREATE);
    },

    _clear_all: function () {
        this.get_children().forEach(this.remove, this);
        this._arrangements = [];
        this._featured_arrangements = [];
        this._non_featured_arrangements = [];
        this._sets = [];
    },

    _clear_items: function () {
        // Only arrangements that have cards in them should be shown
        this._arrangements.forEach(arrangement => {
            arrangement.clear();
            arrangement.hide();
        });
    },
});
<commit_msg>Increment current_index immediately after using it<commit_after>// Copyright 2015 Endless Mobile, Inc.

/* exported ThematicModule */

const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;

const Actions = imports.app.actions;
const CardContainer = imports.app.interfaces.cardContainer;
const Dispatcher = imports.app.dispatcher;
const Engine = imports.search.engine;
const Module = imports.app.interfaces.module;
const QueryObject = imports.search.queryObject;
const Scrollable = imports.app.interfaces.scrollable;
const ThemeableImage = imports.app.widgets.themeableImage;

/**
 * Class: ThematicModule
 * Module for showing themes from one main category
 *
 * This module is designed for apps that have both featured and non-featured
 * sets, where the non-featured sets act as "themes" which unite articles across
 * the featured sets.
 *
 * This module shows a few arrangements consecutively.
 * We recommend placing it in a <ScrollingArrangement> or another module that
 * can allow it to scroll.
 *
 * In contrast to the <HighlightsModule> this module shows articles from one
 * set, subdivided into several arrangements.
 * Each arrangement shows either one theme from the selected featured set,
 * or one featured set that has cards from the selected theme.
 *
 * Clicking on a card in the arrangement takes you directly to that article.
 * Above each arrangement is a card ("header") showing the title of the set
 * which can also be clicked to show more information about that set.
 *
 * Slots:
 *   arrangement - arrangement to display cards in
 *   card-type - type of cards to create for articles
 *   header-card-type - type of cards to create for sets
 */
const ThematicModule = new Lang.Class({
    Name: 'ThematicModule',
    GTypeName: 'EknThematicModule',
    Extends: Gtk.Grid,
    Implements: [ Module.Module, Scrollable.Scrollable,
        CardContainer.CardContainer ],

    Properties: {
        'factory': GObject.ParamSpec.override('factory', Module.Module),
        'factory-name': GObject.ParamSpec.override('factory-name', Module.Module),
        'scroll-server': GObject.ParamSpec.override('scroll-server', Scrollable.Scrollable),
        'fade-cards': GObject.ParamSpec.override('fade-cards',
            CardContainer.CardContainer),
    },

    _init: function (props={}) {
        props.orientation = Gtk.Orientation.VERTICAL;
        this.parent(props);
        this._arrangements = [];
        this._featured_arrangements = [];
        this._non_featured_arrangements = [];
        this._sets = [];

        this.scrollable_init();

        Dispatcher.get_default().register((payload) => {
            switch (payload.action_type) {
                case Actions.SHOW_SET:
                    this._show_set(payload.model);
                    break;
                case Actions.CLEAR_SETS:
                    this._clear_all();
                    break;
                case Actions.CLEAR_ITEMS:
                    this._clear_items();
                    break;
                case Actions.APPEND_SETS:
                    payload.models.forEach(this._add_set, this);
                    break;
            }
        });
    },

    // Module override
    get_slot_names: function () {
        return ['arrangement', 'card-type', 'header-card-type'];
    },

    show_more_content: function () {
        if (this._current_index >= this._current_arrangements.length)
            return;
        let arrangement = this._current_arrangements[this._current_index];
        this._current_index += 1;
        let query = new QueryObject.QueryObject({
            limit: -1,
            tags: this._current_model.child_tags.concat(arrangement.accepted_child_tags),
            tag_match: QueryObject.QueryObjectTagMatch.ALL,
        });
        Engine.get_default().get_objects_by_query(query, null, (engine, task) => {
            let results;
            try {
                [results] = engine.get_objects_by_query_finish(task);
            } catch (e) {
                logError(e, 'Failed to load objects from set');
                return;
            }

            // If we got no results for this arrangement, move onto the next one
            if (results.length === 0) {
                this.show_more_content();
            } else {
                results.forEach((model) => this._add_article_card(model, arrangement));
                arrangement.visible = true;
                Dispatcher.get_default().dispatch({
                    action_type: Actions.CONTENT_ADDED,
                    scroll_server: this.scroll_server,
                });
            }
        });
    },

    _show_set: function (model) {
        this._clear_items();

        this._current_arrangements = model.featured ?
            this._non_featured_arrangements : this._featured_arrangements;
        this._current_index = 0;
        this._current_model = model;
        this.show_more_content();

        Dispatcher.get_default().dispatch({
            action_type: Actions.SET_READY,
            model: model,
        });
    },

    _create_set_card: function (model) {
        let card = this.create_submodule('header-card-type', {
            model: model,
            visible: true,
            halign: Gtk.Align.START,
        });
        card.connect('clicked', () => {
            Dispatcher.get_default().dispatch({
                action_type: Actions.SET_CLICKED,
                model: model,
                context: this._sets,
            });
        });
        return card;
    },

    _add_article_card: function (model, arrangement) {
        let card = this.create_submodule('card-type', {
            model: model,
        });
        card.connect('clicked', () => {
            Dispatcher.get_default().dispatch({
                action_type: Actions.ITEM_CLICKED,
                model: model,
                context: arrangement.get_cards().map((card) => card.model),
                context_label: arrangement.set_title,
            });
        });
        arrangement.add_card(card);
    },

    _add_set: function (model) {
        this._sets.push(model);
        let header = this._create_set_card(model);

        let separator = new ThemeableImage.ThemeableImage({
            visible: true,
            halign: Gtk.Align.FILL,
            valign: Gtk.Align.CENTER,
        });
        separator.get_style_context().add_class(Gtk.STYLE_CLASS_SEPARATOR);

        let arrangement = this.create_submodule('arrangement', {
            vexpand: true,
            visible: false,
            no_show_all: true,
        });
        arrangement.accepted_child_tags = model.child_tags.slice();
        arrangement.set_title = model.title;
        this._arrangements.push(arrangement);

        if (model.featured) {
            this._featured_arrangements.push(arrangement);
        } else {
            this._non_featured_arrangements.push(arrangement);
        }

        let set_grid = new Gtk.Grid({
            orientation: Gtk.Orientation.VERTICAL,
            no_show_all: true,
        });
        set_grid.add(header);
        set_grid.add(separator);
        set_grid.add(arrangement);

        this.add(set_grid);

        arrangement.bind_property('visible', set_grid, 'visible',
            GObject.BindingFlags.SYNC_CREATE);
    },

    _clear_all: function () {
        this.get_children().forEach(this.remove, this);
        this._arrangements = [];
        this._featured_arrangements = [];
        this._non_featured_arrangements = [];
        this._sets = [];
    },

    _clear_items: function () {
        // Only arrangements that have cards in them should be shown
        this._arrangements.forEach(arrangement => {
            arrangement.clear();
            arrangement.hide();
        });
    },
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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
 *
 *     http://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.
 */

CLASS({
  package: 'com.google.watlobby',
  name: 'Remote',
  extends: 'foam.graphics.CView',

  traits: [ 'com.google.watlobby.RemoteTrait' ],

  requires: [
    'com.google.watlobby.Bubble',
    'com.google.watlobby.TopicBubble',
    'com.google.watlobby.AlbumBubble',
    'com.google.watlobby.Topic',
    'com.google.watlobby.TopicDAO',
    'com.google.watlobby.VideoBubble',
    'foam.demos.physics.PhysicalCircle',
    'foam.graphics.ImageCView'
  ],

  imports: [
    'document',
    'window'
  ],

  properties: [
    {
      model_: 'BooleanProperty',
      name: 'clientMode',
      defaultValue: true
    },
    {
      name: 'topics',
      lazyFactory: function() {
        return this.TopicDAO.create({ clientMode: this.clientMode });
      }
    },
    { name: 'n',          defaultValue: 25 },
    { name: 'airBubbles', defaultValue: 0, model_: 'IntProperty' },
    { name: 'width',      factory: function() { return this.window.innerWidth; } },
    { name: 'height',     factory: function() { return this.window.innerHeight } },
    { name: 'background', defaultValue: '#ccf' }
  ],

  listeners: [
    {
      name: 'updateState',
      isFramed: true,
      code: function() {
        this.topics.find(EQ(this.Topic.TOPIC, this.root), {
          put: function (t) {
            t = t.clone();
            t.selected = this.selected;
            t.dir = this.dir;
            this.topics.put(t);
          }.bind(this)
        });
      }
    },
    {
      name: 'layout',
      isFramed: true,
      code: function() {
        while ( this.children.length ) {
          this.removeChild(this.children[this.children.length-1]);
        }

        if ( this.dir )
          this.putTopic(this.Topic.create({
            parent: this.dir,
            topic: this.BACK_TOPIC,
            image: 'img/back.png',
            model: "Photo",
            color: 'grey',
            roundImage: true
          }));
        this.topics.find(EQ(this.Topic.TOPIC, this.dir),{put:this.putTopic.bind(this)});
        this.topics.where(EQ(this.Topic.PARENT, this.dir)).select({put: this.putTopic.bind(this)});
      }
    }
  ],

  methods: [
    function initCView() {
      this.SUPER();

      this.topics.listen({put: function(t) { if ( t.topic !== this.root ) this.layout(); }.bind(this), remove: this.layout});
      this.document.body.addEventListener('click', this.onClick);
      this.selected$.addListener(this.updateState);
      this.dir$.addListener(this.updateState);
      this.dir$.addListener(this.layout);
      this.layout();
    },

    function putTopic(t) {
      if ( t.topic === this.root ) return;

      // console.log('*** putTopic: ', t, t.topic && t.topic.topic);
      // Don't add if we already have topic
      for ( var i = 0 ; i < this.children.length ; i++ ) {
        var c = this.children[i];
        if ( c.topic && c.topic.topic === t.topic ) {
          this.selected = c;
          return;
        }
      }

      t = t.clone();

      var h = (this.height-26) / 4;
      var i = this.children.length;
      var m = this.X.lookup('com.google.watlobby.' + t.model + 'Bubble');
      if ( ! m ) return;
      var c = m.create({
        x: Math.floor(i / 4) * h + h/2,
        y: ( i % 4 ) * h + h/2
      }, this.Y);
      c.topic = t;
      c.image = t.image;
      var r = h/2-20;
      t.r = c.r = r;
      c.scaleX = c.scaleY = 0.1;
      c.alpha = 0.1;
      c.roundImage = t.roundImage;
      if ( t.color ) c.border = t.color;
      if ( t.background ) c.color = t.background;
      this.addChild(c);

      Movement.animate(250, function() { c.alpha = 1; c.scaleX = c.scaleY = 1; })();
    }
  ]
});
<commit_msg>WatLobby: Non-selected items fade out.<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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
 *
 *     http://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.
 */

CLASS({
  package: 'com.google.watlobby',
  name: 'Remote',
  extends: 'foam.graphics.CView',

  traits: [ 'com.google.watlobby.RemoteTrait' ],

  requires: [
    'com.google.watlobby.Bubble',
    'com.google.watlobby.TopicBubble',
    'com.google.watlobby.AlbumBubble',
    'com.google.watlobby.Topic',
    'com.google.watlobby.TopicDAO',
    'com.google.watlobby.VideoBubble',
    'foam.demos.physics.PhysicalCircle',
    'foam.graphics.ImageCView'
  ],

  imports: [
    'document',
    'window'
  ],

  properties: [
    {
      model_: 'BooleanProperty',
      name: 'clientMode',
      defaultValue: true
    },
    {
      name: 'topics',
      lazyFactory: function() {
        return this.TopicDAO.create({ clientMode: this.clientMode });
      }
    },
    { name: 'n',          defaultValue: 25 },
    { name: 'airBubbles', defaultValue: 0, model_: 'IntProperty' },
    { name: 'width',      factory: function() { return this.window.innerWidth; } },
    { name: 'height',     factory: function() { return this.window.innerHeight } },
    { name: 'background', defaultValue: '#ccf' }
  ],

  listeners: [
    {
      name: 'updateState',
      isFramed: true,
      code: function() {
        this.topics.find(EQ(this.Topic.TOPIC, this.root), {
          put: function (t) {
            t = t.clone();
            t.selected = this.selected;
            t.dir = this.dir;
            this.topics.put(t);
          }.bind(this)
        });
      }
    },
    {
      name: 'layout',
      isFramed: true,
      code: function() {
        while ( this.children.length ) {
          this.removeChild(this.children[this.children.length-1]);
        }

        if ( this.dir )
          this.putTopic(this.Topic.create({
            parent: this.dir,
            topic: this.BACK_TOPIC,
            image: 'img/back.png',
            model: "Photo",
            color: 'grey',
            roundImage: true
          }));
        this.topics.find(EQ(this.Topic.TOPIC, this.dir),{put:this.putTopic.bind(this)});
        this.topics.where(EQ(this.Topic.PARENT, this.dir)).select({put: this.putTopic.bind(this)});
      }
    }
  ],

  methods: [
    function initCView() {
      this.SUPER();

      this.topics.listen({put: function(t) { if ( t.topic !== this.root ) this.layout(); }.bind(this), remove: this.layout});
      this.document.body.addEventListener('click', this.onClick);
      this.selected$.addListener(this.updateState);
      this.dir$.addListener(this.updateState);
      this.dir$.addListener(this.layout);
      this.layout();
    },

    function putTopic(t) {
      if ( t.topic === this.root ) return;

      // console.log('*** putTopic: ', t, t.topic && t.topic.topic);
      // Don't add if we already have topic
      for ( var i = 0 ; i < this.children.length ; i++ ) {
        var c = this.children[i];
        if ( c.topic && c.topic.topic === t.topic ) {
          this.selected = c;
          return;
        }
      }

      t = t.clone();

      var h = (this.height-26) / 4;
      var i = this.children.length;
      var m = this.X.lookup('com.google.watlobby.' + t.model + 'Bubble');
      if ( ! m ) return;
      var c = m.create({
        x: Math.floor(i / 4) * h + h/2,
        y: ( i % 4 ) * h + h/2
      }, this.Y);
      c.topic = t;
      c.image = t.image;
      var r = h/2-20;
      t.r = c.r = r;
      c.scaleX = c.scaleY = 0.1;
      c.roundImage = t.roundImage;
      if ( t.color ) c.border = t.color;
      if ( t.background ) c.color = t.background;
      this.addChild(c);

      var l = function(_,_,_,s) { c.alpha = ( !s || s === t.topic ) ? 1 : 0.4; };
      if ( t.topic !== this.BACK_TOPIC ) {
        this.selected$.addListener(l);
        l(null,null,null, this.selected);
      }

      Movement.animate(250, function() { c.scaleX = c.scaleY = 1; })();
    }
  ]
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
var fileName = './app.json';
require('child_process').exec('git rev-list HEAD --count < /dev/tty', function(err, stdout, stderr) {
    var numberOfCommits = parseInt(stdout, 10) + 1;
    try {
        var pkg = require(fileName);
    }
    catch (e) {
        console.log(e);
        process.exit(1);
    }

    pkg.commit = numberOfCommits;
    require('fs').writeFile(fileName, JSON.stringify(pkg, null, 4), function(err) {
        if(err) {
            console.log(err);
        } else {
            console.log("JSON saved to " + fileName);
        }
    });
});
<commit_msg>pre-commit git hook<commit_after>#!/usr/bin/env node
var fileName = '../../app.json';
require('child_process').exec('git rev-list HEAD --count < /dev/tty', function(err, stdout, stderr) {
    var numberOfCommits = parseInt(stdout, 10) + 1;
    try {
        var pkg = require(fileName);
    }
    catch (e) {
        console.log(e);
        process.exit(1);
    }

    pkg.commit = numberOfCommits;
    require('fs').writeFile(fileName, JSON.stringify(pkg, null, 4), function(err) {
        if(err) {
            console.log(err);
        } else {
            console.log("JSON saved to " + fileName);
        }
    });
});
<|endoftext|>


<commit_before>/*
 * Copyright IBM Corporation 2016
 *
 * 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
 *
 * http://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.
 */

'use strict';
var path = require('path');
var assert = require('yeoman-assert');
var helpers = require('yeoman-test');
var fs = require('fs');
var format = require('util').format;

describe('swiftserver:refresh', function () {
  describe('Basic refresh generator test. ' +
           'Check the Swagger file exists and ' +
           'is written out correctly.', function () {

    var dirName;
    var appName = 'testApp';
    var expected = [
      'definitions/%s.yaml'
    ];

    before(function () {
        // Mock the options, set up an output folder and run the generator
        return helpers.run(path.join( __dirname, '../../refresh'))
          .inTmpDir(function (tmpDir) {
            dirName = path.basename(tmpDir);
            expected = expected.map((path) => format(path, appName));
            var tmpFile = path.join(tmpDir, ".swiftservergenerator-project");    //Created to make the dir a kitura project
            fs.writeFileSync(tmpFile, "");
            var config = {
              appName: appName
            };
            var configFile = path.join(tmpDir, "config.json");
            fs.writeFileSync(configFile, JSON.stringify(config));
            fs.mkdirSync(path.join(tmpDir, "models"));
            var testModel = {
              name: "test",
              plural: "tests",
              classname: "Test",
              properties: {
                id: { type: "number", id: true }
              }
            };
            fs.writeFileSync(path.join(tmpDir, "models", "test.json"), JSON.stringify(testModel));
          })
          .toPromise();                        // Get a Promise back when the generator finishes
    });

    it('generates the expected files', function () {
      assert.file(expected);
    });

    // This is only a starter set of checks, we need to add further check in.
    it('the swagger file contains the expected content', function() {
      assert.fileContent([
        [expected[0], 'title: ' + appName],
        [expected[0], 'test:']
      ]);
    });
  });

  describe('Basic refresh generator test with apic option. ' +
           'Check the yaml files exist and ' +
           'are written out correctly.', function () {

    var dirName;
    var expected = [
      'definitions/%s-product.yaml',
      'definitions/%s.yaml'
    ];

    before(function () {
        // Mock the options, set up an output folder and run the generator
        return helpers.run(path.join( __dirname, '../../refresh'))
          .inTmpDir(function (tmpDir) {
            dirName = path.basename(tmpDir);
            expected = expected.map((path) => format(path, dirName));
            var tmpFile = path.join(tmpDir, ".swiftservergenerator-project");    //Created to make the dir a kitura project
            fs.writeFileSync(tmpFile, "");
            fs.mkdirSync(path.join(tmpDir, "models"));
            var testModel = {
              name: "test",
              plural: "tests",
              classname: "Test",
              properties: {
                id: { type: "number", id: true }
              }
            };
            fs.writeFileSync(path.join(tmpDir, "models", "test.json"), JSON.stringify(testModel));
          })
          .withOptions({ apic: true })
          .toPromise();                        // Get a Promise back when the generator finishes
    });

    it('generates the expected files', function () {
      assert.file(expected);
    });

    it('the product file contains the expected content', function() {
      assert.fileContent([
        [expected[0], 'name: ' + dirName],
        [expected[0], 'title: ' + dirName]
      ]);
    });

    // This is only a starter set of checks, we need to add further check in.
    it('the swagger file contains the expected content', function() {
      assert.fileContent([
        [expected[1], 'name: ' + dirName],
        [expected[1], 'title: ' + dirName]
      ]);
    });
  });
});
<commit_msg>Update refresh APIC test<commit_after>/*
 * Copyright IBM Corporation 2016
 *
 * 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
 *
 * http://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.
 */

'use strict';
var path = require('path');
var assert = require('yeoman-assert');
var helpers = require('yeoman-test');
var fs = require('fs');
var format = require('util').format;

describe('swiftserver:refresh', function () {
  describe('Basic refresh generator test. ' +
           'Check the Swagger file exists and ' +
           'is written out correctly.', function () {

    var dirName;
    var appName = 'testApp';
    var expected = [
      'definitions/%s.yaml'
    ];

    before(function () {
        // Mock the options, set up an output folder and run the generator
        return helpers.run(path.join( __dirname, '../../refresh'))
          .inTmpDir(function (tmpDir) {
            dirName = path.basename(tmpDir);
            expected = expected.map((path) => format(path, appName));
            var tmpFile = path.join(tmpDir, ".swiftservergenerator-project");    //Created to make the dir a kitura project
            fs.writeFileSync(tmpFile, "");
            var config = {
              appName: appName
            };
            var configFile = path.join(tmpDir, "config.json");
            fs.writeFileSync(configFile, JSON.stringify(config));
            fs.mkdirSync(path.join(tmpDir, "models"));
            var testModel = {
              name: "test",
              plural: "tests",
              classname: "Test",
              properties: {
                id: { type: "number", id: true }
              }
            };
            fs.writeFileSync(path.join(tmpDir, "models", "test.json"), JSON.stringify(testModel));
          })
          .toPromise();                        // Get a Promise back when the generator finishes
    });

    it('generates the expected files', function () {
      assert.file(expected);
    });

    // This is only a starter set of checks, we need to add further check in.
    it('the swagger file contains the expected content', function() {
      assert.fileContent([
        [expected[0], 'title: ' + appName],
        [expected[0], 'test:']
      ]);
    });
  });

  describe('Basic refresh generator test with apic option. ' +
           'Check the yaml files exist and ' +
           'are written out correctly.', function () {

    var dirName;
    var appName = 'testApp';
    var expected = [
      'definitions/%s-product.yaml',
      'definitions/%s.yaml'
    ];

    before(function () {
        // Mock the options, set up an output folder and run the generator
        return helpers.run(path.join( __dirname, '../../refresh'))
          .inTmpDir(function (tmpDir) {
            dirName = path.basename(tmpDir);
            expected = expected.map((path) => format(path, appName));
            var tmpFile = path.join(tmpDir, ".swiftservergenerator-project");    //Created to make the dir a kitura project
            fs.writeFileSync(tmpFile, "");
            var config = {
              appName: appName
            };
            var configFile = path.join(tmpDir, "config.json");
            fs.writeFileSync(configFile, JSON.stringify(config));
            fs.mkdirSync(path.join(tmpDir, "models"));
            var testModel = {
              name: "test",
              plural: "tests",
              classname: "Test",
              properties: {
                id: { type: "number", id: true }
              }
            };
            fs.writeFileSync(path.join(tmpDir, "models", "test.json"), JSON.stringify(testModel));
          })
          .withOptions({ apic: true })
          .toPromise();                        // Get a Promise back when the generator finishes
    });

    it('generates the expected files', function () {
      assert.file(expected);
    });

    it('the product file contains the expected content', function() {
      assert.fileContent([
        [expected[0], 'name: ' + appName],
        [expected[0], 'title: ' + appName]
      ]);
    });

    // This is only a starter set of checks, we need to add further check in.
    it('the swagger file contains the expected content', function() {
      assert.fileContent([
        [expected[1], 'name: ' + appName],
        [expected[1], 'title: ' + appName]
      ]);
    });
  });
});
<|endoftext|>


<commit_before>/**
 * nodeCleanup() installs a function that performs cleanup activities just
 * before the node process exits. The cleanup function runs when the process
 * exits normally, when the user presses ctrl-C, and when an exception is
 * uncaught. The caller may specify the termination messages to use.
 *
 * See https://github.com/jtlapp/node-cleanup for more information.
 */

module.exports = function nodeCleanup(cleanupHandler, messages) {

    messages = messages || {};
    if (typeof messages.ctrl_C !== 'string')
        messages.ctrl_C = '[ctrl-C]';
    if (typeof messages.uncaughtException !== 'string')
        messages.uncaughtException = 'Uncaught exception...';

    // attach user callback to the process event emitter.
    // if no callback, it will still exit gracefully on Ctrl-C
    cleanupHandler = cleanupHandler || noOp;
    process.on('cleanup', cleanupHandler);

    // do app-specific cleaning before exiting
    process.on('exit', function () {
        process.emit('cleanup');
    });

    // catch ctrl+c event and exit normally
    process.on('SIGINT', function () {
        if (messages.ctrl_C !== '')
            process.stderr.write(messages.ctrl_C + "\n");
        process.exit(2);
    });

    //catch uncaught exceptions, trace, then exit normally
    process.on('uncaughtException', function(e) {
        if (messages.uncaughtException !== '') {
            process.stderr.write(messages.uncaughtException + "\n");
            process.stderr.write(e.stack + "\n");
        }
        process.exit(99);
    });
};

function noOp() {}; // for just the benefit of graceful SIGINTs
<commit_msg>pointed code to stackoverflow<commit_after>/**
 * nodeCleanup() installs a function that performs cleanup activities just
 * before the node process exits. The cleanup function runs when the process
 * exits normally, when the user presses ctrl-C, and when an exception is
 * uncaught. The caller may specify the termination messages to use.
 *
 * See https://github.com/jtlapp/node-cleanup for more information. Code
 * largely borrowed from http://stackoverflow.com/a/21947851/650894.
 */

module.exports = function nodeCleanup(cleanupHandler, messages) {

    messages = messages || {};
    if (typeof messages.ctrl_C !== 'string')
        messages.ctrl_C = '[ctrl-C]';
    if (typeof messages.uncaughtException !== 'string')
        messages.uncaughtException = 'Uncaught exception...';

    // attach user callback to the process event emitter.
    // if no callback, it will still exit gracefully on Ctrl-C
    cleanupHandler = cleanupHandler || noOp;
    process.on('cleanup', cleanupHandler);

    // do app-specific cleaning before exiting
    process.on('exit', function () {
        process.emit('cleanup');
    });

    // catch ctrl+c event and exit normally
    process.on('SIGINT', function () {
        if (messages.ctrl_C !== '')
            process.stderr.write(messages.ctrl_C + "\n");
        process.exit(2);
    });

    //catch uncaught exceptions, trace, then exit normally
    process.on('uncaughtException', function(e) {
        if (messages.uncaughtException !== '') {
            process.stderr.write(messages.uncaughtException + "\n");
            process.stderr.write(e.stack + "\n");
        }
        process.exit(99);
    });
};

function noOp() {}; // for just the benefit of graceful SIGINTs
<|endoftext|>


<commit_before>/*#ifndef(UMD)*/
"use strict";
/*global _gpfErrorDeclare*/ // Declare new gpf.Error names
/*exported _gpfCsvParse*/
/*#endif*/

_gpfErrorDeclare("csv", {
    csvInvalid:
        "Invalid CSV syntax (bad quote sequence or missing end of file)"
});

var
    // Usual CSV separators
    _gpfCsvSeparators = ";,\t ";

/**
 * Deduce CSV separator from line (usually, the header)
 *
 * @param {String} header
 * @return {String}
 */
function _gpfCsvComputeSeparator (header) {
    var len = _gpfCsvSeparators.length,
        idx,
        separator;
    for (idx = 0; idx < len; ++idx) {
        separator = _gpfCsvSeparators.charAt(idx);
        if (-1 !== header.indexOf(separator)) {
            return separator;
        }
    }
    // Default
    return _gpfCsvSeparators.charAt(0);
}

/**
 * Remove final \r from the line
 *
 * @param {String} line
 * @return {String}
 */
function _gpfTrimFinalR (line) {
    var len = line.length - 1;
    if ("\r" === line.charAt(len)) {
        return line.substr(0, len);
    }
    return line;
}

/**
 * CSV Parser
 *
 * @param {String} content CSV content
 * @param {Object} options
 * - {String} [header=undefined] header
 * - {String} [separator=undefined] separator can be deduced from header
 * - {String} [quote="\""] quote
 * @class {_GpfCsvParse}
 * @constructor
 */
function _GpfCsvParser (content, options) {
    /*jshint validthis:true*/ // constructor
    options = options || {}; // to have at least an empty object
    this._lines = content.split("\n").map(_gpfTrimFinalR);
    var header = options.header || this._lines.shift();
    this._separator = options.separator || _gpfCsvComputeSeparator(header);
    this._quote = options.quote || "\"";
    this._columns = header.split(this._separator);
}

_GpfCsvParser.prototype = {

    // @property {String[]} Array of lines
    _lines: [],

    // Column separator
    _separator: "",

    // Quote
    _quote: "",

    // @property {String[]} Columns' name
    _columns: [],

    /**
     * Process quoted value to unescape it properly.
     * Either the quote appears in the middle of the value: it must be followed by another quote.
     * And/Or it appears at the end of the value: it means this ends the quoted value
     *
     * @param {String} value
     * @return {Array}
     * - {String} 0 The result value
     * - {Boolean} 1 Indicates if the quote escaping is still active
     */
    _unquote: function (value) {
        var quote = this._quote,
            pos = value.indexOf(quote),
            inQuotedString = true;
        while (-1 < pos) {
            if (pos === value.length - 1) {
                // Last character of the string
                value = value.substr(0, pos);
                inQuotedString = false;
                break;
            } else if (value.charAt(pos + 1) === quote) {
                // Double quote means escaped one
                value = value.substr(0, pos) + value.substr(pos + 1);
            } else {
                throw gpf.Error.csvInvalid();
            }
            pos = value.indexOf(quote, pos + 1);
        }
        return [value, inQuotedString];
    },

    /**
     * Process the line value knowing it is quoted
     *
     * @param {String[]} line Line split on separator
     * @param {Number} idx Index of the value to consider
     * @param {Object} flags
     * - {Boolean} inQuotedString
     * - {Boolean} includeCarriageReturn
     * @returns {Number} Next value index
     */
    _processQuotedLineValue: function (line, idx, flags) {
        var value = line[idx],
            unQuoted;
        // Concatenate with 'previous' item
        var previousValue = [line[idx - 1]];
        if (flags.includeCarriageReturn) {
            previousValue.push("\r\n");
        } else {
            // part of the escaped string
            previousValue.push(this._separator);
        }
        unQuoted = this._unquote(value);
        previousValue.push(unQuoted[0]);
        flags.inQuotedString = unQuoted[1];
        line[idx - 1] = previousValue.join("");
        flags.includeCarriageReturn = false;
        line.splice(idx, 1);
        return idx;
    },

    /**
     * Process the line value to check if any quote exists
     *
     * @param {String[]} line Line split on separator
     * @param {Number} idx Index of the value to consider
     * @param {Object} flags
     * - {Boolean} inQuotedString
     * - {Boolean} includeCarriageReturn
     * @returns {Number} Next value index
     */
    _processLineValue: function (line, idx, flags) {
        var value = line[idx],
            unQuoted;
        if (0 === value.indexOf(this._quote)) {
            flags.inQuotedString = true;
            unQuoted = this._unquote(value.substr(1));
            line[idx] = unQuoted[0];
            flags.inQuotedString = unQuoted[1];
        }
        return idx + 1;
    },

    /**
     * Convert the line into values
     *
     * @param {String} line
     * @param {String[]} values
     * @param {Object} flags
     * - {Boolean} inQuotedString
     * - {Boolean} includeCarriageReturn
     * @returns {Boolean}
     */
    _processLineValues: function (line, values, flags) {
        var idx;
        if (flags.inQuotedString) {
            flags.includeCarriageReturn = true;
            line.unshift(values.pop()); // Last value is not completed
            idx = 1;
        } else {
            idx = 0;
            flags.includeCarriageReturn = false;
        }
        while (idx < line.length) {
            if (flags.inQuotedString) {
                idx = this._processQuotedLineValue(line, idx, flags);
            } else {
                idx = this._processLineValue(line, idx, flags);
            }
        }
        [].splice.apply(values, [values.length, 0].concat(line));
        return !flags.inQuotedString;
    },

    /**
     * Read one 'line' of values.
     * Quote escaping is handled meaning that a line might be on several lines
     *
     * @returns {String[]}
     */
    _readValues: function () {
        var lines = this._lines,
            separator = this._separator,
            values = [],
            flags = {
                inQuotedString: false,
                includeCarriageReturn: false
            },
            line;
        while (lines.length) {
            line = lines.shift().split(separator);
            if (this._processLineValues(line, values, flags)) {
                break;
            }
        }
        if (flags.inQuotedString) {
            throw gpf.Error.csvInvalid();
        }
        return values;
    },

    /**
     * Read one record
     *
     * @returns {Object}
     */
    read: function () {
        var values = this._readValues(),
            record = {};
        /*gpf:inline(array)*/ this._columns.forEach(function (name, idx) {
            record[name] = values[idx];
        });
        return record;
    },

    /**
     * Read all records
     *
     * @returns {Object[]}
     */
    readAll: function () {
        var result = [];
        while (this._lines.length) {
            result.push(this.read());
        }
        return result;
    }

};

gpf.csv = {

    /**
     * CSV parsing function
     *
     * @param {String} content CSV content
     * @param {Object} options
     * - {String} [header=undefined] header
     * - {String} [separator=undefined] separator can be deduced from header
     * - {String} [quote="\""] quote
     *
     * @return {Object[]} records
     */
    parse: function (content, options) {
        var csvParser = new _GpfCsvParser(content, options);
        return csvParser.readAll();
    }

};
<commit_msg>Modified position of gpf:inline tags<commit_after>/*#ifndef(UMD)*/
"use strict";
/*global _gpfErrorDeclare*/ // Declare new gpf.Error names
/*exported _gpfCsvParse*/
/*#endif*/

_gpfErrorDeclare("csv", {
    csvInvalid:
        "Invalid CSV syntax (bad quote sequence or missing end of file)"
});

var
    // Usual CSV separators
    _gpfCsvSeparators = ";,\t ";

/**
 * Deduce CSV separator from line (usually, the header)
 *
 * @param {String} header
 * @return {String}
 */
function _gpfCsvComputeSeparator (header) {
    var len = _gpfCsvSeparators.length,
        idx,
        separator;
    for (idx = 0; idx < len; ++idx) {
        separator = _gpfCsvSeparators.charAt(idx);
        if (-1 !== header.indexOf(separator)) {
            return separator;
        }
    }
    // Default
    return _gpfCsvSeparators.charAt(0);
}

/**
 * Remove final \r from the line
 *
 * @param {String} line
 * @return {String}
 */
function _gpfTrimFinalR (line) {
    var len = line.length - 1;
    if ("\r" === line.charAt(len)) {
        return line.substr(0, len);
    }
    return line;
}

/**
 * CSV Parser
 *
 * @param {String} content CSV content
 * @param {Object} options
 * - {String} [header=undefined] header
 * - {String} [separator=undefined] separator can be deduced from header
 * - {String} [quote="\""] quote
 * @class {_GpfCsvParse}
 * @constructor
 */
function _GpfCsvParser (content, options) {
    /*jshint validthis:true*/ // constructor
    options = options || {}; // to have at least an empty object
    this._lines = content.split("\n").map(_gpfTrimFinalR);
    var header = options.header || this._lines.shift();
    this._separator = options.separator || _gpfCsvComputeSeparator(header);
    this._quote = options.quote || "\"";
    this._columns = header.split(this._separator);
}

_GpfCsvParser.prototype = {

    // @property {String[]} Array of lines
    _lines: [],

    // Column separator
    _separator: "",

    // Quote
    _quote: "",

    // @property {String[]} Columns' name
    _columns: [],

    /**
     * Process quoted value to unescape it properly.
     * Either the quote appears in the middle of the value: it must be followed by another quote.
     * And/Or it appears at the end of the value: it means this ends the quoted value
     *
     * @param {String} value
     * @return {Array}
     * - {String} 0 The result value
     * - {Boolean} 1 Indicates if the quote escaping is still active
     */
    _unquote: function (value) {
        var quote = this._quote,
            pos = value.indexOf(quote),
            inQuotedString = true;
        while (-1 < pos) {
            if (pos === value.length - 1) {
                // Last character of the string
                value = value.substr(0, pos);
                inQuotedString = false;
                break;
            } else if (value.charAt(pos + 1) === quote) {
                // Double quote means escaped one
                value = value.substr(0, pos) + value.substr(pos + 1);
            } else {
                throw gpf.Error.csvInvalid();
            }
            pos = value.indexOf(quote, pos + 1);
        }
        return [value, inQuotedString];
    },

    /**
     * Process the line value knowing it is quoted
     *
     * @param {String[]} line Line split on separator
     * @param {Number} idx Index of the value to consider
     * @param {Object} flags
     * - {Boolean} inQuotedString
     * - {Boolean} includeCarriageReturn
     * @returns {Number} Next value index
     */
    _processQuotedLineValue: function (line, idx, flags) {
        var value = line[idx],
            unQuoted;
        // Concatenate with 'previous' item
        var previousValue = [line[idx - 1]];
        if (flags.includeCarriageReturn) {
            previousValue.push("\r\n");
        } else {
            // part of the escaped string
            previousValue.push(this._separator);
        }
        unQuoted = this._unquote(value);
        previousValue.push(unQuoted[0]);
        flags.inQuotedString = unQuoted[1];
        line[idx - 1] = previousValue.join("");
        flags.includeCarriageReturn = false;
        line.splice(idx, 1);
        return idx;
    },

    /**
     * Process the line value to check if any quote exists
     *
     * @param {String[]} line Line split on separator
     * @param {Number} idx Index of the value to consider
     * @param {Object} flags
     * - {Boolean} inQuotedString
     * - {Boolean} includeCarriageReturn
     * @returns {Number} Next value index
     */
    _processLineValue: function (line, idx, flags) {
        var value = line[idx],
            unQuoted;
        if (0 === value.indexOf(this._quote)) {
            flags.inQuotedString = true;
            unQuoted = this._unquote(value.substr(1));
            line[idx] = unQuoted[0];
            flags.inQuotedString = unQuoted[1];
        }
        return idx + 1;
    },

    /**
     * Convert the line into values
     *
     * @param {String} line
     * @param {String[]} values
     * @param {Object} flags
     * - {Boolean} inQuotedString
     * - {Boolean} includeCarriageReturn
     * @returns {Boolean}
     */
    _processLineValues: function (line, values, flags) {
        var idx;
        if (flags.inQuotedString) {
            flags.includeCarriageReturn = true;
            line.unshift(values.pop()); // Last value is not completed
            idx = 1;
        } else {
            idx = 0;
            flags.includeCarriageReturn = false;
        }
        while (idx < line.length) {
            if (flags.inQuotedString) {
                idx = this._processQuotedLineValue(line, idx, flags);
            } else {
                idx = this._processLineValue(line, idx, flags);
            }
        }
        [].splice.apply(values, [values.length, 0].concat(line));
        return !flags.inQuotedString;
    },

    /**
     * Read one 'line' of values.
     * Quote escaping is handled meaning that a line might be on several lines
     *
     * @returns {String[]}
     */
    _readValues: function () {
        var lines = this._lines,
            separator = this._separator,
            values = [],
            flags = {
                inQuotedString: false,
                includeCarriageReturn: false
            },
            line;
        while (lines.length) {
            line = lines.shift().split(separator);
            if (this._processLineValues(line, values, flags)) {
                break;
            }
        }
        if (flags.inQuotedString) {
            throw gpf.Error.csvInvalid();
        }
        return values;
    },

    /**
     * Read one record
     *
     * @returns {Object}
     */
    read: function () {
        var values = this._readValues(),
            record = {};
        this._columns.forEach(function (name, idx) { /*gpf:inline(array)*/
            record[name] = values[idx];
        });
        return record;
    },

    /**
     * Read all records
     *
     * @returns {Object[]}
     */
    readAll: function () {
        var result = [];
        while (this._lines.length) {
            result.push(this.read());
        }
        return result;
    }

};

gpf.csv = {

    /**
     * CSV parsing function
     *
     * @param {String} content CSV content
     * @param {Object} options
     * - {String} [header=undefined] header
     * - {String} [separator=undefined] separator can be deduced from header
     * - {String} [quote="\""] quote
     *
     * @return {Object[]} records
     */
    parse: function (content, options) {
        var csvParser = new _GpfCsvParser(content, options);
        return csvParser.readAll();
    }

};
<|endoftext|>


<commit_before>

NOW WATCHING:

	Eps:

Loading...

		<video id="videoPlayer" class="video-js vjs-big-play-centered" width="640" height="360" controls></video>

	<input id="subtitles_button" value="Click to Hide/Show Advanced Subtitles" type="button" onclick="toggleAdvSub()">

			<select size='5' id='results' onchange='playCaption(this)' style='width:100%; height:240px' ></select>

Click a line to jump to that point in the video.
Then use up/down arrows to navigate by line.

<commit_msg>Update animejpnsub.js<commit_after>"use strict"

if ( getQueryFieldValue("v") && jlinks[getQueryFieldValue("v")] !== undefined) {
	var episode = getQueryFieldValue("v");

	// Add titles
	document.title = anime_title + " " + jlinks[episode].name + " - Anime Japanese Subtitles";
	$("#video-title").html(anime_title + " " + jlinks[episode].name);

	// Add links
	Object.keys(jlinks).forEach(function(key){
		if (key == episode)
			$("#episode-links").append(" ", jlinks[episode].name, " ");
		else
			$("#episode-links").append(" ", $("", { href: "?v=" + key }).html(jlinks[key].name), " ");
	});

	// Initialize VideoJS
	var vjs = videojs(document.getElementById("videoPlayer"), {
		"html5": { nativeTextTracks: false }
	});

	// Add source
	vjs.src({type: "video/mp4", src: jlinks[episode].video});

	// Load subtitles
	loadSubs();

	vjs.ready(function() {
		// Enable hotkeys
		this.hotkeys({
			volumeStep: 0.1,
			seekStep: 5,
			alwaysCaptureHotkeys: true,
			enableVolumeScroll: false,
			enableNumbers: false,
			enableModifiersForNumbers: false,
			customKeys: {
				ccKey: {
					key: function(event) {
						// Toggle something with C Key
						return (event.which === 67);
					},
					handler: function(player, options, event) {
						// Toggles the CC button
						var tracks = vjs.textTracks();
						for (var i=0; i < tracks.length; i++) {
							var track = tracks[i];
							if (track.mode === "showing") {
								// disable current
								track.mode = "disabled";
								if ( i < tracks.length - 1) {
									// enable next if current is not last
									tracks[i+1].mode = "showing";
								}
								break
								return
							} else if ( i === tracks.length - 1 ) {
								// enable first if all disabled
								tracks[0].mode = "showing";
								break
								return
							}
						}
					}
				}
			}
		});

		// Show video
		$("#loading-message").remove();
		$("#video-container").show();
	});

} else {
	window.location.href = "?v=" + Object.keys(jlinks)[0];
}

function loadSubs() {
	var l=-1;
	Object.keys(jlinks[episode].subtitles).forEach(function(label){
		l++;

		// Add tracks
		vjs.addRemoteTextTrack({
			src: jlinks[episode].subtitles[label],
			label: label,
			kind: "captions"
		});

		var track = vjs.textTracks()[l];

		// Initialize track
		track.mode = "showing";
		track.mode = "disabled";

		// Add display
		$("

", {
			id: "pre_"+label,
			style: "white-space:pre;" })
			.html("
")
			.appendTo( $("#subtitles_display") )
			.hide();

		// Add checkboxes
		$("", {
			for: "box"+label,
			style: "display:inline-block" })
			.append( $("<input>", {
				type: "checkbox",
				id: "box"+label,
				style: "margin-left: 25px",
				value: label })
				.change(function() {
					if (this.checked)
						$("#pre_"+this.value).show();
					else
						$("#pre_"+this.value).hide();
				})
			,label)
			.appendTo( $("#subtitles_controls") );

		if (label == "Japanese") {
			track.on("loadeddata", function(){
				// Automatically display Japanese
				$("#box"+this.label).attr("checked", true);
				$("#pre_"+this.label).show();

				// Load Japanese captions
				loadCaptions(this.cues);
			});
		}

		// Update display
		track.addEventListener('cuechange', function() {
			var cue = this.activeCues[0];
			var pre = document.getElementById("pre_"+this.label);
			if (cue) {
				pre.innerHTML = "";
				pre.appendChild(cue.getCueAsHTML());
			} else
				pre.innerHTML = "
";
		});

	});
}

function loadCaptions(cues) {
	for (var i=0; i < cues.length; i++) {
		var x = cues[i].getCueAsHTML();
		var option = document.createElement("option");
		option.text = x.textContent;
		option.setAttribute('data-time', cues[i].startTime);
		document.getElementById('results').add(option);
	}
}

function playCaption(control) {
	var t = control.options[control.options.selectedIndex].getAttribute('data-time');
	vjs.currentTime(t);
}

function toggleAdvSub() {
	$(".advanced_subtitles").toggle();
}

function getQueryFieldValue(field) {
	var query = window.location.search.substring(1).split("&");
	for (var i=0; i < query.length; i++) {
		var pair = query[i].split("=");
		if(pair[0] == field){return pair[1];}
	}
	return(false);
}
<|endoftext|>


<commit_before>/*
 *  modules.js
 *
 *  David Janes
 *  IOTDB.org
 *  2014-02-16
 *  "Valentines's Day"
 *
 *  Copyright [2013-2016] [David P. Janes]
 *
 *  Installed Module Management / Package Manager
 *
 *  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
 *
 *     http://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.
 */

"use strict";

const _ = require('./helpers');

const model = require('./model');

const events = require('events');
const util = require('util');
const fs = require('fs');
const path = require('path');

const logger = _.logger.make({
    name: 'iotdb',
    module: 'modules',
});

const Modules = function (paramd) {
    const self = this;

    self.paramd = _.defaults(paramd, {})

    events.EventEmitter.call(this);
    this.setMaxListeners(0);

    self._load();
};

util.inherits(Modules, events.EventEmitter);

/**
 *  Return all the Modules that have been registered
 */
Modules.prototype.modules = function () {
    return _.values(this._moduled);
};

/**
 *  Manually add another module
 *
 *  <Module>.use is like setup, except that it is only
 *  called if you explicitly use use().
 */
Modules.prototype.use = function (module_name, module) {
    const self = this;

    if (!module) {
        module = require(module_name);
    }

    self._moduled[module_name] = module
    self._load_bridges();

    self._use_setup(module_name, module);
    self._use_use(module_name, module);
};

Modules.prototype._use_setup = function (module_name, module) {
    if (!module.setup) {
        return;
    }

    var iotdb = require('./iotdb');

    try {
        module.setup(iotdb);
    } catch (x) {
        logger.error({
            method: "use",
            module_name: module_name,
            exception: x,
            cause: "likely the module has a bad setup function",
            error: _.error.message(x),
            stack: x.stack,
        }, "unexpected exception running module.setup");
        process.exit(1);
    }
};

Modules.prototype._use_use = function (module_name, module) {
    if (!module.use) {
        return;
    }

    try {
        module.use();
    } catch (x) {
        logger.error({
            method: "use",
            module_name: module_name,
            exception: x,
            cause: "likely the module has a bad setup function",
            error: _.error.message(x),
            stack: x.stack,
        }, "unexpected exception running module.use");
        process.exit(1);
    }
};

Modules.prototype._load = function () {
    const self = this;

    self._load_master();
    self._load_bridges();
    self._load_setup();
};

Modules.prototype._load_master = function () {
    const self = this;

    self._moduled = {}

    var moduled = require('./iotdb').keystore().get("modules");
    for (var module_name in moduled) {
        var module_folder = moduled[module_name];
        try {
            var module = require(module_folder);
        } catch (x) {
            logger.error({
                method: "_load",
                module_name: module_name,
                module_folder: module_folder,
                cause: "likely the module being imported is not set up correctly",
                error: _.error.message(x),
                stack: x.stack,
            }, "unexpected exception loading module");
            continue
        }

        module.module_name = module_name;
        module.module_folder = module_folder;

        self._moduled[module_name] = module
    }
};

Modules.prototype._load_bridges = function () {
    const self = this;

    self._bridges = [];

    for (var module_name in self._moduled) {
        var module = self._moduled[module_name];
        if (module.Bridge) {
            module.Bridge.module_name = module_name;
            module.Bridge.bridge_name = _.id.to_dash_case((new module.Bridge()).name());
            self._bridges.push(module.Bridge);
        }
    }
};

/**
 *  A module is a complete package of code, corresponding
 *  to an NPM package (which would have been a better name).
 *  A module has one Bridge, one or more Bindings, and
 *  one or more Models
 *

 *  This will return the module with the module_name,
 *  or undefined if not found.
 */
Modules.prototype.module = function (module_name) {
    return this._moduled[module_name];
};

/**
 *  The Bridge is the code that knows how to talk to
 *  Things. It can be further parameterized by a Binding.
 *

 *  There is one Bridge per Module (maybe more in the future).
 */
Modules.prototype.bridges = function () {
    const self = this;

    return self._bridges;
};

/**
 *  Find a bridge by the *MODULES* name. For the module
 *  part we don't use the Bridge's self-identified
 *  name except for debug purposes
 */
Modules.prototype.bridge = function (module_name) {
    const self = this;

    var module = self._moduled[module_name];
    if (!module) {
        return module;
    }

    return module.Bridge ? module.Bridge : null;
};

Modules.prototype.bindings = function () {
    const self = this;

    if (self._bindings === undefined) {
        self._bindings = [];

        var _setup_binding = function (binding) {
            if (!binding) {
                return;
            } else if (!binding.bridge) {
                return;
            } else if (!binding.model) {
                return;
            }

            if (!_.is.Model(binding.model)) {
                binding.model = model.make_model_from_jsonld(binding.model);

                /*
                var i = new binding.model();
                var c = i.code();
                if (c === "we-mo-socket") {
                    console.log("----");
                    // console.log("HERE:OCT31", i);
                    i.set(':on', true);
                    console.log("----");
                    // process.exit();
                }
                */
            }

            if (!binding.model_code) {
                binding.model_code = (new binding.model()).code();
            } else {
                /* morph the model's code -- see model_maker */
                binding.model_code = _.id.to_dash_case(binding.model_code);
                var old_model = binding.model;
                var new_model = function () {
                    old_model.call(this);
                    this.__code = binding.model_code;
                }
                new_model.prototype = new old_model();

                binding.model = new_model;
            }

            self._bindings.push(binding);
        };

        for (var module_name in self._moduled) {
            var module = self._moduled[module_name];
            if (!module.bindings) {
                continue;
            }

            for (var bi in module.bindings) {
                _setup_binding(module.bindings[bi]);
            }
        }
    }

    // allow bindings to be turned off per model AFTER createion
    var keystore = require('iotdb').keystore();

    var bs = [];
    self._bindings.map(function (binding) {
        if (keystore.get("/enabled/modules/" + binding.bridge.module_name, true)) {
            bs.push(binding);
        }
    });

    return bs;
};

Modules.prototype._load_setup = function () {
    const self = this;
    var iotdb = require('./iotdb');

    for (var module_name in self._moduled) {
        var module = self._moduled[module_name];
        if (!module.setup) {
            continue;
        }

        try {
            module.setup(iotdb);
        } catch (x) {
            logger.error({
                method: "_load_setup",
                module_name: module_name,
                exception: x,
                cause: "likely the module has a bad setup function",
                error: _.error.message(x),
                stack: x.stack,
            }, "unexpected exception running module.setup");
            process.exit(1);
        }
    }
};

var _modules;

/**
 */
const modules = function () {
    if (!_modules) {
        _modules = new Modules();
    }

    return _modules;
}

/*
 *  API
 */
exports.Modules = Modules;
exports.modules = modules;
<commit_msg>make functional<commit_after>/*
 *  modules.js
 *
 *  David Janes
 *  IOTDB.org
 *  2014-02-16
 *  "Valentines's Day"
 *
 *  Copyright [2013-2016] [David P. Janes]
 *
 *  Installed Module Management / Package Manager
 *
 *  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
 *
 *     http://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.
 */

"use strict";

const _ = require('./helpers');

const model = require('./model');

const events = require('events');
const util = require('util');
const fs = require('fs');
const path = require('path');

const logger = _.logger.make({
    name: 'iotdb',
    module: 'modules',
});

const make = () => {
    const self = Object.assign({}, events.EventEmitter.prototype);
    const iotdb = require("iotdb");

    events.EventEmitter.call(self);
    self.setMaxListeners(0);

    const _moduled = {}
    let _bridges = [];
    let _bindings;

    /**
     *  Return all the Modules that have been registered
     */
    self.modules = () => _.values(this._moduled);

    /**
     *  Manually add another module
     *
     *  <Module>.use is like setup, except that it is only
     *  called if you explicitly use use().
     */
    self.use = function (module_name, module) {
        if (!module) {
            module = require(module_name);
        }

        _moduled[module_name] = module
        _load_bridges();

        if (module.setup) {
            module.setup(iotdb);
        }
        if (module.use) {
            module.use();
        }
    };

    const _load_master = () => {
        var moduled = iotdb.keystore().get("modules");

        _.mapObject(moduled, ( module_folder, module_name) => {
            try {
                var module = require(module_folder);
            } catch (x) {
                logger.error({
                    method: "_load",
                    module_name: module_name,
                    module_folder: module_folder,
                    cause: "likely the module being imported is not set up correctly",
                    error: _.error.message(x),
                    stack: x.stack,
                }, "unexpected exception loading module");
                return;
            }

            module.module_name = module_name;
            module.module_folder = module_folder;

            _moduled[module_name] = module
        });
    };

    const _load_bridges = () => {
        _bridges = _.values(_moduled)
            .filter(module => module.Bridge)
            .map(module => {
                module.Bridge.module_name = module.module_name;
                module.Bridge.bridge_name = _.id.to_dash_case((new module.Bridge()).name());
                return module;
            });
    };

    /**
     *  A module is a complete package of code, corresponding
     *  to an NPM package (which would have been a better name).
     *  A module has one Bridge, one or more Bindings, and
     *  one or more Models
     *

     *  This will return the module with the module_name,
     *  or undefined if not found.
     */
    self.module = (module_name) => self._moduled[module_name];

    /**
     *  The Bridge is the code that knows how to talk to
     *  Things. It can be further parameterized by a Binding.
     *

     *  There is one Bridge per Module (maybe more in the future).
     */
    self.bridges = () => _bridges;

    /**
     *  Find a bridge by the *MODULES* name. For the module
     *  part we don't use the Bridge's self-identified
     *  name except for debug purposes
     */
    self.bridge = function (module_name) {
        const module = _moduled[module_name];

        return module && module.Bridge ? module.Bridge : null;
    };

    const _setup_binding = binding => {
        if (!binding) {
            return;
        } else if (!binding.bridge) {
            return;
        } else if (!binding.model) {
            return;
        }

        if (!_.is.Model(binding.model)) {
            binding.model = model.make_model_from_jsonld(binding.model);
        }

        if (!binding.model_code) {
            binding.model_code = (new binding.model()).code();
        } else {
            /* morph the model's code -- see model_maker */
            binding.model_code = _.id.to_dash_case(binding.model_code);
            var old_model = binding.model;
            var new_model = function() {
                old_model.call(this);
                this.__code = binding.model_code;
            }
            new_model.prototype = new old_model();

            binding.model = new_model;
        }

        return binding;
    }

    const _setup_bindings = () => {
        if (!_bindings) {
            _bindings = _.flatten(_.values(_moduled)
                .filter(module => module.bindings)
                .map(module => module.bindings)
                .map(bindings => bindings.map(_setup_binding)), true);
        }

        return _bindings;
    };

    self.bindings = () => _setup_bindings()
        .filter(binding => iotdb.keystore().get("/enabled/modules/" + binding.bridge.module_name, true));

    const _load_setup = () => _.values(_moduled)
        .filter(module => module.setup)
        .forEach(module => module.setup(iotdb));

    _load_master();
    _load_bridges();
    _load_setup();

    return self;
}

let _modules;

/**
 */
const modules = () => {
    if (!_modules) {
        _modules = make();
    }

    return _modules;
}

/*
 *  API
 */
exports.modules = modules;
<|endoftext|>


<commit_before>/**
 * Created by daniel.irwin on 8/7/16.
 */
module.exports = function(cameras){
    var request = require('request');

    //var Jimp = require('jimp');
    //var badCamera = fs.createReadStream( __dirname + '/nocamera.jpg');

    var buffered = require('buffered-stream');

    function calcBaseUrl(camera) {
        return 'http://' + camera.ip + ':' + camera.port;
    }

    function getCamera(cameraFinder, cb){

        var theCamera = cameras.filter((camera) => {
            var port = camera.port;
            if(typeof cameraFinder.name === 'string'){
                return cameraFinder.name === camera.name;
            }
            if(cameraFinder.port && isNaN(cameraFinder.port)){
                port = parseInt(cameraFinder.port);
            }
            return camera.ip === cameraFinder.ip && camera.port === port;
        });

        if(theCamera && theCamera.length > 0){
            return cb(undefined, theCamera[0]);
        }
        cb('no camera found');
    }

    function saveProxyStream(camera, stream){
        if(!camera.proxyStream){
            //function restartProxy(){
            //    camera.proxyStream = proxyVideo(camera);
            //}
            //
            //camera.proxyStream = stream;
            //stream.on('close',  restartProxy);
            //stream.on('end',    restartProxy);
            //stream.on('finish', restartProxy);
            //stream.on('error',  restartProxy);
        }
        return stream;
    }

    var pool = { maxSockets : 15 };

    function ptzRequestOpts(camera) {
        var basicAuth = 'Basic ' + (new Buffer(camera.username + ':' + camera.password, 'utf8')).toString('base64');
        console.log('basicAuth', basicAuth);
        return {
            pool : pool,
            agent : false,
            timeout : 25000,
            forever : true,
            headers : {
                Authorization : basicAuth
            }
        };
    }

    function loadCamera(camera){
        proxyVideoAndSave(camera);
    }

    function proxyVideoAndSave(camera){
        return saveProxyStream(camera, proxyVideo(camera, true));
    }

    function proxyVideo(camera, ignoreSavedStream){
        var url = calcBaseUrl(camera) + camera.video;
        if(camera.proxyStream && !ignoreSavedStream){
            return camera.proxyStream;
        }

        var buffer = buffered(128*1024*1024);
        return request.get(url, ptzRequestOpts(camera)).pipe(buffer);
    }

    function proxySnapshot(camera, res){
        var start = new Date().getTime();

        var uri = calcBaseUrl(camera) + camera.snapshot;
        var reqOpts = ptzRequestOpts(camera);

        console.log('uri', uri, 'reqOpts', reqOpts);

        var proxy = request(uri, reqOpts, function cb(err, response){
            if(err) {
                console.log('err', err);
                return res.json({
                    err : err
                });
            }

            var end = new Date().getTime();
            console.log('firstbyte', end-start);
        });

        proxy.on('end', function () {
            var end = new Date().getTime();
            console.log('total', end-start);
        });

        var buffer = buffered(128*1024*1024);

        proxy.pipe(buffer).pipe(res);

        proxy.on('error', function(err){
            console.log('err', err);
        });
    }

    function proxyAudio(camera){
        var buffer = buffered(128*1024*1024);
        return request.get(calcBaseUrl(camera) + camera.audio, ptzRequestOpts(camera)).pipe(buffer);
    }

    function ptz(camera, action){
        return request.get(calcBaseUrl(camera) + camera.ptz[action], ptzRequestOpts(camera));
    }

    function loadCameras() {
        cameras.forEach((cam) => {
            loadCamera(cam);
        });
    }

    loadCameras();

    function setCameras(input){
        cameras = input;
        loadCameras();
    }

    return {
        setCameras : setCameras,
        getCamera : getCamera,
        proxyVideo : proxyVideo,
        proxyAudio: proxyAudio,
        proxySnapshot : proxySnapshot,
        ptz : ptz
    };
};<commit_msg>removing buffer from all but snapshot and reducing size<commit_after>/**
 * Created by daniel.irwin on 8/7/16.
 */
module.exports = function(cameras){
    var request = require('request');

    //var Jimp = require('jimp');
    //var badCamera = fs.createReadStream( __dirname + '/nocamera.jpg');

    var buffered = require('buffered-stream');

    function calcBaseUrl(camera) {
        return 'http://' + camera.ip + ':' + camera.port;
    }

    function getCamera(cameraFinder, cb){

        var theCamera = cameras.filter((camera) => {
            var port = camera.port;
            if(typeof cameraFinder.name === 'string'){
                return cameraFinder.name === camera.name;
            }
            if(cameraFinder.port && isNaN(cameraFinder.port)){
                port = parseInt(cameraFinder.port);
            }
            return camera.ip === cameraFinder.ip && camera.port === port;
        });

        if(theCamera && theCamera.length > 0){
            return cb(undefined, theCamera[0]);
        }
        cb('no camera found');
    }

    function saveProxyStream(camera, stream){
        if(!camera.proxyStream){
            //function restartProxy(){
            //    camera.proxyStream = proxyVideo(camera);
            //}
            //
            //camera.proxyStream = stream;
            //stream.on('close',  restartProxy);
            //stream.on('end',    restartProxy);
            //stream.on('finish', restartProxy);
            //stream.on('error',  restartProxy);
        }
        return stream;
    }

    var pool = { maxSockets : 15 };

    function ptzRequestOpts(camera) {
        var basicAuth = 'Basic ' + (new Buffer(camera.username + ':' + camera.password, 'utf8')).toString('base64');
        console.log('basicAuth', basicAuth);
        return {
            pool : pool,
            agent : false,
            timeout : 25000,
            forever : true,
            headers : {
                Authorization : basicAuth
            }
        };
    }

    function loadCamera(camera){
        proxyVideoAndSave(camera);
    }

    function proxyVideoAndSave(camera){
        return saveProxyStream(camera, proxyVideo(camera, true));
    }

    function proxyVideo(camera, ignoreSavedStream){
        var url = calcBaseUrl(camera) + camera.video;
        if(camera.proxyStream && !ignoreSavedStream){
            return camera.proxyStream;
        }

        return request.get(url, ptzRequestOpts(camera));
    }

    function proxySnapshot(camera, res){
        var start = new Date().getTime();

        var uri = calcBaseUrl(camera) + camera.snapshot;
        var reqOpts = ptzRequestOpts(camera);

        console.log('uri', uri, 'reqOpts', reqOpts);

        var proxy = request(uri, reqOpts, function cb(err, response){
            if(err) {
                console.log('err', err);
                return res.json({
                    err : err
                });
            }

            var end = new Date().getTime();
            console.log('firstbyte', end-start);
        });

        proxy.on('end', function () {
            var end = new Date().getTime();
            console.log('total', end-start);
        });

        var buffer = buffered(16*1024*1024);

        proxy.pipe(buffer).pipe(res);

        proxy.on('error', function(err){
            console.log('err', err);
        });
    }

    function proxyAudio(camera){
        return request.get(calcBaseUrl(camera) + camera.audio, ptzRequestOpts(camera));
    }

    function ptz(camera, action){
        return request.get(calcBaseUrl(camera) + camera.ptz[action], ptzRequestOpts(camera));
    }

    function loadCameras() {
        cameras.forEach((cam) => {
            loadCamera(cam);
        });
    }

    loadCameras();

    function setCameras(input){
        cameras = input;
        loadCameras();
    }

    return {
        setCameras : setCameras,
        getCamera : getCamera,
        proxyVideo : proxyVideo,
        proxyAudio: proxyAudio,
        proxySnapshot : proxySnapshot,
        ptz : ptz
    };
};<|endoftext|>


<commit_before>app.controller('MainController', ['$scope', function($scope) {
  $scope.jobs = [
                  {
                    startdate: '01/2014',
                    enddate:'01/2017',
                    company:'Centient',
                    title:'Developer',
                    text:'Developing the front end of a web application using jQuery, javascript, CSS and HTML. I added new forms and sections of the site based on features added at the backend. The new system used a custom Freemarker Template Language (FTL) engine as well as a REST API. I used GIT, Stash and JIRA to keep track of issues and updates. Liaising with other developers in charge of different sections of the site (backend and collectors). Testing the system to ensure it worked as intended. From November 2015 I worked remotely from home, interacting with colleagues through Skype, Hipchat and emails.'
                  },
                  {
                    startdate:'09/2013',
                    enddate:'01/2014',
                    company:'Centient',
                    title:'Security Analyst',
                    text:'Using in house software to identify threats to clients. As well as viewing closed off forums and websites that search engines can’t find. During this time the old system was replaced and an external company was brought in to quickly build a new front end. There wasn’t much front end work to be done so I was shifted about the company into whatever role they needed me. I was involved in meeting the external company developers and had a say in the development.'
                  },
                  {
                    startdate:'04/2013',
                    enddate:'09/2013',
                    company:'Centient (previously Cybyl)',
                    title:'Developer',
                    text:' I worked with Python and Django as the old system was assessed for suitability. The old system used Beautiful Soup, Bootstrap, Websockets, and MongoDB. I helped plan the new system and learnt about possible technologies that it could use, such as various database systems and their uses. (MySQL, Oracle, PostGreSQL, MongoDB). I also learnt some Java.'
                  },
                  {
                    startdate:'09/2011',
                    enddate:'09/2013',
                    company:'Cybyl',
                    title:'Cyber Threat Analyst',
                    text:'Monitoring alerts/notifications and writing client facing reports to inform them of intelligence relevant to their sector of operation or directly to the client’s brand, such as phishing campaigns and planned action by hostile factions. Investigating network based threats by reconstructing activity using http headers, response bodies and volatile session information and any resources such as files which might contain useful metadata. Analysis of scripts/sourcecode/binaries found via secondary detection systems to determine its purpose and any inherent threat to clients. Creating Regular Expressions for use in software to identify threats to clients. This role involved shift work.'
                  },
                  {
                    startdate:'04/2003',
                    enddate:'08/2008',
                    company:'Smurfit Kappa West Auckland',
                    title:'Quality Assistant',
                    text:'Collecting machine performance data and updating spreadsheets. Issuing complaints and arranging returns of rejections. Updating the calibration system and document control. Auditing procedures as part of an audit team. General administration duties.'
                  },
                  {
                    startdate:'01/2002',
                    enddate:'04/2003',
                    company:'Teesdale Training',
                    title:'Trainee',
                    text:'Helped out at the Training Centre – looking after IT classes, working on evidence for NVQ Using IT and general office work e.g. photocopying, typing, putting together booklets and making posters.'
                  },
                  {
                    startdate:'10/2001',
                    enddate:'01/2002',
                    company:'Comtek',
                    title:'Shop Assistant',
                    text:'Dealt with customers in the shop. Solved computer problems, received training in various areas of IT. Built computers to specification. '
                  }
                ];
  $scope.skills = [
                  {
                    skill:'HTML',
                    time: '5+ Years',
                    hobby: 'Yes',
                    university: 'Yes',
                    work: 'Yes'
                  },
                  {
                    skill:'Javascript',
                    time: 'Roughly 4 years',
                    hobby: 'No',
                    university: 'Yes',
                    work: 'Yes'
                  },
                  {
                    skill:'jQuery',
                    time: 'Roughly 4 years',
                    hobby: 'No',
                    university: 'Yes',
                    work: 'Yes'
                  },
                  {
                    skill:'CSS',
                    time: 'Roughly 4 years',
                    hobby: 'Yes',
                    university: 'Yes',
                    work: 'Yes'
                  },
                  {
                    skill:'Perl',
                    time: '2 Years',
                    hobby: 'No',
                    university: 'Yes',
                    work: 'Yes'
                  },
                  {
                    skill:'PHP',
                    time: '6 Months',
                    hobby: 'No',
                    university: 'Yes',
                    work: 'No'
                  },
                  {
                    skill:'Python',
                    time: '6 Months',
                    hobby: 'No',
                    university: 'No',
                    work: 'Yes'
                  },
                  {
                    skill:'Django',
                    time: '6 Months',
                    hobby: 'No',
                    university: 'No',
                    work: 'Yes'
                  }
];
  $scope.qualifications = [
                  {
                    startdate: '09/2008',
                    enddate: '07/2011',
                    name: 'Digital Forensics 2:1 at Teesside University'
                  },
                  {
                    startdate: '2005',
                    enddate: '2006',
                    name: 'Business and Administration Advanced Apprenticeship'
                  },
                  {
                    startdate: '01/2004',
                    enddate: '06/2004',
                    name: 'Quality Diploma Unit D3 Tools and Techniques'
                  },
                  {
                    startdate: '2004',
                    enddate: '2004',
                    name: 'Certificate in Internal Quality Auditing'
                  },
                  {
                    startdate: '10/2001',
                    enddate: '04/2003',
                    name: 'NVQ Level 3 Using IT'
                  },
                  {
                    startdate: '09/1999',
                    enddate: '07/2001',
                    name: 'GNVQ Advanced Information Technology'
                  }

  ];

}]);

app.controller('ContactController', function ($scope, $http) {
    $scope.result = 'hidden'
    $scope.resultMessage;
    $scope.formData; //formData is an object holding the name, email, subject, and message
    $scope.submitButtonDisabled = false;
    $scope.submitted = false; //used so that form errors are shown only after the form has been submitted
    $scope.submit = function(contactform) {
        $scope.submitted = true;
        $scope.submitButtonDisabled = true;
        if (contactform.$valid) {
            $http({
                method  : 'POST',
                url     : 'php/formprocess.php',
                data    : $.param($scope.formData),  //param method from jQuery
                headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  //set the headers so angular passing info as form data (not request payload)
            }).success(function(data){
                console.log(data);
                if (data.success) { //success comes from the return json object
                    $scope.submitButtonDisabled = true;
                    $scope.resultMessage = data.message;
                    $scope.result='bg-success';
                } else {
                    $scope.submitButtonDisabled = false;
                    $scope.resultMessage = data.message;
                    $scope.result='bg-danger';
                }
            });
        } else {
            $scope.submitButtonDisabled = false;
            $scope.resultMessage = 'Failed :( Please fill out all the fields.';
            $scope.result='bg-danger';
        }
    }
});
<commit_msg>Minor text fix<commit_after>app.controller('MainController', ['$scope', function($scope) {
  $scope.jobs = [
                  {
                    startdate: '01/2014',
                    enddate:'01/2017',
                    company:'Centient',
                    title:'Developer',
                    text:'Developing the front end of a web application using jQuery, javascript, CSS and HTML. I added new forms and sections of the site based on features added at the backend. The new system used a custom Freemarker Template Language (FTL) engine as well as a REST API. I used GIT, Stash and JIRA to keep track of issues and updates. Liaising with other developers in charge of different sections of the site (backend and collectors). Testing the system to ensure it worked as intended. From November 2015 I worked remotely from home, interacting with colleagues through Skype, Hipchat and emails.'
                  },
                  {
                    startdate:'09/2013',
                    enddate:'01/2014',
                    company:'Centient',
                    title:'Security Analyst',
                    text:'Using in house software to identify threats to clients. As well as viewing closed off forums and websites that search engines can’t find. During this time the old system was replaced and an external company was brought in to quickly build a new front end. There wasn’t much front end work to be done so I was shifted about the company into whatever role they needed me. I was involved in meeting the external company developers and had a say in the development.'
                  },
                  {
                    startdate:'04/2013',
                    enddate:'09/2013',
                    company:'Centient (previously Cybyl)',
                    title:'Developer',
                    text:' I worked with Python and Django as the old system was assessed for suitability. The old system used Beautiful Soup, Bootstrap, Websockets, and MongoDB. I helped plan the new system and learnt about possible technologies that it could use, such as various database systems and their uses. (MySQL, Oracle, PostGreSQL, MongoDB). I also learnt some Java.'
                  },
                  {
                    startdate:'09/2011',
                    enddate:'04/2013',
                    company:'Cybyl',
                    title:'Cyber Threat Analyst',
                    text:'Monitoring alerts/notifications and writing client facing reports to inform them of intelligence relevant to their sector of operation or directly to the client’s brand, such as phishing campaigns and planned action by hostile factions. Investigating network based threats by reconstructing activity using http headers, response bodies and volatile session information and any resources such as files which might contain useful metadata. Analysis of scripts/sourcecode/binaries found via secondary detection systems to determine its purpose and any inherent threat to clients. Creating Regular Expressions for use in software to identify threats to clients. This role involved shift work.'
                  },
                  {
                    startdate:'04/2003',
                    enddate:'08/2008',
                    company:'Smurfit Kappa West Auckland',
                    title:'Quality Assistant',
                    text:'Collecting machine performance data and updating spreadsheets. Issuing complaints and arranging returns of rejections. Updating the calibration system and document control. Auditing procedures as part of an audit team. General administration duties.'
                  },
                  {
                    startdate:'01/2002',
                    enddate:'04/2003',
                    company:'Teesdale Training',
                    title:'Trainee',
                    text:'Helped out at the Training Centre – looking after IT classes, working on evidence for NVQ Using IT and general office work e.g. photocopying, typing, putting together booklets and making posters.'
                  },
                  {
                    startdate:'10/2001',
                    enddate:'01/2002',
                    company:'Comtek',
                    title:'Shop Assistant',
                    text:'Dealt with customers in the shop. Solved computer problems, received training in various areas of IT. Built computers to specification. '
                  }
                ];
  $scope.skills = [
                  {
                    skill:'HTML',
                    time: '5+ Years',
                    hobby: 'Yes',
                    university: 'Yes',
                    work: 'Yes'
                  },
                  {
                    skill:'Javascript',
                    time: 'Roughly 4 years',
                    hobby: 'No',
                    university: 'Yes',
                    work: 'Yes'
                  },
                  {
                    skill:'jQuery',
                    time: 'Roughly 4 years',
                    hobby: 'No',
                    university: 'Yes',
                    work: 'Yes'
                  },
                  {
                    skill:'CSS',
                    time: 'Roughly 4 years',
                    hobby: 'Yes',
                    university: 'Yes',
                    work: 'Yes'
                  },
                  {
                    skill:'Perl',
                    time: '2 Years',
                    hobby: 'No',
                    university: 'Yes',
                    work: 'Yes'
                  },
                  {
                    skill:'PHP',
                    time: '6 Months',
                    hobby: 'No',
                    university: 'Yes',
                    work: 'No'
                  },
                  {
                    skill:'Python',
                    time: '6 Months',
                    hobby: 'No',
                    university: 'No',
                    work: 'Yes'
                  },
                  {
                    skill:'Django',
                    time: '6 Months',
                    hobby: 'No',
                    university: 'No',
                    work: 'Yes'
                  }
];
  $scope.qualifications = [
                  {
                    startdate: '09/2008',
                    enddate: '07/2011',
                    name: 'Digital Forensics 2:1 at Teesside University'
                  },
                  {
                    startdate: '2005',
                    enddate: '2006',
                    name: 'Business and Administration Advanced Apprenticeship'
                  },
                  {
                    startdate: '01/2004',
                    enddate: '06/2004',
                    name: 'Quality Diploma Unit D3 Tools and Techniques'
                  },
                  {
                    startdate: '2004',
                    enddate: '2004',
                    name: 'Certificate in Internal Quality Auditing'
                  },
                  {
                    startdate: '10/2001',
                    enddate: '04/2003',
                    name: 'NVQ Level 3 Using IT'
                  },
                  {
                    startdate: '09/1999',
                    enddate: '07/2001',
                    name: 'GNVQ Advanced Information Technology'
                  }

  ];

}]);

app.controller('ContactController', function ($scope, $http) {
    $scope.result = 'hidden'
    $scope.resultMessage;
    $scope.formData; //formData is an object holding the name, email, subject, and message
    $scope.submitButtonDisabled = false;
    $scope.submitted = false; //used so that form errors are shown only after the form has been submitted
    $scope.submit = function(contactform) {
        $scope.submitted = true;
        $scope.submitButtonDisabled = true;
        if (contactform.$valid) {
            $http({
                method  : 'POST',
                url     : 'php/formprocess.php',
                data    : $.param($scope.formData),  //param method from jQuery
                headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  //set the headers so angular passing info as form data (not request payload)
            }).success(function(data){
                console.log(data);
                if (data.success) { //success comes from the return json object
                    $scope.submitButtonDisabled = true;
                    $scope.resultMessage = data.message;
                    $scope.result='bg-success';
                } else {
                    $scope.submitButtonDisabled = false;
                    $scope.resultMessage = data.message;
                    $scope.result='bg-danger';
                }
            });
        } else {
            $scope.submitButtonDisabled = false;
            $scope.resultMessage = 'Failed :( Please fill out all the fields.';
            $scope.result='bg-danger';
        }
    }
});
<|endoftext|>