<commit_before>'use strict';

// general dependencies
var gulp = require('gulp');
var config = require('../config');
var concat = require('gulp-concat');
var inject = require('gulp-inject');
var _ = require('lodash');
var bowerFiles = require('main-bower-files');

// js dependencies
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
var annotate = require('gulp-ng-annotate');

// templates dependencies
var html2js = require('gulp-ng-html2js');

// scss dependencies
var sass = require('gulp-sass');

function moveAssets() {
  return gulp.src(config.paths.assets)
    .pipe(gulp.dest(config.paths.dest));
}

function buildStylesVendor() {
  return gulp.src(bowerFiles({
      filter: /.*\.css$/,
    }))
    .pipe(concat('vendor.css'))
    .pipe(gulp.dest(config.paths.dest));
}

function buildStyles() {
  return gulp.src(config.paths.scss)
    .pipe(sass().on('error', sass.logError))
    .pipe(gulp.dest(config.paths.dest));
}

function buildTemplates () {
  return gulp.src(config.paths.templates)
    .pipe(html2js({
      moduleName: 'templates',
    }))
    .pipe(concat('templates.js'))
    .pipe(gulp.dest(config.paths.dest));
}

function buildVendor () {
  return gulp.src(bowerFiles({
      filter: /.*\.js$/,
    }))
    .pipe(concat('vendor.js'))
    .pipe(gulp.dest(config.paths.dest))
}

function buildApp () {
  return browserify(config.paths.js, {
    debug: true,
  })
  .transform(babelify)
  .bundle()
  .on('error', console.error)
  .pipe(source('application.js'))
  .pipe(annotate())
  .pipe(gulp.dest(config.paths.dest));
}

var INJECT_OPTIONS = {
  ignorePath: config.paths.dest,
  addRootSlash: false,
};

module.exports = function() {
  return gulp.src(config.paths.index)
    .pipe(inject(buildStylesVendor(), _.merge({ name: 'vendor' }, INJECT_OPTIONS)))
    .pipe(inject(buildStyles(), INJECT_OPTIONS))
    .pipe(inject(buildVendor(), _.merge({ name: 'vendor'}, INJECT_OPTIONS)))
    .pipe(inject(buildTemplates(), _.merge({ name: 'templates' }, INJECT_OPTIONS)))
    .pipe(inject(buildApp(), INJECT_OPTIONS))
    .pipe(gulp.dest(config.paths.dest))
    .pipe(moveAssets());
};
<commit_msg>settings for annotate<commit_after>'use strict';

// general dependencies
var gulp = require('gulp');
var config = require('../config');
var concat = require('gulp-concat');
var inject = require('gulp-inject');
var _ = require('lodash');
var bowerFiles = require('main-bower-files');

// js dependencies
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
var annotate = require('gulp-ng-annotate');

// templates dependencies
var html2js = require('gulp-ng-html2js');

// scss dependencies
var sass = require('gulp-sass');

function moveAssets() {
  return gulp.src(config.paths.assets)
    .pipe(gulp.dest(config.paths.dest));
}

function buildStylesVendor() {
  return gulp.src(bowerFiles({
      filter: /.*\.css$/,
    }))
    .pipe(concat('vendor.css'))
    .pipe(gulp.dest(config.paths.dest));
}

function buildStyles() {
  return gulp.src(config.paths.scss)
    .pipe(sass().on('error', sass.logError))
    .pipe(gulp.dest(config.paths.dest));
}

function buildTemplates () {
  return gulp.src(config.paths.templates)
    .pipe(html2js({
      moduleName: 'templates',
    }))
    .pipe(concat('templates.js'))
    .pipe(gulp.dest(config.paths.dest));
}

function buildVendor () {
  return gulp.src(bowerFiles({
      filter: /.*\.js$/,
    }))
    .pipe(concat('vendor.js'))
    .pipe(gulp.dest(config.paths.dest))
}

function buildApp () {
  return browserify(config.paths.js, {
    debug: true,
  })
  .transform(babelify)
  .bundle()
  .on('error', console.error)
  .pipe(source('application.js'))
  .pipe(annotate({
    add: true,
    remove: true,
    single_quotes: true,
  }).on('error', function (err) {
    sass.logError(err.toString());
    this.emit('end');
  }))
  .pipe(gulp.dest(config.paths.dest));
}

var INJECT_OPTIONS = {
  ignorePath: config.paths.dest,
  addRootSlash: false,
};

module.exports = function() {
  return gulp.src(config.paths.index)
    .pipe(inject(buildStylesVendor(), _.merge({ name: 'vendor' }, INJECT_OPTIONS)))
    .pipe(inject(buildStyles(), INJECT_OPTIONS))
    .pipe(inject(buildVendor(), _.merge({ name: 'vendor'}, INJECT_OPTIONS)))
    .pipe(inject(buildTemplates(), _.merge({ name: 'templates' }, INJECT_OPTIONS)))
    .pipe(inject(buildApp(), INJECT_OPTIONS))
    .pipe(gulp.dest(config.paths.dest))
    .pipe(moveAssets());
};
<|endoftext|>


<commit_before>describe("About Arrays", function() {

  //We shall contemplate truth by testing reality, via spec expectations.
  it("should create arrays", function() {
    var emptyArray = [];
    expect(typeof(emptyArray)).toBe("object"); //A mistake? - http:javascript.crockford.com/remedial.html
    expect(emptyArray.length).toBe(0);

    var multiTypeArray = [0, 1, "two", function () { return 3; }, {value1: 4, value2: 5}, [6, 7]];
    expect(multiTypeArray[0]).toBe(0);
    expect(multiTypeArray[2]).toBe("two");
    expect(multiTypeArray[3]()).toBe(3);
    expect(multiTypeArray[4].value1).toBe(4);
    expect(multiTypeArray[4]["value2"]).toBe(5);
    expect(multiTypeArray[5][0]).toBe(6);
  });

  it("should understand array literals", function () {
    var array = [];
    expect(array).toEqual([]);

    array[0] = 1;
    expect(array).toEqual([1]);

    array[1] = 2;
    expect(array).toEqual([1, 2]);

    array.push(3);
    expect(array).toEqual([1, 2, 3]);
  });

  it("should understand array length", function () {
    var fourNumberArray = [1, 2, 3, 4];

    expect(fourNumberArray.length).toBe(4);
    fourNumberArray.push(5, 6);
    expect(fourNumberArray.length).toBe(6);

    var tenEmptyElementArray = new Array(10);
    expect(tenEmptyElementArray.length).toBe(10);

    tenEmptyElementArray.length = 5;
    expect(tenEmptyElementArray.length).toBe(5);
  });

  it("should slice arrays", function () {
    var array = ["peanut", "butter", "and", "jelly"];

    expect(array.slice(0, 1)).toEqual(FILL_ME_IN);
    expect(array.slice(0, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 20)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 0)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 100)).toEqual(FILL_ME_IN);
    expect(array.slice(5, 1)).toEqual(FILL_ME_IN);
  });

  it("should know array references", function () {
    var array = [ "zero", "one", "two", "three", "four", "five" ];

    function passedByReference(refArray) {
      refArray[1] = "changed in function";
    }
    passedByReference(array);
    expect(array[1]).toBe(FILL_ME_IN);

    var assignedArray = array;
    assignedArray[5] = "changed in assignedArray";
    expect(array[5]).toBe(FILL_ME_IN);

    var copyOfArray = array.slice();
    copyOfArray[3] = "changed in copyOfArray";
    expect(array[3]).toBe(FILL_ME_IN);
  });

  it("should push and pop", function () {
    var array = [1, 2];
    array.push(3);

    expect(array).toEqual(FILL_ME_IN);

    var poppedValue = array.pop();
    expect(poppedValue).toBe(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });

  it("should know about shifting arrays", function () {
    var array = [1, 2];

    array.unshift(3);
    expect(array).toEqual(FILL_ME_IN);

    var shiftedValue = array.shift();
    expect(shiftedValue).toEqual(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });
});
<commit_msg>AboutArray.js part 4<commit_after>describe("About Arrays", function() {

  //We shall contemplate truth by testing reality, via spec expectations.
  it("should create arrays", function() {
    var emptyArray = [];
    expect(typeof(emptyArray)).toBe("object"); //A mistake? - http:javascript.crockford.com/remedial.html
    expect(emptyArray.length).toBe(0);

    var multiTypeArray = [0, 1, "two", function () { return 3; }, {value1: 4, value2: 5}, [6, 7]];
    expect(multiTypeArray[0]).toBe(0);
    expect(multiTypeArray[2]).toBe("two");
    expect(multiTypeArray[3]()).toBe(3);
    expect(multiTypeArray[4].value1).toBe(4);
    expect(multiTypeArray[4]["value2"]).toBe(5);
    expect(multiTypeArray[5][0]).toBe(6);
  });

  it("should understand array literals", function () {
    var array = [];
    expect(array).toEqual([]);

    array[0] = 1;
    expect(array).toEqual([1]);

    array[1] = 2;
    expect(array).toEqual([1, 2]);

    array.push(3);
    expect(array).toEqual([1, 2, 3]);
  });

  it("should understand array length", function () {
    var fourNumberArray = [1, 2, 3, 4];

    expect(fourNumberArray.length).toBe(4);
    fourNumberArray.push(5, 6);
    expect(fourNumberArray.length).toBe(6);

    var tenEmptyElementArray = new Array(10);
    expect(tenEmptyElementArray.length).toBe(10);

    tenEmptyElementArray.length = 5;
    expect(tenEmptyElementArray.length).toBe(5);
  });

  it("should slice arrays", function () {
    var array = ["peanut", "butter", "and", "jelly"];

    expect(array.slice(0, 1)).toEqual(["peanut"]);
    expect(array.slice(0, 2)).toEqual(["peanut","butter"]);
    expect(array.slice(2, 2)).toEqual([]);
    expect(array.slice(2, 20)).toEqual(["and", "jelly"]);
    expect(array.slice(3, 0)).toEqual([]);
    expect(array.slice(3, 100)).toEqual(["jelly"]);
    expect(array.slice(5, 1)).toEqual([]);
  });

  it("should know array references", function () {
    var array = [ "zero", "one", "two", "three", "four", "five" ];

    function passedByReference(refArray) {
      refArray[1] = "changed in function";
    }
    passedByReference(array);
    expect(array[1]).toBe(FILL_ME_IN);

    var assignedArray = array;
    assignedArray[5] = "changed in assignedArray";
    expect(array[5]).toBe(FILL_ME_IN);

    var copyOfArray = array.slice();
    copyOfArray[3] = "changed in copyOfArray";
    expect(array[3]).toBe(FILL_ME_IN);
  });

  it("should push and pop", function () {
    var array = [1, 2];
    array.push(3);

    expect(array).toEqual(FILL_ME_IN);

    var poppedValue = array.pop();
    expect(poppedValue).toBe(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });

  it("should know about shifting arrays", function () {
    var array = [1, 2];

    array.unshift(3);
    expect(array).toEqual(FILL_ME_IN);

    var shiftedValue = array.shift();
    expect(shiftedValue).toEqual(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });
});
<|endoftext|>


<commit_before>// This command stores any string/username [value] for with the user's id [key]
// Anyone can recall another user's key if they wish
// The main purpose is to store the your username for swgoh.gg so that anyone
// can easily access quick information

const swgoh = require("swgoh").swgoh;
const moment = require("moment");
const { RichEmbed } = require("discord.js");
const register = require("./register.js");
const adduser = require("./adduser.js");

exports.run = async (client, message, cmd, args, level) => { // eslint-disable-line no-unused-vars

    try {

        // If they want to edit their stored swgoh.gg username, we'll let them here
        if (args[0] === "add" || args[0] === "edit" || args[0] === "register") {

            // Remove the "add" or "edit"
            args = args.slice(1);

            // Now either run register or adduser commands
            if (args.length === 1) register.run(client, message, cmd, args, level);
            else if (args.length > 1) adduser.run(client, message, cmd, args, level);
            else client.cmdError(message, cmd);

            return;
        }
    } catch (error) {
        client.errlog(cmd, message, level, error);
        client.logger.error(`Error offloading profile command to register:\n${error.stack}`);
    }

    try {

        // Now we actually execute the profile command

        const [username, empty, error] = await client.profileCheck(message, args); // eslint-disable-line prefer-const, no-unused-vars
        if (username === undefined) return await message.reply(error).then(client.cmdError(message, cmd));

        // The courtious "checking" message while the user waits
        const profileMessage = await message.channel.send("Checking... One moment. 👀");

        // Here we pull the profile data from swgoh.gg
        const profile = await swgoh.profile(username);

        if (profile === undefined || profile.userId === undefined) return await profileMessage.edit("I can't find a profile for that username").then(client.cmdError(message, cmd));

        // Some user's don't submit thier profile codes on swgoh.gg, if that's the
        // case, lets not display (undefined) next to their name
        let title = `${profile.username}'s Profile (${profile.allyCode})`;
        const guildName = profile.guildUrl.split("/")[3].replace(/-/g, " ").toProperCase();
        const lastUpdated = moment(profile.lastUpdatedUTC).fromNow();
        if (message.profile.allycode === undefined) title = profile.username;

        let embed = null;

        // We have two options for sending the embed:
        // The first option is with percentages
        // This will only send if "%" is in the args
        if (args.includes("%")) {
            embed = new RichEmbed()
                .setTitle(title)
                .setColor(0x268BD2)
                .setURL(`https://swgoh.gg/u/${encodeURI(username)}/`)
                .setDescription(`Level ${profile.level}
**Guild**: ${guildName}
**Collection Score:** ${profile.collectionScore}
**Arena Rank:** ${profile.arenaRank.toLocaleString()}`
                )
                .addField("Galactic Power (% based on Overall)",
                    `\`\`\`asciidoc
Overall   :: ${profile.galacticPower.toLocaleString()}
Character :: ${profile.charactersGalacticPower.toLocaleString()} (${(profile.charactersGalacticPower / profile.galacticPower * 100).toFixed(1)}%)
Ship      :: ${profile.shipsGalacticPower.toLocaleString()} (${(profile.shipsGalacticPower / profile.galacticPower * 100).toFixed(1)}%)\`\`\``,
                    false
                )
                .addField("Characters (% based on Unlocked)",
                    `\`\`\`asciidoc
Unlocked  :: ${profile.characters}
7 star    :: ${profile.characters7} (${(profile.characters7 / profile.characters * 100).toFixed(1)}%)
6 star    :: ${profile.characters6} (${(profile.characters6 / profile.characters * 100).toFixed(1)}%)
Gear 12   :: ${profile.gearXII} (${(profile.gearXII / profile.characters * 100).toFixed(1)}%)
Gear 11   :: ${profile.gearXI} (${(profile.gearXI / profile.characters * 100).toFixed(1)}%)
Gear 10   :: ${profile.gearX} (${(profile.gearX / profile.characters * 100).toFixed(1)}%)\`\`\``,
                    false
                )
                .setFooter(`Last updated ${lastUpdated}`, "https://swgoh.gg/static/img/bb8.png");
        }

        // The second option is without percentages
        // this is the default embed
        else {
            embed = new RichEmbed()
                .setTitle(title)
                .setColor(0x268BD2)
                .setURL(`https://swgoh.gg/u/${encodeURI(username)}/`)
                .setDescription(`Level ${profile.level}
**Guild**: ${guildName}
**Collection Score:** ${profile.collectionScore}
**Arena Rank:** ${profile.arenaRank.toLocaleString()}`
                )
                .addField("Galactic Power",
                    `\`\`\`asciidoc
Overall   :: ${profile.galacticPower.toLocaleString()}
Character :: ${profile.charactersGalacticPower.toLocaleString()}
Ship      :: ${profile.shipsGalacticPower.toLocaleString()}\`\`\``,
                    false
                )
                .addField("Characters",
                    `\`\`\`asciidoc
Unlocked  :: ${profile.characters}
7 star    :: ${profile.characters7}
6 star    :: ${profile.characters6}
Gear 12   :: ${profile.gearXII}
Gear 11   :: ${profile.gearXI}
Gear 10   :: ${profile.gearX}\`\`\``,
                    false
                )
                .setFooter(`Last updated ${lastUpdated} | For percentages use ${message.settings.prefix}p %`, "https://swgoh.gg/static/img/bb8.png");
        }

        await profileMessage.edit({embed});

    } catch (error) {
        client.errlog(cmd, message, level, error);
        client.logger.error(client, `profile command failure:\n${error.stack}`);
        client.codeError(message);
    }

};

exports.conf = {
    enabled: true,
    guildOnly: false,
    aliases: ["profiles", "p"],
    arguments: ["%", "user mention"],
    permLevel: "User"
};

exports.help = {
    name: "profile",
    category: "Game",
    description: "Returns swgoh.gg stats of specified/mentioned user",
    usage: "profile",
    examples: ["p", "p %", "p @Necavit#0540 %"]
};
<commit_msg>removed guild name<commit_after>// This command stores any string/username [value] for with the user's id [key]
// Anyone can recall another user's key if they wish
// The main purpose is to store the your username for swgoh.gg so that anyone
// can easily access quick information

const swgoh = require("swgoh").swgoh;
const moment = require("moment");
const { RichEmbed } = require("discord.js");
const register = require("./register.js");
const adduser = require("./adduser.js");

exports.run = async (client, message, cmd, args, level) => { // eslint-disable-line no-unused-vars

    try {

        // If they want to edit their stored swgoh.gg username, we'll let them here
        if (args[0] === "add" || args[0] === "edit" || args[0] === "register") {

            // Remove the "add" or "edit"
            args = args.slice(1);

            // Now either run register or adduser commands
            if (args.length === 1) register.run(client, message, cmd, args, level);
            else if (args.length > 1) adduser.run(client, message, cmd, args, level);
            else client.cmdError(message, cmd);

            return;
        }
    } catch (error) {
        client.errlog(cmd, message, level, error);
        client.logger.error(`Error offloading profile command to register:\n${error.stack}`);
    }

    try {

        // Now we actually execute the profile command

        const [username, empty, error] = await client.profileCheck(message, args); // eslint-disable-line prefer-const, no-unused-vars
        if (username === undefined) return await message.reply(error).then(client.cmdError(message, cmd));

        // The courtious "checking" message while the user waits
        const profileMessage = await message.channel.send("Checking... One moment. 👀");

        // Here we pull the profile data from swgoh.gg
        const profile = await swgoh.profile(username);

        if (profile === undefined || profile.userId === undefined) return await profileMessage.edit("I can't find a profile for that username").then(client.cmdError(message, cmd));

        // Some user's don't submit thier profile codes on swgoh.gg, if that's the
        // case, lets not display (undefined) next to their name
        let title = `${profile.username}'s Profile (${profile.allyCode})`;
        const lastUpdated = moment(profile.lastUpdatedUTC).fromNow();
        if (message.profile.allycode === undefined) title = profile.username;

        let embed = null;

        // We have two options for sending the embed:
        // The first option is with percentages
        // This will only send if "%" is in the args
        if (args.includes("%")) {
            embed = new RichEmbed()
                .setTitle(title)
                .setColor(0x268BD2)
                .setURL(`https://swgoh.gg/u/${encodeURI(username)}/`)
                .setDescription(`Level ${profile.level}
**Collection Score:** ${profile.collectionScore}
**Arena Rank:** ${profile.arenaRank.toLocaleString()}`
                )
                .addField("Galactic Power (% based on Overall)",
                    `\`\`\`asciidoc
Overall   :: ${profile.galacticPower.toLocaleString()}
Character :: ${profile.charactersGalacticPower.toLocaleString()} (${(profile.charactersGalacticPower / profile.galacticPower * 100).toFixed(1)}%)
Ship      :: ${profile.shipsGalacticPower.toLocaleString()} (${(profile.shipsGalacticPower / profile.galacticPower * 100).toFixed(1)}%)\`\`\``,
                    false
                )
                .addField("Characters (% based on Unlocked)",
                    `\`\`\`asciidoc
Unlocked  :: ${profile.characters}
7 star    :: ${profile.characters7} (${(profile.characters7 / profile.characters * 100).toFixed(1)}%)
6 star    :: ${profile.characters6} (${(profile.characters6 / profile.characters * 100).toFixed(1)}%)
Gear 12   :: ${profile.gearXII} (${(profile.gearXII / profile.characters * 100).toFixed(1)}%)
Gear 11   :: ${profile.gearXI} (${(profile.gearXI / profile.characters * 100).toFixed(1)}%)
Gear 10   :: ${profile.gearX} (${(profile.gearX / profile.characters * 100).toFixed(1)}%)\`\`\``,
                    false
                )
                .setFooter(`Last updated ${lastUpdated}`, "https://swgoh.gg/static/img/bb8.png");
        }

        // The second option is without percentages
        // this is the default embed
        else {
            embed = new RichEmbed()
                .setTitle(title)
                .setColor(0x268BD2)
                .setURL(`https://swgoh.gg/u/${encodeURI(username)}/`)
                .setDescription(`Level ${profile.level}
**Collection Score:** ${profile.collectionScore}
**Arena Rank:** ${profile.arenaRank.toLocaleString()}`
                )
                .addField("Galactic Power",
                    `\`\`\`asciidoc
Overall   :: ${profile.galacticPower.toLocaleString()}
Character :: ${profile.charactersGalacticPower.toLocaleString()}
Ship      :: ${profile.shipsGalacticPower.toLocaleString()}\`\`\``,
                    false
                )
                .addField("Characters",
                    `\`\`\`asciidoc
Unlocked  :: ${profile.characters}
7 star    :: ${profile.characters7}
6 star    :: ${profile.characters6}
Gear 12   :: ${profile.gearXII}
Gear 11   :: ${profile.gearXI}
Gear 10   :: ${profile.gearX}\`\`\``,
                    false
                )
                .setFooter(`Last updated ${lastUpdated} | For percentages use ${message.settings.prefix}p %`, "https://swgoh.gg/static/img/bb8.png");
        }

        await profileMessage.edit({embed});

    } catch (error) {
        client.errlog(cmd, message, level, error);
        client.logger.error(client, `profile command failure:\n${error.stack}`);
        client.codeError(message);
    }

};

exports.conf = {
    enabled: true,
    guildOnly: false,
    aliases: ["profiles", "p"],
    arguments: ["%", "user mention"],
    permLevel: "User"
};

exports.help = {
    name: "profile",
    category: "Game",
    description: "Returns swgoh.gg stats of specified/mentioned user",
    usage: "profile",
    examples: ["p", "p %", "p @Necavit#0540 %"]
};
<|endoftext|>


<commit_before>define(['marionette', 'views/table', 'collections/containers', 'views/filter', 'utils/table', 'utils'], function(Marionette, TableView, Shipments, FilterView, table, utils) {

    var DisposeCell = Backgrid.Cell.extend({
        events: {
            'click a.dispose': 'disposeContainer',
        },

        initialize: function(options) {
            DisposeCell.__super__.initialize.call(this,options)
            this.listenTo(this.model, 'change', this.render, this)
        },

        disposeContainer: function(e) {
            e.preventDefault()

            utils.confirm({
                title: 'Dispose Container',
                content: 'Are you sure you want to dispose this container? ISPyB will no longer know where this plate is, so it must be removed from the imager',
                callback: this.doDispose.bind(this)
            })
        },

        doDispose: function() {
            this.model.set('DISPOSE', 1)
            this.model.save(this.model.changedAttributes(), { patch: true })
        },

        render: function() {
            this.$el.empty()
            if (this.model.get('IMAGERID')) {
                this.$el.html('')
            }

            return this
        }
    })

  var ClickableRow = table.ClickableRow.extend({
    event: 'container:show',
    argument: 'CONTAINERID',
    cookie: true,
  })

  return Marionette.LayoutView.extend({
    className: 'content',
    template: '

Containers

',
    regions: { wrap: '.wrapper', type: '.type' },

    initialize: function(options) {
      var columns = [{ name: 'NAME', label: 'Name', cell: 'string', editable: false },
                     { name: 'DEWAR', label: 'Dewar', cell: 'string', editable: false },
                     { name: 'BARCODE', label: 'Barcode', cell: 'string', editable: false },
                     { name: 'SHIPMENT', label: 'Shipment', cell: 'string', editable: false },
                     { name: 'SAMPLES', label: '# Samples', cell: 'string', editable: false },
                     { name: 'DCCOUNT', label: '# DCs', cell: 'string', editable: false },
                     { name: 'SUBSAMPLES', label: '# Subsamples', cell: 'string', editable: false },
                     { name: 'CONTAINERTYPE', label: 'Type', cell: 'string', editable: false },
                     { name: 'CONTAINERSTATUS', label: 'Status', cell: 'string', editable: false },
                     { name: 'INSPECTIONS', label: 'Inspections', cell: 'string', editable: false },
                     { name: 'LASTINSPECTION', label: 'Last', cell: 'string', editable: false },
                     { name: 'AGE', label: 'Age (d)', cell: 'string', editable: false },
                     ]

      var filters =[
          { id: 'plate', name: 'Plates'},
          { id: 'puck', name: 'Pucks'},
          { id: 'imager', name: 'In Imager'},
          { id: 'queued', name: 'Queued'},
          { id: 'data', name: 'Has Data'},
          { id: 'processing', name: 'Processing'},
          { id: 'subsamples', name: 'Has Subsamples'},
      ]

      if (app.user_can('disp_cont') && !app.mobile()) {
          columns.push({ name: 'VISIT', label: 'Visit', cell: 'string', editable: false })
          columns.push({ name: 'REQUESTEDIMAGER', label: 'Req. Imager', cell: 'string', editable: false })
          columns.push({ name: 'IMAGER', label: 'Imager', cell: 'string', editable: false })
          columns.push({ label: '', cell: table.TemplateCell, editable: false, test: 'REQUESTEDRETURN', template: '' })
          columns.push({ label: '', cell: DisposeCell, editable: false })
          filters.push({ id: 'todispose', name: 'To Dispose'})
      }

      columns[2].renderable = false
      if (options.barcode) {
          columns[1].renderable = false
          columns[2].renderable = true
      }

      if (app.mobile()) {
        _.each([1,2,5,6,9,10,11], function(v) {
            columns[v].renderable = false
        })
      }

      this.table = new TableView({ collection: options.collection, columns: columns, tableClass: 'containers', filter: 's', search: options.params.s, loading: true, backgrid: { row: ClickableRow, emptyText: 'No containers found' } })

      this.ty = new FilterView({
        url: !options.noFilterUrl,
        collection: options.collection,
        value: options.params && options.params.ty,
        name: 'ty',
        filters: filters
      })

      this.listenTo(this.ty, 'selected:change', this.updateCols)
    },

    updateCols: function(selected) {
        var isPuck = (selected == null || selected == 'puck')

        var dew = this.table.grid.columns.findWhere({ name: 'DEWAR' })
        var bc = this.table.grid.columns.findWhere({ name: 'BARCODE' })
        dew.set('renderable', isPuck)
        bc.set('renderable', !isPuck)
    },

    onRender: function() {
      this.wrap.show(this.table)
      this.type.show(this.ty)
    }
  })

})<commit_msg>set type on load<commit_after>define(['marionette', 'views/table', 'collections/containers', 'views/filter', 'utils/table', 'utils'], function(Marionette, TableView, Shipments, FilterView, table, utils) {

    var DisposeCell = Backgrid.Cell.extend({
        events: {
            'click a.dispose': 'disposeContainer',
        },

        initialize: function(options) {
            DisposeCell.__super__.initialize.call(this,options)
            this.listenTo(this.model, 'change', this.render, this)
        },

        disposeContainer: function(e) {
            e.preventDefault()

            utils.confirm({
                title: 'Dispose Container',
                content: 'Are you sure you want to dispose this container? ISPyB will no longer know where this plate is, so it must be removed from the imager',
                callback: this.doDispose.bind(this)
            })
        },

        doDispose: function() {
            this.model.set('DISPOSE', 1)
            this.model.save(this.model.changedAttributes(), { patch: true })
        },

        render: function() {
            this.$el.empty()
            if (this.model.get('IMAGERID')) {
                this.$el.html('')
            }

            return this
        }
    })

  var ClickableRow = table.ClickableRow.extend({
    event: 'container:show',
    argument: 'CONTAINERID',
    cookie: true,
  })

  return Marionette.LayoutView.extend({
    className: 'content',
    template: '

Containers

',
    regions: { wrap: '.wrapper', type: '.type' },

    initialize: function(options) {
      var columns = [{ name: 'NAME', label: 'Name', cell: 'string', editable: false },
                     { name: 'DEWAR', label: 'Dewar', cell: 'string', editable: false },
                     { name: 'BARCODE', label: 'Barcode', cell: 'string', editable: false },
                     { name: 'SHIPMENT', label: 'Shipment', cell: 'string', editable: false },
                     { name: 'SAMPLES', label: '# Samples', cell: 'string', editable: false },
                     { name: 'DCCOUNT', label: '# DCs', cell: 'string', editable: false },
                     { name: 'SUBSAMPLES', label: '# Subsamples', cell: 'string', editable: false },
                     { name: 'CONTAINERTYPE', label: 'Type', cell: 'string', editable: false },
                     { name: 'CONTAINERSTATUS', label: 'Status', cell: 'string', editable: false },
                     { name: 'INSPECTIONS', label: 'Inspections', cell: 'string', editable: false },
                     { name: 'LASTINSPECTION', label: 'Last', cell: 'string', editable: false },
                     { name: 'AGE', label: 'Age (d)', cell: 'string', editable: false },
                     ]

      var filters =[
          { id: 'plate', name: 'Plates'},
          { id: 'puck', name: 'Pucks'},
          { id: 'imager', name: 'In Imager'},
          { id: 'queued', name: 'Queued'},
          { id: 'data', name: 'Has Data'},
          { id: 'processing', name: 'Processing'},
          { id: 'subsamples', name: 'Has Subsamples'},
      ]

      if (app.user_can('disp_cont') && !app.mobile()) {
          columns.push({ name: 'VISIT', label: 'Visit', cell: 'string', editable: false })
          columns.push({ name: 'REQUESTEDIMAGER', label: 'Req. Imager', cell: 'string', editable: false })
          columns.push({ name: 'IMAGER', label: 'Imager', cell: 'string', editable: false })
          columns.push({ label: '', cell: table.TemplateCell, editable: false, test: 'REQUESTEDRETURN', template: '' })
          columns.push({ label: '', cell: DisposeCell, editable: false })
          filters.push({ id: 'todispose', name: 'To Dispose'})
      }

      columns[2].renderable = false
      if (options.barcode) {
          columns[1].renderable = false
          columns[2].renderable = true
      }

      if (app.mobile()) {
        _.each([1,2,5,6,9,10,11], function(v) {
            columns[v].renderable = false
        })
      }

      this.table = new TableView({ collection: options.collection, columns: columns, tableClass: 'containers', filter: 's', search: options.params.s, loading: true, backgrid: { row: ClickableRow, emptyText: 'No containers found' } })

      this.ty = new FilterView({
        url: !options.noFilterUrl,
        collection: options.collection,
        value: options.params && options.params.ty,
        name: 'ty',
        filters: filters
      })

      this.listenTo(this.ty, 'selected:change', this.updateCols)
    },

    updateCols: function(selected) {
        var isPuck = (selected == null || selected == 'puck')

        var dew = this.table.grid.columns.findWhere({ name: 'DEWAR' })
        var bc = this.table.grid.columns.findWhere({ name: 'BARCODE' })
        dew.set('renderable', isPuck)
        bc.set('renderable', !isPuck)
    },

    onRender: function() {
      this.wrap.show(this.table)
      this.type.show(this.ty)

      this.updateCols(this.ty.selected())
    }
  })

})<|endoftext|>


<commit_before>/* Magic Mirror
 * Node Helper: MMM-KeyBindings
 *
 * By shbatm
 * MIT Licensed.
 */

var NodeHelper = require("node_helper");
var url = require("url");
const exec = require("child_process").exec;
const os = require("os");

module.exports = NodeHelper.create({

	start: function() {
		var self = this;

		console.log("MMM-KeyBindings helper has started...");
		this.restServerCreated = false;
		this.pythonDaemonEnabled = false;
	},

	// MODEL FOR EXECUTING CODE AND RETURNING OUTPUT:
	// child_proc = exec(command,
	// 				   function (error, stdout, stderr) {
	// 				      console.log('stdout: ' + stdout);
	// 				      console.log('stderr: ' + stderr);
	// 				      if (error !== null) {
	// 				          console.log('exec error: ' + error);
	// 				      }
	// 				   });

	createRestServer: function() {
		// Basic URL Interface to accept push notifications formatted like
		// http://localhost:8080/MMM-KeyBindings/notify?notification=TITLE&payload=JSONstringifiedSTRING
		this.expressApp.get("/" + this.name + "/notify", (req, res) => {
			var query = url.parse(req.url, true).query;
			var notification = query.notification;
			var payload
			try {
			  payload = JSON.parse(query.payload);
			} catch (e) {
			// Oh well, but whatever...
			}

			if (typeof payload === "undefined") {
				payload = [];
			}
			this.sendSocketNotification(notification, payload);
			res.sendStatus(200);
		});
	},

	startPythonDaemon: function(args) {
		// Start the Python Daemon to capture input from FireTV Remote via Bluetooth
		// Python Daemon captures inputs using python-evdev and is configured to capture
		// All events from '/dev/input/event0'.  Use `cat /proc/bus/input/devices` to find the
		// correct handler to use.  You can also use `evtest /dev/input/event0` to monitor the output.
		// Note: to stop capturing input without shutting down the mirror, run the following from
		// a shell prompt: `python ~/MagicMirror/modules/MMM-KeyBindings/daemon.py stop`
		var spawn = require('child_process').spawn;

		// expected args: evdev: { enabled: true, event_path:'', disable_grab: false,
		// 							long_press_duration: 1.0, raw_mode: false }
		var daemon_args = [require("path").resolve(__dirname,"daemon.py"), "start", "--server",
							'http://localhost:8080/' + this.name + '/notify'];	// TODO: Reference this.expressApp to get url
		if (args.event_path) {
			daemon_args.push('--event');
			daemon_args.push(args.event_path);
		}
		if (disable_grab) {
			daemon_args.push('--no-grab');
		}
		if (args.raw_mode) {
			daemon_args.push('--raw');
		}
		if (typeof long_press_duration === "float" || typeof long_press_duration === "int") {
			daemon_args.push('-l');
			daemon_args.push(long_press_duration);
		} else if (typeof long_press_duration === "string") {
			daemon_args.push('-l');
			daemon_args.push(parseFloat(long_press_duration));
		}

		// var daemon = spawn("python",["/home/pi/MagicMirror/modules/MMM-KeyBindings/daemon.py", "start"]);
		var daemon = spawn("python",[]);

		daemon.stderr.on('data', (data) => {
			console.error(`MMM-KeyBindings daemon.py stderr: ${data}`);
		});

		daemon.stdout.on('data', (data) => {
			console.log(`MMM-KeyBindings daemon.py stdout: ${data}`);
		});

		daemon.on('close', (code) => {
			console.error(`MMM-KeyBindings daemon.py exited with code ${code}`);
		});
	},

	// Override socketNotificationReceived method.

	/* socketNotificationReceived(notification, payload)
	 * This method is called when a socket notification arrives.
	 *
	 * argument notification string - The identifier of the noitication.
	 * argument payload mixed - The payload of the notification.
	 */
	socketNotificationReceived: function(notification, payload) {
		var self = this;
		if (notification === "ENABLE_RESTNOTIFYSERVER") {
			if (!this.restServerCreated) {
				this.createRestServer();
			}
		}
		if (notification === "ENABLE_PYTHONDAEMON") {
			if (this.restServerCreated && !this.pythonDaemonEnabled) {
				this.startPythonDaemon(payload);
			} else {
				console.error("Cannot enable python daemon. Did the REST server not get enabled?");
			}
		}

		if (notification === "PROCESS_KEYPRESS") {
			switch(payload.KeyName) {
			    case "!POWER_KEY":  // Specially assigned key to toggle power to Screen
			    	screen_status = exec("tvservice --status",
					   function (error, stdout, stderr) {
					   	  if (stdout.indexOf("TV is off") != -1) {
					   	  	// Screen is OFF, turn it ON
							exec("tvservice --preferred && sudo chvt 6 && sudo chvt 7", function(error, stdout, stderr){ self.checkForExecError(error, stdout, stderr); });
					   	  } else if (stdout.indexOf("HDMI") != -1) {
					   	  	// Screen is ON, turn it OFF
							exec("tvservice -o", function(error, stdout, stderr){ self.checkForExecError(error, stdout, stderr); });
					   	  }
					   	  self.checkForExecError(error, stdout, stderr);
					   });
			        break;
			    default:
			        console.log("MMM-KeyBindings Helper received request to process a KEYPRESS of " + payload.KeyName + ":" +
			        		payload.KeyState + ", but there is no handler for this key.");
			}
		}
	},

	checkForExecError: function(error, stdout, stderr) {
		if (stderr) {
			console.log('stderr: "' + stderr + '"');
			return 1;
		}
		if (error !== null) {
		 	console.log('exec error: ' + error);
		 	return 1;
		}
		return 0;
	},
});
<commit_msg>Bug fixes on Start Daemon function<commit_after>/* Magic Mirror
 * Node Helper: MMM-KeyBindings
 *
 * By shbatm
 * MIT Licensed.
 */

var NodeHelper = require("node_helper");
var url = require("url");
const exec = require("child_process").exec;
const os = require("os");

module.exports = NodeHelper.create({

	start: function() {
		var self = this;

		console.log("MMM-KeyBindings helper has started...");
		this.restServerCreated = false;
		this.pythonDaemonEnabled = false;
	},

	// MODEL FOR EXECUTING CODE AND RETURNING OUTPUT:
	// child_proc = exec(command,
	// 				   function (error, stdout, stderr) {
	// 				      console.log('stdout: ' + stdout);
	// 				      console.log('stderr: ' + stderr);
	// 				      if (error !== null) {
	// 				          console.log('exec error: ' + error);
	// 				      }
	// 				   });

	createRestServer: function() {
		var self = this;
		// Basic URL Interface to accept push notifications formatted like
		// http://localhost:8080/MMM-KeyBindings/notify?notification=TITLE&payload=JSONstringifiedSTRING
		this.expressApp.get("/" + this.name + "/notify", (req, res) => {
			var query = url.parse(req.url, true).query;
			var notification = query.notification;
			var payload
			try {
			  payload = JSON.parse(query.payload);
			} catch (e) {
			// Oh well, but whatever...
			}

			if (typeof payload === "undefined") {
				payload = [];
			}
			this.sendSocketNotification(notification, payload);
			res.sendStatus(200);
		});
	},

	startPythonDaemon: function(args) {
		var self = this;
		// Start the Python Daemon to capture input from FireTV Remote via Bluetooth
		// Python Daemon captures inputs using python-evdev and is configured to capture
		// All events from '/dev/input/event0'.  Use `cat /proc/bus/input/devices` to find the
		// correct handler to use.  You can also use `evtest /dev/input/event0` to monitor the output.
		// Note: to stop capturing input without shutting down the mirror, run the following from
		// a shell prompt: `python ~/MagicMirror/modules/MMM-KeyBindings/daemon.py stop`
		var spawn = require('child_process').spawn;

		// expected args: evdev: { enabled: true, event_path:'', disable_grab: false,
		// 							long_press_duration: 1.0, raw_mode: false }
		var daemon_args = [require("path").resolve(__dirname,"daemon.py"), "restart", "--server",
							'http://localhost:8080/' + this.name + '/notify'];	// TODO: Reference this.expressApp to get url
		if (("event_path" in args) && args.event_path) {
			daemon_args.push('--event');
			daemon_args.push(args.event_path);
		}
		if (("disable_grab" in args) && args.disable_grab) {
			daemon_args.push('--no-grab');
		}
		if (("raw_mode" in args) && args.raw_mode) {
			daemon_args.push('--raw');
		}
		if ("long_press_duration" in args) {
			if (typeof args.long_press_duration === "float" || typeof args.long_press_duration === "int") {
				daemon_args.push('-l');
				daemon_args.push(args.long_press_duration);
			} else if (typeof args.long_press_duration === "string") {
				daemon_args.push('-l');
				daemon_args.push(parseFloat(args.long_press_duration));
			}
		}

		var daemon = spawn("python", daemon_args);

		daemon.stderr.on('data', (data) => {
			console.error(`MMM-KeyBindings daemon.py stderr: ${data}`);
		});

		daemon.stdout.on('data', (data) => {
			console.log(`MMM-KeyBindings daemon.py stdout: ${data}`);
		});

		daemon.on('close', (code) => {
			console.error(`MMM-KeyBindings daemon.py exited with code ${code}`);
		});
	},

	// Override socketNotificationReceived method.

	/* socketNotificationReceived(notification, payload)
	 * This method is called when a socket notification arrives.
	 *
	 * argument notification string - The identifier of the noitication.
	 * argument payload mixed - The payload of the notification.
	 */
	socketNotificationReceived: function(notification, payload) {
		var self = this;
		if (notification === "ENABLE_RESTNOTIFYSERVER") {
			if (!this.restServerCreated) {
				this.createRestServer();
			}
		}
		if (notification === "ENABLE_PYTHONDAEMON") {
			if (this.restServerCreated && !this.pythonDaemonEnabled) {
				this.startPythonDaemon(payload);
			} else {
				console.error("Cannot enable python daemon. Did the REST server not get enabled?");
			}
		}

		if (notification === "PROCESS_KEYPRESS") {
			switch(payload.KeyName) {
			    case "!POWER_KEY":  // Specially assigned key to toggle power to Screen
			    	screen_status = exec("tvservice --status",
					   function (error, stdout, stderr) {
					   	  if (stdout.indexOf("TV is off") != -1) {
					   	  	// Screen is OFF, turn it ON
							exec("tvservice --preferred && sudo chvt 6 && sudo chvt 7", function(error, stdout, stderr){ self.checkForExecError(error, stdout, stderr); });
					   	  } else if (stdout.indexOf("HDMI") != -1) {
					   	  	// Screen is ON, turn it OFF
							exec("tvservice -o", function(error, stdout, stderr){ self.checkForExecError(error, stdout, stderr); });
					   	  }
					   	  self.checkForExecError(error, stdout, stderr);
					   });
			        break;
			    default:
			        console.log("MMM-KeyBindings Helper received request to process a KEYPRESS of " + payload.KeyName + ":" +
			        		payload.KeyState + ", but there is no handler for this key.");
			}
		}
	},

	checkForExecError: function(error, stdout, stderr) {
		if (stderr) {
			console.log('stderr: "' + stderr + '"');
			return 1;
		}
		if (error !== null) {
		 	console.log('exec error: ' + error);
		 	return 1;
		}
		return 0;
	},
});
<|endoftext|>


<commit_before>'use strict';

const gulp = require('gulp');
const config = require('../config.js');
const del = require('del');
var plugins = require('gulp-load-plugins')();

gulp.task('clean', function () {
    return del(config.cleanPaths);
});

gulp.task('rebuild', ['clean'], function () {
    return gulp.start('default');
});

gulp.task('default', function(){
    return gulp.start(config.buildTasks);
});
<commit_msg>Added force to clean-task<commit_after>'use strict';

const gulp = require('gulp');
const config = require('../config.js');
const del = require('del');
var plugins = require('gulp-load-plugins')();

gulp.task('clean', function () {
    return del(config.cleanPaths, {force: true});
});

gulp.task('rebuild', ['clean'], function () {
    return gulp.start('default');
});

gulp.task('default', function(){
    return gulp.start(config.buildTasks);
});
<|endoftext|>


<commit_before>'use strict';

import del from 'del';
import gulp from 'gulp';
import util from 'gulp-util';
import uglify from 'gulp-uglify';
import bytediff from 'gulp-bytediff';
import size from 'gulp-size';
import minifyCss from 'gulp-minify-css';
import minifyHtml from 'gulp-minify-html';
import rev from 'gulp-rev';
import header from 'gulp-header';
import usemin from 'gulp-usemin';
import inject from 'gulp-inject';
import runSequence from 'run-sequence';

import {LOG, COLORS} from '../utils';
import {BANNER} from '../const';
import paths from '../paths';

//=============================================
//            UTILS FUNCTIONS
//=============================================

/**
 * Format a number as a percentage
 * @param  {Number} num       Number to format as a percent
 * @param  {Number} precision Precision of the decimal
 * @return {String}           Formatted percentage
 */
function formatPercent(num, precision) {
  return (num * 100).toFixed(precision);
}

/**
 * Formatter for bytediff to display the size changes after processing
 * @param  {Object} data - byte data
 * @return {String}      Difference in bytes, formatted
 */
function bytediffFormatter(data) {
  const difference = (data.savings > 0) ? ' smaller.' : ' larger.';
  return COLORS.yellow(data.fileName + ' went from ' +
    (data.startSize / 1000).toFixed(2) + ' kB to ' +
    (data.endSize / 1000).toFixed(2) + ' kB and is ' +
    formatPercent(1 - data.percent, 2) + '%' + difference);
}

//=============================================
//                  TASKS
//=============================================

/**
 * The 'clean' task delete 'build' and '.tmp' directories.
 * But keeps build/dist/.git (if you git init this folder to push to production via git)
 */
gulp.task('clean', (cb) => {
  const files = [
    paths.build.dist.basePath + '*',
    '!' + paths.build.dist.basePath + '.git*',
    paths.tmp.basePath
  ];
  LOG('Cleaning: ' + COLORS.blue(files));

  return del(files, cb);
});

//@todo complete (uglify / env based / ngAnnotate ...) + jsdoc
gulp.task('compile', ['htmlhint', 'sass', 'bundle'], () => {
  return gulp.src(paths.app.html)
    .pipe(inject(gulp.src(paths.tmp.scripts + 'app.bootstrap.build.js', {read: false})), {
      starttag: '<!-- inject:js -->'
    })
    .pipe(usemin({
      css: [
        bytediff.start(),
        minifyCss({keepSpecialComments: 0}),
        bytediff.stop(bytediffFormatter),
        rev(),
        header(BANNER)
      ],
      js: [
        bytediff.start(),
        uglify(),
        bytediff.stop(bytediffFormatter),
        rev(),
        header(BANNER)
      ],
      html: [
        bytediff.start(),
        minifyHtml({empty: true}),
        bytediff.stop(bytediffFormatter)
      ]
    }))
    .pipe(gulp.dest(paths.build.dist.basePath))
    .pipe(size({title: 'compile', showFiles: true}));
});

/**
 * The 'build' task gets app ready for deployment by processing files
 * and put them into directory ready for production.
 */
//@todo manage environment / root files like .ico .htaccess ... / fonts ?
gulp.task('build', (cb) => {
  runSequence(
    ['clean'],
    ['compile', 'images'],
    cb
  );
});
<commit_msg>chore(assets) add gulp extras task to copy root assets<commit_after>'use strict';

import del from 'del';
import gulp from 'gulp';
import util from 'gulp-util';
import uglify from 'gulp-uglify';
import bytediff from 'gulp-bytediff';
import size from 'gulp-size';
import minifyCss from 'gulp-minify-css';
import minifyHtml from 'gulp-minify-html';
import rev from 'gulp-rev';
import header from 'gulp-header';
import usemin from 'gulp-usemin';
import inject from 'gulp-inject';
import runSequence from 'run-sequence';

import {LOG, COLORS} from '../utils';
import {BANNER} from '../const';
import paths from '../paths';

//=============================================
//            UTILS FUNCTIONS
//=============================================

/**
 * Format a number as a percentage
 * @param  {Number} num       Number to format as a percent
 * @param  {Number} precision Precision of the decimal
 * @return {String}           Formatted percentage
 */
function formatPercent(num, precision) {
  return (num * 100).toFixed(precision);
}

/**
 * Formatter for bytediff to display the size changes after processing
 * @param  {Object} data - byte data
 * @return {String}      Difference in bytes, formatted
 */
function bytediffFormatter(data) {
  const difference = (data.savings > 0) ? ' smaller.' : ' larger.';
  return COLORS.yellow(data.fileName + ' went from ' +
    (data.startSize / 1000).toFixed(2) + ' kB to ' +
    (data.endSize / 1000).toFixed(2) + ' kB and is ' +
    formatPercent(1 - data.percent, 2) + '%' + difference);
}

//=============================================
//                  TASKS
//=============================================

/**
 * The 'clean' task delete 'build' and '.tmp' directories.
 * But keeps build/dist/.git (if you git init this folder to push to production via git)
 */
gulp.task('clean', (cb) => {
  const files = [
    paths.build.dist.basePath + '*',
    '!' + paths.build.dist.basePath + '.git*',
    paths.tmp.basePath
  ];
  LOG('Cleaning: ' + COLORS.blue(files));

  return del(files, cb);
});

/**
 * Copies assets at the root of `src` to the `build/dist` folder, such as :
 * - favicon files
 * - 404.html file
 */
gulp.task('extras', () => {
  return gulp.src([paths.app.basePath + '*.{ico,png,txt}', paths.app.basePath + '404.html'])
    .pipe(gulp.dest(paths.build.dist.basePath));
});

/**
 * The 'compile' task compile all js, css and html files.
 *
 * 1. it inject bundle into `index.html`
 * 2. css      - minify, add revision number, add banner header
 *    js       - minify, add revision number, add banner header
 *    html     - minify
 */
gulp.task('compile', ['htmlhint', 'sass', 'bundle'], () => {
  return gulp.src(paths.app.html)
    .pipe(inject(gulp.src(paths.tmp.scripts + 'app.bootstrap.build.js', {read: false})), {
      starttag: '<!-- inject:js -->'
    })
    .pipe(usemin({
      css: [
        bytediff.start(),
        minifyCss({keepSpecialComments: 0}),
        bytediff.stop(bytediffFormatter),
        rev(),
        header(BANNER)
      ],
      js: [
        bytediff.start(),
        uglify(),
        bytediff.stop(bytediffFormatter),
        rev(),
        header(BANNER)
      ],
      html: [
        bytediff.start(),
        minifyHtml({empty: true}),
        bytediff.stop(bytediffFormatter)
      ]
    }))
    .pipe(gulp.dest(paths.build.dist.basePath))
    .pipe(size({title: 'compile', showFiles: true}));
});

/**
 * The 'build' task gets app ready for deployment by processing files
 * and put them into directory ready for production.
 */
//@todo manage environment / root files like .ico .htaccess ... / fonts ?
gulp.task('build', (cb) => {
  runSequence(
    ['clean'],
    ['compile', 'extras', 'images'],
    cb
  );
});
<|endoftext|>


<commit_before>$.extend( $.expr[ ":" ], {
    data: $.expr.createPseudo ?
        $.expr.createPseudo(function( dataName ) {
            return function( elem ) {
                return !!$.data( elem, dataName );
            };
        }) :
        // support: jQuery <1.8
        function( elem, i, match ) {
            return !!$.data( elem, match[ 3 ] );
        }
});

$(document).ready(function () {
    $.fn.editable.defaults.mode = 'inline';
    $.fn.editable.defaults.ajaxOptions = {type: "PUT"};

    $('li.scribbit h3 a').editable({
        type: 'text',
        url: baseUrl + '/scribbit',
        title: 'Enter new name',
        inputclass: 'input-lg',
        toggle: 'manual',
        success: function (response, newValue) {
            var r = JSON.parse(response);

            // Update links etc that depend on the scribbit name
            $(this).editable('option', 'pk', r.new);
            $(this).parents("li").attr("data-scribbit", r.new);

            $(this).parents("li").find('a').each(function () {
                $(this).attr("href", $(this).attr("href").replace(r.old, r.new));
            });

            $(this).parents("li").find('div.btn-group button').each(function () {
                var newUrl = $(this).attr("data-url").replace(r.old, r.new);
                $(this).attr("data-url", newUrl);
            });
        }
    });

    $('li.scribbit h3 a.edit').click(function (e) {
        e.stopPropagation();
        var a = $(this).parents("li").find('h3 a').not(".edit");

        $(a).editable('toggle');
        $(this).hide();
    });

    $('.editable').on('hidden', function (e, reason) {
        if (reason === 'save' || reason === 'cancel') {
            $('li.scribbit h3 a.edit').show();
        }
    });

    $("li.scribbit .download").click(function () {
        // $(this).data("url") doesn't return new value if data-url has changed
        window.location = $(this).attr("data-url");
    });

    $("li.scribbit .delete").click(function () {
        // $(this).data("url") doesn't return new value if data-url has changed
        var url = $(this).attr("data-url");

        bootbox.confirm("Delete this entire scribbit?", function (result) {
            if (result) {
                $.ajax({
                    type: 'DELETE',
                    url: url,
                    success: function (data, textStatus, jqXHR) {
                        location.reload(true);
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        console.log(scribbit + ' delete failed');
                    }
                });
            }
        });
    });

    var markdownConverter = new Showdown.converter();

    if ($('#bit-editor').length) {
        var editor = ace.edit("bit-editor");
        editor.setTheme("ace/theme/tomorrow");
        editor.getSession().setMode("ace/mode/markdown");
        editor.getSession().setUseWrapMode(true);
        editor.setValue("Write some **markdown** here...");
        editor.clearSelection();
        editor.$blockScrolling = Infinity;
        editor.focus();
    }

    $('#bit-editor').keyup(function () {
        $('#bit-preview').html(markdownConverter.makeHtml(editor.getValue()));
    });

    $('#bit-editor').keyup();

    $('.markdown').each(function () {
        $(this).html(markdownConverter.makeHtml($(this).data('source')));
    });

    $("div.editor-buttons button.cancel").click(function () {
        editor.setValue("Write some **markdown** here...");
        $('#bit-editor').keyup();
        editor.clearSelection();
        editor.focus();
    });

    $("div.editor-buttons button.save").click(function () {
        var content = editor.getValue();
        var requestType = 'POST';
        var scribbit = $("#scribbit").val();
        var bit = '';
        var url = $(this).data("post-url");

        if ($("#bit").val()) {
            requestType = 'PUT';
            bit = $("#bit").val();
            url = $(this).data("put-url");
        }

        $.ajax({
            type: requestType,
            url: url,
            data: {
                bit: bit,
                content: content,
                scribbit: scribbit
            },
            success: function (data, textStatus, jqXHR) {
                location.reload(true);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                console.log(' create failed');
            }
        });

        editor.focus();
    });

    $("div.bit .delete").click(function () {
        var url = $(this).data("url");
        var bitPanel = $(this).parents("div.panel");

        bootbox.confirm("Delete this bit?", function (result) {
            if (result) {
                $.ajax({
                    type: 'DELETE',
                    url: url,
                    success: function (data, textStatus, jqXHR) {
                        bitPanel.remove();
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        console.log(url + ': delete failed');
                    }
                });
            }
        });
    });

    $("div.bit .download").click(function () {
        window.location = $(this).data("url");
    });

    $("div.bit .edit").click(function () {
        var bitPanel = $(this).parents("div.panel");
        var bit = bitPanel.data("bit");
        $("#bit").val(bit);

        var source = bitPanel.find("div.markdown").data('source');
        editor.setValue(source);
        $('#bit-editor').keyup();
        editor.clearSelection();
        editor.focus();
    });
});
<commit_msg>scroll the editor to the last line when editing lengthy existing bits<commit_after>$.extend( $.expr[ ":" ], {
    data: $.expr.createPseudo ?
        $.expr.createPseudo(function( dataName ) {
            return function( elem ) {
                return !!$.data( elem, dataName );
            };
        }) :
        // support: jQuery <1.8
        function( elem, i, match ) {
            return !!$.data( elem, match[ 3 ] );
        }
});

$(document).ready(function () {
    $.fn.editable.defaults.mode = 'inline';
    $.fn.editable.defaults.ajaxOptions = {type: "PUT"};

    $('li.scribbit h3 a').editable({
        type: 'text',
        url: baseUrl + '/scribbit',
        title: 'Enter new name',
        inputclass: 'input-lg',
        toggle: 'manual',
        success: function (response, newValue) {
            var r = JSON.parse(response);

            // Update links etc that depend on the scribbit name
            $(this).editable('option', 'pk', r.new);
            $(this).parents("li").attr("data-scribbit", r.new);

            $(this).parents("li").find('a').each(function () {
                $(this).attr("href", $(this).attr("href").replace(r.old, r.new));
            });

            $(this).parents("li").find('div.btn-group button').each(function () {
                var newUrl = $(this).attr("data-url").replace(r.old, r.new);
                $(this).attr("data-url", newUrl);
            });
        }
    });

    $('li.scribbit h3 a.edit').click(function (e) {
        e.stopPropagation();
        var a = $(this).parents("li").find('h3 a').not(".edit");

        $(a).editable('toggle');
        $(this).hide();
    });

    $('.editable').on('hidden', function (e, reason) {
        if (reason === 'save' || reason === 'cancel') {
            $('li.scribbit h3 a.edit').show();
        }
    });

    $("li.scribbit .download").click(function () {
        // $(this).data("url") doesn't return new value if data-url has changed
        window.location = $(this).attr("data-url");
    });

    $("li.scribbit .delete").click(function () {
        // $(this).data("url") doesn't return new value if data-url has changed
        var url = $(this).attr("data-url");

        bootbox.confirm("Delete this entire scribbit?", function (result) {
            if (result) {
                $.ajax({
                    type: 'DELETE',
                    url: url,
                    success: function (data, textStatus, jqXHR) {
                        location.reload(true);
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        console.log(scribbit + ' delete failed');
                    }
                });
            }
        });
    });

    var markdownConverter = new Showdown.converter();

    if ($('#bit-editor').length) {
        var editor = ace.edit("bit-editor");
        editor.setTheme("ace/theme/tomorrow");
        editor.getSession().setMode("ace/mode/markdown");
        editor.getSession().setUseWrapMode(true);
        editor.setValue("Write some **markdown** here...");
        editor.clearSelection();
        editor.$blockScrolling = Infinity;
        editor.focus();
    }

    $('#bit-editor').keyup(function () {
        $('#bit-preview').html(markdownConverter.makeHtml(editor.getValue()));
    });

    $('#bit-editor').keyup();

    $('.markdown').each(function () {
        $(this).html(markdownConverter.makeHtml($(this).data('source')));
    });

    $("div.editor-buttons button.cancel").click(function () {
        editor.setValue("Write some **markdown** here...");
        $('#bit-editor').keyup();
        editor.clearSelection();
        editor.focus();
    });

    $("div.editor-buttons button.save").click(function () {
        var content = editor.getValue();
        var requestType = 'POST';
        var scribbit = $("#scribbit").val();
        var bit = '';
        var url = $(this).data("post-url");

        if ($("#bit").val()) {
            requestType = 'PUT';
            bit = $("#bit").val();
            url = $(this).data("put-url");
        }

        $.ajax({
            type: requestType,
            url: url,
            data: {
                bit: bit,
                content: content,
                scribbit: scribbit
            },
            success: function (data, textStatus, jqXHR) {
                location.reload(true);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                console.log(' create failed');
            }
        });

        editor.focus();
    });

    $("div.bit .delete").click(function () {
        var url = $(this).data("url");
        var bitPanel = $(this).parents("div.panel");

        bootbox.confirm("Delete this bit?", function (result) {
            if (result) {
                $.ajax({
                    type: 'DELETE',
                    url: url,
                    success: function (data, textStatus, jqXHR) {
                        bitPanel.remove();
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        console.log(url + ': delete failed');
                    }
                });
            }
        });
    });

    $("div.bit .download").click(function () {
        window.location = $(this).data("url");
    });

    $("div.bit .edit").click(function () {
        var bitPanel = $(this).parents("div.panel");
        var bit = bitPanel.data("bit");
        $("#bit").val(bit);

        var source = bitPanel.find("div.markdown").data('source');
        editor.setValue(source);
        $('#bit-editor').keyup();
        editor.clearSelection();
        editor.focus();
        editor.gotoLine(editor.session.doc.getAllLines().length);
    });
});
<|endoftext|>


<commit_before>import { campaignsRef, usersRef, Timestamp } from '../../firebase';
import { firebaseFetchUserData } from '../actions/firebaseAuth';
import {
  firebasePopulateCampaignById,
  firebaseFetchCampaignByIdError
} from '../actions/firebaseActiveCampaign';

// FETCH SIGNATURE ACTIONS
// FETCH FIREBASE USER SIGNATURES REQUEST
export const FETCH_FIREBASE_SIGNATURES_REQUEST = 'FETCH_FIREBASE_SIGNATURES_REQUEST';
export const firebaseFetchUserSignaturesRequest = () => ({
  type: FETCH_FIREBASE_SIGNATURES_REQUEST
});

// POPULATE FIREBASE USER SIGNATURES (SUCCESS)
// TODO UPDATE FUNCTION NAME
export const FETCH_FIREBASE_SIGNATURES_SUCCESS = 'FETCH_FIREBASE_SIGNATURES_SUCCESS';
export const populateFirebaseUserSignatures = firebaseUserSignatures => ({
  type: FETCH_FIREBASE_SIGNATURES_SUCCESS,
  response: firebaseUserSignatures
});

// THUNK FOR FIREBASE SIGNATURES
export const firebaseFetchUserSignatures = firebaseUserSignatures => dispatch => {
  dispatch(firebaseFetchUserData());
  dispatch(populateFirebaseUserSignatures(firebaseUserSignatures));
};

// START LISTENING FOR NEW SIGNATURES
// export const startListeningForSignatures = () => dispatch => {
//   signaturesRef.onSnapshot(querySnapshot => {
//     const signatures = [];
//     querySnapshot.forEach(doc => {
//       signatures.push({ userId: doc.data().userId, campaignId: doc.data().campaignId });
//     });
//     dispatch(firebaseFetchUserSignatures(signatures));
//   });
// };

// ADD SIGNATURE ACTIONS
// FIREBASE ADD SIGNATURE TO CAMPAIGN REQUEST
export const FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_REQUEST =
  'FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_REQUEST';
export const firebaseAddSignatureToCampaignRequest = firebaseUserSignatures => ({
  type: FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_REQUEST
});

// FIREBASE ADD SIGNATURE SUCCESS
export const FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_SUCCESS =
  'FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_SUCCESS';
export const firebaseAddSignatureToCampaignSuccess = addSignatureSuccessObject => ({
  type: FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_SUCCESS,
  response: addSignatureSuccessObject
});

// FIREBASE ADD SIGNATURE ERROR
export const FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_ERROR = 'FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_ERROR';
export const firebaseAddSignatureToCampaignError = addSignatureError => ({
  type: FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_ERROR,
  error: addSignatureError
});

// FIREBASE ADD SIGNATURE THUNK
export const firebaseAddSignatureToCampaign = signatureObject => async dispatch => {
  dispatch(firebaseAddSignatureToCampaignRequest());
  const { campaignId, uid, displayName, signerMessage, keepMeUpdated } = signatureObject;
  const addSignatureRef = campaignsRef
    .doc(campaignId)
    .collection('signatures')
    .doc(uid);
  //  USE UID TO DEFINE SIGNATURE DOC
  addSignatureRef
    .set(
      // IF DOCUMENT EXISTS, OVERWRITE, IF DOESN'T EXIST, CREATE
      {
        uid,
        displayName,
        signerMessage,
        keepMeUpdated,
        createdAt: Timestamp,
        modifiedAt: Timestamp
      }
    )
    // TODO REMOVE AFTER TESTING
    /* eslint-disable no-console */
    .then(dispatch(firebasePopulateCampaignById(campaignId)))
    .catch(err => {
      dispatch(firebaseFetchCampaignByIdError(err));
    });
  const addSignatureUserRef = usersRef.doc(uid);
  addSignatureUserRef
    .set(
      {
        signedCampaignId: campaignId,
        signedCampaignTimestamp: Timestamp
      },
      { merge: true }
    )
    .then(dispatch(firebaseFetchUserData(uid)));
};

// REMOVE SIGNATURE ACTIONS
// FIREBASE REMOVE SIGNATURE REQUEST
export const FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_REQUEST =
  'FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_REQUEST';
export const firebaseRemoveSignatureFromCampaignRequest = () => ({
  type: FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_REQUEST
});

// FIREBASE REMOVE SIGNATURE SUCCESS
export const FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_SUCCESS =
  'FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_SUCCESS';
export const firebaseRemoveSignatureFromCampaignSuccess = () => ({
  type: FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_SUCCESS
});

// FIREBASE REMOVE SIGNATURE ERROR
export const FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_ERROR =
  'FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_ERROR';
export const firebaseRemoveSignatureFromCamaignError = () => ({
  type: FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_ERROR
});

// FIREBASE REMOVE SIGNATURE THUNK
// TODO EXPLORE KEEP RECORD OF DELETED SIGNATURES
export const firebaseRemoveSignatureFromCampaign = (campaignId, uid) => async dispatch => {
  // dispatch(firebaseRemoveSignatureFromCampaignRequest());
  const campaignSignatureRef = campaignsRef.doc(campaignId).collection('signatures');
  let deleteSignatureRef;
  await campaignSignatureRef
    .where('uid', '==', uid)
    .get()
    .then(snapshot => {
      snapshot.forEach(doc => {
        deleteSignatureRef = doc.id;
      });
    });
  await campaignSignatureRef
    .doc(deleteSignatureRef)
    .delete()
    .then(() => {
      dispatch(firebasePopulateCampaignById(campaignId));
      console.log('Document fue deletado');
    })
    .catch(err => {
      console.log('fue error ', err);
    });
  const removeSignatureUserRef = usersRef.doc(uid);
  await removeSignatureUserRef
    .set(
      {
        signedCampaignId: null,
        modifiedSignedCampaignTimestamp: Timestamp
      },
      { merge: true }
    )
    .then(dispatch(firebaseFetchUserData(uid)));
};
<commit_msg>Add Keep Me Updated to DB Patch (#422)<commit_after>import { campaignsRef, usersRef, Timestamp } from '../../firebase';
import { firebaseFetchUserData } from '../actions/firebaseAuth';
import {
  firebasePopulateCampaignById,
  firebaseFetchCampaignByIdError
} from '../actions/firebaseActiveCampaign';

// FETCH SIGNATURE ACTIONS
// FETCH FIREBASE USER SIGNATURES REQUEST
export const FETCH_FIREBASE_SIGNATURES_REQUEST = 'FETCH_FIREBASE_SIGNATURES_REQUEST';
export const firebaseFetchUserSignaturesRequest = () => ({
  type: FETCH_FIREBASE_SIGNATURES_REQUEST
});

// POPULATE FIREBASE USER SIGNATURES (SUCCESS)
// TODO UPDATE FUNCTION NAME
export const FETCH_FIREBASE_SIGNATURES_SUCCESS = 'FETCH_FIREBASE_SIGNATURES_SUCCESS';
export const populateFirebaseUserSignatures = firebaseUserSignatures => ({
  type: FETCH_FIREBASE_SIGNATURES_SUCCESS,
  response: firebaseUserSignatures
});

// THUNK FOR FIREBASE SIGNATURES
export const firebaseFetchUserSignatures = firebaseUserSignatures => dispatch => {
  dispatch(firebaseFetchUserData());
  dispatch(populateFirebaseUserSignatures(firebaseUserSignatures));
};

// START LISTENING FOR NEW SIGNATURES
// export const startListeningForSignatures = () => dispatch => {
//   signaturesRef.onSnapshot(querySnapshot => {
//     const signatures = [];
//     querySnapshot.forEach(doc => {
//       signatures.push({ userId: doc.data().userId, campaignId: doc.data().campaignId });
//     });
//     dispatch(firebaseFetchUserSignatures(signatures));
//   });
// };

// ADD SIGNATURE ACTIONS
// FIREBASE ADD SIGNATURE TO CAMPAIGN REQUEST
export const FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_REQUEST =
  'FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_REQUEST';
export const firebaseAddSignatureToCampaignRequest = firebaseUserSignatures => ({
  type: FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_REQUEST
});

// FIREBASE ADD SIGNATURE SUCCESS
export const FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_SUCCESS =
  'FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_SUCCESS';
export const firebaseAddSignatureToCampaignSuccess = addSignatureSuccessObject => ({
  type: FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_SUCCESS,
  response: addSignatureSuccessObject
});

// FIREBASE ADD SIGNATURE ERROR
export const FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_ERROR = 'FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_ERROR';
export const firebaseAddSignatureToCampaignError = addSignatureError => ({
  type: FIREBASE_ADD_SIGNATURE_TO_CAMPAIGN_ERROR,
  error: addSignatureError
});

// FIREBASE ADD SIGNATURE THUNK
export const firebaseAddSignatureToCampaign = signatureObject => async dispatch => {
  dispatch(firebaseAddSignatureToCampaignRequest());
  const { campaignId, uid, displayName, signerMessage, keepMeUpdated } = signatureObject;
  const addSignatureRef = campaignsRef
    .doc(campaignId)
    .collection('signatures')
    .doc(uid);
  //  USE UID TO DEFINE SIGNATURE DOC
  addSignatureRef
    .set(
      // IF DOCUMENT EXISTS, OVERWRITE, IF DOESN'T EXIST, CREATE
      {
        uid,
        displayName,
        signerMessage,
        keepMeUpdated,
        createdAt: Timestamp,
        modifiedAt: Timestamp
      }
    )
    // TODO REMOVE AFTER TESTING
    /* eslint-disable no-console */
    .then(dispatch(firebasePopulateCampaignById(campaignId)))
    .catch(err => {
      dispatch(firebaseFetchCampaignByIdError(err));
    });
  const addSignatureUserRef = usersRef.doc(uid);
  addSignatureUserRef
    .set(
      {
        signedCampaignId: campaignId,
        signedCampaignTimestamp: Timestamp,
        keepMeUpdated
      },
      { merge: true }
    )
    .then(dispatch(firebaseFetchUserData(uid)));
};

// REMOVE SIGNATURE ACTIONS
// FIREBASE REMOVE SIGNATURE REQUEST
export const FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_REQUEST =
  'FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_REQUEST';
export const firebaseRemoveSignatureFromCampaignRequest = () => ({
  type: FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_REQUEST
});

// FIREBASE REMOVE SIGNATURE SUCCESS
export const FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_SUCCESS =
  'FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_SUCCESS';
export const firebaseRemoveSignatureFromCampaignSuccess = () => ({
  type: FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_SUCCESS
});

// FIREBASE REMOVE SIGNATURE ERROR
export const FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_ERROR =
  'FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_ERROR';
export const firebaseRemoveSignatureFromCamaignError = () => ({
  type: FIREBASE_REMOVE_SIGNATURE_FROM_CAMPAIGN_ERROR
});

// FIREBASE REMOVE SIGNATURE THUNK
// TODO EXPLORE KEEP RECORD OF DELETED SIGNATURES
export const firebaseRemoveSignatureFromCampaign = (campaignId, uid) => async dispatch => {
  // dispatch(firebaseRemoveSignatureFromCampaignRequest());
  const campaignSignatureRef = campaignsRef.doc(campaignId).collection('signatures');
  let deleteSignatureRef;
  await campaignSignatureRef
    .where('uid', '==', uid)
    .get()
    .then(snapshot => {
      snapshot.forEach(doc => {
        deleteSignatureRef = doc.id;
      });
    });
  await campaignSignatureRef
    .doc(deleteSignatureRef)
    .delete()
    .then(() => {
      dispatch(firebasePopulateCampaignById(campaignId));
      console.log('Document fue deletado');
    })
    .catch(err => {
      console.log('fue error ', err);
    });
  const removeSignatureUserRef = usersRef.doc(uid);
  await removeSignatureUserRef
    .set(
      {
        signedCampaignId: null,
        modifiedSignedCampaignTimestamp: Timestamp
      },
      { merge: true }
    )
    .then(dispatch(firebaseFetchUserData(uid)));
};
<|endoftext|>


<commit_before>
/////////////////////////
// Helpers and globals //
/////////////////////////

const expect = chai.expect;

////////////////
// Test suite //
////////////////

describe('Rainbow', function() {
    it('Basic things are defined', () => {
        expect(Rainbow).to.exist;
        expect(Rainbow.color).to.be.a('function');
        expect(Rainbow.extend).to.be.a('function');
        expect(Rainbow.onHighlight).to.be.a('function');
        expect(Rainbow.addClass).to.be.a('function');
        expect(Rainbow.addAlias).to.be.a('function');
    });
});
<commit_msg>Add unit test for applying global class<commit_after>/* global Rainbow */

/////////////////////////
// Helpers and globals //
/////////////////////////

const expect = chai.expect;

////////////////
// Test suite //
////////////////

describe('Rainbow', () => {
    it('Basic things are defined', () => {
        expect(Rainbow).to.exist;
        expect(Rainbow.color).to.be.a('function');
        expect(Rainbow.extend).to.be.a('function');
        expect(Rainbow.onHighlight).to.be.a('function');
        expect(Rainbow.addClass).to.be.a('function');
        expect(Rainbow.addAlias).to.be.a('function');
    });

    it('Should apply global class', (done) => {
        Rainbow.extend([{
            name: 'name',
            pattern: /Craig/gm
        }]);

        Rainbow.addClass('global');

        Rainbow.color('My name is Craig', 'generic', function(result) {
            expect(result).to.equal('My name is Craig');
            done();
        });
    });
});
<|endoftext|>


<commit_before>/*!
 * jQuery lightweight plugin boilerplate
 * Original author: @ajpiano
 * Further changes, comments: @addyosmani
 * Licensed under the MIT license
 */

// the semi-colon before the function invocation is a safety
// net against concatenated scripts and/or other plugins
// that are not closed properly.
;(function ( $, window, document, undefined ) {

    // undefined is used here as the undefined global
    // variable in ECMAScript 3 and is mutable (i.e. it can
    // be changed by someone else). undefined isn't really
    // being passed in so we can ensure that its value is
    // truly undefined. In ES5, undefined can no longer be
    // modified.

    // window and document are passed through as local
    // variables rather than as globals, because this (slightly)
    // quickens the resolution process and can be more
    // efficiently minified (especially when both are
    // regularly referenced in your plugin).

    // Create the defaults once
    var pluginName = 'funloader',
        defaults = {
            propertyName: "value"
        };

    // The actual plugin constructor
    function Plugin( element, options ) {
        this.element = element;

        // jQuery has an extend method that merges the
        // contents of two or more objects, storing the
        // result in the first object. The first object
        // is generally empty because we don't want to alter
        // the default options for future instances of the plugin
        this.options = $.extend( {}, defaults, options) ;

        this._defaults = defaults;
        this._name = pluginName;

        this.init();
    }

    Plugin.prototype.init = function () {
        // Place initialization logic here
        // You already have access to the DOM element and
        // the options via the instance, e.g. this.element
        // and this.options

    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[pluginName] = function ( options ) {
        return this.each(function () {
            if (!$.data(this, 'plugin_' + pluginName)) {
                $.data(this, 'plugin_' + pluginName,
                new Plugin( this, options ));
            }
            var imagePath="/images/anim/100/";
            var imageNumber=Math.floor(Math.random()*35);
            console.log(imageNumber);
            if(imageNumber<10)imageNumber="00"+imageNumber;
            else if(imageNumber<99)imageNumber="0"+imageNumber;

            $(this).attr('src',imagePath+imageNumber+".gif");

        });
    }

})( jQuery, window, document );

$("#testloader").click(function() {
  $("img").funloader()
});
<commit_msg>loader<commit_after>/*!
 * jQuery lightweight plugin boilerplate
 * Original author: @ajpiano
 * Further changes, comments: @addyosmani
 * Licensed under the MIT license
 */

// the semi-colon before the function invocation is a safety
// net against concatenated scripts and/or other plugins
// that are not closed properly.
;(function ( $, window, document, undefined ) {

    // undefined is used here as the undefined global
    // variable in ECMAScript 3 and is mutable (i.e. it can
    // be changed by someone else). undefined isn't really
    // being passed in so we can ensure that its value is
    // truly undefined. In ES5, undefined can no longer be
    // modified.

    // window and document are passed through as local
    // variables rather than as globals, because this (slightly)
    // quickens the resolution process and can be more
    // efficiently minified (especially when both are
    // regularly referenced in your plugin).

    // Create the defaults once
    var pluginName = 'funloader',
        defaults = {
            propertyName: "value"
        };

    // The actual plugin constructor
    function Plugin( element, options ) {
        this.element = element;

        // jQuery has an extend method that merges the
        // contents of two or more objects, storing the
        // result in the first object. The first object
        // is generally empty because we don't want to alter
        // the default options for future instances of the plugin
        this.options = $.extend( {}, defaults, options) ;

        this._defaults = defaults;
        this._name = pluginName;

        this.init();
    }

    Plugin.prototype.init = function () {
        // Place initialization logic here
        // You already have access to the DOM element and
        // the options via the instance, e.g. this.element
        // and this.options

    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[pluginName] = function ( options ) {
        return this.each(function () {
            if (!$.data(this, 'plugin_' + pluginName)) {
                $.data(this, 'plugin_' + pluginName,
                new Plugin( this, options ));
            }
            var imagePath="/images/anim/100/";
            var imageNumber=Math.floor(Math.random()*38);
            console.log(imageNumber);
            if(imageNumber<10)imageNumber="00"+imageNumber;
            else if(imageNumber<99)imageNumber="0"+imageNumber;

            $(this).attr('src',imagePath+imageNumber+".gif");

        });
    }

})( jQuery, window, document );

$("#testloader").click(function() {
  $("img").funloader()
});
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    exec = require('child_process').exec;

gulp.task('jsdoc', function (done) {
    exec('npm docs', function (err, stdout, stderr) {
        console.log(stdout);
        console.log(stderr);

        done(err);
    });
});
<commit_msg>fix npm docs task<commit_after>var gulp = require('gulp'),
    exec = require('child_process').exec;

gulp.task('jsdoc', function (done) {
    exec('npm run docs', function (err, stdout, stderr) {
        console.log(stdout);
        console.log(stderr);

        done(err);
    });
});
<|endoftext|>