<commit_before>var e = module.exports = {};
var bu;
var tags = require('./../tags');

var bot;
e.init = (Tbot, blargutil) => {
    bot = Tbot;
    bu = blargutil;

    e.category = bu.CommandType.GENERAL;

};
e.requireCtx = require;

e.isCommand = true;
e.hidden = false;
e.usage = 'tag help';
e.info = 'Gets tag command help';
e.longinfo = `

        Tags are like public custom commands. You can create them on one guild, and use them on another. Anyone is
        capable of making tags. Tags use a tagging system, so they can can range from simple to
        complex. See the tag page for more details.

tag <name>

        Executes a tag with the given name.

tag create <name> <content>

        Creates a tag with the given name and content. The name must be unique.

tag edit <name> <content>

Edits an existing tag. You must own it to edit it!

tag delete <name>

Deletes the specified tag. You must own it to delete it!

tag raw <name>

Outputs the raw tag

tag author <name>

Tells you who made the specified tag

tag search <name>

Searches for tags with given name

tag list

Lists all tags

tag help

Gets basic tag help.
`;
e.alias = ['t'];

e.execute = (msg, words, text) => {
    if (words[1]) {
        var tagList;
        //       console.log(words[1]);
        //        console.log(words.length);
        switch (words[1].toLowerCase()) {
            case 'test':
                bu.sendMessageToDiscord(msg.channel.id, 'Test output:\n' + tags.processTag(msg, text.replace(words[0], '').trim().replace(words[1], '').trim(), '', 'testTag'));
                break;
            case 'create':
                if (words.length > 3) {

                    //  console.log('checking if tag exists');
                    bu.db.query(`select exists(select 1 from tag where title=?) as kek`,
                        [words[2]], (err, row) => {
                            //   console.log('now were cooking with gas');
                            if (row[0].kek == 0) {
                                var title = words[2].replace(/[^\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u005b\u005d\u005e\u005f\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u007b\u007c\u007d\u007e]/ig, '');
                                bu.db.query(`insert into tag (author, title, contents, lastmodified) values (?, ?, ?, NOW())`,
                                    [msg.author.id, title,
                                        text.replace(words[0], '').trim().replace(words[1], '').trim().replace(words[2], '').trim()]);
                                bu.sendMessageToDiscord(msg.channel.id, `✅ Tag \`${title}\` created. ✅`);
                            } else
                                bu.sendMessageToDiscord(msg.channel.id, `❌ That tag already exists! ❌`);
                        });
                }
                break;
            case 'rename':
                //          console.log('ohh la la')
                if (words.length > 3) {
                    bu.db.beginTransaction((err) => {
                        if (err) {
                            bu.db.rollback(() => {
                                console.log(err);
                                return;
                            });
                        }
                        bu.db.query(`select author, id from tag where title=?`,
                            [words[2]], (err, row) => {
                                //   console.log('now were cooking with gas');

                                if (row) {
                                    if (row[0].author != msg.author.id) {
                                        bu.sendMessageToDiscord(msg.channel.id, `❌ You don't own this tag! ❌`);
                                        //     bu.db.query(`END`);
                                        bu.db.commit((err) => {
                                            if (err) bu.db.rollback(() => {
                                                console.log(err);
                                            });
                                        });
                                        return;
                                    }
                                    bu.db.query(`select exists(select 1 from tag where title=?) as kek`,
                                        [words[3]], (err, row2) => {
                                            if (row2[0].kek == 0) {
                                                bu.db.query('update tag set title=? where id=?',
                                                    [words[3], row[0].id]);

                                                //  stmt = bu.db.prepare(`insert into tag (author, title, contents, lastmodified) values (?, ?, ?, datetime('now'))`)
                                                //    stmt.run(row.author, words[3], row.contents);
                                                //    stmt = bu.db.prepare(`delete from tag where title=?`)
                                                // stmt = bu.db.prepare(`update `)
                                                bu.db.commit((err) => {
                                                    if (err) bu.db.rollback(() => {
                                                        console.log(err);
                                                    });
                                                });
                                                bu.sendMessageToDiscord(msg.channel.id, `✅ Tag \`${words[2]}\` has been renamed to \`${words[3]}\`. ✅`);

                                            } else {
                                                bu.sendMessageToDiscord(msg.channel.id, `❌ The tag \`${words[3]}\` already exist! ❌`);
                                                bu.db.commit((err) => {
                                                    if (err) bu.db.rollback(() => {
                                                        console.log(err);
                                                    });
                                                });

                                            }
                                        });
                                } else {
                                    bu.sendMessageToDiscord(msg.channel.id, `❌ The tag \`${words[2]}\` doesn't exist! ❌`);
                                    bu.db.commit((err) => {
                                        if (err) bu.db.rollback(() => {
                                            console.log(err);
                                        });
                                    });
                                }
                            });
                    });
                }
                break;
            case 'edit':
                bu.db.query(`select author from tag where title=?`,
                    [words[2]], (err, row) => {
                        if (!row[0])
                            bu.sendMessageToDiscord(msg.channel.id, `❌ That tag doesn't exist! ❌`);
                        else if (row[0].author != msg.author.id)
                            bu.sendMessageToDiscord(msg.channel.id, `❌ You don't own this tag! ❌`);
                        else {
                            bu.db.query('update tag set contents=? where title=?',
                                [text.replace(words[0], '').trim().replace(words[1], '').trim().replace(words[2], '').trim(),
                                    words[2]]);
                            bu.sendMessageToDiscord(msg.channel.id, `✅ Tag \`${words[2]}\` edited. ✅`);

                        }
                    });
                break;
            case 'delete':
                bu.db.query(`select author from tag where title=?`, [words[2]], (err, row) => {
                    if (!row[0])
                        bu.sendMessageToDiscord(msg.channel.id, `❌ That tag doesn't exist! ❌`);
                    else if (row[0].author != msg.author.id)
                        bu.sendMessageToDiscord(msg.channel.id, `❌ You don't own this tag! ❌`);
                    else {
                        bu.db.query(`delete from tag where title=?`, [words[2]]);
                        bu.sendMessageToDiscord(msg.channel.id, `✅ Tag \`${words[2]}\` is gone forever! ✅`);
                    }
                });
                break;
            case 'help':
                bu.sendMessageToDiscord(msg.channel.id, tagHelp);
                break;
            case 'raw':
                bu.db.query(`select contents from tag where title=?`, [words[2]], (err, row) => {
                    if (!row[0])
                        bu.sendMessageToDiscord(msg.channel.id, `❌ That tag doesn't exist! ❌`);
                    else if (row[0].author != msg.author.id)
                        bu.sendMessageToDiscord(msg.channel.id, `The code for ${words[2]} is:
\`\`\`
${row[0].contents}
\`\`\``);
                });
                break;
            case 'author':
                bu.db.query(`select author from tag where title=?`, [words[2]], (err, row) => {
                    if (!row[0])
                        bu.sendMessageToDiscord(msg.channel.id, `❌ That tag doesn't exist! ❌`);
                    else {
                        bu.sendMessageToDiscord(msg.channel.id, `The tag \`${words[2]}\` was made by **${bot.users.get(row[0].author).username}#${bot.users.get(row[0].author).discriminator}**`);
                    }
                });
                break;
            case 'search':
                //    var tagList = 'Found these tags:\n';
                tagList = [];
                bu.db.query(`select title from tag where title like ?`, [`%${words[2]}%`], (err, row) => {
                    //     console.log('err');
                    //  if (!err)
                    for (i = 0; i < row.length; i++) {
                        tagList.push(row[i].title);
                    }
                    tagList.sort();
                    console.log('all done');
                    var message = `Found ${tagList.length} tags matching '${words[2]}'.\n\`\`\`${tagList.join(', ').trim()}\n\`\`\``;
                    bu.sendMessageToDiscord(msg.channel.id, message);
                });

                break;

            case 'list':
                if (!words[2]) {
                    tagList = [];
                    bu.db.query(`select title from tag`, (err, row) => {
                        for (var i = 0; i < row.length; i++) {
                            tagList.push(row[i].title);
                        }
                        tagList.sort();
                        console.log('all done');
                        var message = `Found ${tagList.length} tags.\n\`\`\`${tagList.join(', ').trim()}\n\`\`\``;
                        bu.sendMessageToDiscord(msg.channel.id, message);
                    });
                } else {
                    tagList = [];
                    var userToSearch = text.replace(words[0], '').trim().replace(words[1], '').trim();
                    console.log(userToSearch);
                    var obtainedUser = bu.getUserFromName(msg, userToSearch);
                    if (!obtainedUser) {
                        break;
                    }

                    bu.db.query(`select title from tag where author=?`, obtainedUser.id, (err, row) => {
                        //     console.log('err');
                        //  if (!err)
                        for (var i = 0; i < row.length; i++) {
                            tagList.push(row[i].title);
                        }
                        //   else {

                        //   }
                        tagList.sort();
                        console.log('all done');
                        var message = `Found ${tagList.length} tags made by **${obtainedUser.username}#${obtainedUser.discriminator}**.\n\`\`\`${tagList.join(', ').trim()}\n\`\`\``;
                        bu.sendMessageToDiscord(msg.channel.id, message);
                    });
                }
                break;
            default:
                var command = text.replace(words[0], '').trim().replace(words[1], '').trim();
                //    console.log('FUCK FUCK FUCK ' + command);
                tags.executeTag(msg, words[1], command);
                break;
        }
    } else {
        bu.sendMessageToDiscord(msg.channel.id, tagHelp);
    }
};

var tagHelp = `\`\`\`fix
Tag Usage
  Tag <name> - executes tag with given name
  Tag Create <name> <content> - creates a new tag with given name and content
  Tag Rename <tag1> <tag2> - renames the tag by the name of \`tag1\` to \`tag2\`
  Tag Edit <name> <content> - edits an existing tag with given content, provided that you were the one who created it
  Tag Delete <name> - deletes the tag with given name, provided that you own it
  Tag Raw <name> - displays the raw code of a tag
  Tag Author <tag> - displays the name of who made the tag
  Tag Search <name> - searches for a tag based on the provided name
  Tag List - lists all tags
  Tag Help - shows this message
NOTE: Any NSFW tags must contain '{nsfw}' somewhere in their body, or they will be deleted and you will be blacklisted.
\`\`\`
For more information about tags, visit https://blargbot.xyz/tags`;<commit_msg>tag tracking<commit_after>var e = module.exports = {};
var bu;
var tags = require('./../tags');

var bot;
e.init = (Tbot, blargutil) => {
    bot = Tbot;
    bu = blargutil;

    e.category = bu.CommandType.GENERAL;

};
e.requireCtx = require;

e.isCommand = true;
e.hidden = false;
e.usage = 'tag help';
e.info = 'Gets tag command help';
e.longinfo = `

        Tags are like public custom commands. You can create them on one guild, and use them on another. Anyone is
        capable of making tags. Tags use a tagging system, so they can can range from simple to
        complex. See the tag page for more details.

tag <name>

        Executes a tag with the given name.

tag create <name> <content>

        Creates a tag with the given name and content. The name must be unique.

tag edit <name> <content>

Edits an existing tag. You must own it to edit it!

tag delete <name>

Deletes the specified tag. You must own it to delete it!

tag raw <name>

Outputs the raw tag

tag author <name>

Tells you who made the specified tag

tag search <name>

Searches for tags with given name

tag list

Lists all tags

tag help

Gets basic tag help.
`;
e.alias = ['t'];

e.execute = (msg, words, text) => {
    if (words[1]) {
        var tagList;
        //       console.log(words[1]);
        //        console.log(words.length);
        switch (words[1].toLowerCase()) {
            case 'test':
                bu.sendMessageToDiscord(msg.channel.id, 'Test output:\n' + tags.processTag(msg, text.replace(words[0], '').trim().replace(words[1], '').trim(), '', 'testTag'));
                break;
            case 'create':
                if (words.length > 3) {

                    //  console.log('checking if tag exists');
                    bu.db.query(`select exists(select 1 from tag where title=?) as kek`,
                        [words[2]], (err, row) => {
                            //   console.log('now were cooking with gas');
                            if (row[0].kek == 0) {
                                var title = words[2].replace(/[^\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u005b\u005d\u005e\u005f\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u007b\u007c\u007d\u007e]/ig, '');
                                bu.db.query(`insert into tag (author, title, contents, lastmodified) values (?, ?, ?, NOW())`,
                                    [msg.author.id, title,
                                        text.replace(words[0], '').trim().replace(words[1], '').trim().replace(words[2], '').trim()]);
                                bu.sendMessageToDiscord(msg.channel.id, `✅ Tag \`${title}\` created. ✅`);
                        bu.send('230810364164440065', `**__Create__**:\n  **User:** ${msg.author.username} (${msg.author.id})\n  **Tag:** ${words[2]}\n  **Contents**: \`\`\`${text.replace(words[0], '').trim().replace(words[1], '').trim().replace(words[2], '').trim()}\`\`\``);

                            } else
                                bu.sendMessageToDiscord(msg.channel.id, `❌ That tag already exists! ❌`);
                        });
                }
                break;
            case 'rename':
                //          console.log('ohh la la')
                if (words.length > 3) {
                    bu.db.beginTransaction((err) => {
                        if (err) {
                            bu.db.rollback(() => {
                                console.log(err);
                                return;
                            });
                        }
                        bu.db.query(`select author, id from tag where title=?`,
                            [words[2]], (err, row) => {
                                //   console.log('now were cooking with gas');

                                if (row) {
                                    if (row[0].author != msg.author.id) {
                                        bu.sendMessageToDiscord(msg.channel.id, `❌ You don't own this tag! ❌`);
                                        //     bu.db.query(`END`);
                                        bu.db.commit((err) => {
                                            if (err) bu.db.rollback(() => {
                                                console.log(err);
                                            });
                                        });
                                        return;
                                    }
                                    bu.db.query(`select exists(select 1 from tag where title=?) as kek`,
                                        [words[3]], (err, row2) => {
                                            if (row2[0].kek == 0) {
                                                bu.db.query('update tag set title=? where id=?',
                                                    [words[3], row[0].id]);

                                                //  stmt = bu.db.prepare(`insert into tag (author, title, contents, lastmodified) values (?, ?, ?, datetime('now'))`)
                                                //    stmt.run(row.author, words[3], row.contents);
                                                //    stmt = bu.db.prepare(`delete from tag where title=?`)
                                                // stmt = bu.db.prepare(`update `)
                                                bu.db.commit((err) => {
                                                    if (err) bu.db.rollback(() => {
                                                        console.log(err);
                                                    });
                                                });
                                                bu.sendMessageToDiscord(msg.channel.id, `✅ Tag \`${words[2]}\` has been renamed to \`${words[3]}\`. ✅`);
                        bu.send('230810364164440065', `**__Rename__**:\n  **User:** ${msg.author.username} (${msg.author.id})\n  **Old Tag:** ${words[2]}\n  **New Tag**: ${words[3]}`);

                                            } else {
                                                bu.sendMessageToDiscord(msg.channel.id, `❌ The tag \`${words[3]}\` already exist! ❌`);
                                                bu.db.commit((err) => {
                                                    if (err) bu.db.rollback(() => {
                                                        console.log(err);
                                                    });
                                                });

                                            }
                                        });
                                } else {
                                    bu.sendMessageToDiscord(msg.channel.id, `❌ The tag \`${words[2]}\` doesn't exist! ❌`);
                                    bu.db.commit((err) => {
                                        if (err) bu.db.rollback(() => {
                                            console.log(err);
                                        });
                                    });
                                }
                            });
                    });
                }
                break;
            case 'edit':
                bu.db.query(`select author from tag where title=?`,
                    [words[2]], (err, row) => {
                        if (!row[0])
                            bu.sendMessageToDiscord(msg.channel.id, `❌ That tag doesn't exist! ❌`);
                        else if (row[0].author != msg.author.id)
                            bu.sendMessageToDiscord(msg.channel.id, `❌ You don't own this tag! ❌`);
                        else {
                            bu.db.query('update tag set contents=? where title=?',
                                [text.replace(words[0], '').trim().replace(words[1], '').trim().replace(words[2], '').trim(),
                                    words[2]]);
                            bu.sendMessageToDiscord(msg.channel.id, `✅ Tag \`${words[2]}\` edited. ✅`);
                        bu.send('230810364164440065', `**__Edit__**:\n  **User:** ${msg.author.username} (${msg.author.id})\n  **Tag:** ${words[2]}\n  **Contents**: \`\`\`${text.replace(words[0], '').trim().replace(words[1], '').trim().replace(words[2], '').trim()}\`\`\``);

                        }
                    });
                break;
            case 'delete':
                bu.db.query(`select author from tag where title=?`, [words[2]], (err, row) => {
                    if (!row[0])
                        bu.sendMessageToDiscord(msg.channel.id, `❌ That tag doesn't exist! ❌`);
                    else if (row[0].author != msg.author.id)
                        bu.sendMessageToDiscord(msg.channel.id, `❌ You don't own this tag! ❌`);
                    else {
                        bu.db.query(`delete from tag where title=?`, [words[2]]);
                        bu.sendMessageToDiscord(msg.channel.id, `✅ Tag \`${words[2]}\` is gone forever! ✅`);
                        bu.send('230810364164440065', `**__Delete__**:\n  **User:** ${msg.author.username} (${msg.author.id})\n  **Tag:** ${words[2]}`);
                    }
                });
                break;
            case 'help':
                bu.sendMessageToDiscord(msg.channel.id, tagHelp);
                break;
            case 'raw':
                bu.db.query(`select contents from tag where title=?`, [words[2]], (err, row) => {
                    if (!row[0])
                        bu.sendMessageToDiscord(msg.channel.id, `❌ That tag doesn't exist! ❌`);
                    else if (row[0].author != msg.author.id)
                        bu.sendMessageToDiscord(msg.channel.id, `The code for ${words[2]} is:
\`\`\`
${row[0].contents}
\`\`\``);
                });
                break;
            case 'author':
                bu.db.query(`select author from tag where title=?`, [words[2]], (err, row) => {
                    if (!row[0])
                        bu.sendMessageToDiscord(msg.channel.id, `❌ That tag doesn't exist! ❌`);
                    else {
                        bu.sendMessageToDiscord(msg.channel.id, `The tag \`${words[2]}\` was made by **${bot.users.get(row[0].author).username}#${bot.users.get(row[0].author).discriminator}**`);
                    }
                });
                break;
            case 'search':
                //    var tagList = 'Found these tags:\n';
                tagList = [];
                bu.db.query(`select title from tag where title like ?`, [`%${words[2]}%`], (err, row) => {
                    //     console.log('err');
                    //  if (!err)
                    for (i = 0; i < row.length; i++) {
                        tagList.push(row[i].title);
                    }
                    tagList.sort();
                    console.log('all done');
                    var message = `Found ${tagList.length} tags matching '${words[2]}'.\n\`\`\`${tagList.join(', ').trim()}\n\`\`\``;
                    bu.sendMessageToDiscord(msg.channel.id, message);
                });

                break;

            case 'list':
                if (!words[2]) {
                    tagList = [];
                    bu.db.query(`select title from tag`, (err, row) => {
                        for (var i = 0; i < row.length; i++) {
                            tagList.push(row[i].title);
                        }
                        tagList.sort();
                        console.log('all done');
                        var message = `Found ${tagList.length} tags.\n\`\`\`${tagList.join(', ').trim()}\n\`\`\``;
                        bu.sendMessageToDiscord(msg.channel.id, message);
                    });
                } else {
                    tagList = [];
                    var userToSearch = text.replace(words[0], '').trim().replace(words[1], '').trim();
                    console.log(userToSearch);
                    var obtainedUser = bu.getUserFromName(msg, userToSearch);
                    if (!obtainedUser) {
                        break;
                    }

                    bu.db.query(`select title from tag where author=?`, obtainedUser.id, (err, row) => {
                        //     console.log('err');
                        //  if (!err)
                        for (var i = 0; i < row.length; i++) {
                            tagList.push(row[i].title);
                        }
                        //   else {

                        //   }
                        tagList.sort();
                        console.log('all done');
                        var message = `Found ${tagList.length} tags made by **${obtainedUser.username}#${obtainedUser.discriminator}**.\n\`\`\`${tagList.join(', ').trim()}\n\`\`\``;
                        bu.sendMessageToDiscord(msg.channel.id, message);
                    });
                }
                break;
            default:
                var command = text.replace(words[0], '').trim().replace(words[1], '').trim();
                //    console.log('FUCK FUCK FUCK ' + command);
                tags.executeTag(msg, words[1], command);
                break;
        }
    } else {
        bu.sendMessageToDiscord(msg.channel.id, tagHelp);
    }
};

var tagHelp = `\`\`\`fix
Tag Usage
  Tag <name> - executes tag with given name
  Tag Create <name> <content> - creates a new tag with given name and content
  Tag Rename <tag1> <tag2> - renames the tag by the name of \`tag1\` to \`tag2\`
  Tag Edit <name> <content> - edits an existing tag with given content, provided that you were the one who created it
  Tag Delete <name> - deletes the tag with given name, provided that you own it
  Tag Raw <name> - displays the raw code of a tag
  Tag Author <tag> - displays the name of who made the tag
  Tag Search <name> - searches for a tag based on the provided name
  Tag List - lists all tags
  Tag Help - shows this message
NOTE: Any NSFW tags must contain '{nsfw}' somewhere in their body, or they will be deleted and you will be blacklisted.
\`\`\`
For more information about tags, visit https://blargbot.xyz/tags`;<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { Router, browserHistory } from 'react-router';

import routes from './routes';
import reducers from './reducers/store';
const createStoreWithMiddleware = applyMiddleware()(createStore);

// Initialize Firebase
import firebase from 'firebase';

// Alter before deployment to Heroku
// import { ENV } from './environment/environment';
const ENV = {
  apiKey: process.env.apiKey,
  authDomain: process.env.apiKey,
  databaseURL: process.env.databaseURL,
  storageBucket: process.env.storageBucket
};

const firebaseApp = firebase.initializeApp(ENV);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <Router history={browserHistory} routes={routes} />
  </Provider>
, document.getElementById('app'));
<commit_msg>Edit to ENV check<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { Router, browserHistory } from 'react-router';

import routes from './routes';
import reducers from './reducers/store';
const createStoreWithMiddleware = applyMiddleware()(createStore);

// Initialize Firebase
import firebase from 'firebase';

// Alter before deployment to Heroku
// import { ENV } from './environment/environment';
const ENV = {
  apiKey: process.env.apiKey,
  authDomain: process.env.apiKey,
  databaseURL: process.env.databaseURL,
  storageBucket: process.env.storageBucket
};
console.log('Checking retrieval of ENV', ENV);
const firebaseApp = firebase.initializeApp(ENV);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <Router history={browserHistory} routes={routes} />
  </Provider>
, document.getElementById('app'));
<|endoftext|>


<commit_before><commit_msg>bug: fix application erro on heroku [Fixes #134209527]<commit_after><|endoftext|>


<commit_before>
/* File contains spell definitions for the game. */

const RG = require('./rg');
// const Mixin = require('./mixin');

RG.Spell = {};

const compareSpells = function(s1, s2) {
    if (s1.getPower() < s2.getPower()) {
        return -1;
    }
    if (s2.getPower() > s1.getPower()) {
        return 1;
    }
    return 0;
};

RG.Spell.getSelectionObjectDir = function(spell, actor, msg) {
    RG.gameMsg(msg);
    return {
        select: (code) => {
            const args = {};
            args.dir = RG.KeyMap.getDir(code);
            if (args.dir) {
                args.src = actor;
                return () => {
                    const spellCast = new RG.Component.SpellCast();
                    spellCast.setSource(actor);
                    spellCast.setSpell(spell);
                    spellCast.setArgs(args);
                    actor.add('SpellCast', spellCast);
                };
            }
            return null;
        },
        showMenu: () => false
    };
};

const getDirSpellArgs = function(spell, args) {
    const src = args.src;
    const dir = args.dir;
    const x = src.getX();
    const y = src.getY();
    const obj = {
        from: [x, y],
        dir,
        spell: spell,
        src: args.src
    };
    return obj;
};

/* A list of spells known by a single actor. */
RG.Spell.SpellBook = function(actor) {
    const _actor = actor;
    const _spells = [];

    this.getActor = function() {return _actor;};

    this.addSpell = function(spell) {
        _spells.push(spell);
    };

    this.getSpells = function() {
        return _spells;
    };

    /* Returns the object which is used in Brain.Player to make the player
     * selection of spell casting. */
    this.getSelectionObject = function() {
        const powerSorted = _spells.sort(compareSpells);
        return {
            select: function(code) {
                const selection = RG.codeToIndex(code);
                if (selection < powerSorted.length) {
                    return powerSorted[selection].getSelectionObject(actor);
                }
                return null;
            },
            getMenu: function() {
                RG.gameMsg('Please select a spell to cast:');
                const indices = RG.menuIndices.slice(0, _spells.length);
                const obj = {};
                powerSorted.forEach((spell, index) => {
                    obj[indices[index]] = spell.toString();
                });
                return obj;
            },
            showMenu: () => true
        };
    };

    this.toJSON = function() {
        return {
            spells: _spells.map(spell => spell.toJSON())
        };
    };
};

/* Base object for all spells. */
RG.Spell.Base = function(name, power) {
    const _name = name;
    let _power = power || 5;

    this.getName = function() {return _name;};

    this.getPower = function() {return _power;};
    this.setPower = function(power) {_power = power;};

    this.toString = function() {
        const str = `${_name} - ${_power}PP`;
        return str;
    };

    this.toJSON = function() {
        return {
            power: _power
        };
    };

};

RG.Spell.FrostBolt = function() {
    RG.Spell.Base.call(this, 'Frost bolt');

    let _damageDie = RG.FACT.createDie('4d4 + 4');
    let _range = 5;

    this.getRange = function() {return _range;};
    this.setRange = function(range) {_range = range;};
    this.setDice = function(dice) {
        _damageDie = dice[0];
    };
    this.getDice = function() {return [_damageDie];};

    this.cast = function(args) {
        const obj = getDirSpellArgs(this, args);
        obj.damageType = 'ice';
        obj.damage = _damageDie.roll();
        const rayComp = new RG.Component.SpellRay();
        rayComp.setArgs(obj);
        args.src.add('SpellRay', rayComp);
    };

    this.toString = function() {
        let str = `${this.getName()} - ${this.getPower()}pp`;
        str += `D: ${_damageDie.toString()} R: ${_range}`;
        return str;
    };

    this.getSelectionObject = function(actor) {
        RG.gameMsg('Select a direction for firing:');
        return {
            select: (code) => {
                const dir = RG.KeyMap.getDir(code);
                return this.getCastFunc(actor, {dir});
            },
            showMenu: () => false
        };
    };

    this.getCastFunc = function(actor, args) {
        if (args.dir) {
            args.src = actor;
            return () => {
                const spellCast = new RG.Component.SpellCast();
                spellCast.setSource(actor);
                spellCast.setSpell(this);
                spellCast.setArgs(args);
                actor.add('SpellCast', spellCast);
                console.log('Added SpellCast comp');
            };
        }
        return null;
    };

    this.toJSON = function() {
        return {
            name: this.getName(),
            power: this.getPower(),
            range: _range,
            dice: [_damageDie.toJSON()],
            new: 'FrostBolt'
        };
    };

    this.aiShouldCastSpell = function(args) {
        const {actor, enemy} = args;
        const [x0, y0] = [actor.getX(), actor.getY()];
        const [x1, y1] = [enemy.getX(), enemy.getY()];
        const lineXY = RG.Geometry.getStraightLine(x0, y0, x1, y1);
        if (lineXY.length > 1) {
            const dX = lineXY[1][0] - lineXY[0][0];
            const dY = lineXY[1][1] - lineXY[0][1];
            actor.getBrain().setSpellArgs({dir: [dX, dY]});
            return true;
        }
        return false;
    };

};
RG.extend2(RG.Spell.FrostBolt, RG.Spell.Base);

/* Ice shield increase the defense of the caster temporarily. */
RG.Spell.IceShield = function() {
    RG.Spell.Base.call(this, 'Ice shield', 7);

    const _duration = RG.FACT.createDie('5d5 + 5');
    const _defenseDie = RG.FACT.createDie('1d6 + 1');

    this.cast = function(args) {
        const actor = args.src;
        const dur = _duration.roll();
        const combatMods = new RG.Component.CombatMods();
        combatMods.setDefense(_defenseDie.roll());
        if (actor.has('Expiration')) {
            actor.get('Expiration').addEffect(combatMods, dur);
        }
        else {
            const expComp = new RG.Component.Expiration();
            expComp.addEffect(combatMods, dur);
            actor.add('Expiration', expComp);
        }
        RG.gameMsg('You feel a boost to your defense.');
    };

    this.getSelectionObject = function(actor) {
        const func = () => {
            const spellCast = new RG.Component.SpellCast();
            spellCast.setSource(actor);
            spellCast.setSpell(this);
            spellCast.setArgs({src: actor});
            actor.add('SpellCast', spellCast);
        };
        return func;
    };

};
RG.extend2(RG.Spell.IceShield, RG.Spell.Base);

RG.Spell.GraspOfWinter = function() {
    RG.Spell.Base.call(this, 'Grasp of winter');
    const _damageDie = RG.FACT.createDie('4d4 + 4');

    this.cast = function(args) {
        const obj = getDirSpellArgs(this, args);
        obj.damageType = 'ice';
        obj.damage = _damageDie.roll();
        const spellComp = new RG.Component.SpellCell();
        spellComp.setArgs(obj);
        args.src.add('SpellCell', spellComp);
    };

    this.getSelectionObject = function(actor) {
        const msg = 'Select a direction for grasping:';
        return RG.Spell.getSelectionObjectDir(this, actor, msg);
    };
};
RG.extend2(RG.Spell.GraspOfWinter, RG.Spell.Base);

/* Healing spell, duh. */
RG.Spell.Heal = function() {
    RG.Spell.Base.call(this, 'Heal', 6);

    const _healingDie = RG.FACT.createDie('2d4');

    this.cast = function(args) {
        const obj = getDirSpellArgs(this, args);
        obj.targetComp = 'Health';
        obj.set = 'addHP';
        obj.value = _healingDie.roll();
        const spellComp = new RG.Component.SpellCell();
        spellComp.setArgs(obj);
        args.src.add('SpellCell', spellComp);
    };

    this.getSelectionObject = function(actor) {
        const msg = 'Select a direction for healing:';
        return RG.Spell.getSelectionObjectDir(this, actor, msg);
    };
};
RG.extend2(RG.Spell.Heal, RG.Spell.Base);

RG.Spell.addAllSpells = function(book) {
    book.addSpell(new RG.Spell.FrostBolt());
    book.addSpell(new RG.Spell.IceShield());
    book.addSpell(new RG.Spell.GraspOfWinter());
    book.addSpell(new RG.Spell.Heal());
};

module.exports = RG.Spell;
<commit_msg>Added Spell.IcyPrison.<commit_after>
/* File contains spell definitions for the game. */

const RG = require('./rg');
// const Mixin = require('./mixin');

RG.Spell = {};

const compareSpells = function(s1, s2) {
    if (s1.getPower() < s2.getPower()) {
        return -1;
    }
    if (s2.getPower() > s1.getPower()) {
        return 1;
    }
    return 0;
};

const addToExpirationComp = function(actor, comp, dur) {
    if (actor.has('Expiration')) {
        actor.get('Expiration').addEffect(comp, dur);
    }
    else {
        const expComp = new RG.Component.Expiration();
        expComp.addEffect(comp, dur);
        actor.add('Expiration', expComp);
    }
};

RG.Spell.getSelectionObjectDir = function(spell, actor, msg) {
    RG.gameMsg(msg);
    return {
        select: (code) => {
            const args = {};
            args.dir = RG.KeyMap.getDir(code);
            if (args.dir) {
                args.src = actor;
                return () => {
                    const spellCast = new RG.Component.SpellCast();
                    spellCast.setSource(actor);
                    spellCast.setSpell(spell);
                    spellCast.setArgs(args);
                    actor.add('SpellCast', spellCast);
                };
            }
            return null;
        },
        showMenu: () => false
    };
};

const getDirSpellArgs = function(spell, args) {
    const src = args.src;
    const dir = args.dir;
    const x = src.getX();
    const y = src.getY();
    const obj = {
        from: [x, y],
        dir,
        spell: spell,
        src: args.src
    };
    return obj;
};

/* A list of spells known by a single actor. */
RG.Spell.SpellBook = function(actor) {
    const _actor = actor;
    const _spells = [];

    this.getActor = function() {return _actor;};

    this.addSpell = function(spell) {
        _spells.push(spell);
    };

    this.getSpells = function() {
        return _spells;
    };

    /* Returns the object which is used in Brain.Player to make the player
     * selection of spell casting. */
    this.getSelectionObject = function() {
        const powerSorted = _spells.sort(compareSpells);
        return {
            select: function(code) {
                const selection = RG.codeToIndex(code);
                if (selection < powerSorted.length) {
                    return powerSorted[selection].getSelectionObject(actor);
                }
                return null;
            },
            getMenu: function() {
                RG.gameMsg('Please select a spell to cast:');
                const indices = RG.menuIndices.slice(0, _spells.length);
                const obj = {};
                powerSorted.forEach((spell, index) => {
                    obj[indices[index]] = spell.toString();
                });
                return obj;
            },
            showMenu: () => true
        };
    };

    this.toJSON = function() {
        return {
            spells: _spells.map(spell => spell.toJSON())
        };
    };
};

/* Base object for all spells. */
RG.Spell.Base = function(name, power) {
    const _name = name;
    let _power = power || 5;

    this.getName = function() {return _name;};

    this.getPower = function() {return _power;};
    this.setPower = function(power) {_power = power;};

    this.toString = function() {
        const str = `${_name} - ${_power}PP`;
        return str;
    };

    this.toJSON = function() {
        return {
            power: _power
        };
    };

};

RG.Spell.FrostBolt = function() {
    RG.Spell.Base.call(this, 'Frost bolt');

    let _damageDie = RG.FACT.createDie('4d4 + 4');
    let _range = 5;

    this.getRange = function() {return _range;};
    this.setRange = function(range) {_range = range;};
    this.setDice = function(dice) {
        _damageDie = dice[0];
    };
    this.getDice = function() {return [_damageDie];};

    this.cast = function(args) {
        const obj = getDirSpellArgs(this, args);
        obj.damageType = 'ice';
        obj.damage = _damageDie.roll();
        const rayComp = new RG.Component.SpellRay();
        rayComp.setArgs(obj);
        args.src.add('SpellRay', rayComp);
    };

    this.toString = function() {
        let str = `${this.getName()} - ${this.getPower()}pp`;
        str += `D: ${_damageDie.toString()} R: ${_range}`;
        return str;
    };

    this.getSelectionObject = function(actor) {
        RG.gameMsg('Select a direction for firing:');
        return {
            select: (code) => {
                const dir = RG.KeyMap.getDir(code);
                return this.getCastFunc(actor, {dir});
            },
            showMenu: () => false
        };
    };

    this.getCastFunc = function(actor, args) {
        if (args.dir) {
            args.src = actor;
            return () => {
                const spellCast = new RG.Component.SpellCast();
                spellCast.setSource(actor);
                spellCast.setSpell(this);
                spellCast.setArgs(args);
                actor.add('SpellCast', spellCast);
                console.log('Added SpellCast comp');
            };
        }
        return null;
    };

    this.toJSON = function() {
        return {
            name: this.getName(),
            power: this.getPower(),
            range: _range,
            dice: [_damageDie.toJSON()],
            new: 'FrostBolt'
        };
    };

    this.aiShouldCastSpell = function(args) {
        const {actor, enemy} = args;
        const [x0, y0] = [actor.getX(), actor.getY()];
        const [x1, y1] = [enemy.getX(), enemy.getY()];
        const lineXY = RG.Geometry.getStraightLine(x0, y0, x1, y1);
        if (lineXY.length > 1) {
            const dX = lineXY[1][0] - lineXY[0][0];
            const dY = lineXY[1][1] - lineXY[0][1];
            actor.getBrain().setSpellArgs({dir: [dX, dY]});
            return true;
        }
        return false;
    };

};
RG.extend2(RG.Spell.FrostBolt, RG.Spell.Base);

/* Ice shield increase the defense of the caster temporarily. */
RG.Spell.IceShield = function() {
    RG.Spell.Base.call(this, 'Ice shield', 7);

    const _duration = RG.FACT.createDie('5d5 + 5');
    const _defenseDie = RG.FACT.createDie('1d6 + 1');

    this.cast = function(args) {
        const actor = args.src;
        const dur = _duration.roll();
        const combatMods = new RG.Component.CombatMods();
        combatMods.setDefense(_defenseDie.roll());
        addToExpirationComp(actor, combatMods, dur);
        RG.gameMsg('You feel a boost to your defense.');
    };

    this.getSelectionObject = function(actor) {
        const func = () => {
            const spellCast = new RG.Component.SpellCast();
            spellCast.setSource(actor);
            spellCast.setSpell(this);
            spellCast.setArgs({src: actor});
            actor.add('SpellCast', spellCast);
        };
        return func;
    };

};
RG.extend2(RG.Spell.IceShield, RG.Spell.Base);

RG.Spell.GraspOfWinter = function() {
    RG.Spell.Base.call(this, 'Grasp of winter');
    const _damageDie = RG.FACT.createDie('4d4 + 4');

    this.cast = function(args) {
        const obj = getDirSpellArgs(this, args);
        obj.damageType = 'ice';
        obj.damage = _damageDie.roll();
        const spellComp = new RG.Component.SpellCell();
        spellComp.setArgs(obj);
        args.src.add('SpellCell', spellComp);
    };

    this.getSelectionObject = function(actor) {
        const msg = 'Select a direction for grasping:';
        return RG.Spell.getSelectionObjectDir(this, actor, msg);
    };
};
RG.extend2(RG.Spell.GraspOfWinter, RG.Spell.Base);

/* IcyPrison spell which paralyses actors for a certain duration. */
RG.Spell.IcyPrison = function() {
    RG.Spell.Base.call(this, 'Icy prison', 10);

    const _duration = RG.FACT.createDie('1d6 + 1');

    this.cast = function(args) {
        const obj = getDirSpellArgs(this, args);
        const dur = _duration.roll();

        const paralysis = new RG.Component.Paralysis();
        paralysis.setSource(args.src);
        obj.addComp = {comp: paralysis, duration: dur};

        const spellComp = new RG.Component.SpellCell();
        spellComp.setArgs(obj);
        args.src.add('SpellCell', spellComp);
    };

    this.getSelectionObject = function(actor) {
        const msg = 'Select a direction for casting:';
        return RG.Spell.getSelectionObjectDir(this, actor, msg);
    };

};

/* Healing spell, duh. */
RG.Spell.Heal = function() {
    RG.Spell.Base.call(this, 'Heal', 6);

    const _healingDie = RG.FACT.createDie('2d4');

    this.cast = function(args) {
        const obj = getDirSpellArgs(this, args);
        obj.targetComp = 'Health';
        obj.set = 'addHP';
        obj.value = _healingDie.roll();
        const spellComp = new RG.Component.SpellCell();
        spellComp.setArgs(obj);
        args.src.add('SpellCell', spellComp);
    };

    this.getSelectionObject = function(actor) {
        const msg = 'Select a direction for healing:';
        return RG.Spell.getSelectionObjectDir(this, actor, msg);
    };
};
RG.extend2(RG.Spell.Heal, RG.Spell.Base);

RG.Spell.addAllSpells = function(book) {
    book.addSpell(new RG.Spell.FrostBolt());
    book.addSpell(new RG.Spell.IceShield());
    book.addSpell(new RG.Spell.GraspOfWinter());
    book.addSpell(new RG.Spell.IcyPrison());
    book.addSpell(new RG.Spell.Heal());
};

module.exports = RG.Spell;
<|endoftext|>


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

    // Use a common namespace
    var module;
    try {
        module = angular.module('coUtils');
    } catch (e) {
        module = angular.module('coUtils', ['ngGesture']);
    }

    // Ensures this module is loaded.
    angular.module('ngGesture');

    module
        .directive('coRange', [
                '$timeout',
            function ($timeout) {
                return {
                    restrict: 'A',
                    scope: {
                        model: '=?',
                        min: '=?',
                        max: '=?',
                        step: '=?',
                        precision: '=?',
                        horizontal: '=?',
                        disabled: '=?',
                        userCallback: '=?',
                        dragging: '=?'
                    },

                    template:
                        '
' +
                            '

' +
                            '

' +
                            '

' +
                        '
',

                    link: function($scope, $element, attrs) {
                        var input    = $element.find('input'),
                            handle   = $element.find('.handle'),
                            progress = $element.find('.progress'),

                            // Don't override scope variable (may not be set yet)
                            minVal = $scope.min || 0,
                            maxVal = $scope.max || 100;

                        // defaults
                        $scope.step = $scope.step || 1;
                        $scope.horizontal = $scope.horizontal !== false;
                        $scope.disabled = $scope.disabled === false || attrs.hasOwnProperty('disabled');

                        // Add class to outer element (no replace)
                        $element.addClass('co-range-slider');
                        if (!$scope.horizontal) {
                            $element.addClass('vert');
                        }

                        // Keep precision in sync
                        var precision,
                            setPrecision = function () {
                                precision = Math.pow(10, $scope.precision || $scope.step);
                            };
                        $scope.$watch('precision', setPrecision);
                        $scope.$watch('step',      setPrecision);
                        $scope.$watch('min',       function (value) {
                            minVal = value || 0;
                        });
                        $scope.$watch('max',       function (value) {
                            maxVal = value || 100;
                        });

                        // Keep orientation in sync
                        var handleProperty,
                            progressProperty;

                        $scope.$watch('horizontal', function (horizontal) {
                            if (handleProperty !== undefined) {
                                // remove the old styles
                                progress.css(progressProperty, '');
                                handle.css(handleProperty, '');
                            }

                            if (horizontal) {
                                handleProperty   = 'left';
                                progressProperty = 'width';
                                $element.removeClass('vert');
                            } else {
                                handleProperty   = 'bottom';
                                progressProperty = 'height';
                                $element.addClass('vert');
                            }

                            // Update to the new orientation
                            $timeout(slide, 0, false);
                        });

                        // ---------------------
                        // binding
                        // ---------------------
                        var lastModelValue = 0;

                        $scope.$watch('model', function(val) {
                            // Ensure we are always in a valid range
                            if (val < minVal) {
                                $scope.model = minVal;
                                val = $scope.model;
                            } else if (val > maxVal) {
                                $scope.model = maxVal;
                                val = $scope.model;
                            }

                            if ($scope.dragging) {
                                lastModelValue = val;
                                return;
                            } else if (val !== $scope.value && $scope.model !== undefined && $scope.model !== null) {
                                $scope.value = val;
                                slide();
                            }
                        });

                        // ---------------------
                        // rendering
                        // ---------------------
                        function calculateValue(event) {
                            if ($scope.horizontal) {
                                var pos = event.center.pageX - $element.offset().left;
                                var percent = pos / $element.width();
                            } else {
                                var pos = event.center.pageY - $element.offset().top;
                                var percent = 1 - (pos / $element.height());
                            }

                            // Normalise the range
                            var range = maxVal - minVal;

                            // expand the value to an number min...max, and clip
                            // it to a multiple of step
                            var stepped = Math.round((percent * range) / $scope.step) * $scope.step;

                            // round the stepped value to a precision level
                            var rounded = Math.round(stepped * precision) / precision;

                            // constraint min..X..max
                            return Math.min(maxVal, Math.max(minVal, (rounded + minVal)));
                        }

                        function slide() {
                            var percent = (($scope.value - minVal) / (maxVal - minVal)) * 100;
                            progress.css(progressProperty, percent + '%');
                            handle.css(handleProperty, percent + '%');
                        }

                        function handleEvent(event) {
                            $scope.value = calculateValue(event);
                            $scope.model = $scope.value;
                            slide();

                            if ($scope.userCallback)
                                $scope.userCallback($scope.value);
                        }

                        // ---------------------
                        // events
                        // ---------------------
                        $scope.clicked = function(event) {
                            if ($scope.disabled || event.target === handle[0]) {
                                event.stopPropagation();
                                return event.preventDefault();
                            } else {
                                handleEvent(event);
                            }
                        }

                        $scope.dragStart = function(event) {
                            event.stopPropagation();
                            event.preventDefault();
                            if (!$scope.disabled) {
                                $scope.dragging = true;
                                lastModelValue = $scope.value;
                            }
                        };

                        $scope.drag = function(event) {
                            if ($scope.disabled)
                                return;
                            else
                                handleEvent(event);
                        };

                        $scope.dragEnd = function() {
                            $scope.dragging = false;
                            $scope.value = lastModelValue;
                            slide();
                        };

                        // ---------------------
                        // initialisation
                        // ---------------------
                        $scope.value = $scope.model || minVal;
                        $scope.dragging = false;
                        // NOTE:: the watch on scope.horizontal will set the initial slide value
                    }
                }
            }
        ]);

}(this.angular));
<commit_msg>slider should only change the model on user input<commit_after>(function (angular) {
    'use strict';

    // Use a common namespace
    var module;
    try {
        module = angular.module('coUtils');
    } catch (e) {
        module = angular.module('coUtils', ['ngGesture']);
    }

    // Ensures this module is loaded.
    angular.module('ngGesture');

    module
        .directive('coRange', [
                '$timeout',
            function ($timeout) {
                return {
                    restrict: 'A',
                    scope: {
                        model: '=?',
                        min: '=?',
                        max: '=?',
                        step: '=?',
                        precision: '=?',
                        horizontal: '=?',
                        disabled: '=?',
                        userCallback: '=?',
                        dragging: '=?'
                    },

                    template:
                        '
' +
                            '

' +
                            '

' +
                            '

' +
                        '
',

                    link: function($scope, $element, attrs) {
                        var input    = $element.find('input'),
                            handle   = $element.find('.handle'),
                            progress = $element.find('.progress'),

                            // Don't override scope variable (may not be set yet)
                            minVal = $scope.min || 0,
                            maxVal = $scope.max || 100;

                        // defaults
                        $scope.step = $scope.step || 1;
                        $scope.horizontal = $scope.horizontal !== false;
                        $scope.disabled = $scope.disabled === false || attrs.hasOwnProperty('disabled');

                        // Add class to outer element (no replace)
                        $element.addClass('co-range-slider');
                        if (!$scope.horizontal) {
                            $element.addClass('vert');
                        }

                        // Keep precision in sync
                        var precision,
                            setPrecision = function () {
                                precision = Math.pow(10, $scope.precision || $scope.step);
                            },
                            updateSlider = function () {
                                $timeout(function () {
                                    if (minVal < maxVal) {
                                        setValue($scope.model || minVal);
                                    }
                                }, 0, false);
                            };

                        $scope.$watch('precision', setPrecision);
                        $scope.$watch('step',      setPrecision);
                        $scope.$watch('min',       function (value) {
                            minVal = value || 0;

                            // Slide if the value has been updated
                            if (!isNaN(value)) { updateSlider(); }
                        });
                        $scope.$watch('max',       function (value) {
                            maxVal = value || 100;

                            // Slide if the value has been updated
                            if (!isNaN(value)) { updateSlider(); }
                        });

                        // Keep orientation in sync
                        var handleProperty,
                            progressProperty;

                        $scope.$watch('horizontal', function (horizontal) {
                            if (handleProperty !== undefined) {
                                // remove the old styles
                                progress.css(progressProperty, '');
                                handle.css(handleProperty, '');
                            }

                            if (horizontal) {
                                handleProperty   = 'left';
                                progressProperty = 'width';
                                $element.removeClass('vert');
                            } else {
                                handleProperty   = 'bottom';
                                progressProperty = 'height';
                                $element.addClass('vert');
                            }

                            // Update to the new orientation
                            $timeout(slide, 0, false);
                        });

                        // ---------------------
                        // binding
                        // ---------------------
                        var lastModelValue = 0,
                            setValue = function (val) {
                                // Ensure we are always in a valid range
                                if (val < minVal) {
                                    val = minVal;
                                } else if (val > maxVal) {
                                    val = maxVal;
                                }

                                if ($scope.dragging) {
                                    lastModelValue = val;
                                    return;
                                } else if (val !== $scope.value) {
                                    $scope.value = val;
                                    slide();
                                }
                            };

                        $scope.$watch('model', function(val) {
                            if (isNaN(val)) { return; }

                            // Ensure we are always in a valid range
                            setValue(val);
                        });

                        // ---------------------
                        // rendering
                        // ---------------------
                        function calculateValue(event) {
                            if ($scope.horizontal) {
                                var pos = event.center.pageX - $element.offset().left;
                                var percent = pos / $element.width();
                            } else {
                                var pos = event.center.pageY - $element.offset().top;
                                var percent = 1 - (pos / $element.height());
                            }

                            // Normalise the range
                            var range = maxVal - minVal;

                            // expand the value to an number min...max, and clip
                            // it to a multiple of step
                            var stepped = Math.round((percent * range) / $scope.step) * $scope.step;

                            // round the stepped value to a precision level
                            var rounded = Math.round(stepped * precision) / precision;

                            // constraint min..X..max
                            return Math.min(maxVal, Math.max(minVal, (rounded + minVal)));
                        }

                        function slide() {
                            var percent = (($scope.value - minVal) / (maxVal - minVal)) * 100;
                            progress.css(progressProperty, percent + '%');
                            handle.css(handleProperty, percent + '%');
                        }

                        function handleEvent(event) {
                            $scope.value = calculateValue(event);
                            $scope.model = $scope.value;
                            slide();

                            if ($scope.userCallback)
                                $scope.userCallback($scope.value);
                        }

                        // ---------------------
                        // events
                        // ---------------------
                        $scope.clicked = function(event) {
                            if ($scope.disabled || event.target === handle[0]) {
                                event.stopPropagation();
                                return event.preventDefault();
                            } else {
                                handleEvent(event);
                            }
                        }

                        $scope.dragStart = function(event) {
                            event.stopPropagation();
                            event.preventDefault();
                            if (!$scope.disabled) {
                                $scope.dragging = true;
                                lastModelValue = $scope.value;
                            }
                        };

                        $scope.drag = function(event) {
                            if ($scope.disabled)
                                return;
                            else
                                handleEvent(event);
                        };

                        $scope.dragEnd = function() {
                            $scope.dragging = false;
                            $scope.value = lastModelValue;
                            slide();
                        };

                        // ---------------------
                        // initialisation
                        // ---------------------
                        $scope.value = $scope.model || minVal;
                        $scope.dragging = false;
                        // NOTE:: the watch on scope.horizontal will set the initial slide value
                    }
                }
            }
        ]);

}(this.angular));
<|endoftext|>


<commit_before>(function () {
  atc = function (elementID) {
    var Timeline = function (elementID) {
      this.element = typeof elementID === "string" ? document.getElementById(elementID) : elementID || {};
      this.queue = [];
      this.queueIndex = 0;
      this.stopped = false;
      this.duration = 0;
      this.endText = "";
      this.defaults = {
        frameRate: atc.defaults.frameRate,
        pauseDuration: atc.defaults.pauseDuration,
        loop: atc.defaults.loop
      };
    };

    Timeline.prototype.go = function (timelineObj) {
      var thiz = this,
          funktion,
          len,
          nextAnimation;

      if (timelineObj) {
        funktion = function () {
          timelineObj.go();
        };

        this.addToQueue(funktion, timelineObj.duration, timelineObj.endText);
      } else {
        len = this.queue.length;
        this.stopped = false;

        nextAnimation = function () {
          if (thiz.queueIndex < len && !thiz.stopped) {
            thiz.queue[thiz.queueIndex].funktion();
            setTimeout(nextAnimation, thiz.queue[thiz.queueIndex].duration);
            thiz.queueIndex += 1;
          } else if (!thiz.stopped) {
            thiz.queueIndex = 0;
            if (thiz.defaults.loop) {
              nextAnimation();
            }
          }
        };

        nextAnimation();
      }

      return this;
    };

    Timeline.prototype.stop = function () {
      var thiz = this,
      funktion = function () {
        thiz.stopped = true;
      };

      this.addToQueue(funktion, 0, this.findText());

      return this;
    };

    Timeline.prototype.frameRate = function (frameRate) {
      this.defaults.frameRate = frameRate || this.defaults.frameRate;

      return this;
    };

    Timeline.prototype.pauseDuration = function (duration) {
      this.defaults.pauseDuration = duration || this.defaults.pauseDuration;

      return this;
    };

    Timeline.prototype.loop = function (bool) {
      this.defaults.loop = typeof bool === "undefined" ? true : bool;

      return this;
    };

    Timeline.prototype.findText = function () {
      var text;

      try {
        text = this.queue[this.queue.length - 1].endText;
      } catch (e) {
        text = this.element.textContent;
      }

      return text;
    };

    Timeline.prototype.addToQueue = function (funktion, duration, endText) {
      this.duration += duration;
      this.endText = endText;
      this.queue.push({ funktion: funktion, duration: duration, endText: endText });
    };

    Timeline.prototype.on = function (eventType, funktion, useCapture) {
      useCapture = useCapture || false;
      this.element.addEventListener(eventType, funktion, useCapture);

      return this;
    };

    Timeline.prototype.text = function (text) {
      if (text) {
        var thiz = this,
            funktion;

        funktion = function () {
          thiz.element.textContent = text;
        };

        this.addToQueue(funktion, 0, text);

        return this;
      } else {
        return this.element.textContent;
      }
    };

    Timeline.prototype.html = function (html) {
      var thiz = this,
      funktion = function () {
        thiz.element.innerHTML = html;
      };

      this.addToQueue(funktion, 0, html);

      return this;
    };

    Timeline.prototype.switchElement = function (elementID) {
      var thiz = this,
      funktion = function () {
        thiz.element = typeof elementID === "string" ? document.getElementById(elementID) : elementID;
      };

      this.addToQueue(funktion, 0, this.element.textContent); // TODO fix endText value

      return this;
    };

    Timeline.prototype.custom = function (funktion, duration, endText) {
      duration = duration || 0;
      endText = endText || this.findText();

      this.addToQueue(funktion, duration, endText);

      return this;
    };

    Timeline.prototype.frameByFrame = function (frames, loops, duration) {
      var thiz = this,
          len = frames.length,
          lastFrame = frames[len - 1],
          totalFrames,
          frameRate,
          funktion,
          i = 0;

      loops = loops || 1;
      totalFrames = len * loops;
      duration = duration || totalFrames * this.defaults.frameRate;
      frameRate = duration / totalFrames;

      funktion = function () {
        if (i < totalFrames) {
          thiz.element.textContent = frames[i % len];

          setTimeout(funktion, frameRate);
          i++;
        } else {
          i = 0;
        }
      };

      this.addToQueue(funktion, duration, lastFrame);

      return this;
    };

    Timeline.prototype.rollNumbers = function (startValue, endValue, increment, duration) {
      var thiz = this,
          difference = endValue - startValue,
          newValue = startValue,
          addFrame,
          totalFrames,
          frameRate,
          funktion,
          i = 0;

      increment = increment || 1;
      addFrame = increment;

      if (difference < 0) {
        difference = -difference;
        addFrame = -addFrame;
      }

      totalFrames = difference / increment;
      frameRate = duration / totalFrames || this.defaults.frameRate;
      duration = duration || this.defaults.frameRate * totalFrames;

      funktion = function () {
        if (i < totalFrames) {
          newValue += addFrame;
          thiz.element.textContent = newValue;

          setTimeout(funktion, frameRate);
          i++;
        } else {
          thiz.element.textContent = endValue;
          newValue = startValue;
          i = 0;
        }
      };

      this.addToQueue(funktion, duration, endValue);

      return this;
    };

    Timeline.prototype.erase = function (duration) {
      var thiz = this,
          originalText = this.findText(),
          textArray = originalText.split(''),
          len = originalText.length,
          frameRate = duration / len || this.defaults.frameRate,
          funktion,
          i = 0;

      duration = duration || this.defaults.frameRate * len;

      funktion = function () {
        if (i < len) {
          textArray.pop();
          thiz.element.textContent = textArray.join('');

          setTimeout(funktion, frameRate);
          i++;
        } else {
          textArray = originalText.split('');
          i = 0;
        }
      };

      this.addToQueue(funktion, duration, "");

      return this;
    };

    Timeline.prototype.typeIn = function (text, duration) {
      var thiz = this,
          textArray = text.split(''),
          displayTextArray = [],
          len = text.length,
          frameRate = duration / len || this.defaults.frameRate,
          funktion,
          i = 0;

      duration = duration || this.defaults.frameRate * len;

      funktion = function () {
        if (i < len) {
          displayTextArray.push(textArray.shift());
          thiz.element.textContent = displayTextArray.join('');

          setTimeout(funktion, frameRate);
          i++;
        } else {
          textArray = displayTextArray;
          displayTextArray = [];
          i = 0;
        }
      };

      this.addToQueue(funktion, duration, text);

      return this;
    };

    Timeline.prototype.pause = function (duration) {
      var endText = this.findText(),
          funktion = function () {};

      duration = duration || this.defaults.pauseDuration;
      this.addToQueue(funktion, duration, endText);

      return this;
    };

    Timeline.prototype.clearTimeline = function () {
      this.queue = [];
      this.duration = 0;
      this.endText = "";

      return this;
    };

    return new Timeline(elementID);
  };

  atc.defaults = {
    frameRate: 1000/24,
    pauseDuration: 2000,
    loop: false
  };

  atc.frameRate = function (frameRate) {
    atc.defaults.frameRate = frameRate || atc.defaults.frameRate;

    return atc;
  };

  atc.pauseDuration = function (duration) {
    atc.defaults.pauseDuration = duration || atc.defaults.pauseDuration;

    return atc;
  };

  atc.loop = function (bool) {
    atc.defaults.loop = typeof bool === "undefined" ? true : bool;

    return atc;
  };
}());<commit_msg>added ability to stop animation immediately<commit_after>(function () {
  atc = function (elementID) {
    var Timeline = function (elementID) {
      this.element = typeof elementID === "string" ? document.getElementById(elementID) : elementID || {};
      this.queue = [];
      this.queueIndex = 0;
      this.stopped = false;
      this.duration = 0;
      this.endText = "";
      this.defaults = {
        frameRate: atc.defaults.frameRate,
        pauseDuration: atc.defaults.pauseDuration,
        loop: atc.defaults.loop
      };
    };

    Timeline.prototype.go = function (timelineObj) {
      var thiz = this,
          funktion,
          len,
          nextAnimation;

      if (timelineObj) {
        funktion = function () {
          timelineObj.go();
        };

        this.addToQueue(funktion, timelineObj.duration, timelineObj.endText);
      } else {
        len = this.queue.length;
        this.stopped = false;

        nextAnimation = function () {
          if (thiz.queueIndex < len && !thiz.stopped) {
            thiz.queue[thiz.queueIndex].funktion();
            setTimeout(nextAnimation, thiz.queue[thiz.queueIndex].duration);
            thiz.queueIndex += 1;
          } else if (!thiz.stopped) {
            thiz.queueIndex = 0;
            if (thiz.defaults.loop) {
              nextAnimation();
            }
          }
        };

        nextAnimation();
      }

      return this;
    };

    Timeline.prototype.stop = function (now) {
      if (now) {
        this.stopped = true;
      } else {
        var thiz = this,
        funktion = function () {
          thiz.stopped = true;
        };

        this.addToQueue(funktion, 0, this.findText());
      }

      return this;
    };

    Timeline.prototype.frameRate = function (frameRate) {
      this.defaults.frameRate = frameRate || this.defaults.frameRate;

      return this;
    };

    Timeline.prototype.pauseDuration = function (duration) {
      this.defaults.pauseDuration = duration || this.defaults.pauseDuration;

      return this;
    };

    Timeline.prototype.loop = function (bool) {
      this.defaults.loop = typeof bool === "undefined" ? true : bool;

      return this;
    };

    Timeline.prototype.findText = function () {
      var text;

      try {
        text = this.queue[this.queue.length - 1].endText;
      } catch (e) {
        text = this.element.textContent;
      }

      return text;
    };

    Timeline.prototype.addToQueue = function (funktion, duration, endText) {
      this.duration += duration;
      this.endText = endText;
      this.queue.push({ funktion: funktion, duration: duration, endText: endText });
    };

    Timeline.prototype.on = function (eventType, funktion, useCapture) {
      useCapture = useCapture || false;
      this.element.addEventListener(eventType, funktion, useCapture);

      return this;
    };

    Timeline.prototype.text = function (text) {
      if (text) {
        var thiz = this,
            funktion;

        funktion = function () {
          thiz.element.textContent = text;
        };

        this.addToQueue(funktion, 0, text);

        return this;
      } else {
        return this.element.textContent;
      }
    };

    Timeline.prototype.html = function (html) {
      var thiz = this,
      funktion = function () {
        thiz.element.innerHTML = html;
      };

      this.addToQueue(funktion, 0, html);

      return this;
    };

    Timeline.prototype.switchElement = function (elementID) {
      var thiz = this,
      funktion = function () {
        thiz.element = typeof elementID === "string" ? document.getElementById(elementID) : elementID;
      };

      this.addToQueue(funktion, 0, this.element.textContent); // TODO fix endText value

      return this;
    };

    Timeline.prototype.custom = function (funktion, duration, endText) {
      duration = duration || 0;
      endText = endText || this.findText();

      this.addToQueue(funktion, duration, endText);

      return this;
    };

    Timeline.prototype.frameByFrame = function (frames, loops, duration) {
      var thiz = this,
          len = frames.length,
          lastFrame = frames[len - 1],
          totalFrames,
          frameRate,
          funktion,
          i = 0;

      loops = loops || 1;
      totalFrames = len * loops;
      duration = duration || totalFrames * this.defaults.frameRate;
      frameRate = duration / totalFrames;

      funktion = function () {
        if (i < totalFrames && !thiz.stopped) {
          thiz.element.textContent = frames[i % len];

          setTimeout(funktion, frameRate);
          i++;
        } else {
          i = 0;
        }
      };

      this.addToQueue(funktion, duration, lastFrame);

      return this;
    };

    Timeline.prototype.rollNumbers = function (startValue, endValue, increment, duration) {
      var thiz = this,
          difference = endValue - startValue,
          newValue = startValue,
          addFrame,
          totalFrames,
          frameRate,
          funktion,
          i = 0;

      increment = increment || 1;
      addFrame = increment;

      if (difference < 0) {
        difference = -difference;
        addFrame = -addFrame;
      }

      totalFrames = difference / increment;
      frameRate = duration / totalFrames || this.defaults.frameRate;
      duration = duration || this.defaults.frameRate * totalFrames;

      funktion = function () {
        if (i < totalFrames && !thiz.stopped) {
          newValue += addFrame;
          thiz.element.textContent = newValue;

          setTimeout(funktion, frameRate);
          i++;
        } else {
          thiz.element.textContent = endValue;
          newValue = startValue;
          i = 0;
        }
      };

      this.addToQueue(funktion, duration, endValue);

      return this;
    };

    Timeline.prototype.erase = function (duration) {
      var thiz = this,
          originalText = this.findText(),
          textArray = originalText.split(''),
          len = originalText.length,
          frameRate = duration / len || this.defaults.frameRate,
          funktion,
          i = 0;

      duration = duration || this.defaults.frameRate * len;

      funktion = function () {
        if (i < len && !thiz.stopped) {
          textArray.pop();
          thiz.element.textContent = textArray.join('');

          setTimeout(funktion, frameRate);
          i++;
        } else {
          textArray = originalText.split('');
          i = 0;
        }
      };

      this.addToQueue(funktion, duration, "");

      return this;
    };

    Timeline.prototype.typeIn = function (text, duration) {
      var thiz = this,
          textArray = text.split(''),
          displayTextArray = [],
          len = text.length,
          frameRate = duration / len || this.defaults.frameRate,
          funktion,
          i = 0;

      duration = duration || this.defaults.frameRate * len;

      funktion = function () {
        if (i < len && !thiz.stopped) {
          displayTextArray.push(textArray.shift());
          thiz.element.textContent = displayTextArray.join('');

          setTimeout(funktion, frameRate);
          i++;
        } else {
          textArray = displayTextArray;
          displayTextArray = [];
          i = 0;
        }
      };

      this.addToQueue(funktion, duration, text);

      return this;
    };

    Timeline.prototype.pause = function (duration) {
      var endText = this.findText(),
          funktion = function () {};

      duration = duration || this.defaults.pauseDuration;
      this.addToQueue(funktion, duration, endText);

      return this;
    };

    Timeline.prototype.clearTimeline = function () {
      this.queue = [];
      this.duration = 0;
      this.endText = "";

      return this;
    };

    return new Timeline(elementID);
  };

  atc.defaults = {
    frameRate: 1000/24,
    pauseDuration: 2000,
    loop: false
  };

  atc.frameRate = function (frameRate) {
    atc.defaults.frameRate = frameRate || atc.defaults.frameRate;

    return atc;
  };

  atc.pauseDuration = function (duration) {
    atc.defaults.pauseDuration = duration || atc.defaults.pauseDuration;

    return atc;
  };

  atc.loop = function (bool) {
    atc.defaults.loop = typeof bool === "undefined" ? true : bool;

    return atc;
  };
}());<|endoftext|>


<commit_before>/*
*********************************************************************************************

  System Loader Implementation

    - Implemented to https://github.com/jorendorff/js-loaders/blob/master/browser-loader.js

    - <script type="module"> supported

*********************************************************************************************
*/

var System;

function SystemLoader() {
  Loader.call(this);
  this.paths = {};
}

// NB no specification provided for System.paths, used ideas discussed in https://github.com/jorendorff/js-loaders/issues/25
function applyPaths(paths, name) {
  // most specific (most number of slashes in path) match wins
  var pathMatch = '', wildcard, maxSlashCount = 0;

  // check to see if we have a paths entry
  for (var p in paths) {
    var pathParts = p.split('*');
    if (pathParts.length > 2)
      throw new TypeError('Only one wildcard in a path is permitted');

    // exact path match
    if (pathParts.length == 1) {
      if (name == p) {
        pathMatch = p;
        break;
      }
    }
    // wildcard path match
    else {
      var slashCount = p.split('/').length;
      if (slashCount >= maxSlashCount &&
          name.substr(0, pathParts[0].length) == pathParts[0] &&
          name.substr(name.length - pathParts[1].length) == pathParts[1]) {
            maxSlashCount = slashCount;
            pathMatch = p;
            wildcard = name.substr(pathParts[0].length, name.length - pathParts[1].length - pathParts[0].length);
          }
    }
  }

  var outPath = paths[pathMatch] || name;
  if (wildcard)
    outPath = outPath.replace('*', wildcard);

  return outPath;
}

// inline Object.create-style class extension
function LoaderProto() {}
LoaderProto.prototype = Loader.prototype;
SystemLoader.prototype = new LoaderProto();
<commit_msg>permit empty wildcards<commit_after>/*
*********************************************************************************************

  System Loader Implementation

    - Implemented to https://github.com/jorendorff/js-loaders/blob/master/browser-loader.js

    - <script type="module"> supported

*********************************************************************************************
*/

var System;

function SystemLoader() {
  Loader.call(this);
  this.paths = {};
}

// NB no specification provided for System.paths, used ideas discussed in https://github.com/jorendorff/js-loaders/issues/25
function applyPaths(paths, name) {
  // most specific (most number of slashes in path) match wins
  var pathMatch = '', wildcard, maxSlashCount = 0;

  // check to see if we have a paths entry
  for (var p in paths) {
    var pathParts = p.split('*');
    if (pathParts.length > 2)
      throw new TypeError('Only one wildcard in a path is permitted');

    // exact path match
    if (pathParts.length == 1) {
      if (name == p) {
        pathMatch = p;
        break;
      }
    }
    // wildcard path match
    else {
      var slashCount = p.split('/').length;
      if (slashCount >= maxSlashCount &&
          name.substr(0, pathParts[0].length) == pathParts[0] &&
          name.substr(name.length - pathParts[1].length) == pathParts[1]) {
            maxSlashCount = slashCount;
            pathMatch = p;
            wildcard = name.substr(pathParts[0].length, name.length - pathParts[1].length - pathParts[0].length);
          }
    }
  }

  var outPath = paths[pathMatch] || name;
  if (typeof wildcard == 'string')
    outPath = outPath.replace('*', wildcard);

  return outPath;
}

// inline Object.create-style class extension
function LoaderProto() {}
LoaderProto.prototype = Loader.prototype;
SystemLoader.prototype = new LoaderProto();
<|endoftext|>