<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 *
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
 *
 * ***** END LICENSE BLOCK ***** */

"use strict";

// SDK
var { Services } = require("resource://gre/modules/Services.jsm");
//var tabsSDK = require("sdk/tabs");
//var tabsUtils = require("sdk/tabs/utils");
var stylesheetUtils = require("sdk/stylesheet/utils");
//var contentMod = require("sdk/content/mod");
//var Style = require("sdk/stylesheet/style").Style;

const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const TAB_DROP_TYPE = "application/x-moz-tabbrowser-tab";

/*
 * Vertical Tabs Reloaded
 *
 * Main entry point of this add-on.
 */

var VerticalTabsReloaded = class VerticalTabsReloaded
{
    constructor(window, webextPortP, webExtPreferences)
    {
        this.webextPort = webextPortP;
        this.window = window;
        this.document = window.document;
        this.webExtPreferences = webExtPreferences;
        this.parsedStyle = undefined;
        this.changedDisplayState = false;
        this.unloaders = [];
        this.init();
    }

    init()
    {
        this.window.VerticalTabsReloaded = this;
        this.unloaders.push(function() {
            delete this.window.VerticalTabsReloaded;
        });

        this.rearrangeUI();
        this.initEventListeners();
    }

    preferences(settingName)
    {
        this.debugOutput(settingName + " (sdk lib): " + this.webExtPreferences[settingName]);
        return this.webExtPreferences[settingName];
    }

    webext_sendMsg(message)
    {
        // Send message to WebExtension
        this.webextPort.postMessage(message);
    }

    webext_sendChangedSetting(settingName, newValue)
    {
        // Changed addon preferences
        this.webext_sendMsg({
            type: "settings.post",
            name: settingName,
            value: newValue
        });
    }

    installStylesheet(uri)
    {
        uri = Services.io.newURI(uri, null, null);
        stylesheetUtils.loadSheet(this.window, uri);
        this.debugOutput(uri);
    }

    removeStylesheet(uri)
    {
        uri = Services.io.newURI(uri, null, null);
        stylesheetUtils.removeSheet(this.window, uri);
        this.debugOutput(uri);
    }

    applyThemeStylesheet()
    {
        if(this.preferences("theme") != "none")
        {
            this.installStylesheet(this.getThemeStylesheet(this.preferences("theme")));
        }
    }

    removeThemeStylesheet()
    {
        if(this.preferences("theme") != "none")
        {
            this.debugOutput("remove: " + this.getThemeStylesheet(this.preferences("theme")));
            this.removeStylesheet(this.getThemeStylesheet(this.preferences("theme")));
        }
    }

    getThemeStylesheet(theme)
    {
        var stylesheet;
        switch (theme)
        {
            default:
                stylesheet = "theme/"+theme+"/index.css";
                break;
        }

        return this.preferences("dataPath") + stylesheet;
    }

    rearrangeUI()
    {
        const window = this.window;
        const document = this.document;

        // Ugly workaround: save the label of the first tab for later…
        let tabs = document.getElementById("tabbrowser-tabs");
        let label = tabs.firstChild.label;

        // Injecting CSS and init gruesome XBL binding
        this.installStylesheet(this.preferences("dataPath") + "override-bindings.css");
        this.installStylesheet(this.preferences("dataPath") + "theme/base.css");
        this.applyThemeStylesheet();
        if (this.preferences("compact") == true)
        {
            this.installStylesheet(this.preferences("dataPath") + "compact.css");
            //this.webext_sendMsg({type: "css.get", name: "compact", file: "compact.css"});
        }

        // Move the bottom stuff (findbar, addonbar, etc.) in with the
        // tabbrowser.  That way it will share the same (horizontal)
        // space as the browser.  In other words, the bottom stuff no
        // longer extends across the whole bottom of the window.
        let contentbox = document.getElementById("appcontent");
        let bottom = document.getElementById("browser-bottombox");
        contentbox.appendChild(bottom);

        // Create a box next to the app content. It will hold the tab
        // bar and the tab toolbar.
        let browserbox = document.getElementById("browser");
        let leftbox = document.createElementNS(NS_XUL, "vbox");
        leftbox.id = "verticaltabs-box";
        browserbox.insertBefore(leftbox, contentbox);

        let splitter = document.createElementNS(NS_XUL, "splitter");
        splitter.id = "verticaltabs-splitter";
        splitter.className = "chromeclass-extrachrome";
        browserbox.insertBefore(splitter, contentbox);
        // Hook up event handler for splitter so that the width of the
        // tab bar is persisted.
        splitter.addEventListener("mouseup", this, false);

        // Move the tabs next to the app content, make them vertical,

        if (this.preferences("right"))
        {
            browserbox.dir = "reverse";
        }

        tabs.setAttribute("data-vertical", true);
        leftbox.insertBefore(tabs, leftbox.firstChild);
        tabs.orient = "vertical";
        tabs.mTabstrip.orient = "vertical";
        tabs.tabbox.orient = "horizontal"; // probably not necessary

        // Restore width of tab bar from previous session
        tabs.setAttribute("width", this.preferences("width"));

        // Move the tabs toolbar into the tab strip
        let toolbar = document.getElementById("TabsToolbar");
        toolbar.setAttribute("collapsed", "false"); // no more vanishing new tab toolbar
        toolbar._toolbox = null; // reset value set by constructor
        toolbar.setAttribute("toolboxid", "navigator-toolbox");

        if (this.preferences("tabtoolbarPosition") == "top")
        {
            leftbox.insertBefore(toolbar, leftbox.firstChild);
        }
        else
        {
            leftbox.appendChild(toolbar);
        }

        // Init every tab
        tabs.addEventListener("TabOpen", this, false);
        for (let i=0; i < tabs.childNodes.length; i++)
        {
            this.initTab(tabs.childNodes[i]);
        }

        // And restore the label here.
        this.debugOutput("label: "+label);
        tabs.firstChild.label = label;

        this.unloaders.push(function()
        {
            // Move the bottom back to being the next sibling of contentbox.
            browserbox.insertBefore(bottom, contentbox.nextSibling);

            // Move the tabs toolbar back to where it was
            toolbar._toolbox = null; // reset value set by constructor
            toolbar.removeAttribute("toolboxid");
            let toolbox = document.getElementById("navigator-toolbox");
            let navbar = document.getElementById("nav-bar");
            //toolbox.appendChild(toolbar);

            // Restore the tab strip.
            toolbox.insertBefore(toolbar, navbar);

            let new_tab_button = document.getElementById("new-tab-button");

            // Put the tabs back up
            toolbar.insertBefore(tabs, new_tab_button);
            tabs.removeAttribute("data-vertical");
            tabs.orient = "horizontal";
            tabs.mTabstrip.orient = "horizontal";
            tabs.tabbox.orient = "vertical"; // probably not necessary
            tabs.removeAttribute("width");

            // Restore all individual tabs.
            tabs.removeEventListener("TabOpen", this, false);
            for (let i = 0; i < tabs.childNodes.length; i++)
            {
                let tab = tabs.childNodes[i];
                tab.removeAttribute("align");
                tab.maxWidth = tab.minWidth = "";
            }

            // Remove everything we added.
            splitter.removeEventListener("mouseup", this, false);
            browserbox.removeChild(leftbox);
            browserbox.removeChild(splitter);
            browserbox.dir = "normal";
            leftbox = splitter = null;

            this.removeStylesheet(this.preferences("dataPath") + "override-bindings.css");
            this.removeStylesheet(this.preferences("dataPath") + "theme/base.css");
            this.removeThemeStylesheet();
            if (this.preferences("compact") == true)
            {
                this.removeStylesheet(this.preferences("dataPath") + "compact.css");
            }
        });
    }

    initTab(aTab)
    {
        aTab.setAttribute("align", "stretch");
        aTab.maxWidth = 65000;
        aTab.minWidth = 0;
    }

    setPinnedSizes()
    {
        //this.debugOutput("set pinned sizes!");
    }

    onTabbarResized()
    {
        let tabs = this.document.getElementById("tabbrowser-tabs");
        this.setPinnedSizes();
        this.window.setTimeout(this.webext_sendChangedSetting("width", tabs.boxObject.width), 10);
    }

    onPreferenceChange(prefName, newValue)
    {
        switch (prefName)
        {
            case "right":
                this.webExtPreferences = newValue;
                let browserbox = this.document.getElementById("browser");
                if (browserbox.dir != "reverse")
                {
                    browserbox.dir = "reverse";
                }
                else
                {
                    browserbox.dir = "normal";
                }
                break;
            case "css":
                /*if(this.parsedStyle != undefined)
                {
                    contentMod.detachFrom(this.parsedStyle, this.window);
                }

                this.webExtPreferences = newValue;
                let newStyle;

                Object.keys(this.webExtPreferences["css"]).forEach(k =>
                {
                    this.debugOutput(k);
                    newStyle = newStyle + this.webExtPreferences["css"][k];
                    this.debugOutput(this.webExtPreferences["css"][k]);
                });

                var style = Style({ source: newStyle });
                this.parsedStyle = style;
                this.debugOutput("css changed!");
                this.debugOutput(this.parsedStyle);
                contentMod.attachTo(this.parsedStyle, this.window);
                break;*/
            case "theme":
                this.removeThemeStylesheet();
                this.webExtPreferences = newValue;
                //this.webext_sendMsg({type: "css.get", name: "theme", file: this.getThemeStylesheet(this.preferences("theme"))});
                this.applyThemeStylesheet();
                break;
            case "hideInFullscreen":
                this.onSizeModeChange();
                break;
            case "compact":
                this.webExtPreferences = newValue;
                if (this.preferences("compact") == true)
                {
                    this.installStylesheet(this.preferences("dataPath") + "compact.css");
                    //this.webext_sendMsg({type: "css.get", name: "compact", file: "compact.css"});
                }
                else
                {
                    this.removeStylesheet(this.preferences("dataPath") + "compact.css");
                    //this.webext_sendMsg({type: "css.get", name: "compact", file: "none"});
                }
                break;
            case "tabtoolbarPosition":
                this.webExtPreferences = newValue;
                // Position toggle/move of the tabtoolbar
                let toolbar = this.document.getElementById("TabsToolbar");
                let leftbox = this.document.getElementById("verticaltabs-box");
                if (this.preferences("tabtoolbarPosition") == "top")
                {
                    leftbox.insertBefore(toolbar, leftbox.firstChild);
                }
                else
                {
                    leftbox.appendChild(toolbar);
                }
                break;
            default:
                this.webExtPreferences = newValue;
                break;
        }
    }

    initEventListeners()
    {
        // Note: Not all eventsListener are set up here
        this.window.addEventListener("sizemodechange", this, false);
        this.window.addEventListener("resize", this, false);

        this.unloaders.push(function()
        {
            this.window.removeEventListener("sizemodechange", this, false);
            this.window.removeEventListener("resize", this, false);
        });
    }

    // Event handlers
    handleEvent(aEvent)
    {
        //debugOutput("aEvent.type: "+aEvent.type);
        switch (aEvent.type)
        {
            case "TabOpen":
                this.initTab(aEvent.target);
                this.setPinnedSizes();
                return;
            case "mouseup":
                if (aEvent.target.getAttribute("id") == "verticaltabs-splitter")
                {
                    this.onTabbarResized();
                }
                return;
            case "sizemodechange":
                this.onSizeModeChange();
                return;
            //case "popupshowing":
                //return;
            case "resize":
                this.setPinnedSizes();
                return;
        }
    }

    toggleDisplayState()
    {
        const document = this.document;

        if(document.getElementById("verticaltabs-box").style.display == "")
        {
            this.changeDisplayState("none");
            this.changedDisplayState = true;
        }
        else
        {
            this.changeDisplayState("");
            this.changedDisplayState = false;
        }
    }

    changeDisplayState(display)
    {
        const document = this.document;

        let tabs = document.getElementById("verticaltabs-box").style;
        let splitter = document.getElementById("verticaltabs-splitter").style;

        if (tabs.display == display && splitter.display == display)
        {
            return;
        }

        tabs.display = splitter.display = display;
    }

    /*
    * The size of the window changed, check if we entered/left fullscreen and
    * hide/show tabs according to user setting
    */
    onSizeModeChange()
    {
        if(this.changedDisplayState == true)
        {
            return;
        }

        const window = this.window;
        const document = this.document;

        let hideOk = this.preferences("hideInFullscreen");
        let display = hideOk && window.windowState == window.STATE_FULLSCREEN ? "none" : "";

        this.changeDisplayState(display);
    }

    unload()
    {
        this.unloaders.forEach(function(func)
        {
            func.call(this);
        }, this);

        this.unloaders = [];
    }

    debugOutput(output)
    {
        this.webext_sendMsg({
            type: "debug.log",
            value: output
        });
    }

}

exports.VerticalTabsReloaded = VerticalTabsReloaded;
<commit_msg>verticaltabs.js: Make it more clear what SDK modules are still in use<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 *
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
 *
 * ***** END LICENSE BLOCK ***** */

"use strict";

// SDK
var ioServices = require("resource://gre/modules/Services.jsm").Services.io;
var stylesheetUtils = require("sdk/stylesheet/utils");

//var tabsSDK = require("sdk/tabs");
//var tabsUtils = require("sdk/tabs/utils");
//var contentMod = require("sdk/content/mod");
//var Style = require("sdk/stylesheet/style").Style;

const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const TAB_DROP_TYPE = "application/x-moz-tabbrowser-tab";

/*
 * Vertical Tabs Reloaded
 *
 * Main entry point of this add-on.
 */

var VerticalTabsReloaded = class VerticalTabsReloaded
{
    constructor(window, webextPortP, webExtPreferences)
    {
        this.webextPort = webextPortP;
        this.window = window;
        this.document = window.document;
        this.webExtPreferences = webExtPreferences;
        this.parsedStyle = undefined;
        this.changedDisplayState = false;
        this.unloaders = [];
        this.init();
    }

    init()
    {
        this.window.VerticalTabsReloaded = this;
        this.unloaders.push(function() {
            delete this.window.VerticalTabsReloaded;
        });

        this.rearrangeUI();
        this.initEventListeners();
    }

    preferences(settingName)
    {
        this.debugOutput(settingName + " (sdk lib): " + this.webExtPreferences[settingName]);
        return this.webExtPreferences[settingName];
    }

    webext_sendMsg(message)
    {
        // Send message to WebExtension
        this.webextPort.postMessage(message);
    }

    webext_sendChangedSetting(settingName, newValue)
    {
        // Changed addon preferences
        this.webext_sendMsg({
            type: "settings.post",
            name: settingName,
            value: newValue
        });
    }

    installStylesheet(uri)
    {
        uri = ioServices.newURI(uri, null, null);
        stylesheetUtils.loadSheet(this.window, uri);
        this.debugOutput(uri);
    }

    removeStylesheet(uri)
    {
        uri = ioServices.newURI(uri, null, null);
        stylesheetUtils.removeSheet(this.window, uri);
        this.debugOutput(uri);
    }

    applyThemeStylesheet()
    {
        if(this.preferences("theme") != "none")
        {
            this.installStylesheet(this.getThemeStylesheet(this.preferences("theme")));
        }
    }

    removeThemeStylesheet()
    {
        if(this.preferences("theme") != "none")
        {
            this.debugOutput("remove: " + this.getThemeStylesheet(this.preferences("theme")));
            this.removeStylesheet(this.getThemeStylesheet(this.preferences("theme")));
        }
    }

    getThemeStylesheet(theme)
    {
        var stylesheet;
        switch (theme)
        {
            default:
                stylesheet = "theme/"+theme+"/index.css";
                break;
        }

        return this.preferences("dataPath") + stylesheet;
    }

    rearrangeUI()
    {
        const window = this.window;
        const document = this.document;

        // Ugly workaround: save the label of the first tab for later…
        let tabs = document.getElementById("tabbrowser-tabs");
        let label = tabs.firstChild.label;

        // Injecting CSS and init gruesome XBL binding
        this.installStylesheet(this.preferences("dataPath") + "override-bindings.css");
        this.installStylesheet(this.preferences("dataPath") + "theme/base.css");
        this.applyThemeStylesheet();
        if (this.preferences("compact") == true)
        {
            this.installStylesheet(this.preferences("dataPath") + "compact.css");
            //this.webext_sendMsg({type: "css.get", name: "compact", file: "compact.css"});
        }

        // Move the bottom stuff (findbar, addonbar, etc.) in with the
        // tabbrowser.  That way it will share the same (horizontal)
        // space as the browser.  In other words, the bottom stuff no
        // longer extends across the whole bottom of the window.
        let contentbox = document.getElementById("appcontent");
        let bottom = document.getElementById("browser-bottombox");
        contentbox.appendChild(bottom);

        // Create a box next to the app content. It will hold the tab
        // bar and the tab toolbar.
        let browserbox = document.getElementById("browser");
        let leftbox = document.createElementNS(NS_XUL, "vbox");
        leftbox.id = "verticaltabs-box";
        browserbox.insertBefore(leftbox, contentbox);

        let splitter = document.createElementNS(NS_XUL, "splitter");
        splitter.id = "verticaltabs-splitter";
        splitter.className = "chromeclass-extrachrome";
        browserbox.insertBefore(splitter, contentbox);
        // Hook up event handler for splitter so that the width of the
        // tab bar is persisted.
        splitter.addEventListener("mouseup", this, false);

        // Move the tabs next to the app content, make them vertical,

        if (this.preferences("right"))
        {
            browserbox.dir = "reverse";
        }

        tabs.setAttribute("data-vertical", true);
        leftbox.insertBefore(tabs, leftbox.firstChild);
        tabs.orient = "vertical";
        tabs.mTabstrip.orient = "vertical";
        tabs.tabbox.orient = "horizontal"; // probably not necessary

        // Restore width of tab bar from previous session
        tabs.setAttribute("width", this.preferences("width"));

        // Move the tabs toolbar into the tab strip
        let toolbar = document.getElementById("TabsToolbar");
        toolbar.setAttribute("collapsed", "false"); // no more vanishing new tab toolbar
        toolbar._toolbox = null; // reset value set by constructor
        toolbar.setAttribute("toolboxid", "navigator-toolbox");

        if (this.preferences("tabtoolbarPosition") == "top")
        {
            leftbox.insertBefore(toolbar, leftbox.firstChild);
        }
        else
        {
            leftbox.appendChild(toolbar);
        }

        // Init every tab
        tabs.addEventListener("TabOpen", this, false);
        for (let i=0; i < tabs.childNodes.length; i++)
        {
            this.initTab(tabs.childNodes[i]);
        }

        // And restore the label here.
        this.debugOutput("label: "+label);
        tabs.firstChild.label = label;

        this.unloaders.push(function()
        {
            // Move the bottom back to being the next sibling of contentbox.
            browserbox.insertBefore(bottom, contentbox.nextSibling);

            // Move the tabs toolbar back to where it was
            toolbar._toolbox = null; // reset value set by constructor
            toolbar.removeAttribute("toolboxid");
            let toolbox = document.getElementById("navigator-toolbox");
            let navbar = document.getElementById("nav-bar");
            //toolbox.appendChild(toolbar);

            // Restore the tab strip.
            toolbox.insertBefore(toolbar, navbar);

            let new_tab_button = document.getElementById("new-tab-button");

            // Put the tabs back up
            toolbar.insertBefore(tabs, new_tab_button);
            tabs.removeAttribute("data-vertical");
            tabs.orient = "horizontal";
            tabs.mTabstrip.orient = "horizontal";
            tabs.tabbox.orient = "vertical"; // probably not necessary
            tabs.removeAttribute("width");

            // Restore all individual tabs.
            tabs.removeEventListener("TabOpen", this, false);
            for (let i = 0; i < tabs.childNodes.length; i++)
            {
                let tab = tabs.childNodes[i];
                tab.removeAttribute("align");
                tab.maxWidth = tab.minWidth = "";
            }

            // Remove everything we added.
            splitter.removeEventListener("mouseup", this, false);
            browserbox.removeChild(leftbox);
            browserbox.removeChild(splitter);
            browserbox.dir = "normal";
            leftbox = splitter = null;

            this.removeStylesheet(this.preferences("dataPath") + "override-bindings.css");
            this.removeStylesheet(this.preferences("dataPath") + "theme/base.css");
            this.removeThemeStylesheet();
            if (this.preferences("compact") == true)
            {
                this.removeStylesheet(this.preferences("dataPath") + "compact.css");
            }
        });
    }

    initTab(aTab)
    {
        aTab.setAttribute("align", "stretch");
        aTab.maxWidth = 65000;
        aTab.minWidth = 0;
    }

    setPinnedSizes()
    {
        //this.debugOutput("set pinned sizes!");
    }

    onTabbarResized()
    {
        let tabs = this.document.getElementById("tabbrowser-tabs");
        this.setPinnedSizes();
        this.window.setTimeout(this.webext_sendChangedSetting("width", tabs.boxObject.width), 10);
    }

    onPreferenceChange(prefName, newValue)
    {
        switch (prefName)
        {
            case "right":
                this.webExtPreferences = newValue;
                let browserbox = this.document.getElementById("browser");
                if (browserbox.dir != "reverse")
                {
                    browserbox.dir = "reverse";
                }
                else
                {
                    browserbox.dir = "normal";
                }
                break;
            case "css":
                /*if(this.parsedStyle != undefined)
                {
                    contentMod.detachFrom(this.parsedStyle, this.window);
                }

                this.webExtPreferences = newValue;
                let newStyle;

                Object.keys(this.webExtPreferences["css"]).forEach(k =>
                {
                    this.debugOutput(k);
                    newStyle = newStyle + this.webExtPreferences["css"][k];
                    this.debugOutput(this.webExtPreferences["css"][k]);
                });

                var style = Style({ source: newStyle });
                this.parsedStyle = style;
                this.debugOutput("css changed!");
                this.debugOutput(this.parsedStyle);
                contentMod.attachTo(this.parsedStyle, this.window);
                break;*/
            case "theme":
                this.removeThemeStylesheet();
                this.webExtPreferences = newValue;
                //this.webext_sendMsg({type: "css.get", name: "theme", file: this.getThemeStylesheet(this.preferences("theme"))});
                this.applyThemeStylesheet();
                break;
            case "hideInFullscreen":
                this.onSizeModeChange();
                break;
            case "compact":
                this.webExtPreferences = newValue;
                if (this.preferences("compact") == true)
                {
                    this.installStylesheet(this.preferences("dataPath") + "compact.css");
                    //this.webext_sendMsg({type: "css.get", name: "compact", file: "compact.css"});
                }
                else
                {
                    this.removeStylesheet(this.preferences("dataPath") + "compact.css");
                    //this.webext_sendMsg({type: "css.get", name: "compact", file: "none"});
                }
                break;
            case "tabtoolbarPosition":
                this.webExtPreferences = newValue;
                // Position toggle/move of the tabtoolbar
                let toolbar = this.document.getElementById("TabsToolbar");
                let leftbox = this.document.getElementById("verticaltabs-box");
                if (this.preferences("tabtoolbarPosition") == "top")
                {
                    leftbox.insertBefore(toolbar, leftbox.firstChild);
                }
                else
                {
                    leftbox.appendChild(toolbar);
                }
                break;
            default:
                this.webExtPreferences = newValue;
                break;
        }
    }

    initEventListeners()
    {
        // Note: Not all eventsListener are set up here
        this.window.addEventListener("sizemodechange", this, false);
        this.window.addEventListener("resize", this, false);

        this.unloaders.push(function()
        {
            this.window.removeEventListener("sizemodechange", this, false);
            this.window.removeEventListener("resize", this, false);
        });
    }

    // Event handlers
    handleEvent(aEvent)
    {
        //debugOutput("aEvent.type: "+aEvent.type);
        switch (aEvent.type)
        {
            case "TabOpen":
                this.initTab(aEvent.target);
                this.setPinnedSizes();
                return;
            case "mouseup":
                if (aEvent.target.getAttribute("id") == "verticaltabs-splitter")
                {
                    this.onTabbarResized();
                }
                return;
            case "sizemodechange":
                this.onSizeModeChange();
                return;
            //case "popupshowing":
                //return;
            case "resize":
                this.setPinnedSizes();
                return;
        }
    }

    toggleDisplayState()
    {
        const document = this.document;

        if(document.getElementById("verticaltabs-box").style.display == "")
        {
            this.changeDisplayState("none");
            this.changedDisplayState = true;
        }
        else
        {
            this.changeDisplayState("");
            this.changedDisplayState = false;
        }
    }

    changeDisplayState(display)
    {
        const document = this.document;

        let tabs = document.getElementById("verticaltabs-box").style;
        let splitter = document.getElementById("verticaltabs-splitter").style;

        if (tabs.display == display && splitter.display == display)
        {
            return;
        }

        tabs.display = splitter.display = display;
    }

    /*
    * The size of the window changed, check if we entered/left fullscreen and
    * hide/show tabs according to user setting
    */
    onSizeModeChange()
    {
        if(this.changedDisplayState == true)
        {
            return;
        }

        const window = this.window;
        const document = this.document;

        let hideOk = this.preferences("hideInFullscreen");
        let display = hideOk && window.windowState == window.STATE_FULLSCREEN ? "none" : "";

        this.changeDisplayState(display);
    }

    unload()
    {
        this.unloaders.forEach(function(func)
        {
            func.call(this);
        }, this);

        this.unloaders = [];
    }

    debugOutput(output)
    {
        this.webext_sendMsg({
            type: "debug.log",
            value: output
        });
    }

}

exports.VerticalTabsReloaded = VerticalTabsReloaded;
<|endoftext|>


<commit_before>import React from "react";

import MetadataStore from "#SRC/js/stores/MetadataStore";

const summaryDocsURL = MetadataStore.buildDocsURI(
  "/overview/concepts/#mesos-resource-offer"
);

module.exports = {
  summaryIntro: (

      {
        "When you attempt to deploy a service, DC/OS waits for offers to match the resources your service requires. If the offer does not satisfy the requirement, it is declined and DC/OS retries. "
      }

        Learn more
      .

  )
};
<commit_msg>feat(DeclinedOffersHelpText): localize with Trans macro<commit_after>import { Trans } from "@lingui/macro";
import React from "react";

import MetadataStore from "#SRC/js/stores/MetadataStore";

const summaryDocsURL = MetadataStore.buildDocsURI(
  "/overview/concepts/#mesos-resource-offer"
);

module.exports = {
  summaryIntro: (
    <Trans render="span">
      When you attempt to deploy a service, DC/OS waits for offers to match the{" "}
      resources your service requires. If the offer does not satisfy the{" "}
      requirement, it is declined and DC/OS retries.{" "}

        Learn more
      .
    </Trans>
  )
};
<|endoftext|>


<commit_before>Parse.initialize("ONeIYsbSCtIJg6bo0M823t6Z8ZqmqEM4Zfgh2U5a", "A1lJ2mF6YV48qcO5KBkQ1XCEC2BDF3mAt1MlqqlB");

var user = Parse.User.current();
updateScores();

function onLogin() {
  console.log('Welcome!  Fetching your information.... ');

  FB.api("/me", function (response) {
    if (response && !response.error) {
      user.set("fbId", response.id);
      user.set("name", response.name);
      if(user.get("statusesShown" == 0)) {
        user.set("accuracy", 0);
      }
      user.save();
    }
    //console.log(response);
  });

  FB.api("/me/friends",
    function (response) {
      if (response && !response.error) {
        console.log("friends----");
        console.log(response);

        var ids = [];
        var query = new Parse.Query(Parse.User);
        var relation = user.relation("friendsUsingApp");
        //get size of dictionaries

        for (i = 0; i < response.data.length; i++) {
          ids[i] = response.data[i].id;
        }
        console.log(ids);
        console.log("gerodfksdjflsdjf");
        query.containedIn("fbId", ids);
        query.find({
          success: function(friends) {
            console.log(friends);
            console.log("SUCCESS");
            relation.add(friends);
            user.save();
          }
        });
      }
    }
  );

  fetchStatuses();
}

function updateScores() {
  var relation = user.relation("friendsUsingApp");
  var collection = relation.query().descending("accuracy").collection();
  var str = '';
  str += "My score  :  " + user.get("accuracy") + "% accuracy

";
  collection.fetch({
    success: function(friends) {
      console.log("friendsUsingApp");
      console.log(friends)
      friends.each(function(object) {
        str += object.get("name") + "  :  " + object.get("accuracy") + "% accuracy
";
      });
      $('#scoreboard').html(str);
    },
    error: function(collection, error) {
      // The collection could not be retrieved.
    }
  });
}

var pagesGrabbed = 0;
var postslist = [];

function fetchStatuses() {
  $('#statusPost').text("Loading your friends' statuses...");
  FB.api("/me/home", getPosts);
}

function getPosts(response){
  for (element in response.data){
    post = response.data[element]
    if(post.hasOwnProperty('message')&&!post.hasOwnProperty('to')&&!post.from.hasOwnProperty('category')){
      //console.log(post.from.name + ": " +post.message);
      //console.log(post);
      postslist.push({name:post.from.name, nameid:post.from.id, message:post.message, postid:post.id});
    }
  }
  if(pagesGrabbed < 4){
    nextPage = response.paging.next;
    pagesGrabbed++;
    $.get(nextPage, getPosts, "json");
  } else {
    updateText();
  }
}

var prevPosts = [];
var chosen = 10;
var alreadyChosen = true;
var score = 0;

function updateText() {
  alreadyChosen = false;
  $('#panel1').toggleClass('falsebox',false);
  $('#panel1').toggleClass('truebox',false);
  $('#panel2').toggleClass('falsebox',false);
  $('#panel2').toggleClass('truebox',false);
  $('#panel3').toggleClass('falsebox',false);
  $('#panel3').toggleClass('truebox',false);
  $('#panel4').toggleClass('falsebox',false);
  $('#panel4').toggleClass('truebox',false);
  var arr = [];
  for(var i = 0; i < 4; i++) {
    var addpost = function(){
		  arr[i] = postslist[Math.floor((Math.random() * postslist.length))];
		  for(var j = 0;j<i;j++){
			  if(arr[i].nameid === arr[j].nameid){
				  addpost();
			  }
		  }
    };
    addpost();
  }
  chosen = Math.floor((Math.random() * 4));
  for(var k = 0;k<prevPosts.length;k++){
		if(arr[chosen].postid===prevPosts[k])
			chosen = Math.floor((Math.random() * 4));
  }
  prevPosts.push(chosen);
  var message = arr[chosen].message;
  $('#statusPost').text(message);
  $('#img1').attr('src',"https://graph.facebook.com/" + arr[0].nameid + "/picture?type=large");
  $('#name1').text(arr[0].name);
  $('#img2').attr('src',"https://graph.facebook.com/" + arr[1].nameid + "/picture?type=large");
  $('#name2').text(arr[1].name);
  $('#img3').attr('src',"https://graph.facebook.com/" + arr[2].nameid + "/picture?type=large");
  $('#name3').text(arr[2].name);
  $('#img4').attr('src',"https://graph.facebook.com/" + arr[3].nameid + "/picture?type=large");
  $('#name4').text(arr[3].name);
  $('#next').prop('disabled', true);
}

function correctAns(num){
	if(!alreadyChosen){
		if(num===chosen){
			if(num===0){
				$('#panel1').toggleClass('truebox',true);
			}
			else if(num===1){
				$('#panel2').toggleClass('truebox',true);
			}
			else if(num===2){
				$('#panel3').toggleClass('truebox',true);
			}
			else if(num===3){
				$('#panel4').toggleClass('truebox',true);
			}
			score+=10;
			user.increment("correctAnswers");
		}
		else if(num!==chosen){
			if(num===0){
			$('#panel1').toggleClass('falsebox',true);
			}
			else if(num===1){
			$('#panel2').toggleClass('falsebox',true);
			}
			else if(num===2){
			$('#panel3').toggleClass('falsebox',true);
			}
			else if(num===3){
			  $('#panel4').toggleClass('falsebox',true);
			}
			if(chosen===0){
			  $('#panel1').toggleClass('truebox',true);
			}
			else if(chosen===1){
			  $('#panel2').toggleClass('truebox',true);
			}
			else if(chosen===2){
			  $('#panel3').toggleClass('truebox',true);
			}
			else if(chosen===3){
			  $('#panel4').toggleClass('truebox',true);
			}
			score-=5;
		}
    user.increment("statusesShown");
    user.set("accuracy", Math.round(user.get("correctAnswers") / user.get("statusesShown") * 100));
		user.save();
	}
  $('#scorelabel').text(score);
  $('#next').prop('disabled', false);
  alreadyChosen = true;
  chosen = 10;
  updateScores();
}

<commit_msg>speed up fetch<commit_after>Parse.initialize("ONeIYsbSCtIJg6bo0M823t6Z8ZqmqEM4Zfgh2U5a", "A1lJ2mF6YV48qcO5KBkQ1XCEC2BDF3mAt1MlqqlB");

var user = Parse.User.current();
updateScores();

function onLogin() {
  console.log('Welcome!  Fetching your information.... ');

  FB.api("/me", function (response) {
    if (response && !response.error) {
      user.set("fbId", response.id);
      user.set("name", response.name);
      if(user.get("statusesShown" == 0)) {
        user.set("accuracy", 0);
      }
      user.save();
    }
    //console.log(response);
  });

  FB.api("/me/friends",
    function (response) {
      if (response && !response.error) {
        console.log("friends----");
        console.log(response);

        var ids = [];
        var query = new Parse.Query(Parse.User);
        var relation = user.relation("friendsUsingApp");
        //get size of dictionaries

        for (i = 0; i < response.data.length; i++) {
          ids[i] = response.data[i].id;
        }
        console.log(ids);
        console.log("gerodfksdjflsdjf");
        query.containedIn("fbId", ids);
        query.find({
          success: function(friends) {
            console.log(friends);
            console.log("SUCCESS");
            relation.add(friends);
            user.save();
          }
        });
      }
    }
  );

  fetchStatuses();
}

function updateScores() {
  var relation = user.relation("friendsUsingApp");
  var collection = relation.query().descending("accuracy").collection();
  var str = '';
  str += "My score  :  " + user.get("accuracy") + "% accuracy

";
  collection.fetch({
    success: function(friends) {
      friends.each(function(object) {
        str += object.get("name") + "  :  " + object.get("accuracy") + "% accuracy
";
      });
      $('#scoreboard').html(str);
    },
    error: function(collection, error) {
      // The collection could not be retrieved.
    }
  });
}

var postslist = [];
var nextPage = null;

function fetchStatuses() {
  $('#statusPost').text("Loading your friends' statuses...");
  if(nextPage == null) {
    FB.api("/me/home", getPosts);
  } else {
    $.get(nextPage, getPosts, "json");
  }
}

function getPosts(response){
  if(response && !response.error) {
    for(element in response.data){
      post = response.data[element]
      if(post.hasOwnProperty('message')&&!post.hasOwnProperty('to')&&!post.from.hasOwnProperty('category')){
        //console.log(post.from.name + ": " +post.message);
        //console.log(post);
        postslist.push({name:post.from.name, nameid:post.from.id, message:post.message, postid:post.id});
      }
    }
    nextPage = response.paging.next;
    updateText();
  }
}

var prevPosts = [];
var chosen = 10;
var alreadyChosen = true;
var score = 0;

function updateText() {
  alreadyChosen = false;
  $('#panel1').toggleClass('falsebox',false);
  $('#panel1').toggleClass('truebox',false);
  $('#panel2').toggleClass('falsebox',false);
  $('#panel2').toggleClass('truebox',false);
  $('#panel3').toggleClass('falsebox',false);
  $('#panel3').toggleClass('truebox',false);
  $('#panel4').toggleClass('falsebox',false);
  $('#panel4').toggleClass('truebox',false);
  var arr = [];
  for(var i = 0; i < 4; i++) {
    var addpost = function(){
		  arr[i] = postslist[Math.floor((Math.random() * postslist.length))];
		  for(var j = 0; j < i ; j++){
			  if(arr[i].nameid === arr[j].nameid){
				  addpost();
			  }
		  }
    };
    addpost();
  }
  chosen = Math.floor((Math.random() * 4));
  for(var k = 0;k<prevPosts.length;k++){
		if(arr[chosen].postid===prevPosts[k])
			chosen = Math.floor((Math.random() * 4));
  }
  prevPosts.push(chosen);
  var message = arr[chosen].message;
  $('#statusPost').text(message);
  $('#img1').attr('src',"https://graph.facebook.com/" + arr[0].nameid + "/picture?type=large");
  $('#name1').text(arr[0].name);
  $('#img2').attr('src',"https://graph.facebook.com/" + arr[1].nameid + "/picture?type=large");
  $('#name2').text(arr[1].name);
  $('#img3').attr('src',"https://graph.facebook.com/" + arr[2].nameid + "/picture?type=large");
  $('#name3').text(arr[2].name);
  $('#img4').attr('src',"https://graph.facebook.com/" + arr[3].nameid + "/picture?type=large");
  $('#name4').text(arr[3].name);
  $('#next').prop('disabled', true);
}

function correctAns(num){
	if(!alreadyChosen){
		if(num===chosen){
			if(num===0){
				$('#panel1').toggleClass('truebox',true);
			}
			else if(num===1){
				$('#panel2').toggleClass('truebox',true);
			}
			else if(num===2){
				$('#panel3').toggleClass('truebox',true);
			}
			else if(num===3){
				$('#panel4').toggleClass('truebox',true);
			}
			score+=10;
			user.increment("correctAnswers");
		}
		else if(num!==chosen){
			if(num===0){
			$('#panel1').toggleClass('falsebox',true);
			}
			else if(num===1){
			$('#panel2').toggleClass('falsebox',true);
			}
			else if(num===2){
			$('#panel3').toggleClass('falsebox',true);
			}
			else if(num===3){
			  $('#panel4').toggleClass('falsebox',true);
			}
			if(chosen===0){
			  $('#panel1').toggleClass('truebox',true);
			}
			else if(chosen===1){
			  $('#panel2').toggleClass('truebox',true);
			}
			else if(chosen===2){
			  $('#panel3').toggleClass('truebox',true);
			}
			else if(chosen===3){
			  $('#panel4').toggleClass('truebox',true);
			}
			score-=5;
		}
    user.increment("statusesShown");
    user.set("accuracy", Math.round(user.get("correctAnswers") / user.get("statusesShown") * 100));
		user.save();
	}
  $('#scorelabel').text(score);
  $('#next').prop('disabled', false);
  alreadyChosen = true;
  chosen = 10;
  updateScores();
}

<|endoftext|>


<commit_before>require( './Tracking_SocialWorkerHistory' ),
require( './List_State' );
require( './Agency' );

var keystone				= require( 'keystone' ),
	async 					= require( 'async' ),
	Types					= keystone.Field.Types,
	SocialWorkerHistory		= keystone.list( 'Social Worker History' ),
	User					= require( './User' );
	ChangeHistoryMiddleware	= require( '../routes/middleware/models_change-history' );

// Create model
var SocialWorker = new keystone.List( 'Social Worker', {
	inherits	: User,
	track		: true,
	map			: { name: 'name.full' },
	defaultSort	: 'name.full',
	hidden		: false
});

// Create fields
SocialWorker.add( 'General Information', {

	name: {
		first: { type: Types.Text, label: 'first name', required: true, initial: true },
		last: { type: Types.Text, label: 'last name', required: true, initial: true },
		full: { type: Types.Text, label: 'name', hidden: true, noedit: true, initial: false }
	},

	avatar: { type: Types.CloudinaryImage, label: 'avatar', folder: 'users/social workers', selectPrefix: 'users/social workers', autoCleanup: true }

}, 'Contact Information', {

	email: { type: Types.Email, label: 'email address', unique: true, required: true, initial: true },

	phone: {
		work: { type: Types.Text, label: 'work phone number', initial: true },
		mobile: { type: Types.Text, label: 'mobile phone number', initial: true },
		preferred: { type: Types.Select, label: 'preferred phone', options: 'work, mobile', initial: true }
	}

}, 'Social Worker Information', {

	// position: { type: Types.Relationship, label: 'Position', ref: 'Social Worker Position', initial: true },
	position: { type: Types.Select, options: 'adoption worker, recruitment worker, supervisor, administrator, family worker, other', label: 'position', initial: true },
	agency: { type: Types.Relationship, label: 'agency', ref: 'Agency', initial: true },
	agencyNotListed: { type: Types.Boolean, label: 'agency isn\'t listed', initial: true },
	agencyText: { type: Types.Text, label: 'agency', dependsOn: { agencyNotListed: true }, initial: true },

	address: {
	    street1: { type: Types.Text, label: 'street 1', initial: true },
		street2: { type: Types.Text, label: 'street 2', initial: true },
		city: { type: Types.Text, label: 'city', initial: true },
		state: { type: Types.Relationship, label: 'state', ref: 'State', initial: true },
		zipCode: { type: Types.Text, label: 'zip code', initial: true }
	},

	title: { type: Types.Text, label: 'title', initial: true },
	notes: { type: Types.Textarea, label: 'notes', initial: true }

}, 'User Selections', {

	bookmarkedChildren: { type: Types.Relationship, label: 'bookmarked children', ref: 'Child', many: true, noedit: true }

});

// Set up relationship values to show up at the bottom of the model if any exist
SocialWorker.relationship( { ref: 'Child', refPath: 'adoptionWorker', path: 'children', label: 'children' } );
SocialWorker.relationship( { ref: 'Inquiry', refPath: 'socialWorker', path: 'my-inquiries', label: 'my inquiries' } );
SocialWorker.relationship( { ref: 'Inquiry', refPath: 'childsSocialWorker', path: 'family-inquiries', label: 'family inquiries' } );
SocialWorker.relationship( { ref: 'Mailing List', refPath: 'socialWorkerSubscribers', path: 'mailing-lists', label: 'mailing lists' } );
SocialWorker.relationship( { ref: 'Event', refPath: 'socialWorkerAttendees', path: 'events', label: 'events' } );
SocialWorker.relationship( { ref: 'Internal Note', refPath: 'socialWorker', path: 'internal-notes', label: 'internal notes' } );
SocialWorker.relationship( { ref: 'Social Worker History', refPath: 'socialWorker', path: 'social-worker-histories', label: 'change history' } );

// Post Init - used to store all the values before anything is changed
SocialWorker.schema.post( 'init', function() {
	'use strict';

	this._original = this.toObject();
});

// Pre Save
SocialWorker.schema.pre('save', function(next) {
	'use strict';

	var model = this;

	async.parallel([
		done => { model.setFullName(done); }, // Create a full name for the child based on their first, middle, and last names
		done => { model.setUserType(done); }, // Create an identifying name for file uploads
		done => { model.setChangeHistory(done); } // Process change history
	], () => {

		console.log( 'social worker information updated' );

		next();
	});
});

/* TODO: VERY IMPORTANT:  Need to fix this to provide the link to access the keystone admin panel again */
/* 						  Changing names or reworking this file changed the check in node_modules/keystone/templates/views/signin.jade
/*						  for user.isAdmin on line 14 */
// Provide access to Keystone
SocialWorker.schema.virtual( 'canAccessKeystone' ).get( function() {
	'use strict';

	return false;
});

SocialWorker.schema.methods.setFullName = function( done ) {
	'use strict';

	// Populate the full name string for better identification when linking through Relationship field types
	this.name.full = `${ this.name.first } ${ this.name.last }`;

	done();
};

SocialWorker.schema.methods.setUserType = function( done ) {
	'use strict'

	// Set the userType for role based page rendering
	this.userType = 'social worker';

	done();
};

SocialWorker.schema.methods.setChangeHistory = function setChangeHistory( done ) {
	'use strict';

	var modelBefore	= this._original,
		model		= this;

	var changeHistory = new SocialWorkerHistory.model({
		socialWorker	: this,
	    date			: Date.now(),
	    changes			: '',
	    modifiedBy		: this.updatedBy
	});

	// if the model is being saved for the first time, mark only that fact in an initial change history record
	if( !model._original ) {

		changeHistory.changes = 'record created';

		changeHistory.save( () => {
			console.log('record created change history saved successfully');
			done();
		}, err => {
			console.log( err );
			console.log( 'error saving record created change history' );
			done();
		});

	} else {
		// Any time a new field is added, it MUST be added to this list in order to be considered for display in change history
		// Computed fields and fields internal to the object SHOULD NOT be added to this list
		async.parallel([
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'name',
											name: 'first',
											label: 'first name',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'name',
											name: 'last',
											label: 'last name',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'email',
											label: 'email address',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'phone',
											name: 'work',
											label: 'work phone number',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'phone',
											name: 'mobile',
											label: 'mobile phone number',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'phone',
											name: 'preferred',
											label: 'preferred phone',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'position',
											label: 'position',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'agency',
											targetField: 'name',
											label: 'agency',
											type: 'relationship',
											model: 'Agency' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'agencyNotListed',
											label: 'agency isnt listed',
											type: 'boolean' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'agencyText',
											label: 'agency (free text)',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'address',
											name: 'street1',
											label: 'street 1',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'address',
											name: 'street2',
											label: 'street 2',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'address',
											name: 'city',
											label: 'city',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'address',
											name: 'state',
											targetField: 'state',
											label: 'state',
											type: 'relationship',
											model: 'State' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'address',
											name: 'zipCode',
											label: 'zip code',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'title',
											label: 'title',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'notes',
											label: 'notes',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'bookmarkedChildren',
											targetParent: 'name',
											targetField: 'full',
											label: 'bookmarked children',
											type: 'relationship',
											model: 'Child' }, model, modelBefore, changeHistory, done);
			}

		], () => {

			if ( changeHistory.changes === '' ) {
				done();
			} else {
				changeHistory.save( () => {
					console.log( 'change history saved successfully' );
					done();
				}, err => {
					console.log( err );
					console.log( 'error saving change history' );
					done();
				});
			}
		});
	}
};

// Define default columns in the admin interface and register the model
SocialWorker.defaultColumns = 'name.full, phone.work, phone.home, phone.cell, phone.preferred, email, permissions.isActive';
SocialWorker.register();

// Export to make it available using require.  The keystone.list import throws a ReferenceError when importing a list
// that comes later when sorting alphabetically
exports = module.exports = SocialWorker;<commit_msg>#61 | add bookmarked sibling groups to social worker with change tracking<commit_after>require( './Tracking_SocialWorkerHistory' ),
require( './List_State' );
require( './Agency' );

var keystone				= require( 'keystone' ),
	async 					= require( 'async' ),
	Types					= keystone.Field.Types,
	SocialWorkerHistory		= keystone.list( 'Social Worker History' ),
	User					= require( './User' );
	ChangeHistoryMiddleware	= require( '../routes/middleware/models_change-history' );

// Create model
var SocialWorker = new keystone.List( 'Social Worker', {
	inherits	: User,
	track		: true,
	map			: { name: 'name.full' },
	defaultSort	: 'name.full',
	hidden		: false
});

// Create fields
SocialWorker.add( 'General Information', {

	name: {
		first: { type: Types.Text, label: 'first name', required: true, initial: true },
		last: { type: Types.Text, label: 'last name', required: true, initial: true },
		full: { type: Types.Text, label: 'name', hidden: true, noedit: true, initial: false }
	},

	avatar: { type: Types.CloudinaryImage, label: 'avatar', folder: 'users/social workers', selectPrefix: 'users/social workers', autoCleanup: true }

}, 'Contact Information', {

	email: { type: Types.Email, label: 'email address', unique: true, required: true, initial: true },

	phone: {
		work: { type: Types.Text, label: 'work phone number', initial: true },
		mobile: { type: Types.Text, label: 'mobile phone number', initial: true },
		preferred: { type: Types.Select, label: 'preferred phone', options: 'work, mobile', initial: true }
	}

}, 'Social Worker Information', {

	// position: { type: Types.Relationship, label: 'Position', ref: 'Social Worker Position', initial: true },
	position: { type: Types.Select, options: 'adoption worker, recruitment worker, supervisor, administrator, family worker, other', label: 'position', initial: true },
	agency: { type: Types.Relationship, label: 'agency', ref: 'Agency', initial: true },
	agencyNotListed: { type: Types.Boolean, label: 'agency isn\'t listed', initial: true },
	agencyText: { type: Types.Text, label: 'agency', dependsOn: { agencyNotListed: true }, initial: true },

	address: {
	    street1: { type: Types.Text, label: 'street 1', initial: true },
		street2: { type: Types.Text, label: 'street 2', initial: true },
		city: { type: Types.Text, label: 'city', initial: true },
		state: { type: Types.Relationship, label: 'state', ref: 'State', initial: true },
		zipCode: { type: Types.Text, label: 'zip code', initial: true }
	},

	title: { type: Types.Text, label: 'title', initial: true },
	notes: { type: Types.Textarea, label: 'notes', initial: true }

}, 'User Selections', {

	bookmarkedChildren: { type: Types.Relationship, label: 'bookmarked children', ref: 'Child', many: true, noedit: true },
	bookmarkedSiblingGroups: { type: Types.Relationship, label: 'bookmarked sibling group children', ref: 'Child', many: true, noedit: true }

});

// Set up relationship values to show up at the bottom of the model if any exist
SocialWorker.relationship( { ref: 'Child', refPath: 'adoptionWorker', path: 'children', label: 'children' } );
SocialWorker.relationship( { ref: 'Inquiry', refPath: 'socialWorker', path: 'my-inquiries', label: 'my inquiries' } );
SocialWorker.relationship( { ref: 'Inquiry', refPath: 'childsSocialWorker', path: 'family-inquiries', label: 'family inquiries' } );
SocialWorker.relationship( { ref: 'Mailing List', refPath: 'socialWorkerSubscribers', path: 'mailing-lists', label: 'mailing lists' } );
SocialWorker.relationship( { ref: 'Event', refPath: 'socialWorkerAttendees', path: 'events', label: 'events' } );
SocialWorker.relationship( { ref: 'Internal Note', refPath: 'socialWorker', path: 'internal-notes', label: 'internal notes' } );
SocialWorker.relationship( { ref: 'Social Worker History', refPath: 'socialWorker', path: 'social-worker-histories', label: 'change history' } );

// Post Init - used to store all the values before anything is changed
SocialWorker.schema.post( 'init', function() {
	'use strict';

	this._original = this.toObject();
});

// Pre Save
SocialWorker.schema.pre('save', function(next) {
	'use strict';

	var model = this;

	async.parallel([
		done => { model.setFullName(done); }, // Create a full name for the child based on their first, middle, and last names
		done => { model.setUserType(done); }, // Create an identifying name for file uploads
		done => { model.setChangeHistory(done); } // Process change history
	], () => {

		console.log( 'social worker information updated' );

		next();
	});
});

/* TODO: VERY IMPORTANT:  Need to fix this to provide the link to access the keystone admin panel again */
/* 						  Changing names or reworking this file changed the check in node_modules/keystone/templates/views/signin.jade
/*						  for user.isAdmin on line 14 */
// Provide access to Keystone
SocialWorker.schema.virtual( 'canAccessKeystone' ).get( function() {
	'use strict';

	return false;
});

SocialWorker.schema.methods.setFullName = function( done ) {
	'use strict';

	// Populate the full name string for better identification when linking through Relationship field types
	this.name.full = `${ this.name.first } ${ this.name.last }`;

	done();
};

SocialWorker.schema.methods.setUserType = function( done ) {
	'use strict'

	// Set the userType for role based page rendering
	this.userType = 'social worker';

	done();
};

SocialWorker.schema.methods.setChangeHistory = function setChangeHistory( done ) {
	'use strict';

	var modelBefore	= this._original,
		model		= this;

	var changeHistory = new SocialWorkerHistory.model({
		socialWorker	: this,
	    date			: Date.now(),
	    changes			: '',
	    modifiedBy		: this.updatedBy
	});

	// if the model is being saved for the first time, mark only that fact in an initial change history record
	if( !model._original ) {

		changeHistory.changes = 'record created';

		changeHistory.save( () => {
			console.log('record created change history saved successfully');
			done();
		}, err => {
			console.log( err );
			console.log( 'error saving record created change history' );
			done();
		});

	} else {
		// Any time a new field is added, it MUST be added to this list in order to be considered for display in change history
		// Computed fields and fields internal to the object SHOULD NOT be added to this list
		async.parallel([
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'name',
											name: 'first',
											label: 'first name',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'name',
											name: 'last',
											label: 'last name',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'email',
											label: 'email address',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'phone',
											name: 'work',
											label: 'work phone number',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'phone',
											name: 'mobile',
											label: 'mobile phone number',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'phone',
											name: 'preferred',
											label: 'preferred phone',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'position',
											label: 'position',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'agency',
											targetField: 'name',
											label: 'agency',
											type: 'relationship',
											model: 'Agency' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'agencyNotListed',
											label: 'agency isnt listed',
											type: 'boolean' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'agencyText',
											label: 'agency (free text)',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'address',
											name: 'street1',
											label: 'street 1',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'address',
											name: 'street2',
											label: 'street 2',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'address',
											name: 'city',
											label: 'city',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'address',
											name: 'state',
											targetField: 'state',
											label: 'state',
											type: 'relationship',
											model: 'State' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											parent: 'address',
											name: 'zipCode',
											label: 'zip code',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'title',
											label: 'title',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'notes',
											label: 'notes',
											type: 'string' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'bookmarkedChildren',
											targetParent: 'name',
											targetField: 'full',
											label: 'bookmarked children',
											type: 'relationship',
											model: 'Child' }, model, modelBefore, changeHistory, done);
			},
			done => {
				ChangeHistoryMiddleware.checkFieldForChanges({
											name: 'bookmarkedSiblingGroups',
											targetParent: 'name',
											targetField: 'full',
											label: 'bookmarked sibling group children',
											type: 'relationship',
											model: 'Child' }, model, modelBefore, changeHistory, done);
			}

		], () => {

			if ( changeHistory.changes === '' ) {
				done();
			} else {
				changeHistory.save( () => {
					console.log( 'change history saved successfully' );
					done();
				}, err => {
					console.log( err );
					console.log( 'error saving change history' );
					done();
				});
			}
		});
	}
};

// Define default columns in the admin interface and register the model
SocialWorker.defaultColumns = 'name.full, phone.work, phone.home, phone.cell, phone.preferred, email, permissions.isActive';
SocialWorker.register();

// Export to make it available using require.  The keystone.list import throws a ReferenceError when importing a list
// that comes later when sorting alphabetically
exports = module.exports = SocialWorker;<|endoftext|>


<commit_before>exports.BattleMovedex = {
	'fling': {
		inherit: true,
		snowball: false,
		onPrepareHit: function (target, source, move) {
			if (!source.volatiles['fling']) return false;
			var item = this.getItem(source.volatiles['fling'].item);
			this.add("-enditem", source, item.name, '[from] move: Fling');
			if (item.name === 'Snowball') {
				move.snowball = true;
			}
		},
		onAfterMove: function (source, target, move) {
			var sub = false;
			if (target.volatiles['substitute'] && target.volatiles['substitute'].hp > 0) {
				sub = true;
			}
			if (!sub && move.snowball) {
				source.side.snowballs++;
				this.add('-message', "Ding! " + source.side.name + " scored a point!");
				this.add('-message', 'Total Score: ' + source.side.name + ': ' + source.side.snowballs + ', ' + target.side.name + ': ' + target.side.snowballs);
			}
		}
	}
}<commit_msg>Fixed style mistakes OpieOP<commit_after>exports.BattleMovedex = {
	'fling': {
		inherit: true,
		snowball: false,
		onPrepareHit: function (target, source, move) {
			if (!source.volatiles['fling']) return false;
			var item = this.getItem(source.volatiles['fling'].item);
			this.add("-enditem", source, item.name, '[from] move: Fling');
			if (item.name === 'Snowball') {
				move.snowball = true;
			}
		},
		onAfterMove: function (source, target, move) {
			var sub = false;
			if (target.volatiles['substitute'] && target.volatiles['substitute'].hp > 0) {
				sub = true;
			}
			if (!sub && move.snowball) {
				source.side.snowballs++;
				this.add('-message', "Ding! " + source.side.name + " scored a point!");
				this.add('-message', 'Total Score: ' + source.side.name + ': ' + source.side.snowballs + ', ' + target.side.name + ': ' + target.side.snowballs);
			}
		}
	}
};
<|endoftext|>


<commit_before>$(document).ready(function() {

	//Die Karte wird in der index-html in das Div mit der id "mymap" gezeichnet
	map = new L.Map("map");

	var min = 11; //minimale Zoomstufe
	var max = 16; //maximale Zoomstufe

	myTiles = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; //hier wird angegeben von wo die Tiles für die Karte geladen werden sollen
	osmCopyright = "Map data © 2012 OpenStreetMap contributors"; //Copyrigth, das unten rechts erscheint
	myLayer = new L.TileLayer(myTiles, { minZoom:min, maxZoom: max, attribution: osmCopyright, zIndex:0, reuseTiles:true } ); //Nun wird mit diesen tiles eine ebene erstellt (hier gibt es nur eine Ebene, es sind aber auch mehrere Ebenen möglich)
	map.addLayer( myLayer ); //Füge die Ebene der Karte hinzu

	var center = new L.LatLng(52.484766470498954, 13.363323211669922); //Fokus der Karte
	map.setView(center, min);

	var fernsehturm = L.icon({
    iconUrl: '/static/img/Fernsehturm_grau_26px3.png',
    iconSize:     [27, 125], // size of the icon
    iconAnchor:   [8,111] // point of the icon which will correspond to marker's location
	});

	var fernsehturmMarker = L.marker([52.520841,13.409405],{icon: fernsehturm}).addTo(map);

	var funkturm = L.icon({
    iconUrl: '/static/img/Funkturm_36px_neu.png',
    iconSize:     [36, 110], // size of the icon
    iconAnchor:   [16,108] // point of the icon which will correspond to marker's location
	});
	var funkturmMarker = L.marker([52.5050681,13.278211400000032],{icon: funkturm}).addTo(map);

	var greenIcon = L.icon({
    iconUrl: '/static/img/marker_green.png',
    iconSize:     [21, 32], // size of the icon width,height
    iconAnchor:   [14, 45], // point of the icon which will correspond to marker's location
    popupAnchor:  [4, -20] // point from which the popup should open relative to the iconAnchor
	});

    var redIcon = L.icon({
    iconUrl: '/static/img/marker_red.png',
    iconSize:     [21, 32], // size of the icon width,height
    iconAnchor:   [14, 45], // point of the icon which will correspond to marker's location
    popupAnchor:  [4, -20] // point from which the popup should open relative to the iconAnchor
	});

    $.each(bbps, function(key,bbp){
        var lon = bbp.fields.lon;
        var lat = bbp.fields.lat;
        var t = bbp.fields.vorhaben;
        var marker = L.marker([lat,lon],{icon: redIcon}).addTo(map);
        marker.bindPopup(t);

    });

    $.each(projects, function(key,project){
        var lon = project.fields.lon;
        var lat = project.fields.lat;
        var t = project.fields.titel;
        var marker = L.marker([lat,lon],{icon: greenIcon}).addTo(map);
        marker.bindPopup(t);

    });
});<commit_msg>Links eingefügt<commit_after>$(document).ready(function() {

	//Die Karte wird in der index-html in das Div mit der id "mymap" gezeichnet
	map = new L.Map("map");

	var min = 11; //minimale Zoomstufe
	var max = 16; //maximale Zoomstufe

	myTiles = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; //hier wird angegeben von wo die Tiles für die Karte geladen werden sollen
	osmCopyright = "Map data © 2012 OpenStreetMap contributors"; //Copyrigth, das unten rechts erscheint
	myLayer = new L.TileLayer(myTiles, { minZoom:min, maxZoom: max, attribution: osmCopyright, zIndex:0, reuseTiles:true } ); //Nun wird mit diesen tiles eine ebene erstellt (hier gibt es nur eine Ebene, es sind aber auch mehrere Ebenen möglich)
	map.addLayer( myLayer ); //Füge die Ebene der Karte hinzu

	var center = new L.LatLng(52.484766470498954, 13.363323211669922); //Fokus der Karte
	map.setView(center, min);

	var fernsehturm = L.icon({
    iconUrl: '/static/img/Fernsehturm_grau_26px3.png',
    iconSize:     [27, 125], // size of the icon
    iconAnchor:   [8,111] // point of the icon which will correspond to marker's location
	});

	var fernsehturmMarker = L.marker([52.520841,13.409405],{icon: fernsehturm}).addTo(map);

	var funkturm = L.icon({
    iconUrl: '/static/img/Funkturm_36px_neu.png',
    iconSize:     [36, 110], // size of the icon
    iconAnchor:   [16,108] // point of the icon which will correspond to marker's location
	});
	var funkturmMarker = L.marker([52.5050681,13.278211400000032],{icon: funkturm}).addTo(map);

	var greenIcon = L.icon({
    iconUrl: '/static/img/marker_green.png',
    iconSize:     [21, 32], // size of the icon width,height
    iconAnchor:   [14, 45], // point of the icon which will correspond to marker's location
    popupAnchor:  [4, -20] // point from which the popup should open relative to the iconAnchor
	});

    var redIcon = L.icon({
    iconUrl: '/static/img/marker_red.png',
    iconSize:     [21, 32], // size of the icon width,height
    iconAnchor:   [14, 45], // point of the icon which will correspond to marker's location
    popupAnchor:  [4, -20] // point from which the popup should open relative to the iconAnchor
	});

    $.each(bbps, function(key,bbp){
        var lon = bbp.fields.lon;
        var lat = bbp.fields.lat;
        var t = bbp.fields.vorhaben;
        var link = bbp.fields.link;
        var marker = L.marker([lat,lon],{icon: redIcon}).addTo(map);

        popuptext = "' + t + "";
        marker.bindPopup(popuptext);

    });

    $.each(projects, function(key,project){
        var lon = project.fields.lon;
        var lat = project.fields.lat;
        var t = project.fields.titel;
        var marker = L.marker([lat,lon],{icon: greenIcon}).addTo(map);
        marker.bindPopup(t);

    });
});<|endoftext|>


<commit_before>'use strict';

// Exams controller
angular.module('exams').controller('ExamsController', ['$scope', '$stateParams', '$location', '$window', 'Authentication', 'Exams', 'MyExams', 'Copies', '$http', 'Upload', function($scope, $stateParams, $location, $window, Authentication, Exams, MyExams, Copies, $http, Upload) {
	$scope.authentication = Authentication;
	$scope.split = false;

	// Load courses
	$scope.courses = [];
	var coursesList = [];
	$http.get('/courses').success(function(data, status, headers, config) {
		for (var i = 0; i < data.length; i++) {
			coursesList.push({
				name: data[i].ID,
				course: data[i]
			});
		}
	});
	$scope.loadCourses = function(query) {
		return coursesList;
	};

	// Load activities
	$scope.activities = [];
	var allActivities = [];
	$scope.activitiesList = [];
	$http.get('/activities').success(function(data, status, headers, config) {
		allActivities = data;
	});
	$scope.loadActivities = function(query) {
		return $scope.activitiesList;
	};

	// Load rooms
	$scope.rooms = [];
	var roomsList = [];
	$http.get('/rooms').success(function(data, status, headers, config) {
		for (var i = 0; i < data.length; i++) {
			roomsList.push({
				name: data[i].ID,
				room: data[i]
			});
		}
	});
	$scope.loadRooms = function(query) {
		return roomsList;
	};

	// Load groups
	$scope.groups = [];
	var groupsList = [];
	$http.get('/groups').success(function(data, status, headers, config) {
		for (var i = 0; i < data.length; i++) {
			groupsList.push({
				name: data[i].name,
				group: data[i]
			});
		}
	});
	$scope.loadGroups = function(query) {
		return groupsList;
	};

	// Create new exam
	$scope.create = function() {
		var activityIDs = [];
		for (var i = 0; i < $scope.activities.length; i++) {
			activityIDs.push($scope.activities[i].activity._id);
		}
		var roomIDs = [];
		for (i = 0; i < $scope.rooms.length; i++) {
			roomIDs.push($scope.rooms[i].room._id);
		}
		var groupIDs = [];
		for (i = 0; i < $scope.groups.length; i++) {
			groupIDs.push($scope.groups[i].group._id);
		}
    var course = [];
    if($scope.courses[0] !== undefined)
      course = $scope.courses[0]._id;
		// Create new exam object
		var exam = new Exams({
			course: course,
			activities: this.split ? [] : activityIDs,
			split: ! this.split,
			date: this.date,
			rooms: roomIDs,
			groups: groupIDs
		});
		// Redirect after save
		exam.$save(function(response) {
			$location.path('exams/' + response._id);
			// Clear form fields
			$scope.name = '';
		}, function(errorResponse) {
			$scope.error = errorResponse.data.message;
		});
	};

	// Remove existing exam
	$scope.remove = function(exam) {
		if (exam) {
			exam.$remove();
			for (var i in $scope.exams) {
				if ($scope.exams[i] === exam) {
					$scope.exams.splice(i, 1);
				}
			}
		} else {
			$scope.exam.$remove(function() {
				$location.path('exams');
			});
		}
	};

	// Update existing exam
	$scope.update = function() {
		var exam = $scope.exam;
		exam.$update(function() {
			$location.path('exams/' + exam._id);
		}, function(errorResponse) {
			$scope.error = errorResponse.data.message;
		});
	};

	// Find a list of exams
	$scope.find = function() {
		$scope.exams = Exams.query();
	};

	$scope.findMyExams = function(){
		$scope.exams = MyExams.query();
	};

	// Find existing exam
	$scope.findOne = function() {
		$scope.exam = Exams.get({
			examId: $stateParams.examId
		});
	};

	$scope.findCopy = function(activity, copies) {
		for (var i = 0; i < copies.length; i++) {
			if (copies[i].activity === activity._id) {
				return true;
			}
		}
		return false;
	};

	$scope.testCopy = function(activity, copy) {
		return activity._id === copy.activity;
	};

	$scope.findTeacher = function(user, teachers) {
		for (var i = 0; i < teachers.length; i++) {
			if (teachers[i]._id === user._id) {
				return true;
			}
		}
		return false;
	};

	$scope.changeUnique = function() {
		if (! $scope.split || $scope.courses.length !== 1) {
			$scope.activities = [];
		}
	};

	function findActivity(course, activity) {
		for (var i = 0; i < course.activities.length; i++) {
			if (course.activities[i]._id === activity._id) {
				return true;
			}
		}
		return false;
	}

	$scope.changeCourse = function() {
		$scope.activitiesList = [];
		for (var i = 0; i < allActivities.length; i++) {
			if (findActivity($scope.courses[0].course, allActivities[i])) {
				$scope.activitiesList.push({
					name: allActivities[i].ID,
					activity: allActivities[i]
				});
			}
		}
	};

	// Set the number of series
	$scope.setSeries = function (activityID) {
		// Create new copy object
		var copy = new Copies({
			exam: $scope.exam._id,
			activity: activityID === -1 ? null : activityID,
			series: this.series
		});
		// Redirect after save
		copy.$save(function(response) {
			// Attach copy to exam
			$scope.exam.copies.push(copy._id);
			$scope.exam.$update(function() {
				$window.location.reload();
			}, function(errorResponse) {
				$scope.error = errorResponse.data.message;
			});
		}, function(errorResponse) {
			$scope.error = errorResponse.data.message;
		});
	};

	$scope.getNumber = function(n) {
		return new Array(n);
	};

	$scope.fileSelected = function(files, event, index, copy) {
		if (files && files.length === 1) {
			Upload.upload({
				url: 'upload/copy',
				fields: {
					'username': $scope.authentication.user._id,
					'copy': copy._id,
					'index': index
				},
				file: files[0]
			}).progress(function(evt) {
				var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
				console.log('progress: ' + progressPercentage + '% ');
			}).success(function(data, status, headers, config) {
				console.log('Upload finished ' + config.file.name + ', response ' + data);
				copy.files[index] = data;
			});
		}
	};
}]);
<commit_msg>Correct issue #5<commit_after>'use strict';

// Exams controller
angular.module('exams').controller('ExamsController', ['$scope', '$stateParams', '$location', '$window', 'Authentication', 'Exams', 'MyExams', 'Copies', '$http', 'Upload', function($scope, $stateParams, $location, $window, Authentication, Exams, MyExams, Copies, $http, Upload) {
	$scope.authentication = Authentication;
	$scope.split = false;

	// Load courses
	$scope.courses = [];
	var coursesList = [];
	$http.get('/courses').success(function(data, status, headers, config) {
		for (var i = 0; i < data.length; i++) {
			coursesList.push({
				name: data[i].ID,
				course: data[i]
			});
		}
	});
	$scope.loadCourses = function(query) {
		return coursesList;
	};

	// Load activities
	$scope.activities = [];
	var allActivities = [];
	$scope.activitiesList = [];
	$http.get('/activities').success(function(data, status, headers, config) {
		allActivities = data;
	});
	$scope.loadActivities = function(query) {
		return $scope.activitiesList;
	};

	// Load rooms
	$scope.rooms = [];
	var roomsList = [];
	$http.get('/rooms').success(function(data, status, headers, config) {
		for (var i = 0; i < data.length; i++) {
			roomsList.push({
				name: data[i].ID,
				room: data[i]
			});
		}
	});
	$scope.loadRooms = function(query) {
		return roomsList;
	};

	// Load groups
	$scope.groups = [];
	var groupsList = [];
	$http.get('/groups').success(function(data, status, headers, config) {
		for (var i = 0; i < data.length; i++) {
			groupsList.push({
				name: data[i].name,
				group: data[i]
			});
		}
	});
	$scope.loadGroups = function(query) {
		return groupsList;
	};

	// Create new exam
	$scope.create = function() {
		var activityIDs = [];
		for (var i = 0; i < $scope.activities.length; i++) {
			activityIDs.push($scope.activities[i].activity._id);
		}
		var roomIDs = [];
		for (i = 0; i < $scope.rooms.length; i++) {
			roomIDs.push($scope.rooms[i].room._id);
		}
		var groupIDs = [];
		for (i = 0; i < $scope.groups.length; i++) {
			groupIDs.push($scope.groups[i].group._id);
		}
		var course = [];
		if ($scope.courses.length > 0) {
			course = $scope.courses[0].course._id;
		}
		// Create new exam object
		var exam = new Exams({
			course: course,
			activities: this.split ? [] : activityIDs,
			split: ! this.split,
			date: this.date,
			rooms: roomIDs,
			groups: groupIDs
		});
		// Redirect after save
		exam.$save(function(response) {
			$location.path('exams/' + response._id);
			// Clear form fields
			$scope.name = '';
		}, function(errorResponse) {
			$scope.error = errorResponse.data.message;
		});
	};

	// Remove existing exam
	$scope.remove = function(exam) {
		if (exam) {
			exam.$remove();
			for (var i in $scope.exams) {
				if ($scope.exams[i] === exam) {
					$scope.exams.splice(i, 1);
				}
			}
		} else {
			$scope.exam.$remove(function() {
				$location.path('exams');
			});
		}
	};

	// Update existing exam
	$scope.update = function() {
		var exam = $scope.exam;
		exam.$update(function() {
			$location.path('exams/' + exam._id);
		}, function(errorResponse) {
			$scope.error = errorResponse.data.message;
		});
	};

	// Find a list of exams
	$scope.find = function() {
		$scope.exams = Exams.query();
	};

	$scope.findMyExams = function(){
		$scope.exams = MyExams.query();
	};

	// Find existing exam
	$scope.findOne = function() {
		$scope.exam = Exams.get({
			examId: $stateParams.examId
		});
	};

	$scope.findCopy = function(activity, copies) {
		for (var i = 0; i < copies.length; i++) {
			if (copies[i].activity === activity._id) {
				return true;
			}
		}
		return false;
	};

	$scope.testCopy = function(activity, copy) {
		return activity._id === copy.activity;
	};

	$scope.findTeacher = function(user, teachers) {
		for (var i = 0; i < teachers.length; i++) {
			if (teachers[i]._id === user._id) {
				return true;
			}
		}
		return false;
	};

	$scope.changeUnique = function() {
		if ($scope.split || $scope.courses.length !== 1) {
			$scope.activities = [];
		}
	};

	function findActivity(course, activity) {
		for (var i = 0; i < course.activities.length; i++) {
			if (course.activities[i]._id === activity._id) {
				return true;
			}
		}
		return false;
	}

	$scope.changeCourse = function() {
		$scope.activitiesList = [];
		for (var i = 0; i < allActivities.length; i++) {
			if (findActivity($scope.courses[0].course, allActivities[i])) {
				$scope.activitiesList.push({
					name: allActivities[i].ID,
					activity: allActivities[i]
				});
			}
		}
	};

	// Set the number of series
	$scope.setSeries = function (activityID) {
		// Create new copy object
		var copy = new Copies({
			exam: $scope.exam._id,
			activity: activityID === -1 ? null : activityID,
			series: this.series
		});
		// Redirect after save
		copy.$save(function(response) {
			// Attach copy to exam
			$scope.exam.copies.push(copy._id);
			$scope.exam.$update(function() {
				$window.location.reload();
			}, function(errorResponse) {
				$scope.error = errorResponse.data.message;
			});
		}, function(errorResponse) {
			$scope.error = errorResponse.data.message;
		});
	};

	$scope.getNumber = function(n) {
		return new Array(n);
	};

	$scope.fileSelected = function(files, event, index, copy) {
		if (files && files.length === 1) {
			Upload.upload({
				url: 'upload/copy',
				fields: {
					'username': $scope.authentication.user._id,
					'copy': copy._id,
					'index': index
				},
				file: files[0]
			}).progress(function(evt) {
				var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
				console.log('progress: ' + progressPercentage + '% ');
			}).success(function(data, status, headers, config) {
				console.log('Upload finished ' + config.file.name + ', response ' + data);
				copy.files[index] = data;
			});
		}
	};
}]);
<|endoftext|>


<commit_before>'use strict';

// Games controller
angular.module('games').controller('GamesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Games','Socket','$http',
	function($scope, $stateParams, $location, Authentication, Games,Socket,$http) {
		$scope.authentication = Authentication;
		$scope.player1Life=100;
		$scope.player2Life=100;

		// Create new Game
		$scope.create = function() {
			// Create new Game object
			var game = new Games ({
				player1: $scope.authentication.user._id
			});

			// Redirect after save
			game.$save(function(response) {
				$location.path('fight/' + response._id);

				// Clear form fields
				$scope.name = '';
			}, function(errorResponse) {
				$scope.error = errorResponse.data.message;
			});
		};
		$scope.games=[];
		$scope.getFightList=function(){
			Socket.on('games', function(game) {
					// console.log(game);
					$scope.games.push(game);

			});
		};

		// Remove existing Game
		$scope.remove = function(game) {
			if ( game ) {
				game.$remove();

				for (var i in $scope.games) {
					if ($scope.games [i] === game) {
						$scope.games.splice(i, 1);
					}
				}
			} else {
				$scope.game.$remove(function() {
					$location.path('games');
				});
			}
		};

		// Update existing Game
		$scope.update = function() {
			var game = $scope.game;

			game.$update(function() {
				$location.path('games/' + game._id);
			}, function(errorResponse) {
				$scope.error = errorResponse.data.message;
			});
		};

		// Find a list of Games
		$scope.find = function() {
			$scope.games = Games.query(function(response){
				console.log(response);
			});
		};

		$scope.viewHolograms=function(){
			Socket.on('holograms/', function(player) {
					 console.log(player);
					 if (player.player2) {
						$scope.player2=player.player2;

					 }
					 if (player.player1) {
						$scope.player1=player.player1;//si somos el player 1 escucharemos las acciones del player2
					 }
					 Socket.on('player1/', function(actions) {
						 console.log(actions);
						 $scope.player1Actions=actions

					 });
					 Socket.on('player2/', function(actions) {
						 console.log(actions);
						 $scope.player2Actions=actions

					 });

			});
		};

		$scope.player1Emit=function(){
			console.log('estoy enviando');
			// 			console.log($scope.emitir);
			// console.log(Socket);
			// 			Socket.emit('/holograms/',{player1:'affdf'},function(result){
			// 				console.log(result);
			// 			});
			console.log($scope.emitir);

			$scope.emitir=$scope.danmage();
			$scope.player2Life=$scope.player2Life-($scope.emitir*100);

			$http.post('/player1', {action:$scope.emitir}).success(function(response){
				console.log(response);
			});

		};

		$scope.player2Emit=function(){
			$scope.emitir=$scope.danmage();
			console.log($scope.emitir);

			$scope.player1Life=$scope.player1Life-($scope.emitir*100);
			$http.post('/player2', {action:$scope.emitir}).success(function(response){
				console.log(response);
			});

		};

		$scope.danmage=function(){
			var danmage,acert;
			// acert=Math.random();
			// if (acert>=.5) {
			danmage=Math.random();
			// }
			// console.log(acert);
			return danmage;
		};

		// Find existing Game
		$scope.player2={};
		$scope.player1={};
		$scope.findOne = function() {
			$scope.game = Games.get({
				gameId: $stateParams.gameId
			},function(response){

				if (response.player1._id+''==$scope.authentication.user._id) {
					Socket.on('player2/', function(actions) {
						console.log(actions);
						$scope.player1Life=$scope.player1Life-(actions*100);
					});
				}else {
					Socket.on('player1/', function(actions) {
						console.log(actions);
						$scope.player2Life=$scope.player2Life-(actions*100);

					});

				}

				console.log(response);
				Socket.on('figthRoom/'+$stateParams.gameId, function(player) {
						 console.log(player);
						 if (player.player2) {
						 	$scope.player2=player.player2;
						 }

				});
			});
		};

		$scope.mainView = function() {

		}

		$scope.battle = function() {

		}

		var stage, w, h, loader, manifest;
		var sky, grant, ground, hill, hill2;
		$scope.init=function() {
			//examples.showDistractor();
			stage = new createjs.Stage("testCanvas");
			// grab canvas width and height for later calculations:
			w = stage.canvas.width;
			h = stage.canvas.height;
			manifest = [
				{src: "spritesheet_grant.png", id: "grant"},
				{src: "sky.png", id: "sky"},
				{src: "ground.png", id: "ground"},
				{src: "hill1.png", id: "hill"},
				{src: "hill2.png", id: "hill2"}
			];
			loader = new createjs.LoadQueue(false);
			loader.addEventListener("complete", handleComplete);
			loader.loadManifest(manifest, true, "/modules/games/img/");
		}

		function handleComplete() {
			sky = new createjs.Shape();
			sky.graphics.beginBitmapFill(loader.getResult("sky")).drawRect(0, 0, w, h);
			var groundImg = loader.getResult("ground");
			ground = new createjs.Shape();
			ground.graphics.beginBitmapFill(groundImg).drawRect(0, 0, w + groundImg.width, groundImg.height);
			ground.tileW = groundImg.width;
			ground.y = h - groundImg.height;
			hill = new createjs.Bitmap(loader.getResult("hill"));
			hill.setTransform(Math.random() * w, h - hill.image.height * 4 - groundImg.height, 4, 4);
			hill.alpha = 0.5;
			hill2 = new createjs.Bitmap(loader.getResult("hill2"));
			hill2.setTransform(Math.random() * w, h - hill2.image.height * 3 - groundImg.height, 3, 3);
			var spriteSheet = new createjs.SpriteSheet({
				framerate: 30,
				"images": [loader.getResult("grant")],
				"frames": {"regX": 82, "height": 292, "count": 64, "regY": 0, "width": 165},
				// define two animations, run (loops, 1.5x speed) and jump (returns to run):
				"animations": {
					"run": [0, 25, "run", 1.5],
					"jump": [26, 63, "run"]
				}
			});
			grant = new createjs.Sprite(spriteSheet, "run");
			grant.y = 35;
			stage.addChild(sky, hill, hill2, ground, grant);
			stage.addEventListener("stagemousedown", handleJumpStart);
			createjs.Ticker.timingMode = createjs.Ticker.RAF;
			createjs.Ticker.addEventListener("tick", tick);
		}
		function handleJumpStart() {
			grant.gotoAndPlay("jump");
		}
		function tick(event) {
			var deltaS = event.delta / 1000;
			var position = grant.x + 150 * deltaS;
			var grantW = grant.getBounds().width * grant.scaleX;
			grant.x = (position >= w + grantW) ? -grantW : position;
			ground.x = (ground.x - deltaS * 150) % ground.tileW;
			hill.x = (hill.x - deltaS * 30);
			if (hill.x + hill.image.width * hill.scaleX <= 0) {
				hill.x = w;
			}
			hill2.x = (hill2.x - deltaS * 45);
			if (hill2.x + hill2.image.width * hill2.scaleX <= 0) {
				hill2.x = w;
			}
			stage.update(event);
		}

		$('.spriteP1').sprite({fps: 6, no_of_frames: 6});
	}
]);
<commit_msg>enviar accion en el socket<commit_after>'use strict';

// Games controller
angular.module('games').controller('GamesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Games','Socket','$http',
	function($scope, $stateParams, $location, Authentication, Games,Socket,$http) {
		$scope.authentication = Authentication;
		$scope.player1Life=100;
		$scope.player2Life=100;

		// Create new Game
		$scope.create = function() {
			// Create new Game object
			var game = new Games ({
				player1: $scope.authentication.user._id
			});

			// Redirect after save
			game.$save(function(response) {
				$location.path('fight/' + response._id);

				// Clear form fields
				$scope.name = '';
			}, function(errorResponse) {
				$scope.error = errorResponse.data.message;
			});
		};
		$scope.games=[];
		$scope.getFightList=function(){
			Socket.on('games', function(game) {
					// console.log(game);
					$scope.games.push(game);

			});
		};

		// Remove existing Game
		$scope.remove = function(game) {
			if ( game ) {
				game.$remove();

				for (var i in $scope.games) {
					if ($scope.games [i] === game) {
						$scope.games.splice(i, 1);
					}
				}
			} else {
				$scope.game.$remove(function() {
					$location.path('games');
				});
			}
		};

		// Update existing Game
		$scope.update = function() {
			var game = $scope.game;

			game.$update(function() {
				$location.path('games/' + game._id);
			}, function(errorResponse) {
				$scope.error = errorResponse.data.message;
			});
		};

		// Find a list of Games
		$scope.find = function() {
			$scope.games = Games.query(function(response){
				console.log(response);
			});
		};

		$scope.viewHolograms=function(){
			Socket.on('holograms/', function(player) {
					 console.log(player);
					 if (player.player2) {
						$scope.player2=player.player2;

					 }
					 if (player.player1) {
						$scope.player1=player.player1;//si somos el player 1 escucharemos las acciones del player2
					 }
					 Socket.on('player1/', function(actions) {
						 console.log(actions);
						 $scope.player1Actions=actions

					 });
					 Socket.on('player2/', function(actions) {
						 console.log(actions);
						 $scope.player2Actions=actions

					 });

			});
		};

		$scope.player1Emit=function(){
			console.log('estoy enviando');
			// 			console.log($scope.emitir);
			// console.log(Socket);
			// 			Socket.emit('/holograms/',{player1:'affdf'},function(result){
			// 				console.log(result);
			// 			});
			$scope.actionSprite=0;
			console.log($scope.emitir);

			$scope.emitir=$scope.danmage();
			$scope.player2Life=$scope.player2Life-($scope.emitir*100);

			$http.post('/player1', {action:
				{
				danmage:$scope.emitir,
				action:$scope.actionSprite
				}
			}).success(function(response){
				console.log(response);
			});

		};

		$scope.player2Emit=function(){
			$scope.emitir=$scope.danmage();
			console.log($scope.emitir);
			$scope.actionSprite=0;
			$scope.player1Life=$scope.player1Life-($scope.emitir*100);
			$http.post('/player2', {action:	{
				danmage:$scope.emitir,
				action:$scope.actionSprite
				}
			}).success(function(response){
				console.log(response);
			});

		};

		$scope.danmage=function(){
			var danmage,acert;
			// acert=Math.random();
			// if (acert>=.5) {
			danmage=Math.random();
			// }
			// console.log(acert);
			return danmage;
		};

		// Find existing Game
		$scope.player2={};
		$scope.player1={};
		$scope.findOne = function() {
			$scope.game = Games.get({
				gameId: $stateParams.gameId
			},function(response){

				if (response.player1._id+''==$scope.authentication.user._id) {
					Socket.on('player2/', function(actions) {
						console.log(actions);
						$scope.player1Life=$scope.player1Life-(actions.danmage*100);
					});
				}else {
					Socket.on('player1/', function(actions) {
						console.log(actions);
						$scope.player2Life=$scope.player2Life-(actions.danmage*100);

					});

				}

				console.log(response);
				Socket.on('figthRoom/'+$stateParams.gameId, function(player) {
						 console.log(player);
						 if (player.player2) {
						 	$scope.player2=player.player2;
						 }

				});
			});
		};

		$scope.mainView = function() {

		}

		$scope.battle = function() {

		}

		var stage, w, h, loader, manifest;
		var sky, grant, ground, hill, hill2;
		$scope.init=function() {
			//examples.showDistractor();
			stage = new createjs.Stage("testCanvas");
			// grab canvas width and height for later calculations:
			w = stage.canvas.width;
			h = stage.canvas.height;
			manifest = [
				{src: "spritesheet_grant.png", id: "grant"},
				{src: "sky.png", id: "sky"},
				{src: "ground.png", id: "ground"},
				{src: "hill1.png", id: "hill"},
				{src: "hill2.png", id: "hill2"}
			];
			loader = new createjs.LoadQueue(false);
			loader.addEventListener("complete", handleComplete);
			loader.loadManifest(manifest, true, "/modules/games/img/");
		}

		function handleComplete() {
			sky = new createjs.Shape();
			sky.graphics.beginBitmapFill(loader.getResult("sky")).drawRect(0, 0, w, h);
			var groundImg = loader.getResult("ground");
			ground = new createjs.Shape();
			ground.graphics.beginBitmapFill(groundImg).drawRect(0, 0, w + groundImg.width, groundImg.height);
			ground.tileW = groundImg.width;
			ground.y = h - groundImg.height;
			hill = new createjs.Bitmap(loader.getResult("hill"));
			hill.setTransform(Math.random() * w, h - hill.image.height * 4 - groundImg.height, 4, 4);
			hill.alpha = 0.5;
			hill2 = new createjs.Bitmap(loader.getResult("hill2"));
			hill2.setTransform(Math.random() * w, h - hill2.image.height * 3 - groundImg.height, 3, 3);
			var spriteSheet = new createjs.SpriteSheet({
				framerate: 30,
				"images": [loader.getResult("grant")],
				"frames": {"regX": 82, "height": 292, "count": 64, "regY": 0, "width": 165},
				// define two animations, run (loops, 1.5x speed) and jump (returns to run):
				"animations": {
					"run": [0, 25, "run", 1.5],
					"jump": [26, 63, "run"]
				}
			});
			grant = new createjs.Sprite(spriteSheet, "run");
			grant.y = 35;
			stage.addChild(sky, hill, hill2, ground, grant);
			stage.addEventListener("stagemousedown", handleJumpStart);
			createjs.Ticker.timingMode = createjs.Ticker.RAF;
			createjs.Ticker.addEventListener("tick", tick);
		}
		function handleJumpStart() {
			grant.gotoAndPlay("jump");
		}
		function tick(event) {
			var deltaS = event.delta / 1000;
			var position = grant.x + 150 * deltaS;
			var grantW = grant.getBounds().width * grant.scaleX;
			grant.x = (position >= w + grantW) ? -grantW : position;
			ground.x = (ground.x - deltaS * 150) % ground.tileW;
			hill.x = (hill.x - deltaS * 30);
			if (hill.x + hill.image.width * hill.scaleX <= 0) {
				hill.x = w;
			}
			hill2.x = (hill2.x - deltaS * 45);
			if (hill2.x + hill2.image.width * hill2.scaleX <= 0) {
				hill2.x = w;
			}
			stage.update(event);
		}

		$('.spriteP1').sprite({fps: 6, no_of_frames: 6});
	}
]);
<|endoftext|>