<commit_before>// bitbucket.js
// https://confluence.atlassian.com/bitbucket/manage-webhooks-735643732.html
// ========
module.exports = {
    parse: function (req, discordPayload) {
        const body = req.body;
        const type = req.get("X-Event-Key");
        const baseLink = 'https://bitbucket.org/';

        discordPayload.setEmbedColor(0x205081);

        let project = null;
        let user = null;

        switch (type) {
            case "repo:push":
                project = {
                    name: body.repository.name,
                    url: baseLink + body.repository.full_name,
                    branch: null,
                    commits: null
                };
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                for (let i = 0; i < body.push.changes.length; i++) {
                    let change = body.push.changes[i];
                    project.branch = (change.old !== null) ? change.old.name : change.new.name;
                    project.commits = change.commits;

                    let commits = [];
                    for (let j = 0; j < project.commits.length; j++) {
                        let commit = project.commits[j];
                        let message = (commit.message.length > 50) ? commit.message.substring(0, 47) + "..." : commit.message;
                        let author = (typeof commit.author.user !== "undefined") ? commit.author.user.display_name : "Unknown";

                        commits.push({
                            name: "Commit from " + author,
                            value: "(" + "[`" + commit.hash.substring(0, 7) + "`](" + commit.links.html.href + ")" + ")" + message.replace(/\n/g, " ").replace(/\r/g, " "),
                            inline: false
                        });
                        //commits = commits + "[`" + commit.hash.substring(0, 7) + "`](" + commit.links.html.href + ") " + message.replace(/\n/g, " ").replace(/\r/g, " ") + author + "\n";
                    }

                    discordPayload.addEmbed({
                        title: "[" + project.name + ":" + project.branch + "] " + project.commits.length + " commit" + ((project.commits.length > 1) ? "s" : ""),
                        url: project.url,
                        author: user,
                        fields: commits
                        //description: commits
                    });
                }
                break;
            case "repo:fork":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                discordPayload.addEmbed({
                    author: user,
                    description: "Created a [`fork`](" + baseLink + body.fork.full_name + ") of [`" + body.repository.name + "`](" + baseLink + body.repository.full_name + ")"
                });
                break;
            case "repo:updated":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                let changes = [];
                if (typeof body.changes.name !== "undefined") {
                    changes.push("**Name:** \"" + body.changes.name.old + "\" -> \"" + body.changes.name.new + "\"");
                }
                if (typeof body.changes.website !== "undefined") {
                    changes.push("**Website:** \"" + body.changes.website.old + "\" -> \"" + body.changes.website.new + "\"");
                }
                if (typeof body.changes.language !== "undefined") {
                    changes.push("**Language:** \"" + body.changes.language.old + "\" -> \"" + body.changes.language.new + "\"");
                }
                if (typeof body.changes.description !== "undefined") {
                    changes.push("**Description:** \"" + body.changes.description.old + "\" -> \"" + body.changes.description.new + "\"");
                }

                discordPayload.addEmbed({
                    author: user,
                    title: "Changed general information of " + body.repository.name,
                    url: baseLink + body.repository.full_name,
                    description: changes.join("\n")
                });
                break;
            case "repo:commit_comment_created":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Wrote a comment to commit " + body.commit.hash.substring(0, 7) + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/commits/" + body.commit.hash,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 1024) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 1021) + "..." : body.comment.content.html.replace(/<.*?>/g, '')
                });
                break;
            case "repo:commit_status_created":
                discordPayload.addEmbed({
                    author: {
                        name: body.repository.name,
                        url: baseLink + body.repository.full_name,
                        icon_url: body.repository.links.avatar.href
                    },
                    title: body.commit_status.name,
                    url: body.commit_status.url,
                    description: "**State:** " + body.commit_status.state + "\n" + body.commit_status.description
                });
                break;
            case "repo:commit_status_updated":
                discordPayload.addEmbed({
                    author: {
                        name: body.repository.name,
                        url: baseLink + body.repository.full_name,
                        icon_url: body.repository.links.avatar.href
                    },
                    title: body.commit_status.name,
                    url: body.commit_status.url,
                    description: "**State:** " + body.commit_status.state + "\n" + body.commit_status.description
                });
                break;
            case "issue:created":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Created a new Issue on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id,
                    description: "",
                    fields: [
                        {
                            name: body.issue.title,
                            value: "**State:** " + body.issue.state + "\n" +
                            "**Type:** " + body.issue.type + "\n" +
                            "**Priority:** " + body.issue.priority + "\n"
                        }
                    ]
                });
                break;
            case "issue:updated":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                discordPayload.addEmbed({
                    author: user,
                    title: "Updated Issue #" + body.issue.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id
                });
                break;
            case "issue:comment_created":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Wrote a comment to Issue #" + body.issue.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 1024) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 1021) + "..." : body.comment.content.html.replace(/<.*?>/g, '')
                });
                break;
            case "pullrequest:created":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Created a new pull request on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: body.pullrequest.description,
                    fields: [
                        {
                            name: body.pullrequest.title,
                            value: "**Destination branch:** " + body.pullrequest.destination.branch.name + "\n" +
                            "**State:** " + body.pullrequest.state + "\n"
                        }
                    ]
                });
                break;
            case "pullrequest:updated":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Updated pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: body.pullrequest.description,
                    fields: [
                        {
                            name: body.pullrequest.title,
                            value: "**Destination branch:** " + body.pullrequest.destination.branch.name + "\n" +
                            "**State:** " + body.pullrequest.state + "\n"
                        }
                    ]
                });
                break;
            case "pullrequest:approved":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Approved pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                });
                break;
            case "pullrequest:unapproved":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Removed his approval for pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id
                });
                break;
            case "pullrequest:fulfilled":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Merged pull request #" + body.pullrequest.id + " into " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id
                });
                break;
            case "pullrequest:rejected":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Declined pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: (typeof body.pullrequest.reason !== "undefined") ? body.pullrequest.reason : ""
                });
                break;
            case "pullrequest:comment_created":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Wrote a comment to pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 100) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 97) + "..." : body.comment.content.html.replace(/<.*?>/g, '')
                });
                break;
            case "pullrequest:comment_updated":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Updated a comment at pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 100) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 97) + "..." : body.comment.content.html.replace(/<.*?>/g, '')
                });
                break;
            case "pullrequest:comment_deleted":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Deleted a comment at pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 100) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 97) + "..." : body.comment.content.html.replace(/<.*?>/g, '')
                });
                break;
        }
    }
};
<commit_msg>showing max 4 commits in bitbucket<commit_after>// bitbucket.js
// https://confluence.atlassian.com/bitbucket/manage-webhooks-735643732.html
// ========
module.exports = {
    parse: function (req, discordPayload) {
        const body = req.body;
        const type = req.get("X-Event-Key");
        const baseLink = 'https://bitbucket.org/';

        discordPayload.setEmbedColor(0x205081);

        let project = null;
        let user = null;

        switch (type) {
            case "repo:push":
                project = {
                    name: body.repository.name,
                    url: baseLink + body.repository.full_name,
                    branch: null,
                    commits: null
                };
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                for (let i = 0; (i < body.push.changes.length && i <4); i++) {
                    let change = body.push.changes[i];
                    project.branch = (change.old !== null) ? change.old.name : change.new.name;
                    project.commits = change.commits;

                    let commits = [];
                    for (let j = 0; j < project.commits.length; j++) {
                        let commit = project.commits[j];
                        let message = (commit.message.length > 50) ? commit.message.substring(0, 47) + "..." : commit.message;
                        let author = (typeof commit.author.user !== "undefined") ? commit.author.user.display_name : "Unknown";

                        commits.push({
                            name: "Commit from " + author,
                            value: "(" + "[`" + commit.hash.substring(0, 7) + "`](" + commit.links.html.href + ")" + ")" + message.replace(/\n/g, " ").replace(/\r/g, " "),
                            inline: false
                        });
                        //commits = commits + "[`" + commit.hash.substring(0, 7) + "`](" + commit.links.html.href + ") " + message.replace(/\n/g, " ").replace(/\r/g, " ") + author + "\n";
                    }

                    discordPayload.addEmbed({
                        title: "[" + project.name + ":" + project.branch + "] " + project.commits.length + " commit" + ((project.commits.length > 1) ? "s" : ""),
                        url: project.url,
                        author: user,
                        fields: commits
                        //description: commits
                    });
                }
                break;
            case "repo:fork":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                discordPayload.addEmbed({
                    author: user,
                    description: "Created a [`fork`](" + baseLink + body.fork.full_name + ") of [`" + body.repository.name + "`](" + baseLink + body.repository.full_name + ")"
                });
                break;
            case "repo:updated":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                let changes = [];
                if (typeof body.changes.name !== "undefined") {
                    changes.push("**Name:** \"" + body.changes.name.old + "\" -> \"" + body.changes.name.new + "\"");
                }
                if (typeof body.changes.website !== "undefined") {
                    changes.push("**Website:** \"" + body.changes.website.old + "\" -> \"" + body.changes.website.new + "\"");
                }
                if (typeof body.changes.language !== "undefined") {
                    changes.push("**Language:** \"" + body.changes.language.old + "\" -> \"" + body.changes.language.new + "\"");
                }
                if (typeof body.changes.description !== "undefined") {
                    changes.push("**Description:** \"" + body.changes.description.old + "\" -> \"" + body.changes.description.new + "\"");
                }

                discordPayload.addEmbed({
                    author: user,
                    title: "Changed general information of " + body.repository.name,
                    url: baseLink + body.repository.full_name,
                    description: changes.join("\n")
                });
                break;
            case "repo:commit_comment_created":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Wrote a comment to commit " + body.commit.hash.substring(0, 7) + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/commits/" + body.commit.hash,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 1024) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 1021) + "..." : body.comment.content.html.replace(/<.*?>/g, '')
                });
                break;
            case "repo:commit_status_created":
                discordPayload.addEmbed({
                    author: {
                        name: body.repository.name,
                        url: baseLink + body.repository.full_name,
                        icon_url: body.repository.links.avatar.href
                    },
                    title: body.commit_status.name,
                    url: body.commit_status.url,
                    description: "**State:** " + body.commit_status.state + "\n" + body.commit_status.description
                });
                break;
            case "repo:commit_status_updated":
                discordPayload.addEmbed({
                    author: {
                        name: body.repository.name,
                        url: baseLink + body.repository.full_name,
                        icon_url: body.repository.links.avatar.href
                    },
                    title: body.commit_status.name,
                    url: body.commit_status.url,
                    description: "**State:** " + body.commit_status.state + "\n" + body.commit_status.description
                });
                break;
            case "issue:created":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Created a new Issue on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id,
                    description: "",
                    fields: [
                        {
                            name: body.issue.title,
                            value: "**State:** " + body.issue.state + "\n" +
                            "**Type:** " + body.issue.type + "\n" +
                            "**Priority:** " + body.issue.priority + "\n"
                        }
                    ]
                });
                break;
            case "issue:updated":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                discordPayload.addEmbed({
                    author: user,
                    title: "Updated Issue #" + body.issue.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id
                });
                break;
            case "issue:comment_created":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Wrote a comment to Issue #" + body.issue.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 1024) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 1021) + "..." : body.comment.content.html.replace(/<.*?>/g, '')
                });
                break;
            case "pullrequest:created":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Created a new pull request on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: body.pullrequest.description,
                    fields: [
                        {
                            name: body.pullrequest.title,
                            value: "**Destination branch:** " + body.pullrequest.destination.branch.name + "\n" +
                            "**State:** " + body.pullrequest.state + "\n"
                        }
                    ]
                });
                break;
            case "pullrequest:updated":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Updated pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: body.pullrequest.description,
                    fields: [
                        {
                            name: body.pullrequest.title,
                            value: "**Destination branch:** " + body.pullrequest.destination.branch.name + "\n" +
                            "**State:** " + body.pullrequest.state + "\n"
                        }
                    ]
                });
                break;
            case "pullrequest:approved":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Approved pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                });
                break;
            case "pullrequest:unapproved":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Removed his approval for pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id
                });
                break;
            case "pullrequest:fulfilled":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Merged pull request #" + body.pullrequest.id + " into " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id
                });
                break;
            case "pullrequest:rejected":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Declined pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: (typeof body.pullrequest.reason !== "undefined") ? body.pullrequest.reason : ""
                });
                break;
            case "pullrequest:comment_created":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Wrote a comment to pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 100) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 97) + "..." : body.comment.content.html.replace(/<.*?>/g, '')
                });
                break;
            case "pullrequest:comment_updated":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Updated a comment at pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 100) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 97) + "..." : body.comment.content.html.replace(/<.*?>/g, '')
                });
                break;
            case "pullrequest:comment_deleted":
                user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.addEmbed({
                    author: user,
                    title: "Deleted a comment at pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 100) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 97) + "..." : body.comment.content.html.replace(/<.*?>/g, '')
                });
                break;
        }
    }
};
<|endoftext|>


<commit_before>var EventEmitter = require("events").EventEmitter;
require('rootpath')();
var nmx = require('motion/drivers/nmx.js');
var GenieMini = require('motion/drivers/genie_mini.js');

var motion = new EventEmitter();

motion.status = {
	motors: [],
	available: false
}

motion.nmx = nmx;
motion.gm = new GenieMini();

motion.move = function() {

}

motion.joystick = function() {

}

motion.zero = function(driver, motor, callback) {
	if(driver == "NMX") {
		nmx.resetMotorPosition(motorId, callback);
	} else if(driver == "GM") {
		gm.resetMotorPosition(motorId, callback);
	}
}

function updateStatus() {
	var nmxStatus = nmx.getStatus();
	var gmStatus = gm.getStatus();

    var available = (nmxStatus.connected || gmStatus.connected) && (status.motor1 || status.motor2 || status.motor2 || gmStatus.motor1);
    var motors = [];
    motors.push({driver:'NMX', motor:1, connected:status.motor1, position:status.motor1pos, unit: 'steps'});
    motors.push({driver:'NMX', motor:2, connected:status.motor2, position:status.motor2pos, unit: 'steps'});
    motors.push({driver:'NMX', motor:3, connected:status.motor3, position:status.motor3pos, unit: 'steps'});
    motors.push({driver:'GM', motor:1, connected:status.motor1, position:status.motor1pos, unit: '°'});
    motion.status = {
        available: available,
        motors: motors
    };
    motion.emit('status', motion.status);
}

motion.nmx.on('status', function(status) {
    updateStatus()
});
motion.gm.on('status', function(status) {
	updateStatus()
});

module.exports = motion;<commit_msg>correction<commit_after>var EventEmitter = require("events").EventEmitter;
require('rootpath')();
var nmx = require('motion/drivers/nmx.js');
var GenieMini = require('motion/drivers/genie_mini.js');

var motion = new EventEmitter();

motion.status = {
	motors: [],
	available: false
}

motion.nmx = nmx;
motion.gm = new GenieMini();

motion.move = function() {

}

motion.joystick = function() {

}

motion.zero = function(driver, motor, callback) {
	if(driver == "NMX") {
		nmx.resetMotorPosition(motorId, callback);
	} else if(driver == "GM") {
		gm.resetMotorPosition(motorId, callback);
	}
}

function updateStatus() {
	var nmxStatus = motion.nmx.getStatus();
	var gmStatus = motion.gm.getStatus();

    var available = (nmxStatus.connected || gmStatus.connected) && (status.motor1 || status.motor2 || status.motor2 || gmStatus.motor1);
    var motors = [];
    motors.push({driver:'NMX', motor:1, connected:status.motor1, position:status.motor1pos, unit: 'steps'});
    motors.push({driver:'NMX', motor:2, connected:status.motor2, position:status.motor2pos, unit: 'steps'});
    motors.push({driver:'NMX', motor:3, connected:status.motor3, position:status.motor3pos, unit: 'steps'});
    motors.push({driver:'GM', motor:1, connected:status.motor1, position:status.motor1pos, unit: '°'});
    motion.status = {
        available: available,
        motors: motors
    };
    motion.emit('status', motion.status);
}

motion.nmx.on('status', function(status) {
    updateStatus()
});
motion.gm.on('status', function(status) {
	updateStatus()
});

module.exports = motion;<|endoftext|>


<commit_before>/*! @license ©2014 Ruben Verborgh - Multimedia Lab / iMinds / Ghent University */
/* A MultiTransformIterator transforms items of a source into zero, one, or multiple items.
    To this end, it creates a new transforming iterator for each item it reads from the source. */

var TransformIterator = require('./Iterator').TransformIterator;

// Creates a new MultiTransformIterator
function MultiTransformIterator(source, options) {
  if (!(this instanceof MultiTransformIterator))
    return new MultiTransformIterator(source, options);
  TransformIterator.call(this, source, options);

  // Keep a copy of the options to create transformers, removing the `optional` setting
  this._options = options || {};
  if (this._optional = this._options.optional || false)
    (this._options = Object.create(this._options)).optional = false;
  // Queue of transformers, each corresponding to a different item of the source
  this._transformerQueue = [];
  // Bound event handlers that will be attached to transformers
  var self = this;
  this._emitError = function (error) { self.emit('error', error); };
  this._fillBufferBound = function () { self._fillBuffer(); };
}
TransformIterator.inherits(MultiTransformIterator);

// Reads an item from the next readable transformer,
// creating transformers for new items as necessary
MultiTransformIterator.prototype._read = function () {
  var item, transformer, transformerQueue = this._transformerQueue, optional = this._optional;

  // Find the first readable transformer by dequeuing ended transformers
  while ((transformer = transformerQueue[0]) && transformer.ended) {
    transformerQueue.shift();
    // If transforming is optional and the transformer was empty, read the original item
    if (optional) {
      if (!this._itemTransformed)
        return this._push(transformer.item);
      this._itemTransformed = false;
    }
  }

  // Create new transformers if no readable transformer was left
  if (!transformer) {
    do {
      // Create a transformer for the next item
      if (item = this._source.read()) {
        transformer = this._createTransformer(item, this._options);
        // If the transformer has items, add it to the queue and listen for events
        if (transformer && !transformer.ended) {
          transformer.item = item;
          transformerQueue.push(transformer);
          transformer.on('error',    this._emitError);
          transformer.on('readable', this._fillBufferBound);
          transformer.on('end',      this._fillBufferBound);
        }
        // If transforming is optional and the transformer is empty, read the original item
        else if (optional) return this._push(item);
      }
    } while (item && transformerQueue.length < this._maxBufferSize);
    // If no fragments are left, this iterator has ended
    if (!(transformer = transformerQueue[0]))
      return this._source.ended && this._end();
  }

  // Read an item from the first readable transformer
  item = this._readTransformer(transformer, transformer.item);
  if (item !== null) {
    optional && (this._itemTransformed = true);
    this._push(item);
  }
};

// Creates a transforming iterator for the given item.
// A transformer may output several items per item.
MultiTransformIterator.prototype._createTransformer = function (item, options) {
  throw new Error('The _createTransformer method has not been implemented.');
};

// Reads an item from the given transforming iterator
MultiTransformIterator.prototype._readTransformer = function (transformer, transformerItem) {
  return transformer.read();
};

// Flushes remaining data after the source has ended
MultiTransformIterator.prototype._flush = function () {
  // Transformers might still have items, so try to fill the buffer
  this._fillBuffer();
};

module.exports = MultiTransformIterator;
<commit_msg>Disallow recursive multi-transformations.<commit_after>/*! @license ©2014 Ruben Verborgh - Multimedia Lab / iMinds / Ghent University */
/* A MultiTransformIterator transforms items of a source into zero, one, or multiple items.
    To this end, it creates a new transforming iterator for each item it reads from the source. */

var TransformIterator = require('./Iterator').TransformIterator;

// Creates a new MultiTransformIterator
function MultiTransformIterator(source, options) {
  if (!(this instanceof MultiTransformIterator))
    return new MultiTransformIterator(source, options);
  TransformIterator.call(this, source, options);

  // Keep a copy of the options to create transformers, removing the `optional` setting
  this._options = options || {};
  if (this._optional = this._options.optional || false)
    (this._options = Object.create(this._options)).optional = false;
  // Queue of transformers, each corresponding to a different item of the source
  this._transformerQueue = [];
  // Bound event handlers that will be attached to transformers
  var self = this;
  this._emitError = function (error) { self.emit('error', error); };
  this._fillBufferBound = function () { self._fillBuffer(); };
}
TransformIterator.inherits(MultiTransformIterator);

// Keep track of the transformer's status
var WAITING = 0, TRANSFORMING = 1, ENDING = 2;

// Reads an item from the next readable transformer,
// creating transformers for new items as necessary
MultiTransformIterator.prototype._read = function () {
  var item, transformer, transformerQueue = this._transformerQueue, optional = this._optional;

  // Disallow recursive transformations
  if (this._transformStatus !== WAITING) return;
  this._transformStatus = TRANSFORMING;

  // Find the first readable transformer by dequeuing ended transformers
  while ((transformer = transformerQueue[0]) && transformer.ended) {
    transformerQueue.shift();
    // If transforming is optional and the transformer was empty, read the original item
    if (optional) {
      if (!this._itemTransformed) {
        this._push(transformer.item);
        return this._transformStatus = WAITING;
      }
      this._itemTransformed = false;
    }
  }

  // Create new transformers if no readable transformer was left
  if (!transformer) {
    do {
      // Create a transformer for the next item
      if (item = this._source.read()) {
        transformer = this._createTransformer(item, this._options);
        // If the transformer has items, add it to the queue and listen for events
        if (transformer && !transformer.ended) {
          transformer.item = item;
          transformerQueue.push(transformer);
          transformer.on('error',    this._emitError);
          transformer.on('readable', this._fillBufferBound);
          transformer.on('end',      this._fillBufferBound);
        }
        // If transforming is optional and the transformer is empty, read the original item
        else if (optional) {
          this._push(item);
          return this._transformStatus = WAITING;
        }
      }
    } while (item && transformerQueue.length < this._maxBufferSize);
    // If no fragments are left, this iterator has ended
    if (!(transformer = transformerQueue[0])) {
      if (this._source.ended)
        this._end();
      return this._transformStatus = WAITING;
    }
  }

  // Read an item from the first readable transformer
  item = this._readTransformer(transformer, transformer.item);
  if (item !== null) {
    optional && (this._itemTransformed = true);
    this._push(item);
  }
  this._transformStatus = WAITING;
};

// Creates a transforming iterator for the given item.
// A transformer may output several items per item.
MultiTransformIterator.prototype._createTransformer = function (item, options) {
  throw new Error('The _createTransformer method has not been implemented.');
};

// Reads an item from the given transforming iterator
MultiTransformIterator.prototype._readTransformer = function (transformer, transformerItem) {
  return transformer.read();
};

// Flushes remaining data after the source has ended
MultiTransformIterator.prototype._flush = function () {
  // Transformers might still have items, so try to fill the buffer
  this._fillBuffer();
};

module.exports = MultiTransformIterator;
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');
var arrayUtils = require('utils/array_utils');

/**
 * @typedef {Em.Object} StackType
 * @property {string} stackName
 * @property {App.Stack[]} stacks
 * @property {boolean} isSelected
 */

/**
 * @type {Em.Object}
 */
var StackType = Em.Object.extend({
  stackName: '',
  stacks: [],
  isSelected: Em.computed.someBy('stacks', 'isSelected', true)
});

App.WizardStep1Controller = Em.Controller.extend({

  name: 'wizardStep1Controller',

  /**
   * Skip repo-validation
   *
   * @type {bool}
   */
  skipValidationChecked: false,

  /**
   * @type {App.Stack}
   */
  selectedStack: Em.computed.findBy('content.stacks', 'isSelected', true),

  /**
   * @type {App.ServiceSimple[]}
   */
  servicesForSelectedStack: Em.computed.filterBy('selectedStack.stackServices', 'isHidden', false),

  /**
   * Some network issues exist if there is no stack with stackDefault = false
   *
   * @type {boolean}
   */
  networkIssuesExist: function() {
    if (this.get('content.stacks') && this.get('content.stacks.length') > 1) {
      return this.get('content.stacks').everyProperty('stackDefault', true);
    }
    return false;
  }.property('content.stacks.@each.stackDefault'),

  /**
   * No stacks have repo update URL section (aka "latest") defined in repoinfo.xml
   *
   * @type {boolean}
   */
  stackRepoUpdateLinkExists: Em.computed.someBy('content.stacks', 'stackRepoUpdateLinkExists', true),

  optionsToSelect: {
    'usePublicRepo': {
      index: 0,
      isSelected: true
    },
    'useLocalRepo': {
      index: 1,
      isSelected: false,
      'uploadFile': {
        index: 0,
        name: 'uploadFile',
        file: '',
        hasError: false,
        isSelected: true
      },
      'enterUrl': {
        index: 1,
        name: 'enterUrl',
        url: '',
        placeholder: Em.I18n.t('installer.step1.useLocalRepo.enterUrl.placeholder'),
        hasError: false,
        isSelected: false
      }
    }
  },

  /**
   * Checks if user selected to input url or upload file but didn't do it
   * true  - url-radio is checked but url-field is empty
   *       - file-radio is checked but file is not selected
   * false - otherwise
   *
   * @type {boolean}
   */
  readInfoIsNotProvided: function () {
    var useLocalRepo = this.get('optionsToSelect.useLocalRepo');
    if(Em.get(useLocalRepo, 'uploadFile.isSelected')) {
      return !Em.get(useLocalRepo, 'uploadFile.file');
    }
    if (Em.get(useLocalRepo, 'enterUrl.isSelected')) {
      return !Em.get(useLocalRepo, 'enterUrl.url');
    }
    return false;
  }.property('optionsToSelect.useLocalRepo.isSelected', 'optionsToSelect.useLocalRepo.uploadFile.isSelected',
    'optionsToSelect.useLocalRepo.uploadFile.file', 'optionsToSelect.useLocalRepo.enterUrl.url'),

  /**
   * List of stacks grouped by stackNameVersion
   *
   * @type {StackType[]}
   */
  availableStackTypes: function () {
    var stacks = this.get('content.stacks');
    return stacks ? stacks.mapProperty('stackNameVersion').uniq().sort().reverse().map(function (stackName) {
      return StackType.create({
        stackName: stackName,
        stacks: stacks.filterProperty('stackNameVersion', stackName).sort(arrayUtils.sortByIdAsVersion).reverse()
      })
    }) : [];
  }.property('content.stacks.@each.stackNameVersion'),

  /**
   * @type {StackType}
   */
  selectedStackType: Em.computed.findBy('availableStackTypes', 'isSelected', true),

  isLoadingComplete: Em.computed.equal('wizardController.loadStacksRequestsCounter', 0),

  /**
   * Load selected file to current page content
   */
  readVersionInfo: function () {
    var data = {};
    var isXMLdata = false;
    if (this.get("optionsToSelect.useLocalRepo.enterUrl.isSelected")) {
      var url = this.get("optionsToSelect.useLocalRepo.enterUrl.url");
      data = {
        VersionDefinition: {
          version_url: url
        }
      };
      App.db.setLocalRepoVDFData(url);
    }
    else {
      if (this.get("optionsToSelect.useLocalRepo.uploadFile.isSelected")) {
        isXMLdata = true;
        // load from file browser
        data = this.get("optionsToSelect.useLocalRepo.uploadFile.file");
        App.db.setLocalRepoVDFData(data);
      }
    }
    return App.router.get('installerController').postVersionDefinitionFile(isXMLdata, data);
  },

  /**
   * On click handler for removing OS
   */
  removeOS: function (event) {
    if (this.get('selectedStack.useRedhatSatellite')) {
      return;
    }
    var osToRemove = event.context;
    Em.set(osToRemove, 'isSelected', false);
  },

  /**
   * On click handler for adding new OS
   */
  addOS: function (event) {
    var osToAdd = event.context;
    Em.set(osToAdd, 'isSelected', true);
  },

  /**
   * Use Local Repo if some network issues exist
   */
  onNetworkIssuesExist: function() {
    if (this.get('networkIssuesExist')) {
      this.get('content.stacks').forEach(function (stack) {
        stack.setProperties({
          usePublicRepo: false,
          useLocalRepo: true
        });
        stack.cleanReposBaseUrls();
      });
    }
  }.observes('networkIssuesExist'),

  /**
   * Select stack with field equal to the value
   * Example:
   *

   *   selectStackBy('id', 'HDP-2.5-2.5.0.0'); // select stack with id = 'HDP-2.5-2.5.0.0'
   *   selectStackBy('stackNameVersion', 'HDP-2.5'); // select first stack with stackNameVersion = 'HDP-2.5'
   *

   *
   * @param {string} field
   * @param {string} value
   */
  selectStackBy: function (field, value) {
    this.get('content.stacks').setEach('isSelected', false);
    this.get('content.stacks').findProperty(field, value).set('isSelected', true);
  },

  /**
   * Restore base urls for selected stack when user select to use public repository
   */
  usePublicRepo: function () {
    var selectedStack = this.get('selectedStack');
    if (selectedStack) {
      selectedStack.setProperties({
        useRedhatSatellite: false,
        usePublicRepo: true,
        useLocalRepo: false
      });
      selectedStack.restoreReposBaseUrls();
    }
  },

  /**
   * Clean base urls for selected stack when user select to use local repository
   */
  useLocalRepo: function () {
    var selectedStack = this.get('selectedStack');
    if (selectedStack) {
      selectedStack.setProperties({
        usePublicRepo: false,
        useLocalRepo: true
      });
      selectedStack.cleanReposBaseUrls();
    }
  },

  /**
   * Restores url value to be its default value.
   * @method doRestoreDefaultValue
   */
  doRestoreDefaultValue: function (event) {
    var repo = event.contexts[0];
    repo.set('baseUrl', repo.get('baseUrlInit'));
  },

  /**
   * Restores url value to empty string.
   * @method doRestoreToEmpty
   */
  doRestoreToEmpty: function (event) {
    var repo = event.contexts[0];
    repo.set('baseUrl', '');
  },

  /**
   * Click-handler for left-tabs with stack types
   * Select first available stack with stackName equal to chosen
   *
   * @param {{context: StackType}} event
   */
  selectRepoInList: function (event) {
    var id = this.get('availableStackTypes').findProperty('stackName', event.context.stackName).get('stacks.firstObject.id');
    this.selectStackBy('id', id);
  },

  /**
   * Click-handler for StackVersion-tabs
   *
   * @param {{context: App.Stack}} event
   */
  changeVersion: function (event) {
    this.selectStackBy('id', event.context.get('id'));
  },

  /**
   * Show popup with options to upload new version
   *
   * @returns {App.ModalPopup}
   */
  uploadVdf: function () {
    return App.ModalPopup.show({

      controller: this,

      header: Em.I18n.t('installer.step1.addVersion.title'),

      primary: Em.I18n.t('installer.step1.useLocalRepo.readButton'),

      disablePrimary: Em.computed.alias('controller.readInfoIsNotProvided'),

      'data-qa': 'vdf-modal',

      /**
       * Try to read version info from the url or file (if provided)
       */
      onPrimary: function () {
        var controller = this.get('controller');
        controller.readVersionInfo().done(function (response) {
          // load successfully, so make this local stack repo as selectedStack
          var newStackId = response.stackNameVersion + '-' + response.actualVersion;
          var oldStackNameVersion = controller.get('selectedStack.stackNameVersion');
          controller.selectStackBy('id', newStackId);
          if (oldStackNameVersion && oldStackNameVersion !== response.stackNameVersion) {
            App.showAlertPopup(Em.I18n.t('common.warning'), Em.I18n.t('installer.step1.addVersion.stackChanged.popup.body').format(oldStackNameVersion, response.stackNameVersion));
          }
          Ember.run.next(function () {
            App.tooltip($("[rel=skip-validation-tooltip]"), {html: true, placement: 'left'});
            $("[rel=use-redhat-tooltip]").tooltip({placement: 'right'});
          });
        });
        this.restoreUploadOptions();
        this._super();
      },

      /**
       * Disable url/file fields on popup-close
       */
      onSecondary: function () {
        this.restoreUploadOptions();
        this._super();
      },

      /**
       * Disable url/file fields on popup-close
       */
      onClose: function () {
        this.restoreUploadOptions();
        this._super();
      },

      /**
       * Deselect file/url radio
       */
      restoreUploadOptions: function () {
        this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', false);
        this.set('controller.optionsToSelect.useLocalRepo.enterUrl.url', '');
        this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', true);
        this.set('controller.optionsToSelect.useLocalRepo.uploadFile.file', '');
      },

      bodyClass: Em.View.extend({

        controller: this,

        templateName: require('templates/wizard/step1/vdf_upload'),

        /**
         * Wrapper for 'upload-file' elements
         *
         * @type {Em.View}
         */
        uploadFileView: Em.View.extend({

          classNames: ['clearfix'],

          /**
           * Radio button for Use local Repo > Upload VDF file
           *
           * @type {App.RadioButtonView}
           */
          uploadFileRadioButton: App.RadioButtonView.extend({
            labelTranslate: 'installer.step1.useLocalRepo.uploadFile',
            checked: Em.computed.alias('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected')
          }),

          /**
           * Is File API available
           *
           * @type {bool}
           */
          isFileApi: window.File && window.FileReader && window.FileList,

          /**
           * Upload file is disabled when some stack is selected or url-field is selected
           *
           * @type {boolean}
           */
          fileBrowserDisabled: Em.computed.alias('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected'),

          /**
           * Input to select vdf-file
           *
           * @type {Em.View}
           */
          fileInputView: Em.View.extend({
            template: Em.Handlebars.compile('<input type="file" {{bindAttr class="controller.optionsToSelect.useLocalRepo.enterUrl.isSelected:disabled"}} {{QAAttr "vdf-input"}}/>'),

            change: function (e) {
              var self = this;
              if (e.target.files && e.target.files.length === 1) {
                var file = e.target.files[0];
                var reader = new FileReader();

                reader.onload = (function () {
                  return function (event) {
                    self.set('controller.optionsToSelect.useLocalRepo.uploadFile.file', event.target.result);
                  };
                })(file);
                reader.readAsText(file);
              }
            }

          }),

          click: function () {
            if (!this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected')) {
              this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', false);
              this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', true);
              this.set('controller.optionsToSelect.useLocalRepo.enterUrl.hasError', false);
              this.set('controller.optionsToSelect.useLocalRepo.uploadFile.hasError', false);
            }
          }
        }),

        /**
         * Wrapper for 'enter-url' elements
         *
         * @type {Em.View}
         */
        enterUrlView: Em.View.extend({

          /**
           * Url-field is disable when some stack is selected or upload file is selected
           *
           * @type {boolean}
           */
          enterUrlFieldDisabled: Em.computed.alias('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected'),

          /**
           * Input for file upload
           *
           * @type {Em.TextField}
           */
          enterUrlField: Em.TextField.extend({
            classNameBindings: [':input-block-level', 'controller.optionsToSelect.useLocalRepo.uploadFile.isSelected:disabled']
          }),

          /**
           * Radio button for Use local Repo > Enter Url of VDF file
           *
           * @type {App.RadioButtonView}
           */
          enterUrlRadioButton: App.RadioButtonView.extend({
            labelTranslate: 'installer.step1.useLocalRepo.enterUrl',
            checked: Em.computed.alias('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected')
          }),

          click: function () {
            if (!this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected')) {
              this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', true);
              this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', false);
              this.set('controller.optionsToSelect.useLocalRepo.enterUrl.hasError', false);
              this.set('controller.optionsToSelect.useLocalRepo.uploadFile.hasError', false);
            }
          }
        })

      })
    });
  }

});
<commit_msg>AMBARI-25069 - Ambari wrties Empty baseurl values written to Repo Files when using a local repository causing stack installation failure (#2743)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');
var arrayUtils = require('utils/array_utils');

/**
 * @typedef {Em.Object} StackType
 * @property {string} stackName
 * @property {App.Stack[]} stacks
 * @property {boolean} isSelected
 */

/**
 * @type {Em.Object}
 */
var StackType = Em.Object.extend({
  stackName: '',
  stacks: [],
  isSelected: Em.computed.someBy('stacks', 'isSelected', true)
});

App.WizardStep1Controller = Em.Controller.extend({

  name: 'wizardStep1Controller',

  /**
   * Skip repo-validation
   *
   * @type {bool}
   */
  skipValidationChecked: false,

  /**
   * @type {App.Stack}
   */
  selectedStack: Em.computed.findBy('content.stacks', 'isSelected', true),

  /**
   * @type {App.ServiceSimple[]}
   */
  servicesForSelectedStack: Em.computed.filterBy('selectedStack.stackServices', 'isHidden', false),

  /**
   * Some network issues exist if there is no stack with stackDefault = false
   *
   * @type {boolean}
   */
  networkIssuesExist: function() {
    if (this.get('content.stacks') && this.get('content.stacks.length') > 1) {
      return this.get('content.stacks').everyProperty('stackDefault', true);
    }
    return false;
  }.property('content.stacks.@each.stackDefault'),

  /**
   * No stacks have repo update URL section (aka "latest") defined in repoinfo.xml
   *
   * @type {boolean}
   */
  stackRepoUpdateLinkExists: Em.computed.someBy('content.stacks', 'stackRepoUpdateLinkExists', true),

  optionsToSelect: {
    'usePublicRepo': {
      index: 0,
      isSelected: true
    },
    'useLocalRepo': {
      index: 1,
      isSelected: false,
      'uploadFile': {
        index: 0,
        name: 'uploadFile',
        file: '',
        hasError: false,
        isSelected: true
      },
      'enterUrl': {
        index: 1,
        name: 'enterUrl',
        url: '',
        placeholder: Em.I18n.t('installer.step1.useLocalRepo.enterUrl.placeholder'),
        hasError: false,
        isSelected: false
      }
    }
  },

  /**
   * Checks if user selected to input url or upload file but didn't do it
   * true  - url-radio is checked but url-field is empty
   *       - file-radio is checked but file is not selected
   * false - otherwise
   *
   * @type {boolean}
   */
  readInfoIsNotProvided: function () {
    var useLocalRepo = this.get('optionsToSelect.useLocalRepo');
    if(Em.get(useLocalRepo, 'uploadFile.isSelected')) {
      return !Em.get(useLocalRepo, 'uploadFile.file');
    }
    if (Em.get(useLocalRepo, 'enterUrl.isSelected')) {
      return !Em.get(useLocalRepo, 'enterUrl.url');
    }
    return false;
  }.property('optionsToSelect.useLocalRepo.isSelected', 'optionsToSelect.useLocalRepo.uploadFile.isSelected',
    'optionsToSelect.useLocalRepo.uploadFile.file', 'optionsToSelect.useLocalRepo.enterUrl.url'),

  /**
   * List of stacks grouped by stackNameVersion
   *
   * @type {StackType[]}
   */
  availableStackTypes: function () {
    var stacks = this.get('content.stacks');
    return stacks ? stacks.mapProperty('stackNameVersion').uniq().sort().reverse().map(function (stackName) {
      return StackType.create({
        stackName: stackName,
        stacks: stacks.filterProperty('stackNameVersion', stackName).sort(arrayUtils.sortByIdAsVersion).reverse()
      })
    }) : [];
  }.property('content.stacks.@each.stackNameVersion'),

  /**
   * @type {StackType}
   */
  selectedStackType: Em.computed.findBy('availableStackTypes', 'isSelected', true),

  isLoadingComplete: Em.computed.equal('wizardController.loadStacksRequestsCounter', 0),

  /**
   * Load selected file to current page content
   */
  readVersionInfo: function () {
    var data = {};
    var isXMLdata = false;
    if (this.get("optionsToSelect.useLocalRepo.enterUrl.isSelected")) {
      var url = this.get("optionsToSelect.useLocalRepo.enterUrl.url");
      data = {
        VersionDefinition: {
          version_url: url
        }
      };
      App.db.setLocalRepoVDFData(url);
    }
    else {
      if (this.get("optionsToSelect.useLocalRepo.uploadFile.isSelected")) {
        isXMLdata = true;
        // load from file browser
        data = this.get("optionsToSelect.useLocalRepo.uploadFile.file");
        App.db.setLocalRepoVDFData(data);
      }
    }
    return App.router.get('installerController').postVersionDefinitionFile(isXMLdata, data);
  },

  /**
   * On click handler for removing OS
   */
  removeOS: function (event) {
    if (this.get('selectedStack.useRedhatSatellite')) {
      return;
    }
    var osToRemove = event.context;
    Em.set(osToRemove, 'isSelected', false);
  },

  /**
   * On click handler for adding new OS
   */
  addOS: function (event) {
    var osToAdd = event.context;
    Em.set(osToAdd, 'isSelected', true);
  },

  /**
   * Use Local Repo if some network issues exist
   */
  onNetworkIssuesExist: function() {
    if (this.get('networkIssuesExist')) {
      this.get('content.stacks').forEach(function(stack) {
        if (stack.get('useLocalRepo') !== true) {
          stack.setProperties({
            usePublicRepo: false,
            useLocalRepo: true
          });
          stack.cleanReposBaseUrls();
        }
      });
    }
  }.observes('networkIssuesExist'),

  /**
   * Select stack with field equal to the value
   * Example:
   *

   *   selectStackBy('id', 'HDP-2.5-2.5.0.0'); // select stack with id = 'HDP-2.5-2.5.0.0'
   *   selectStackBy('stackNameVersion', 'HDP-2.5'); // select first stack with stackNameVersion = 'HDP-2.5'
   *

   *
   * @param {string} field
   * @param {string} value
   */
  selectStackBy: function (field, value) {
    this.get('content.stacks').setEach('isSelected', false);
    this.get('content.stacks').findProperty(field, value).set('isSelected', true);
  },

  /**
   * Restore base urls for selected stack when user select to use public repository
   */
  usePublicRepo: function () {
    var selectedStack = this.get('selectedStack');
    if (selectedStack) {
      selectedStack.setProperties({
        useRedhatSatellite: false,
        usePublicRepo: true,
        useLocalRepo: false
      });
      selectedStack.restoreReposBaseUrls();
    }
  },

  /**
   * Clean base urls for selected stack when user select to use local repository
   */
  useLocalRepo: function () {
    var selectedStack = this.get('selectedStack');
    if (selectedStack) {
      selectedStack.setProperties({
        usePublicRepo: false,
        useLocalRepo: true
      });
      selectedStack.cleanReposBaseUrls();
    }
  },

  /**
   * Restores url value to be its default value.
   * @method doRestoreDefaultValue
   */
  doRestoreDefaultValue: function (event) {
    var repo = event.contexts[0];
    repo.set('baseUrl', repo.get('baseUrlInit'));
  },

  /**
   * Restores url value to empty string.
   * @method doRestoreToEmpty
   */
  doRestoreToEmpty: function (event) {
    var repo = event.contexts[0];
    repo.set('baseUrl', '');
  },

  /**
   * Click-handler for left-tabs with stack types
   * Select first available stack with stackName equal to chosen
   *
   * @param {{context: StackType}} event
   */
  selectRepoInList: function (event) {
    var id = this.get('availableStackTypes').findProperty('stackName', event.context.stackName).get('stacks.firstObject.id');
    this.selectStackBy('id', id);
  },

  /**
   * Click-handler for StackVersion-tabs
   *
   * @param {{context: App.Stack}} event
   */
  changeVersion: function (event) {
    this.selectStackBy('id', event.context.get('id'));
  },

  /**
   * Show popup with options to upload new version
   *
   * @returns {App.ModalPopup}
   */
  uploadVdf: function () {
    return App.ModalPopup.show({

      controller: this,

      header: Em.I18n.t('installer.step1.addVersion.title'),

      primary: Em.I18n.t('installer.step1.useLocalRepo.readButton'),

      disablePrimary: Em.computed.alias('controller.readInfoIsNotProvided'),

      'data-qa': 'vdf-modal',

      /**
       * Try to read version info from the url or file (if provided)
       */
      onPrimary: function () {
        var controller = this.get('controller');
        controller.readVersionInfo().done(function (response) {
          // load successfully, so make this local stack repo as selectedStack
          var newStackId = response.stackNameVersion + '-' + response.actualVersion;
          var oldStackNameVersion = controller.get('selectedStack.stackNameVersion');
          controller.selectStackBy('id', newStackId);
          if (oldStackNameVersion && oldStackNameVersion !== response.stackNameVersion) {
            App.showAlertPopup(Em.I18n.t('common.warning'), Em.I18n.t('installer.step1.addVersion.stackChanged.popup.body').format(oldStackNameVersion, response.stackNameVersion));
          }
          Ember.run.next(function () {
            App.tooltip($("[rel=skip-validation-tooltip]"), {html: true, placement: 'left'});
            $("[rel=use-redhat-tooltip]").tooltip({placement: 'right'});
          });
        });
        this.restoreUploadOptions();
        this._super();
      },

      /**
       * Disable url/file fields on popup-close
       */
      onSecondary: function () {
        this.restoreUploadOptions();
        this._super();
      },

      /**
       * Disable url/file fields on popup-close
       */
      onClose: function () {
        this.restoreUploadOptions();
        this._super();
      },

      /**
       * Deselect file/url radio
       */
      restoreUploadOptions: function () {
        this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', false);
        this.set('controller.optionsToSelect.useLocalRepo.enterUrl.url', '');
        this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', true);
        this.set('controller.optionsToSelect.useLocalRepo.uploadFile.file', '');
      },

      bodyClass: Em.View.extend({

        controller: this,

        templateName: require('templates/wizard/step1/vdf_upload'),

        /**
         * Wrapper for 'upload-file' elements
         *
         * @type {Em.View}
         */
        uploadFileView: Em.View.extend({

          classNames: ['clearfix'],

          /**
           * Radio button for Use local Repo > Upload VDF file
           *
           * @type {App.RadioButtonView}
           */
          uploadFileRadioButton: App.RadioButtonView.extend({
            labelTranslate: 'installer.step1.useLocalRepo.uploadFile',
            checked: Em.computed.alias('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected')
          }),

          /**
           * Is File API available
           *
           * @type {bool}
           */
          isFileApi: window.File && window.FileReader && window.FileList,

          /**
           * Upload file is disabled when some stack is selected or url-field is selected
           *
           * @type {boolean}
           */
          fileBrowserDisabled: Em.computed.alias('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected'),

          /**
           * Input to select vdf-file
           *
           * @type {Em.View}
           */
          fileInputView: Em.View.extend({
            template: Em.Handlebars.compile('<input type="file" {{bindAttr class="controller.optionsToSelect.useLocalRepo.enterUrl.isSelected:disabled"}} {{QAAttr "vdf-input"}}/>'),

            change: function (e) {
              var self = this;
              if (e.target.files && e.target.files.length === 1) {
                var file = e.target.files[0];
                var reader = new FileReader();

                reader.onload = (function () {
                  return function (event) {
                    self.set('controller.optionsToSelect.useLocalRepo.uploadFile.file', event.target.result);
                  };
                })(file);
                reader.readAsText(file);
              }
            }

          }),

          click: function () {
            if (!this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected')) {
              this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', false);
              this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', true);
              this.set('controller.optionsToSelect.useLocalRepo.enterUrl.hasError', false);
              this.set('controller.optionsToSelect.useLocalRepo.uploadFile.hasError', false);
            }
          }
        }),

        /**
         * Wrapper for 'enter-url' elements
         *
         * @type {Em.View}
         */
        enterUrlView: Em.View.extend({

          /**
           * Url-field is disable when some stack is selected or upload file is selected
           *
           * @type {boolean}
           */
          enterUrlFieldDisabled: Em.computed.alias('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected'),

          /**
           * Input for file upload
           *
           * @type {Em.TextField}
           */
          enterUrlField: Em.TextField.extend({
            classNameBindings: [':input-block-level', 'controller.optionsToSelect.useLocalRepo.uploadFile.isSelected:disabled']
          }),

          /**
           * Radio button for Use local Repo > Enter Url of VDF file
           *
           * @type {App.RadioButtonView}
           */
          enterUrlRadioButton: App.RadioButtonView.extend({
            labelTranslate: 'installer.step1.useLocalRepo.enterUrl',
            checked: Em.computed.alias('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected')
          }),

          click: function () {
            if (!this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected')) {
              this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', true);
              this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', false);
              this.set('controller.optionsToSelect.useLocalRepo.enterUrl.hasError', false);
              this.set('controller.optionsToSelect.useLocalRepo.uploadFile.hasError', false);
            }
          }
        })

      })
    });
  }

});
<|endoftext|>


<commit_before>/*! quiz-game 2014-12-03 15:11:48 */
function Quiz(a) {
    this.qData = a.qData, this.stat = {
        total: a.qData.length,
        hp: 0,
        passed: 0,
        num: 0,
        question: "",
        score: 0,
        options: [],
        answers: [],
        selected: [],
        answered: !1,
        ended: !1
    }, this.stat.hp = 0 === a.totalScore ? a.qData.reduce(function(a, b) {
        return a + b.score
    }, 0) : a.totalScore
}
Quiz.prototype = {
    _orderNum: function(a, b) {
        return a - b
    },
    next: function() {
        var a = 0;
        if (this.stat.num < this.stat.total) {
        	this.stat.num++;
        	if (1 === this.stat.num) {
        		this.stat.ended = !1;
        	};
        	a = this.stat.num - 1;
        	this.stat.question = this.qData[a].question;
        	this.stat.options = this.qData[a].options;
        	this.stat.answers = this.qData[a].answers;
        	this.stat.score = this.qData[a].score;
        };
    },
    submitAnswer: function(a) {
        var b = null;
        return a && this.inputAnswer(a), this.stat.ended || (this.stat.answers.sort(this._orderNum).toString() === this.stat.selected.sort(this._orderNum).toString() ? (this.stat.passed++, b = !0) : (this.stat.hp -= this.stat.score, b = !1), this.stat.answered = !0, (this.stat.hp <= 0 || this.stat.num >= this.stat.total) && (this.stat.ended = !0)), b
    },
    inputAnswer: function(a) {
        var b = this;
        this.stat.selected = [], a.length && a.forEach(function(a) {
            -1 === b.stat.selected.indexOf(+a) && b.stat.selected.push(+a)
        })
    },
    removeAnswer: function(a) {
        var b = this,
            c = -1;
        a ? a.length && a.forEach(function(a) {
            c = b.stat.selected.indexOf(+a), -1 !== c && b.stat.selected.splice(c, 1)
        }) : this.stat.selected = []
    }
}, $(function() {
    "use strict";

    function updateViewQItem(qItemView, quiz) {
        var c = "";
        qItemView.quesNode.text(quiz.question);
        qItemView.hpNode.text(quiz.hp);
        c = quiz.options.reduce(function(previousValue, currentValue, index) {
            return previousValue + '
' + String.fromCharCode(65 + index) + '' + currentValue + "
"
        }, "");
        qItemView.optNode.html(c)
    }

    function bindSelectAction(optionNode) {
        optionNode.on("click", "li", function() {
        	if (quiz) {
        		quiz.submitAnswer([$(this).index()]);
        		quiz.stat.ended === !0 ? (optionNode.empty(), result()) : (quiz.next(), updateViewQItem(qItemIDs, quiz.stat))
        	};
            return !1
        })
    }

    function result() {
        function updateResult(a) {
            $("#J-container").html(a);
            var b = $("#J-result"),
                c = $("#J-comment");
            if (quiz.stat.num <=3) {
            	b.html('弱爆了，你答对了' + quiz.stat.passed + "/" + quiz.stat.total + "题，
丁香医生鉴定结果：");
            	c.html("谣言病毒 病原体
「我不知道，我什么都不知道~」");
            };
            if (quiz.stat.num <= 6) {
            	b.html('太 Low 了，你答对了' + quiz.stat.passed + "/" + quiz.stat.total + "题，
丁香医生鉴定结果：");
            	c.html("谣言病毒 传播者
「等会儿再看，先转了再说！」");
            };
            if (quiz.stat.num <= 9) {
            	b.html('还需继续加油，你答对了' + quiz.stat.passed + "/" + quiz.stat.total + "题，
丁香医生鉴定结果：");
            	c.html("谣言病毒 携带者
「其实…我也想做个好人！」");
            };
            if (10 === quiz.stat.num && quiz.stat.hp < 90) {
            	b.html('干的不错，你答对了' + quiz.stat.passed + "/" + quiz.stat.total + "题，
丁香医生鉴定结果：");
            	c.html("谣言病毒 易感者
「我猜...这个应该也是谣言吧？」");
            };
            if (10 === quiz.stat.num && 90 === quiz.stat.hp) {
            	b.html('棒极了，你答对了' + quiz.stat.passed + "/" + quiz.stat.total + "题，
丁香医生鉴定结果：");
            	c.html("谣言病毒 免疫体
「不辨是非的谣言再来约一架！」");
            };
            if (10 === quiz.stat.num && 90 === quiz.stat.hp) {
            	$(".btn-box").addClass("hide")
            }else{
            	 $(".full-score").addClass("hide");
            	 /MicroMessenger/i.test(navigator.userAgent) || $(".share-img").addClass("hide");
            	 $("#J-restart").on("click", function() {
            	 	newGame()
                });
            };
        }
        updateResult(resultTemplate ? resultTemplate : getRemoteData("tpl/1412/result.html", "resultPageHTML"))
    }

    function newGame() {
        function newQuiz(c) {
            quiz = new Quiz(JSON.parse(c));
            quiz.next()
            qItemIDs = {
                quesNode: $("#J-qu"),
                hpNode: $("#J-hp"),
                optNode: $("#J-opt")
            };
            updateViewQItem(qItemIDs, quiz.stat);
            bindSelectAction(qItemIDs.optNode);
        }
        $("#J-container").html(qItemTemplate ? qItemTemplate : getRemoteData("tpl/1412/game.html", "gamePageHTML")), newQuiz(quizDataJSON ? quizDataJSON : getRemoteData("json/question-data-1412.json", "quizDataStr"))
    }

    function getRemoteData(requestURL, localKey) {
        var returnData = "";
        return window.sessionStorage && sessionStorage[localKey] ? sessionStorage[localKey] : ($.ajax({
            type: "GET",
            url: appURL + requestURL,
            data: {
                t: timeStamp
            },
            dataType: "text",
            async: !1,
            success: function(responseDate) {
                window.sessionStorage && (sessionStorage[key] = responseDate), returnData = responseDate
            }
        }), returnData)
    }
    var appURL = "http://357-quiz.avosapps.com/",
        timeStamp = "1417770871684",
        quiz = null,
        qItemIDs = null,
        qItemTemplate = "",
        resultTemplate = "",
        quizDataJSON = "";
        qItemTemplate = getRemoteData("questionItem.html", "gamePageHTML"),
        quizDataJSON = getRemoteData("json/20141205.json", "quizDataStr"),
        resultTemplate = getRemoteData("result.html", "resultPageHTML"),
        $("#J-startGame").on("click", function() {
        newGame()
    }).addClass("loaded"), WeixinApi.ready(function(a) {
        var b = {
                async: !0,
                ready: function() {
                    var a = {
                        appId: "",
                        imgUrl: "http://357-quiz.avosapps.com/images/share-logo.png?t=1417770871684",
                        link: "http://357-quiz.avosapps.com/",
                        desc: "@丁香医生",
                        title: $("title").text()
                    };
                    quiz && quiz.stat.ended === !0 && (a.desc = "经丁香医生鉴定，我对谣言病毒的抵抗力为：" + $("#J-comment em").text()), this.dataLoaded(a)
                },
                fail: function() {
                    alert("分享失败，请稍候再试。")
                },
                confirm: function() {

                }
            },
            c = {
                async: !0,
                ready: function() {
                    var a = {
                        appId: "",
                        imgUrl: "http://357-quiz.avosapps.com/images/share-logo.png?t=1417770871684",
                        link: "http://357-quiz.avosapps.com/",
                        desc: $("title").text(),
                        title: $("title").text()
                    };
                    quiz && quiz.stat.ended === !0 && (a.desc = "经丁香医生鉴定，我对谣言病毒的抵抗力为：" + $("#J-comment em").text()), this.dataLoaded(a)
                },
                fail: function() {
                    alert("分享失败，请稍候再试。")
                },
                confirm: function() {

                }
            };
        a.shareToFriend({}, b), a.shareToTimeline({}, c)
    })
});<commit_msg>fixed missing typo<commit_after>/*! quiz-game 2014-12-03 15:11:48 */
function Quiz(a) {
    this.qData = a.qData, this.stat = {
        total: a.qData.length,
        hp: 0,
        passed: 0,
        num: 0,
        question: "",
        score: 0,
        options: [],
        answers: [],
        selected: [],
        answered: !1,
        ended: !1
    }, this.stat.hp = 0 === a.totalScore ? a.qData.reduce(function(a, b) {
        return a + b.score
    }, 0) : a.totalScore
}
Quiz.prototype = {
    _orderNum: function(a, b) {
        return a - b
    },
    next: function() {
        var a = 0;
        if (this.stat.num < this.stat.total) {
        	this.stat.num++;
        	if (1 === this.stat.num) {
        		this.stat.ended = !1;
        	};
        	a = this.stat.num - 1;
        	this.stat.question = this.qData[a].question;
        	this.stat.options = this.qData[a].options;
        	this.stat.answers = this.qData[a].answers;
        	this.stat.score = this.qData[a].score;
        };
    },
    submitAnswer: function(a) {
        var b = null;
        return a && this.inputAnswer(a), this.stat.ended || (this.stat.answers.sort(this._orderNum).toString() === this.stat.selected.sort(this._orderNum).toString() ? (this.stat.passed++, b = !0) : (this.stat.hp -= this.stat.score, b = !1), this.stat.answered = !0, (this.stat.hp <= 0 || this.stat.num >= this.stat.total) && (this.stat.ended = !0)), b
    },
    inputAnswer: function(a) {
        var b = this;
        this.stat.selected = [], a.length && a.forEach(function(a) {
            -1 === b.stat.selected.indexOf(+a) && b.stat.selected.push(+a)
        })
    },
    removeAnswer: function(a) {
        var b = this,
            c = -1;
        a ? a.length && a.forEach(function(a) {
            c = b.stat.selected.indexOf(+a), -1 !== c && b.stat.selected.splice(c, 1)
        }) : this.stat.selected = []
    }
}, $(function() {
    "use strict";

    function updateViewQItem(qItemView, quiz) {
        var c = "";
        qItemView.quesNode.text(quiz.question);
        qItemView.hpNode.text(quiz.hp);
        c = quiz.options.reduce(function(previousValue, currentValue, index) {
            return previousValue + '
' + String.fromCharCode(65 + index) + '' + currentValue + "
"
        }, "");
        qItemView.optNode.html(c)
    }

    function bindSelectAction(optionNode) {
        optionNode.on("click", "li", function() {
        	if (quiz) {
        		quiz.submitAnswer([$(this).index()]);
        		quiz.stat.ended === !0 ? (optionNode.empty(), result()) : (quiz.next(), updateViewQItem(qItemIDs, quiz.stat))
        	};
            return !1
        })
    }

    function result() {
        function updateResult(a) {
            $("#J-container").html(a);
            var b = $("#J-result"),
                c = $("#J-comment");
            if (quiz.stat.num <=3) {
            	b.html('弱爆了，你答对了' + quiz.stat.passed + "/" + quiz.stat.total + "题，
丁香医生鉴定结果：");
            	c.html("谣言病毒 病原体
「我不知道，我什么都不知道~」");
            };
            if (quiz.stat.num <= 6) {
            	b.html('太 Low 了，你答对了' + quiz.stat.passed + "/" + quiz.stat.total + "题，
丁香医生鉴定结果：");
            	c.html("谣言病毒 传播者
「等会儿再看，先转了再说！」");
            };
            if (quiz.stat.num <= 9) {
            	b.html('还需继续加油，你答对了' + quiz.stat.passed + "/" + quiz.stat.total + "题，
丁香医生鉴定结果：");
            	c.html("谣言病毒 携带者
「其实…我也想做个好人！」");
            };
            if (10 === quiz.stat.num && quiz.stat.hp < 90) {
            	b.html('干的不错，你答对了' + quiz.stat.passed + "/" + quiz.stat.total + "题，
丁香医生鉴定结果：");
            	c.html("谣言病毒 易感者
「我猜...这个应该也是谣言吧？」");
            };
            if (10 === quiz.stat.num && 90 === quiz.stat.hp) {
            	b.html('棒极了，你答对了' + quiz.stat.passed + "/" + quiz.stat.total + "题，
丁香医生鉴定结果：");
            	c.html("谣言病毒 免疫体
「不辨是非的谣言再来约一架！」");
            };
            if (10 === quiz.stat.num && 90 === quiz.stat.hp) {
            	$(".btn-box").addClass("hide")
            }else{
            	 $(".full-score").addClass("hide");
            	 /MicroMessenger/i.test(navigator.userAgent) || $(".share-img").addClass("hide");
            	 $("#J-restart").on("click", function() {
            	 	newGame()
                });
            };
        }
        updateResult(resultTemplate ? resultTemplate : getRemoteData("tpl/1412/result.html", "resultPageHTML"))
    }

    function newGame() {
        function newQuiz(c) {
            quiz = new Quiz(JSON.parse(c));
            quiz.next()
            qItemIDs = {
                quesNode: $("#J-qu"),
                hpNode: $("#J-hp"),
                optNode: $("#J-opt")
            };
            updateViewQItem(qItemIDs, quiz.stat);
            bindSelectAction(qItemIDs.optNode);
        }
        $("#J-container").html(qItemTemplate ? qItemTemplate : getRemoteData("tpl/1412/game.html", "gamePageHTML")), newQuiz(quizDataJSON ? quizDataJSON : getRemoteData("json/question-data-1412.json", "quizDataStr"))
    }

    function getRemoteData(requestURL, localKey) {
        var returnData = "";
        return window.sessionStorage && sessionStorage[localKey] ? sessionStorage[localKey] : ($.ajax({
            type: "GET",
            url: appURL + requestURL,
            data: {
                t: timeStamp
            },
            dataType: "text",
            async: !1,
            success: function(responseDate) {
                window.sessionStorage && (sessionStorage[localKey] = responseDate), returnData = responseDate
            }
        }), returnData)
    }
    var appURL = "http://357-quiz.avosapps.com/",
        timeStamp = "1417770871684",
        quiz = null,
        qItemIDs = null,
        qItemTemplate = "",
        resultTemplate = "",
        quizDataJSON = "";
        qItemTemplate = getRemoteData("questionItem.html", "gamePageHTML"),
        quizDataJSON = getRemoteData("json/20141205.json", "quizDataStr"),
        resultTemplate = getRemoteData("result.html", "resultPageHTML"),
        $("#J-startGame").on("click", function() {
        newGame()
    }).addClass("loaded"), WeixinApi.ready(function(a) {
        var b = {
                async: !0,
                ready: function() {
                    var a = {
                        appId: "",
                        imgUrl: "http://357-quiz.avosapps.com/images/share-logo.png?t=1417770871684",
                        link: "http://357-quiz.avosapps.com/",
                        desc: "@丁香医生",
                        title: $("title").text()
                    };
                    quiz && quiz.stat.ended === !0 && (a.desc = "经丁香医生鉴定，我对谣言病毒的抵抗力为：" + $("#J-comment em").text()), this.dataLoaded(a)
                },
                fail: function() {
                    alert("分享失败，请稍候再试。")
                },
                confirm: function() {

                }
            },
            c = {
                async: !0,
                ready: function() {
                    var a = {
                        appId: "",
                        imgUrl: "http://357-quiz.avosapps.com/images/share-logo.png?t=1417770871684",
                        link: "http://357-quiz.avosapps.com/",
                        desc: $("title").text(),
                        title: $("title").text()
                    };
                    quiz && quiz.stat.ended === !0 && (a.desc = "经丁香医生鉴定，我对谣言病毒的抵抗力为：" + $("#J-comment em").text()), this.dataLoaded(a)
                },
                fail: function() {
                    alert("分享失败，请稍候再试。")
                },
                confirm: function() {

                }
            };
        a.shareToFriend({}, b), a.shareToTimeline({}, c)
    })
});<|endoftext|>


<commit_before>$(document).ready(function() {
    $.fn.editable.defaults.;
    $('.x-editable').editable({
        mode = 'inline',
        },
        success: function(response, newValue) {
            if(!response) {
                return "Unknown error!";
            }
            if(response.success === false) {
                 return response.msg;
            }
        }
    });
});
<commit_msg>Javascript lol<commit_after>$(document).ready(function() {
    $.fn.editable.defaults.mode = 'inline';
    $('.x-editable').editable({
        success: function(response, newValue) {
            if(!response) {
                return "Unknown error!";
            }
            if(response.success === false) {
                 return response.msg;
            }
        }
    });
});
<|endoftext|>


<commit_before>/* eslint-env browser */

/**
 * Note: window.gapiReady must be a promise that resolves to
 * window.gapi.
 *
 * @template T
 * @param {string} name the library to load
 * @return {Promise<T>}
 */
function gapiLoad(name) {
  return new Promise((resolve, reject) => {
    if ('gapiReady' in window) {
      window.gapiReady.then(gapi => {
        gapi.load(name, () => resolve(gapi[name]));
      });
    } else {
      reject('Promise window.gapiReady not found');
    }
  });
}

/**
 * Promise'd version of [`gapi.client.load`](https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiclientloadname--------version--------callback).
 *
 * @template T
 * @param {string} name the API client to load
 * @param {string} [version="v1"] version
 * @return {Promise<T>} Promise resolving to gapi.client[name]
 */
function clientLoad(name, version) {
  version = version ? version : 'v1';
  return gapiLoad('client').then(client => {
    return new Promise(resolve => {
      client.load(name, version, () => resolve(client[name]));
    });
  });
}

/**
 * Promise'd version of [`gapi.auth2.init`](https://developers.google.com/identity/sign-in/web/reference#gapiauth2initparams).
 *
 * @param {any} params https://developers.google.com/identity/sign-in/web/reference#gapiauth2initparams
 * @return {Promise<gapi.auth2.GoogleAuth>} Promise resolving to an initialized gapi.auth2.GoogleAuth object
 */
function authInit(params) {
  return gapiLoad('auth2').then(auth2 => {
    /* Ideally we'd just return `auth2.init(params)` here, but
     * instead we need to work around a few bugs and surprises in
     * `auth2.init()` and the "Promise" it returns.
     */
    return new Promise(resolve => {
      auth2.init(params).then(t => {
        t.then = null;
        resolve(t);
      });
    });
  });
}

(() => {
  const [login, logout] = [document.getElementById('login'), document.getElementById('logout')];

  /**
   * @param {GoogleUser} user
   */
  function onChange(user) {
    if (user.isSignedIn()) {
      // @TODO Send id_token to backend
      console.log('id_token', user.getAuthResponse().id_token);
      login.disabled = true;
      logout.disabled = false;
    } else {
      console.log('user signed out/never signed in');
      login.disabled = false;
      logout.disabled = true;
    }
  }

  /* eslint-disable camelcase */
  const params = {
    scope: 'email',
    client_id: '605287872172-js6omne47i1k79hnfo7d4bdu9rlemslr.apps.googleusercontent.com',
    fetch_basic_profile: false
  };
  /* eslint-enable camelcase */

  authInit(params).then(auth => {
    auth.currentUser.listen(onChange);
    onChange(auth.currentUser.get()); // User may be signed in already

    login.addEventListener('click', () => auth.signIn());
    logout.addEventListener('click', () => auth.signOut());
  });
})();
<commit_msg>Make eslint happy<commit_after>/* eslint-env browser */

/**
 * Note: window.gapiReady must be a promise that resolves to
 * window.gapi.
 *
 * @template T
 * @param {string} name the library to load
 * @return {Promise<T>}
 */
function gapiLoad(name) {
  return new Promise((resolve, reject) => {
    if ('gapiReady' in window) {
      window.gapiReady.then(gapi => {
        gapi.load(name, () => resolve(gapi[name]));
      });
    } else {
      reject('Promise window.gapiReady not found');
    }
  });
}

/**
 * Promise'd version of [`gapi.client.load`](https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiclientloadname--------version--------callback).
 *
 * @template T
 * @param {string} name the API client to load
 * @param {string} [version="v1"] version
 * @return {Promise<T>} Promise resolving to gapi.client[name]
 */
function clientLoad(name, version) { // eslint-disable-line no-unused-vars
  version = version ? version : 'v1';
  return gapiLoad('client').then(client => {
    return new Promise(resolve => {
      client.load(name, version, () => resolve(client[name]));
    });
  });
}

/**
 * Promise'd version of [`gapi.auth2.init`](https://developers.google.com/identity/sign-in/web/reference#gapiauth2initparams).
 *
 * @param {any} params https://developers.google.com/identity/sign-in/web/reference#gapiauth2initparams
 * @return {Promise<gapi.auth2.GoogleAuth>} Promise resolving to an initialized gapi.auth2.GoogleAuth object
 */
function authInit(params) {
  return gapiLoad('auth2').then(auth2 => {
    /* Ideally we'd just return `auth2.init(params)` here, but
     * instead we need to work around a few bugs and surprises in
     * `auth2.init()` and the "Promise" it returns.
     */
    return new Promise(resolve => {
      auth2.init(params).then(t => {
        t.then = null;
        resolve(t);
      });
    });
  });
}

(() => {
  const [login, logout] = [document.getElementById('login'), document.getElementById('logout')];

  /**
   * @param {GoogleUser} user
   */
  function onChange(user) {
    if (user.isSignedIn()) {
      // @TODO Send id_token to backend
      console.log('id_token', user.getAuthResponse().id_token);
      login.disabled = true;
      logout.disabled = false;
    } else {
      console.log('user signed out/never signed in');
      login.disabled = false;
      logout.disabled = true;
    }
  }

  /* eslint-disable camelcase */
  const params = {
    scope: 'email',
    client_id: '605287872172-js6omne47i1k79hnfo7d4bdu9rlemslr.apps.googleusercontent.com',
    fetch_basic_profile: false
  };
  /* eslint-enable camelcase */

  authInit(params).then(auth => {
    auth.currentUser.listen(onChange);
    onChange(auth.currentUser.get()); // User may be signed in already

    login.addEventListener('click', () => auth.signIn());
    logout.addEventListener('click', () => auth.signOut());
  });
})();
<|endoftext|>