<commit_before>import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import * as Vue from 'vue';
import PrimeVue from 'primevue/config';

// import 'bootstrap/dist/css/bootstrap.min.css';
// import 'primevue/resources/themes/saga-blue/theme.css';
import 'primevue/resources/themes/bootstrap4-light-blue/theme.css';
import 'primevue/resources/primevue.css';
import 'primeflex/primeflex.css';
import 'primeicons/primeicons.css';

import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'
import { far } from '@fortawesome/free-regular-svg-icons'

import ToastService from 'primevue/toastservice';
import Tooltip from 'primevue/tooltip';
import BadgeDirective from 'primevue/badgedirective';

import router from './router'
import ui from './global.js';
import Root from './Root.vue'

import alerts from '@/common/services/Alerts.js';
import http from '@/common/services/HttpClient.js';
import authSvc from '@/common/services/Authorization.js';
import pluginLoader from '@/common/services/PluginLoader.js';
import settingSvc from '@/common/services/Setting.js';
import util from '@/common/services/Util.js';
import userSvc from '@/administrative/services/User.js';
import routerSvc from '@/common/services/Router.js';

// import itemsSvc from '@/common/services/ItemsHolder.js';

import showIfAllowed from '@/common/directives/ShowIfAllowed.js';

import CommonComponents from '@/common/components';
import CommonServices   from '@/common/services';
import CommonFilters    from '@/common/filters';
import AdminServices    from '@/administrative/services';
import BioSpmnServices  from '@/biospecimen/services';

window['Vue'] = Vue;
const app = createApp(Root)
  .use(ToastService)
  .use(CommonComponents)
  .use(CommonServices)
  .use(CommonFilters)
  .use(AdminServices)
  .use(BioSpmnServices);

app.directive('show-if-allowed', showIfAllowed);
app.directive('os-tooltip', Tooltip);
app.directive('os-badge', BadgeDirective);

function registerHomePageCards(osSvc) {
  osSvc.homePageSvc.registerCards([
    {
      showIf: {resource: 'CollectionProtocol', operations: ['Read']},
      href: '#/cps',
      icon: 'fa fa-calendar',
      title: 'Collection Protocols',
      description: 'Create, update SOP of visits and specimens'
    },

    {
      showIf: 'admin',
      href: '#/institutes',
      icon: 'fa fa-institution',
      title: 'Institutes',
      description: 'Update information about institutions'
    },

    {
      showIf: {resource: 'User', operations: ['Create', 'Update']},
      href: '#/users',
      icon: 'fa fa-user',
      title: 'Users',
      description: 'Add, rename and manage users'
    },

    {
      showIf: {resource: 'User', operations: ['Create', 'Update']},
      href: '#/roles',
      icon: 'fa fa-lock',
      title: 'Roles',
      description: 'Create, update user access controls'
    },

    {
      showIf: 'institute-admin',
      href: '#/sites',
      icon: 'fa fa-hospital-o',
      title: 'Sites',
      description: 'Add and update sites'
    },

    {
      showIf: {resource: 'StorageContainer', operations: ['Read']},
      href: '#/containers',
      icon: 'fa fa-dropbox',
      title: 'Containers',
      description: 'Manage containers and their restrictions'
    },

    {
      showIf: {resource: 'Query', operations: ['Read']},
      href: '#/queries/list',
      icon: 'fa fa-dashboard',
      title: 'Queries',
      description: 'Create, share, and schedule queries'
    },

    {
      showIf: {resources: ['Specimen', 'PrimarySpecimen'], operations: ['Read']},
      href: '#/specimen-lists',
      icon: 'fa fa-shopping-cart',
      title: 'Carts',
      description: 'Create, share, and manage specimen carts'
    },

    {
      href: '#/forms',
      icon: 'fa fa-copy',
      title: 'Forms',
      description: 'Create and manage custom forms',
      showIf: () => ui.currentUser.admin || ui.currentUser.instituteAdmin || ui.currentUser.manageForms
    },

    {
      showIf: {resource: 'DistributionProtocol', operations: ['Read']},
      href: '#/dps',
      icon: 'fa fa-truck',
      title: 'Distribution Protocols',
      description: 'Create, update procedures for distributing specimens'
    },

    {
      showIf: {resource: 'Order', operations: ['Read']},
      href: '#/orders',
      icon: 'fa fa-share',
      title: 'Orders',
      description: 'Create, execute request orders for distributing specimens'
    },

    {
      showIf: {resource: 'ShippingAndTracking', operations: ['Read']},
      href: '#/shipments',
      icon: 'fa fa-paper-plane-o',
      title: 'Shipments',
      description: 'Create, ship, track, and receive specimen shipments'
    },

    {
      showIf: {resource: 'ScheduledJob', operations: ['Read']},
      href: '#/jobs',
      icon: 'fa fa-gears',
      title: 'Jobs',
      description: 'Create, schedule, execute jobs'
    },

    {
      showIf: 'institute-admin',
      href: '#/consent-statements',
      icon: 'fa fa-file-text-o',
      title: 'Consents',
      description: 'Manage coded consent statements'
    },

    {
      href: async () => {
        let setting = await settingSvc.getSetting('training', 'training_url');
        return setting[0].value;
      },
      icon: 'fa fa-graduation-cap',
      title: 'Training',
      description: 'User manual and training videos portal',
      newTab: true
    },

    {
      showIf: 'admin',
      href: '#/settings/settings-list',
      icon: 'fa fa-wrench',
      title: 'Settings',
      description: 'Manage application configuration settings'
    }
  ]);
}

app.config.globalProperties.$goto =
  (name, params, query) => routerSvc.goto(name, params, query);

app.config.globalProperties.$goback = () => routerSvc.back();

alerts.toastSvc = app.config.globalProperties.$toast;
library.add(fas);
library.add(far);

let url = window.location.href;
let urlParts = url.split('?')
let query = urlParts.length > 1 ? urlParts[1] : '';
let params = new URLSearchParams(query);

window.osUiApp = app;
window.osUi    = app.config.globalProperties.$ui = ui;
let server = ui.server || {};
http.protocol = server.secure ? 'https' : 'http';
http.host = server.hostname;
http.port = server.port;
http.path = server.app || '..';
if (http.path) {
  http.path += '/';
}

// http.path += 'rest/ng'
if (params.get('token')) {
  localStorage.osAuthToken = http.headers['X-OS-API-TOKEN'] = params.get('token');
} else {
  http.headers['X-OS-API-TOKEN'] = localStorage.osAuthToken;
}

let settingsQ  = settingSvc.getAppProps();
let localeQ    = settingSvc.getLocale();
let messagesQ  = settingSvc.getI18nMessages();
let currUserQ  = userSvc.getCurrentUser();
let usrStateQ  = userSvc.getUiState();
let usrRightsQ = authSvc.loadUserRights();
let spmnPropsQ = util.loadSpecimenTypeProps();

Promise.all([settingsQ, localeQ, messagesQ, currUserQ, usrRightsQ, usrStateQ, spmnPropsQ]).then(
  (resp) => {
    let appProps = resp[0];
    let locale   = resp[1];
    let messages = resp[2];
    let currUser = resp[3];

    const i18n = window.osI18n = createI18n({locale: locale, messages: messages});
    app.use(i18n);

    ui.global = {
      defaultDomain: 'openspecimen',
      filterWaitInterval: appProps.searchDelay,
      appProps: appProps,
      locale: {
        dateFmt: locale.dateFmt,
        shortDateFmt: locale.deBeDateFmt,
        timeFmt: locale.timeFmt,
        queryDateFmt: {format: locale.deFeDateFmt},
        dateTimeFmt: locale.dateFmt + ' ' + locale.timeFmt,
        locale: locale.locale,
        utcOffset: locale.utcOffset
      },
      state: resp[5]
    };

    let osSvc = window.osSvc = app.config.globalProperties.$osSvc;
    ui.currentUser = currUser;
    registerHomePageCards(osSvc);

    app.provide('ui', ui);
    app.provide('osSvc', osSvc);

    let count = appProps.plugins.length;
    appProps.plugins.forEach(
      (pluginName) => {
        pluginLoader.load(pluginName).then(
          function(pluginModule) {
            app.use(pluginModule.default, { router, osSvc });
            --count;
            if (count <= 0) {
              app.use(router).use(PrimeVue)
                .mount('#app');
            }
          },

          function(error) {
            console.log('Error loading the plugin: ' + pluginName);
            console.log(error);
            --count;
            if (count <= 0) {
              app.use(router).use(PrimeVue)
                .mount('#app');
            }
          }
        )
      }
    );
  }
);
<commit_msg>Removed blank/empty lines.<commit_after>import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import * as Vue from 'vue';
import PrimeVue from 'primevue/config';

// import 'bootstrap/dist/css/bootstrap.min.css';
// import 'primevue/resources/themes/saga-blue/theme.css';
import 'primevue/resources/themes/bootstrap4-light-blue/theme.css';
import 'primevue/resources/primevue.css';
import 'primeflex/primeflex.css';
import 'primeicons/primeicons.css';

import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'
import { far } from '@fortawesome/free-regular-svg-icons'

import ToastService from 'primevue/toastservice';
import Tooltip from 'primevue/tooltip';
import BadgeDirective from 'primevue/badgedirective';

import router from './router'
import ui from './global.js';
import Root from './Root.vue'

import alerts from '@/common/services/Alerts.js';
import http from '@/common/services/HttpClient.js';
import authSvc from '@/common/services/Authorization.js';
import pluginLoader from '@/common/services/PluginLoader.js';
import settingSvc from '@/common/services/Setting.js';
import util from '@/common/services/Util.js';
import userSvc from '@/administrative/services/User.js';
import routerSvc from '@/common/services/Router.js';

// import itemsSvc from '@/common/services/ItemsHolder.js';

import showIfAllowed from '@/common/directives/ShowIfAllowed.js';

import CommonComponents from '@/common/components';
import CommonServices   from '@/common/services';
import CommonFilters    from '@/common/filters';
import AdminServices    from '@/administrative/services';
import BioSpmnServices  from '@/biospecimen/services';

window['Vue'] = Vue;
const app = createApp(Root)
  .use(ToastService)
  .use(CommonComponents)
  .use(CommonServices)
  .use(CommonFilters)
  .use(AdminServices)
  .use(BioSpmnServices);

app.directive('show-if-allowed', showIfAllowed);
app.directive('os-tooltip', Tooltip);
app.directive('os-badge', BadgeDirective);

function registerHomePageCards(osSvc) {
  osSvc.homePageSvc.registerCards([
    {
      showIf: {resource: 'CollectionProtocol', operations: ['Read']},
      href: '#/cps',
      icon: 'fa fa-calendar',
      title: 'Collection Protocols',
      description: 'Create, update SOP of visits and specimens'
    },

    {
      showIf: 'admin',
      href: '#/institutes',
      icon: 'fa fa-institution',
      title: 'Institutes',
      description: 'Update information about institutions'
    },

    {
      showIf: {resource: 'User', operations: ['Create', 'Update']},
      href: '#/users',
      icon: 'fa fa-user',
      title: 'Users',
      description: 'Add, rename and manage users'
    },

    {
      showIf: {resource: 'User', operations: ['Create', 'Update']},
      href: '#/roles',
      icon: 'fa fa-lock',
      title: 'Roles',
      description: 'Create, update user access controls'
    },

    {
      showIf: 'institute-admin',
      href: '#/sites',
      icon: 'fa fa-hospital-o',
      title: 'Sites',
      description: 'Add and update sites'
    },

    {
      showIf: {resource: 'StorageContainer', operations: ['Read']},
      href: '#/containers',
      icon: 'fa fa-dropbox',
      title: 'Containers',
      description: 'Manage containers and their restrictions'
    },

    {
      showIf: {resource: 'Query', operations: ['Read']},
      href: '#/queries/list',
      icon: 'fa fa-dashboard',
      title: 'Queries',
      description: 'Create, share, and schedule queries'
    },

    {
      showIf: {resources: ['Specimen', 'PrimarySpecimen'], operations: ['Read']},
      href: '#/specimen-lists',
      icon: 'fa fa-shopping-cart',
      title: 'Carts',
      description: 'Create, share, and manage specimen carts'
    },

    {
      href: '#/forms',
      icon: 'fa fa-copy',
      title: 'Forms',
      description: 'Create and manage custom forms',
      showIf: () => ui.currentUser.admin || ui.currentUser.instituteAdmin || ui.currentUser.manageForms
    },

    {
      showIf: {resource: 'DistributionProtocol', operations: ['Read']},
      href: '#/dps',
      icon: 'fa fa-truck',
      title: 'Distribution Protocols',
      description: 'Create, update procedures for distributing specimens'
    },

    {
      showIf: {resource: 'Order', operations: ['Read']},
      href: '#/orders',
      icon: 'fa fa-share',
      title: 'Orders',
      description: 'Create, execute request orders for distributing specimens'
    },

    {
      showIf: {resource: 'ShippingAndTracking', operations: ['Read']},
      href: '#/shipments',
      icon: 'fa fa-paper-plane-o',
      title: 'Shipments',
      description: 'Create, ship, track, and receive specimen shipments'
    },

    {
      showIf: {resource: 'ScheduledJob', operations: ['Read']},
      href: '#/jobs',
      icon: 'fa fa-gears',
      title: 'Jobs',
      description: 'Create, schedule, execute jobs'
    },

    {
      showIf: 'institute-admin',
      href: '#/consent-statements',
      icon: 'fa fa-file-text-o',
      title: 'Consents',
      description: 'Manage coded consent statements'
    },

    {
      href: async () => {
        let setting = await settingSvc.getSetting('training', 'training_url');
        return setting[0].value;
      },
      icon: 'fa fa-graduation-cap',
      title: 'Training',
      description: 'User manual and training videos portal',
      newTab: true
    },

    {
      showIf: 'admin',
      href: '#/settings/settings-list',
      icon: 'fa fa-wrench',
      title: 'Settings',
      description: 'Manage application configuration settings'
    }
  ]);
}

app.config.globalProperties.$goto =
  (name, params, query) => routerSvc.goto(name, params, query);

app.config.globalProperties.$goback = () => routerSvc.back();

alerts.toastSvc = app.config.globalProperties.$toast;
library.add(fas);
library.add(far);

let url = window.location.href;
let urlParts = url.split('?')
let query = urlParts.length > 1 ? urlParts[1] : '';
let params = new URLSearchParams(query);

window.osUiApp = app;
window.osUi    = app.config.globalProperties.$ui = ui;
let server = ui.server || {};
http.protocol = server.secure ? 'https' : 'http';
http.host = server.hostname;
http.port = server.port;
http.path = server.app || '..';
if (http.path) {
  http.path += '/';
}

// http.path += 'rest/ng'
if (params.get('token')) {
  localStorage.osAuthToken = http.headers['X-OS-API-TOKEN'] = params.get('token');
} else {
  http.headers['X-OS-API-TOKEN'] = localStorage.osAuthToken;
}

let settingsQ  = settingSvc.getAppProps();
let localeQ    = settingSvc.getLocale();
let messagesQ  = settingSvc.getI18nMessages();
let currUserQ  = userSvc.getCurrentUser();
let usrStateQ  = userSvc.getUiState();
let usrRightsQ = authSvc.loadUserRights();
let spmnPropsQ = util.loadSpecimenTypeProps();

Promise.all([settingsQ, localeQ, messagesQ, currUserQ, usrRightsQ, usrStateQ, spmnPropsQ]).then(
  (resp) => {
    let appProps = resp[0];
    let locale   = resp[1];
    let messages = resp[2];
    let currUser = resp[3];

    const i18n = window.osI18n = createI18n({locale: locale, messages: messages});
    app.use(i18n);

    ui.global = {
      defaultDomain: 'openspecimen',
      filterWaitInterval: appProps.searchDelay,
      appProps: appProps,
      locale: {
        dateFmt: locale.dateFmt,
        shortDateFmt: locale.deBeDateFmt,
        timeFmt: locale.timeFmt,
        queryDateFmt: {format: locale.deFeDateFmt},
        dateTimeFmt: locale.dateFmt + ' ' + locale.timeFmt,
        locale: locale.locale,
        utcOffset: locale.utcOffset
      },
      state: resp[5]
    };

    let osSvc = window.osSvc = app.config.globalProperties.$osSvc;
    ui.currentUser = currUser;
    registerHomePageCards(osSvc);

    app.provide('ui', ui);
    app.provide('osSvc', osSvc);

    let count = appProps.plugins.length;
    appProps.plugins.forEach(
      (pluginName) => {
        pluginLoader.load(pluginName).then(
          function(pluginModule) {
            app.use(pluginModule.default, { router, osSvc });
            --count;
            if (count <= 0) {
              app.use(router).use(PrimeVue)
                .mount('#app');
            }
          },

          function(error) {
            console.log('Error loading the plugin: ' + pluginName);
            console.log(error);
            --count;
            if (count <= 0) {
              app.use(router).use(PrimeVue)
                .mount('#app');
            }
          }
        )
      }
    );
  }
);
<|endoftext|>


<commit_before>MWF.xDesktop.requireApp("process.Xform", "$Module", null, false);
MWF.require("MWF.widget.Tab", null, false);
/** @class Tab 分页组件。
 * @o2cn 分页组件
 * @example
 * //可以在脚本中获取该组件
 * //方法1：
 * var tab = this.form.get("fieldId"); //获取组件
 * //方法2
 * var tab = this.target; //在组件本身的脚本中获取
 * @extends MWF.xApplication.process.Xform.$Module
 * @o2category FormComponents
 * @o2range {Process|CMS|Portal}
 * @hideconstructor
 */
MWF.xApplication.process.Xform.Tab = MWF.APPTab =  new Class(
    /** @lends MWF.xApplication.process.Xform.Tab# */
{
	Extends: MWF.APP$Module,

	_loadUserInterface: function(){
        this.elements = [];
        this.containers = [];

        var style = "form";
        if (layout.mobile) style = "mobileForm";

        /**
         * @summary tab组件，平台使用该组件实现分页组件的功能
         * @member {MWF.widget.Tab}
         * @example
         *  //可以在脚本中获取该组件
         * var tab = this.form.get("fieldId").tab; //获取组件对象
         * var pages = tab.pages //获取每个分页
         * pages[1].addEvent("queryShow", function(){
         *     //添加显示分页前事件
         * })
         * pages[1].addEvent("postShow", function(){
         *     //添加显示分页后事件
         * })
         * pages[1]._showTab(); //显示第2个分页
         */
		this.tab = new MWF.widget.Tab(this.node, {"style": style});

		this._setTabWidgetStyles();

		this.tab.tabNodeContainer = this.node.getFirst("div");
		this.tab.contentNodeContainer = this.tab.tabNodeContainer.getNext("div");

		var lastNode = this.tab.tabNodeContainer.getLast();
		var tabs;
		if (lastNode && lastNode.hasClass("tabNodeContainerLeft")){
            this.tab.tabNodeContainerRight = this.tab.tabNodeContainer.getFirst();
            this.tab.tabNodeContainerLeft = lastNode;
            this.tab.tabNodeContainerArea = lastNode.getFirst();

            var menuNode = this.node.getElement(".MWFMenu");
            if (menuNode) menuNode.destroy();
            this.tab.load();
            tabs = this.tab.tabNodeContainerArea.getChildren("div");
        }else{
            tabs = this.tab.tabNodeContainer.getChildren("div");
            this.tab.load();
        }

		var contents = this.tab.contentNodeContainer.getChildren("div");
		tabs.each(function(tab, idx){
			this.tab.rebuildTab(contents[idx], contents[idx].getFirst(), tab);
		}.bind(this));

		if( this.json.defaultIndex && this.tab.pages[this.json.defaultIndex]){
            his.tab.pages[this.json.defaultIndex]._showTab();
        }else{
            this.tab.pages[0]._showTab();
        }
        this.loadSubModule();
	},
    loadSubModule: function(){
        this.tab.pages.each(function(page){
            var node = page.tabNode;
            var json = this.form._getDomjson(node);
            var tab = this;
            var module = this.form._loadModule(json, node, function(){
                if( tab.widget )this.widget = tab.widget;
                this.tab = tab;
            });
            this.elements.push(module);
            this.form.modules.push(module);

            if( json.width && json.width.toInt()>60 ){
                node.setStyle("width", json.width+"px");
            }
            if( json.description){
                node.set("title", json.description);
            }
            if (page.isShow){
                this.showContentModule.call(page, this);
            }else{
                if (this.json.isDelay){
                    var _self = this;
                    page.showContentModuleFun = function(){_self.showContentModule.call(page, _self)};
                    page.addEvent("show", page.showContentModuleFun);
                }else{
                    this.showContentModule.call(page, this);
                }
            }
        }.bind(this));
    },
    showContentModule: function(_self){
        var node = this.contentNode;
        node.isLoadModule = true;
        var json = _self.form._getDomjson(node);
        var tab = _self;
        var module = _self.form._loadModule(json, node, function(){
            if( _self.widget )this.widget = _self.widget;
            this.tab = tab;
        });
        _self.containers.push(module);
        _self.form.modules.push(module);

        if (this.showContentModuleFun) this.removeEvent("show", this.showContentModuleFun);
    },

	_setTabWidgetStyles: function(){
        if (this.json.tabNodeContainer) this.tab.css.tabNodeContainer = Object.clone(this.json.tabNodeContainer);
        if (this.json.contentNodeContainer) this.tab.css.contentNodeContainer = Object.clone(this.json.contentNodeContainer);
		this.tab.css.tabNode = Object.clone(this.json.tabStyles);
		this.tab.css.tabTextNode = Object.clone(this.json.tabTextStyles);
		this.tab.css.tabNodeCurrent = Object.clone(this.json.tabCurrentStyles);
		this.tab.css.tabTextNodeCurrent = Object.clone(this.json.tabTextCurrentStyles);
	}
});
MWF.xApplication.process.Xform.tab$Page = MWF.APPTab$Page =  new Class({
    Extends: MWF.APP$Module
});
MWF.xApplication.process.Xform.tab$Content = MWF.APPTab$Content =  new Class({
    Extends: MWF.APP$Module,
    _loadUserInterface: function(){
        var _self = this;
        this.form._loadModules(this.node, function () {
            if( _self.widget )this.widget = _self.widget;
        });
    }
});
<commit_msg>defaulttab<commit_after>MWF.xDesktop.requireApp("process.Xform", "$Module", null, false);
MWF.require("MWF.widget.Tab", null, false);
/** @class Tab 分页组件。
 * @o2cn 分页组件
 * @example
 * //可以在脚本中获取该组件
 * //方法1：
 * var tab = this.form.get("fieldId"); //获取组件
 * //方法2
 * var tab = this.target; //在组件本身的脚本中获取
 * @extends MWF.xApplication.process.Xform.$Module
 * @o2category FormComponents
 * @o2range {Process|CMS|Portal}
 * @hideconstructor
 */
MWF.xApplication.process.Xform.Tab = MWF.APPTab =  new Class(
    /** @lends MWF.xApplication.process.Xform.Tab# */
{
	Extends: MWF.APP$Module,

	_loadUserInterface: function(){
        this.elements = [];
        this.containers = [];

        var style = "form";
        if (layout.mobile) style = "mobileForm";

        /**
         * @summary tab组件，平台使用该组件实现分页组件的功能
         * @member {MWF.widget.Tab}
         * @example
         *  //可以在脚本中获取该组件
         * var tab = this.form.get("fieldId").tab; //获取组件对象
         * var pages = tab.pages //获取每个分页
         * pages[1].addEvent("queryShow", function(){
         *     //添加显示分页前事件
         * })
         * pages[1].addEvent("postShow", function(){
         *     //添加显示分页后事件
         * })
         * pages[1]._showTab(); //显示第2个分页
         */
		this.tab = new MWF.widget.Tab(this.node, {"style": style});

		this._setTabWidgetStyles();

		this.tab.tabNodeContainer = this.node.getFirst("div");
		this.tab.contentNodeContainer = this.tab.tabNodeContainer.getNext("div");

		var lastNode = this.tab.tabNodeContainer.getLast();
		var tabs;
		if (lastNode && lastNode.hasClass("tabNodeContainerLeft")){
            this.tab.tabNodeContainerRight = this.tab.tabNodeContainer.getFirst();
            this.tab.tabNodeContainerLeft = lastNode;
            this.tab.tabNodeContainerArea = lastNode.getFirst();

            var menuNode = this.node.getElement(".MWFMenu");
            if (menuNode) menuNode.destroy();
            this.tab.load();
            tabs = this.tab.tabNodeContainerArea.getChildren("div");
        }else{
            tabs = this.tab.tabNodeContainer.getChildren("div");
            this.tab.load();
        }

		var contents = this.tab.contentNodeContainer.getChildren("div");
		tabs.each(function(tab, idx){
			this.tab.rebuildTab(contents[idx], contents[idx].getFirst(), tab);
		}.bind(this));

		if( this.json.defaultIndex && this.tab.pages[this.json.defaultIndex]){
            this.tab.pages[this.json.defaultIndex]._showTab();
        }else{
            this.tab.pages[0]._showTab();
        }
        this.loadSubModule();
	},
    loadSubModule: function(){
        this.tab.pages.each(function(page){
            var node = page.tabNode;
            var json = this.form._getDomjson(node);
            var tab = this;
            var module = this.form._loadModule(json, node, function(){
                if( tab.widget )this.widget = tab.widget;
                this.tab = tab;
            });
            this.elements.push(module);
            this.form.modules.push(module);

            if( json.width && json.width.toInt()>60 ){
                node.setStyle("width", json.width+"px");
            }
            if( json.description){
                node.set("title", json.description);
            }
            if (page.isShow){
                this.showContentModule.call(page, this);
            }else{
                if (this.json.isDelay){
                    var _self = this;
                    page.showContentModuleFun = function(){_self.showContentModule.call(page, _self)};
                    page.addEvent("show", page.showContentModuleFun);
                }else{
                    this.showContentModule.call(page, this);
                }
            }
        }.bind(this));
    },
    showContentModule: function(_self){
        var node = this.contentNode;
        node.isLoadModule = true;
        var json = _self.form._getDomjson(node);
        var tab = _self;
        var module = _self.form._loadModule(json, node, function(){
            if( _self.widget )this.widget = _self.widget;
            this.tab = tab;
        });
        _self.containers.push(module);
        _self.form.modules.push(module);

        if (this.showContentModuleFun) this.removeEvent("show", this.showContentModuleFun);
    },

	_setTabWidgetStyles: function(){
        if (this.json.tabNodeContainer) this.tab.css.tabNodeContainer = Object.clone(this.json.tabNodeContainer);
        if (this.json.contentNodeContainer) this.tab.css.contentNodeContainer = Object.clone(this.json.contentNodeContainer);
		this.tab.css.tabNode = Object.clone(this.json.tabStyles);
		this.tab.css.tabTextNode = Object.clone(this.json.tabTextStyles);
		this.tab.css.tabNodeCurrent = Object.clone(this.json.tabCurrentStyles);
		this.tab.css.tabTextNodeCurrent = Object.clone(this.json.tabTextCurrentStyles);
	}
});
MWF.xApplication.process.Xform.tab$Page = MWF.APPTab$Page =  new Class({
    Extends: MWF.APP$Module
});
MWF.xApplication.process.Xform.tab$Content = MWF.APPTab$Content =  new Class({
    Extends: MWF.APP$Module,
    _loadUserInterface: function(){
        var _self = this;
        this.form._loadModules(this.node, function () {
            if( _self.widget )this.widget = _self.widget;
        });
    }
});
<|endoftext|>


<commit_before>/*
 * The contents of this file are subject to the OpenMRS Public License
 * Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
define(openhmis.url.backboneBase + "js/openhmis",
	[
		openhmis.url.backboneBase + 'js/lib/jquery',
		openhmis.url.backboneBase + 'js/lib/underscore',
		openhmis.url.backboneBase + 'js/lib/backbone',
		openhmis.url.backboneBase + 'js/lib/i18n',
		openhmis.url.backboneBase + 'js/lib/backbone-forms'
	],
	function($, _, Backbone, __) {

		// Use <? ?> for template tags.
		_.templateSettings = {
			evaluate:  /<\?(.+?)\?>/g,
			interpolate: /<\?=(.+?)\?>/g
		};

		var openhmis = window.openhmis || {};
		openhmis.templates = {};

		openhmis.url.getPage = function (moduleBaseName) {
			return openhmis.url.page + openhmis.url[moduleBaseName];
		};

		//TODO: Better system for identifying specific errors
		openhmis.error = function (model, resp) {
			var handleErrorResp = function (resp) {
				var o = (typeof resp === "string") ? $.parseJSON(resp).error : resp;
				if (o.detail.indexOf("ContextAuthenticationException") !== -1) {
					alert(__("Your session has timed out.  You will be redirected to the login page."));
					window.location.reload();
				}
				else if (o.detail.indexOf("AccessControlException") !== -1) {
					if (o.detail.indexOf("refund") !== -1) {
						alert(__("The total of the bill is negative and you do not have the required privileges to process a refund.\n\nPlease contact your supervisor about processing refunds."));
					}
					else if (o.detail.indexOf("adjust") !== -1) {
						alert(__("You do not have the required privileges to adjust a bill.\n\nPlease contact your supervisor about adjusting a bill."));
					}
				}
				else if (o.message.indexOf("no rounding item ID") !== -1) {
					alert(__(o.message + "\n\nPlease specify a rounding item or disable rounding."));
				}
				else {
					var firstLfPos = o.detail.indexOf('\n');
					if (firstLfPos !== -1)
						o.detail = o.detail.substring(0, firstLfPos);
					alert('An error occurred during the request.\n\n' + o.message + '\n\nCode: ' + o.code + '\n\n' + o.detail);
				}
			};

			if (!(model instanceof Backbone.Model)) {
				if (model.responseText)
					handleErrorResp(model.responseText);
				else
					handleErrorResp(model);
			} else if (resp !== undefined) {
				handleErrorResp(resp.responseText);
				//var str = "";
				//for (var i in resp) {
				//	if (str.length > 0) str += ",\n";
				//	str += i + ": " + resp[i];
				//}
				//alert(str);
			}
		};

		openhmis.getQueryStringParameter = function (name) {
			name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
			var regexS = "[\\?&]" + name + "=([^&#]*)";
			var regex = new RegExp(regexS);
			var results = regex.exec(window.location.search);
			if (results == null)
				return "";
			else
				return decodeURIComponent(results[1].replace(/\+/g, " "));
		};

		openhmis.addQueryStringParameter = function (queryString, parameter) {
			return queryString ? queryString + "&" + parameter : parameter;
		};

		openhmis.padZero = function (n) {
			return n < 10 ? "0" + n : n;
		};

		openhmis.pad2Zeros = function (n) {
			if (n < 100) n = '0' + n;
			if (n < 10) n = '0' + n;
			return n;
		};

		openhmis.dateFormat = function (date, includeTime) {
			var padZero = openhmis.padZero;
			var day = date.getDate();
			var month = date.getMonth() + 1;
			var year = date.getFullYear();
			day = padZero(day);
			month = padZero(month);
			var strDate = day + '-' + month + '-' + year;
			if (includeTime === true) {
				strDate += " " + padZero(date.getHours())
					+ ":" + padZero(date.getMinutes());
			}
			return strDate;
		};

		openhmis.dateFormatLocale = function (date) {
			if (typeof date === "string") {
				date = new Date(date);
			}

			return date ? date.toLocaleDateString() : "";
		};

		openhmis.dateTimeFormatLocale = function (date) {
			if (typeof date === "string") {
				date = new Date(date);
			}

			return date ? date.toLocaleString() : "";
		};

		openhmis.iso8601Date = function (d) {
			var padZero = openhmis.padZero;
			var pad2Zeros = openhmis.pad2Zeros;
			return d.getUTCFullYear() + '-' + padZero(d.getUTCMonth() + 1) + '-' + padZero(d.getUTCDate()) + 'T' + padZero(d.getUTCHours()) + ':' + padZero(d.getUTCMinutes()) + ':' + padZero(d.getUTCSeconds()) + '.' + pad2Zeros(d.getUTCMilliseconds()) + '+0000';
		};

		openhmis.tryParsingFuzzyDate = function (fuzzyString) {
			var numberOfSomething = /^([0-9]+)\s?(\w+)(\s+.*)?$/;
			var matches = fuzzyString.match(numberOfSomething);
			var number;
			if (matches && matches[2] && !isNaN(number = parseInt(matches[1]))) {
				matches[1] = number;
				return matches;
			}
			return null;
		};

		openhmis.toFuzzyDate = function (seconds) {
			var timeChunks = [
				[31536000, __("year")],
				[604800, __("week")],
				[86400, __("day")]
			];
			for (var i in timeChunks) {
				var chunk = timeChunks[i]
				var numberOfChunks;
				if ((numberOfChunks = Math.floor(seconds / chunk[0])) >= 1) {
					var string = numberOfChunks === 1
						? __("%d %s", numberOfChunks, chunk[1])
						: __("%d %s", numberOfChunks, openhmis.pluralize(chunk[1]));
					var remainder = seconds % chunk[0];
					if (remainder > 0)
						return string + " " + openhmis.toFuzzyDate(remainder);
					else
						return string;
				}
			}
			return null;
		};

		openhmis.fromFuzzyDate = function (fuzzyString, carry) {
			var timeChunks = [
				["year", 31536000],
				["week", 604800],
				["day", 86400]
			];
			var matches = openhmis.tryParsingFuzzyDate($.trim(fuzzyString))
			if (matches) {
				for (var i in timeChunks) {
					var chunk = timeChunks[i];
					if (matches[2] === chunk[0] || matches[2] === (chunk[0] + "s")) {
						var seconds = matches[1] * chunk[1];
						if (matches[3])
							return openhmis.fromFuzzyDate(matches[3], seconds + (carry || 0));
						else
							return seconds + (carry || 0);
					}
				}
			}

			return carry;
		};

		openhmis.validationMessage = function (parentEl, message, inputEl) {
			if ($(parentEl).length > 1) parentEl = $(parentEl)[0];
			if ($(parentEl).find('.validation').length > 0) return;
			var prevPosition = $(parentEl).css("position");
			$(parentEl).css("position", "relative");
			var el = $('

');
			el.text(message);
			$(parentEl).append(el);
			if (inputEl !== undefined) $(inputEl).focus();
			setTimeout(function () {
				$(el).remove();
				if (prevPosition !== "static")
					$(parentEl).css("position", prevPosition);
			}, 5000);
		};

		openhmis.round = function (val, nearest, mode) {
			nearest = nearest ? nearest : 1;
			if (nearest === 0) return val;
			var factor = 1 / nearest;
			switch (mode) {
				case 'FLOOR':
					return Math.floor(val * factor) / factor;
				case 'CEILING':
					return Math.ceil(val * factor) / factor;
				default:
					return Math.round(val * factor) / factor;
			}
		};

		openhmis.isNumeric = function (n) {
			return !isNaN(parseFloat(n)) && isFinite(n);
		};

		openhmis.toCamelCase = function (str, firstCapital) {
			firstCapital = firstCapital !== undefined ? firstCapital : false;
			str.replace(
				/\b(\S)(\S*)/g,
				function (match, first, rest) {
					return first.toUpperCase() + rest.toLowerCase();
				}
			);
			if (!firstCapital)
				str = str.charAt(0).toLowerCase() + str.substring(1);
			return str;
		};

		// Use uuid for id
		Backbone.Model.prototype.idAttribute = 'uuid';

		/**
		 * Template helper function
		 *
		 * Fetches a template from a remote URI unless it has been previously fetched
		 * and cached.
		 */
		Backbone.View.prototype.tmplFileRoot = openhmis.url.resources;
		Backbone.View.prototype.getTemplate = function(tmplFile, tmplSelector) {
			tmplFile = tmplFile ? tmplFile : this.tmplFile;
			tmplSelector = tmplSelector ? tmplSelector : this.tmplSelector;
			var view = this;
			if (openhmis.templates[tmplFile] === undefined) {
				var uri = view.tmplFileRoot === undefined ? tmplFile : view.tmplFileRoot + tmplFile;
				$.ajax({
					url: uri,
					async: false,
					dataType: "html",
					success: function(data, status, jq) {
						openhmis.templates[tmplFile] = $("
").html(data);
					}
				});
			}

			var template = _.template($(openhmis.templates[tmplFile]).find(tmplSelector).html());
			var augmentedTemplate = function(context) {
				if (context !== undefined) {
					context.__ = context.__ ? context.__ : __;
					context.urls = context.urls ? context.urls : openhmis.url;
					context.helpers = context.helpers ? context.helpers : Backbone.Form.helpers
					context.pluralize = openhmis.pluralize;
				}

				return template.call(this, context);
			};

			return augmentedTemplate;
		};

		return openhmis;
	}
);
<commit_msg>Fixed bug in error message processing.<commit_after>/*
 * The contents of this file are subject to the OpenMRS Public License
 * Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
define(openhmis.url.backboneBase + "js/openhmis",
	[
		openhmis.url.backboneBase + 'js/lib/jquery',
		openhmis.url.backboneBase + 'js/lib/underscore',
		openhmis.url.backboneBase + 'js/lib/backbone',
		openhmis.url.backboneBase + 'js/lib/i18n',
		openhmis.url.backboneBase + 'js/lib/backbone-forms'
	],
	function($, _, Backbone, __) {

		// Use <? ?> for template tags.
		_.templateSettings = {
			evaluate:  /<\?(.+?)\?>/g,
			interpolate: /<\?=(.+?)\?>/g
		};

		var openhmis = window.openhmis || {};
		openhmis.templates = {};

		openhmis.url.getPage = function (moduleBaseName) {
			return openhmis.url.page + openhmis.url[moduleBaseName];
		};

		//TODO: Better system for identifying specific errors
		openhmis.error = function (model, resp) {
			var handleErrorResp = function (resp) {
				var o = (typeof resp === "string") ? $.parseJSON(resp).error : resp;
				if (o.detail.indexOf("ContextAuthenticationException") !== -1) {
					alert(__("Your session has timed out.  You will be redirected to the login page."));
					window.location.reload();
				}
				else if (o.detail.indexOf("AccessControlException") !== -1) {
					if (o.detail.indexOf("refund") !== -1) {
						alert(__("The total of the bill is negative and you do not have the required privileges to process a refund.\n\nPlease contact your supervisor about processing refunds."));
					}
					else if (o.detail.indexOf("adjust") !== -1) {
						alert(__("You do not have the required privileges to adjust a bill.\n\nPlease contact your supervisor about adjusting a bill."));
					}
				}
				else if (o.message && o.message.indexOf("no rounding item ID") !== -1) {
					alert(__(o.message + "\n\nPlease specify a rounding item or disable rounding."));
				}
				else {
					var firstLfPos = o.detail.indexOf('\n');
					if (firstLfPos !== -1)
						o.detail = o.detail.substring(0, firstLfPos);
					alert('An error occurred during the request.\n\n' + o.message + '\n\nCode: ' + o.code + '\n\n' + o.detail);
				}
			};

			if (!(model instanceof Backbone.Model)) {
				if (model.responseText)
					handleErrorResp(model.responseText);
				else
					handleErrorResp(model);
			} else if (resp !== undefined) {
				handleErrorResp(resp.responseText);
				//var str = "";
				//for (var i in resp) {
				//	if (str.length > 0) str += ",\n";
				//	str += i + ": " + resp[i];
				//}
				//alert(str);
			}
		};

		openhmis.getQueryStringParameter = function (name) {
			name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
			var regexS = "[\\?&]" + name + "=([^&#]*)";
			var regex = new RegExp(regexS);
			var results = regex.exec(window.location.search);
			if (results == null)
				return "";
			else
				return decodeURIComponent(results[1].replace(/\+/g, " "));
		};

		openhmis.addQueryStringParameter = function (queryString, parameter) {
			return queryString ? queryString + "&" + parameter : parameter;
		};

		openhmis.padZero = function (n) {
			return n < 10 ? "0" + n : n;
		};

		openhmis.pad2Zeros = function (n) {
			if (n < 100) n = '0' + n;
			if (n < 10) n = '0' + n;
			return n;
		};

		openhmis.dateFormat = function (date, includeTime) {
			if (typeof date === "string") {
				date = new Date(date);
			}

			var padZero = openhmis.padZero;
			var day = date.getDate();
			var month = date.getMonth() + 1;
			var year = date.getFullYear();
			day = padZero(day);
			month = padZero(month);
			var strDate = day + '-' + month + '-' + year;
			if (includeTime === true) {
				strDate += " " + padZero(date.getHours())
					+ ":" + padZero(date.getMinutes());
			}
			return strDate;
		};

		openhmis.dateFormatLocale = function (date) {
			if (typeof date === "string") {
				date = new Date(date);
			}

			return date ? date.toLocaleDateString() : "";
		};

		openhmis.dateTimeFormatLocale = function (date) {
			if (typeof date === "string") {
				date = new Date(date);
			}

			return date ? date.toLocaleString() : "";
		};

		openhmis.timeFormatLocale = function(date) {
			if (typeof date === "string") {
				date = new Date(date);
			}

			return date ? date.toLocaleTimeString() : "";
		};

		openhmis.iso8601Date = function (d) {
			var padZero = openhmis.padZero;
			var pad2Zeros = openhmis.pad2Zeros;
			return d.getUTCFullYear() + '-' + padZero(d.getUTCMonth() + 1) + '-' + padZero(d.getUTCDate()) + 'T' + padZero(d.getUTCHours()) + ':' + padZero(d.getUTCMinutes()) + ':' + padZero(d.getUTCSeconds()) + '.' + pad2Zeros(d.getUTCMilliseconds()) + '+0000';
		};

		openhmis.tryParsingFuzzyDate = function (fuzzyString) {
			var numberOfSomething = /^([0-9]+)\s?(\w+)(\s+.*)?$/;
			var matches = fuzzyString.match(numberOfSomething);
			var number;
			if (matches && matches[2] && !isNaN(number = parseInt(matches[1]))) {
				matches[1] = number;
				return matches;
			}
			return null;
		};

		openhmis.toFuzzyDate = function (seconds) {
			var timeChunks = [
				[31536000, __("year")],
				[604800, __("week")],
				[86400, __("day")]
			];
			for (var i in timeChunks) {
				var chunk = timeChunks[i]
				var numberOfChunks;
				if ((numberOfChunks = Math.floor(seconds / chunk[0])) >= 1) {
					var string = numberOfChunks === 1
						? __("%d %s", numberOfChunks, chunk[1])
						: __("%d %s", numberOfChunks, openhmis.pluralize(chunk[1]));
					var remainder = seconds % chunk[0];
					if (remainder > 0)
						return string + " " + openhmis.toFuzzyDate(remainder);
					else
						return string;
				}
			}
			return null;
		};

		openhmis.fromFuzzyDate = function (fuzzyString, carry) {
			var timeChunks = [
				["year", 31536000],
				["week", 604800],
				["day", 86400]
			];
			var matches = openhmis.tryParsingFuzzyDate($.trim(fuzzyString))
			if (matches) {
				for (var i in timeChunks) {
					var chunk = timeChunks[i];
					if (matches[2] === chunk[0] || matches[2] === (chunk[0] + "s")) {
						var seconds = matches[1] * chunk[1];
						if (matches[3])
							return openhmis.fromFuzzyDate(matches[3], seconds + (carry || 0));
						else
							return seconds + (carry || 0);
					}
				}
			}

			return carry;
		};

		openhmis.validationMessage = function (parentEl, message, inputEl) {
			if ($(parentEl).length > 1) parentEl = $(parentEl)[0];
			if ($(parentEl).find('.validation').length > 0) return;
			var prevPosition = $(parentEl).css("position");
			$(parentEl).css("position", "relative");
			var el = $('

');
			el.text(message);
			$(parentEl).append(el);
			if (inputEl !== undefined) $(inputEl).focus();
			setTimeout(function () {
				$(el).remove();
				if (prevPosition !== "static")
					$(parentEl).css("position", prevPosition);
			}, 5000);
		};

		openhmis.round = function (val, nearest, mode) {
			nearest = nearest ? nearest : 1;
			if (nearest === 0) return val;
			var factor = 1 / nearest;
			switch (mode) {
				case 'FLOOR':
					return Math.floor(val * factor) / factor;
				case 'CEILING':
					return Math.ceil(val * factor) / factor;
				default:
					return Math.round(val * factor) / factor;
			}
		};

		openhmis.isNumeric = function (n) {
			return !isNaN(parseFloat(n)) && isFinite(n);
		};

		openhmis.toCamelCase = function (str, firstCapital) {
			firstCapital = firstCapital !== undefined ? firstCapital : false;
			str.replace(
				/\b(\S)(\S*)/g,
				function (match, first, rest) {
					return first.toUpperCase() + rest.toLowerCase();
				}
			);
			if (!firstCapital)
				str = str.charAt(0).toLowerCase() + str.substring(1);
			return str;
		};

		// Use uuid for id
		Backbone.Model.prototype.idAttribute = 'uuid';

		/**
		 * Template helper function
		 *
		 * Fetches a template from a remote URI unless it has been previously fetched
		 * and cached.
		 */
		Backbone.View.prototype.tmplFileRoot = openhmis.url.resources;
		Backbone.View.prototype.getTemplate = function(tmplFile, tmplSelector) {
			tmplFile = tmplFile ? tmplFile : this.tmplFile;
			tmplSelector = tmplSelector ? tmplSelector : this.tmplSelector;
			var view = this;
			if (openhmis.templates[tmplFile] === undefined) {
				var uri = view.tmplFileRoot === undefined ? tmplFile : view.tmplFileRoot + tmplFile;
				$.ajax({
					url: uri,
					async: false,
					dataType: "html",
					success: function(data, status, jq) {
						openhmis.templates[tmplFile] = $("
").html(data);
					}
				});
			}

			var template = _.template($(openhmis.templates[tmplFile]).find(tmplSelector).html());
			var augmentedTemplate = function(context) {
				if (context !== undefined) {
					context.__ = context.__ ? context.__ : __;
					context.urls = context.urls ? context.urls : openhmis.url;
					context.helpers = context.helpers ? context.helpers : Backbone.Form.helpers
					context.pluralize = openhmis.pluralize;
				}

				return template.call(this, context);
			};

			return augmentedTemplate;
		};

		return openhmis;
	}
);
<|endoftext|>


<commit_before>var React = require('react');
var CSSPropertyOperations = require('react/lib/CSSPropertyOperations');
var reduce = require('lodash/collection/reduce');

function buildCssString (selector, rules) {
  if (!selector || !rules) {
    return;
  }

  return selector + "{" +
    CSSPropertyOperations.createMarkupForStyles(rules) +
  "}";
}

var Style = React.createClass({
  propTypes: {
    scopeSelector: React.PropTypes.string,
    rules: React.PropTypes.arrayOf(React.PropTypes.object)
  },

  getDefaultProps: function () {
    return {
      scopeSelector: ""
    }
  },

  render: function () {
    if (!this.props.rules) {
      return null;
    }

    var styles = reduce(this.props.rules, function (s, item) {
      var selector = Object.keys(item)[0];
      var rules = item[selector];
      var completeSelector = this.props.scopeSelector + " " + selector;

      return s += buildCssString(completeSelector, rules);
    }, "", this);

    return React.createElement(
      "style",
      {dangerouslySetInnerHTML: {__html: styles}}
    );
  }
});

module.exports = Style;
<commit_msg>Break `_buildStyles` out into function; add `_buildMediaQueryString` to process queries; add `_prepareContextMediaQueries` to check for queries initiated via MatchMediaBase<commit_after>var React = require('react');
var CSSPropertyOperations = require('react/lib/CSSPropertyOperations');
var reduce = require('lodash/collection/reduce');
var MatchMediaItem = require('../mixins/match-media-item');

function buildCssString (selector, rules) {
  if (!selector || !rules) {
    return;
  }

  return selector + "{" +
    CSSPropertyOperations.createMarkupForStyles(rules) +
  "}";
}

var Style = React.createClass({
  mixins: [ MatchMediaItem ],

  propTypes: {
    scopeSelector: React.PropTypes.string,
    rules: React.PropTypes.arrayOf(React.PropTypes.object)
  },

  getDefaultProps: function () {
    return {
      scopeSelector: ""
    }
  },

  _buildStyles: function (stylesArr) {
    var styles = reduce(stylesArr, function (accumulator, item) {
      var selector = Object.keys(item)[0];
      var rules = item[selector];

      if (selector === "mediaQueries") {
        accumulator += this._buildMediaQueryString(rules);
      } else {
        var completeSelector = (this.props.scopeSelector ?
          this.props.scopeSelector + " " :
          "") +
          selector;
        accumulator += buildCssString(completeSelector, rules);
      }

      return accumulator;
    }, "", this);

    return styles;
  },

  _buildMediaQueryString: function (mediaQueryObj) {
    var mediaQueries = "";

    Object.keys(mediaQueryObj).forEach(function (query) {
      var completeQuery = this.contextMediaQueries[query] ?
        this.contextMediaQueries[query] :
        query;
      mediaQueries += "@media " + completeQuery + "{" +
        this._buildStyles(mediaQueryObj[query]) +
      "}";
    }.bind(this));

    return mediaQueries;
  },

  _prepareContextMediaQueries: function () {
    this.contextMediaQueries = {};
    if (this.context && this.context.mediaQueries) {
      Object.keys(this.context.mediaQueries).forEach(function (query) {
        this.contextMediaQueries[query] = this.context.mediaQueries[query].media;
      }.bind(this));
    }
  },

  render: function () {
    if (!this.props.rules) {
      return null;
    }

    this._prepareContextMediaQueries();
    var styles = this._buildStyles(this.props.rules);

    return React.createElement(
      "style",
      {dangerouslySetInnerHTML: {__html: styles}}
    );
  }
});

module.exports = Style;
<|endoftext|>


<commit_before>import ChangeText from '../Manipulation/ChangeText';
import CombineBlocks from '../Manipulation/CombineBlocks';

const KEY_CODES = {
  'shift': 16, 'ctrl': 17, 'alt': 18, 'meta': 91,
  'left': 37, 'up': 38, 'right': 39, 'down': 40
};

class OtherKey {
  constructor(content, selection) {
    this.content   = content;
    this.selection = selection;
  }

  static getName() {
    return 'other';
  }

  // catch-all for all content keys
  static matches(event) {
    const ignores = Object.keys(KEY_CODES).map(key => KEY_CODES[key]);
    return ignores.indexOf(event.keyCode) === -1;
  }

  down(callback) {
    const guids = this.selection.guids();
    const offsets = this.selection.offsets();
    let results;

    if (this.selection.crossBlock()) {
      results = this._combineBlocks().execute(guids, offsets);
    }
    this._complete(results, callback);
  }

  up(callback) {
    const guids = this.selection.guids();
    const offsets = this.selection.offsets();

    const node = document.getElementsByName(guids.anchor)[0];
    let text;
    if (false && node && node.getAttribute('data-figure')) {
      const caption = node.getElementsByTagName("figcaption")[0];
      text = caption.textContent;
    } else {
      text = node && node.textContent;
    }

    const results = this._changeText().execute(guids, offsets, { node: node, text: text });

    this._complete(results, callback);
  }

  _complete(results, callback) {
    const content = results ? results.content : this.content;
    const position = results ? results.position : null;

    callback({
      content: content,
      position: position,
      stopPropagation: false,
      preventDefault: false,
      emit: false
    });
  }

  _changeText() {
    return new ChangeText(this.content);
  }

  _combineBlocks() {
    return new CombineBlocks(this.content);
  }
}

export default OtherKey;
<commit_msg>don't record key event changes if ctrl/meta/alt are pressed<commit_after>import ChangeText from '../Manipulation/ChangeText';
import CombineBlocks from '../Manipulation/CombineBlocks';

const KEY_CODES = {
  'shift': 16, 'ctrl': 17, 'alt': 18, 'meta': 91,
  'left': 37, 'up': 38, 'right': 39, 'down': 40
};

class OtherKey {
  constructor(content, selection) {
    this.content   = content;
    this.selection = selection;
  }

  static getName() {
    return 'other';
  }

  // catch-all for all content keys
  static matches(event) {
    if (event.ctrlKey || event.metaKey || event.altKey) return false;
    const ignores = Object.keys(KEY_CODES).map(key => KEY_CODES[key]);
    return ignores.indexOf(event.keyCode) === -1;
  }

  down(callback) {
    const guids = this.selection.guids();
    const offsets = this.selection.offsets();
    let results;

    if (this.selection.crossBlock()) {
      results = this._combineBlocks().execute(guids, offsets);
    }
    this._complete(results, callback);
  }

  up(callback) {
    const guids = this.selection.guids();
    const offsets = this.selection.offsets();

    const node = document.getElementsByName(guids.anchor)[0];
    let text;
    if (false && node && node.getAttribute('data-figure')) {
      const caption = node.getElementsByTagName("figcaption")[0];
      text = caption.textContent;
    } else {
      text = node && node.textContent;
    }

    const results = this._changeText().execute(guids, offsets, { node: node, text: text });

    this._complete(results, callback);
  }

  _complete(results, callback) {
    const content = results ? results.content : this.content;
    const position = results ? results.position : null;

    callback({
      content: content,
      position: position,
      stopPropagation: false,
      preventDefault: false,
      emit: false
    });
  }

  _changeText() {
    return new ChangeText(this.content);
  }

  _combineBlocks() {
    return new CombineBlocks(this.content);
  }
}

export default OtherKey;
<|endoftext|>


<commit_before>/**
 * @file betFlip command
 * @author Sankarsan Kampa (a.k.a k3rn31p4nic)
 * @license MIT
 */

let recentUsers = [];

exports.run = (Bastion, message, args) => {
  if (!recentUsers.includes(message.author.id)) {
    if (!args.money || args.money < 1 || !/^(heads|tails)$/i.test(args.outcome)) {
      /**
       * The command was ran with invalid parameters.
       * @fires commandUsage
       */
      return Bastion.emit('commandUsage', message, this.help);
    }

    if (args.money < 5) {
      return message.channel.send({
        embed: {
          color: Bastion.colors.red,
          description: 'Minimum bet amount is 5 Bastion Currencies.'
        }
      }).catch(e => {
        Bastion.log.error(e.stack);
      });
    }

    let outcomes = [
      'Heads',
      'Tails'
    ];
    let outcome = outcomes[Math.floor(Math.random() * outcomes.length)];
    // let outcome = outcomes.random();

    Bastion.db.get(`SELECT bastionCurrencies FROM profiles WHERE userID=${message.author.id}`).then(profile => {
      if (args.money > profile.bastionCurrencies) {
        return message.channel.send({
          embed: {
            color: Bastion.colors.red,
            description: `Unfortunately, you can't bet. You only have **${profile.bastionCurrencies}** Bastion Currencies.`
          }
        }).catch(e => {
          Bastion.log.error(e.stack);
        });
      }

      recentUsers.push(message.author.id);

      let result;
      if (outcome.toLowerCase() === args.outcome.toLowerCase()) {
        let prize = args.money < 50 ? args.money + outcomes.length : args.money < 100 ? args.money : args.money * 1.5;
        result = `Congratulations! You won the bet.\nYou won **${prize}** Bastion Currencies.`;

        /**
         * User's account is debited with Bastion Currencies
         * @fires userDebit
         */
        Bastion.emit('userDebit', message.author, prize);
      }
      else {
        result = 'Sorry, you lost the bet. Better luck next time.';

        /**
         * User's account is credited with Bastion Currencies
         * @fires userCredit
         */
        Bastion.emit('userCredit', message.author, args.money);
      }

      message.channel.send({
        embed: {
          color: Bastion.colors.blue,
          title: `Flipped ${outcome}`,
          description: result
        }
      }).then(() => {
        setTimeout(function () {
          recentUsers.splice(recentUsers.indexOf(message.author.id), 1);
        }, 60 * 1000);
      }).catch(e => {
        Bastion.log.error(e.stack);
      });
    }).catch(e => {
      Bastion.log.error(e.stack);
    });
  }
  else {
    message.channel.send({
      embed: {
        color: Bastion.colors.red,
        description: `${message.author} you have gambled recently for this game, please wait at least 60 seconds before gambling again.`
      }
    }).catch(e => {
      Bastion.log.error(e.stack);
    });
  }
};

exports.config = {
  aliases: [ 'bf' ],
  enabled: true,
  argsDefinitions: [
    { name: 'outcome', type: String, alias: 'o', multiple: true, defaultOption: true },
    { name: 'money', type: Number, alias: 'm' }
  ]
};

exports.help = {
  name: 'betflip',
  description: 'Bets a specified amount of Bastion currency on prediction of the outcome of flipping a coin. If you win, you win more Bastion Currencies. If you lose, you lose the amount of currency you\'ve bet.',
  botPermission: '',
  userPermission: '',
  usage: 'betflip <amount> <heads|tails>',
  example: [ 'betflip 100 heads' ]
};
<commit_msg>Improved betFlip command<commit_after>/**
 * @file betFlip command
 * @author Sankarsan Kampa (a.k.a k3rn31p4nic)
 * @license MIT
 */

let recentUsers = [];

exports.run = (Bastion, message, args) => {
  if (!recentUsers.includes(message.author.id)) {
    if (!args.money || args.money < 1 || !/^(heads|tails)$/i.test(args.outcome)) {
      /**
       * The command was ran with invalid parameters.
       * @fires commandUsage
       */
      return Bastion.emit('commandUsage', message, this.help);
    }

    args.money = parseInt(args.money);

    if (args.money < 5) {
      return message.channel.send({
        embed: {
          color: Bastion.colors.red,
          description: 'Minimum bet amount is 5 Bastion Currencies.'
        }
      }).catch(e => {
        Bastion.log.error(e.stack);
      });
    }

    let outcomes = [
      'Heads',
      'Tails'
    ];
    let outcome = outcomes[Math.floor(Math.random() * outcomes.length)];
    // let outcome = outcomes.random();

    Bastion.db.get(`SELECT bastionCurrencies FROM profiles WHERE userID=${message.author.id}`).then(profile => {
      if (args.money > profile.bastionCurrencies) {
        return message.channel.send({
          embed: {
            color: Bastion.colors.red,
            description: `Unfortunately, you can't bet. You only have **${profile.bastionCurrencies}** Bastion Currencies.`
          }
        }).catch(e => {
          Bastion.log.error(e.stack);
        });
      }

      recentUsers.push(message.author.id);

      let result;
      if (outcome.toLowerCase() === args.outcome.toLowerCase()) {
        let prize = args.money < 50 ? args.money + outcomes.length : args.money < 100 ? args.money : args.money * 1.5;
        result = `Congratulations! You won the bet.\nYou won **${prize}** Bastion Currencies.`;

        /**
         * User's account is debited with Bastion Currencies
         * @fires userDebit
         */
        Bastion.emit('userDebit', message.author, prize);
      }
      else {
        result = 'Sorry, you lost the bet. Better luck next time.';

        /**
         * User's account is credited with Bastion Currencies
         * @fires userCredit
         */
        Bastion.emit('userCredit', message.author, args.money);
      }

      message.channel.send({
        embed: {
          color: Bastion.colors.blue,
          title: `Flipped ${outcome}`,
          description: result
        }
      }).then(() => {
        setTimeout(function () {
          recentUsers.splice(recentUsers.indexOf(message.author.id), 1);
        }, 60 * 1000);
      }).catch(e => {
        Bastion.log.error(e.stack);
      });
    }).catch(e => {
      Bastion.log.error(e.stack);
    });
  }
  else {
    message.channel.send({
      embed: {
        color: Bastion.colors.red,
        description: `${message.author} you have gambled recently for this game, please wait at least 60 seconds before gambling again.`
      }
    }).catch(e => {
      Bastion.log.error(e.stack);
    });
  }
};

exports.config = {
  aliases: [ 'bf' ],
  enabled: true,
  argsDefinitions: [
    { name: 'outcome', type: String, alias: 'o', multiple: true, defaultOption: true },
    { name: 'money', type: Number, alias: 'm' }
  ]
};

exports.help = {
  name: 'betflip',
  description: 'Bets a specified amount of Bastion currency on prediction of the outcome of flipping a coin. If you win, you win more Bastion Currencies. If you lose, you lose the amount of currency you\'ve bet.',
  botPermission: '',
  userPermission: '',
  usage: 'betflip < heads/tails > <-m amount>',
  example: [ 'betflip heads -m 100' ]
};
<|endoftext|>


<commit_before>'use strict'

let co = require('co'),
	fs = require('fs-promise'),
	path = require('path'),
	express = require('express'),
	wrap = require('co-express'),
	bodyParser = require('body-parser'),
	requestLogger = require('morgan'),
	getAuthMiddleware = (passKey) => (req, res, next) => {
		if (req.header('X-Auth-Passkey') !== passKey) {
			return res.status(401).end()
		}
		next()
	}

class Migrations {
	constructor(config, db) {
		let instance = this

		this.config = config
		this.db = db

		this.app = express()
		this.router = express.Router()
		this.paths = ['/seed', '/sync', '/generateSeed', '/generateBackup']

		this.app.use(requestLogger(`[Migrations Module API] :method request to :url; result: :status; completed in: :response-time; :date`))
		this.app.use(bodyParser.json())

		this.router.get('/seed', wrap(function* (req, res, next) {
			try {
				res.json({data: yield instance.seed({
					seedFolder: req.query.seedFolder && decodeURIComponent(req.query.seedFolder) || instance.config.migrations.seedfilesFolder,
					seedFile: req.query.seedFile && decodeURIComponent(req.query.seedFile) || instance.config.migrations.defaultSeedfileName
				})})
			} catch (error) {
				req.locals = {error}
				next()
			}
		}))

		this.router.get('/sync', wrap(function* (req, res, next) {
			try {
				res.json({data: yield instance.sync()})
			} catch (error) {
				req.locals = {error}
				next()
			}
		}))

		this.router.get('/generateSeed', wrap(function* (req, res, next) {
			try {
				res.json({data: yield instance.generateSeed({
					seedFile: req.query.seedFile && decodeURIComponent(req.query.seedFile) || instance.config.migrations.defaultSeedfileName
				})})
			} catch (error) {
				req.locals = {error}
				next()
			}
		}))

		this.router.get('/generateBackup', wrap(function* (req, res, next) {
			try {
				res.json({data: yield instance.generateBackup()})
			} catch (error) {
				req.locals = {error}
				next()
			}
		}))

		this.app.use('/', this.router)
		this.app.use(this.paths, (req, res) => {
			if (req.locals && req.locals.error) {
				console.log(req.locals.error)
				return res.status(500).end()
			}
			res.status(200).end()
		})
	}

	getFullTableData() {
		try {
			let instance = this
			return co(function*() {
				let data = {},
					schemas = yield instance.db.sequelize.query('SELECT "t"."table_name" FROM "information_schema"."tables" AS "t" ' +
						'WHERE "t"."table_schema"=\'' + instance.config.db.schema + '\'')
				for (let i = 0; i < schemas[0].length; i++) {
					data[schemas[0][i].table_name] = (yield instance.db.sequelize.query('SELECT * FROM "' +
						instance.config.db.schema + '"."' + schemas[0][i].table_name + '"'))[0]
				}
				return data
			})
		} catch (e) {
			console.log(e)
		}
	}

	getTableLayout(t) {
		try {
			let instance = this
			return co(function*() {
				let data = {},
					schemas = yield instance.db.sequelize.query('SELECT "t"."table_name","c"."column_name" FROM "information_schema"."tables" AS "t" ' +
						'INNER JOIN "information_schema"."columns" AS "c" ON "t"."table_name"="c"."table_name"' +
						'WHERE "t"."table_schema"=\'' + instance.config.db.schema + '\'', {transaction: t})
				for (let i = 0; i < schemas[0].length; i++) {
					if (typeof(data[schemas[0][i].table_name]) === 'undefined') {
						data[schemas[0][i].table_name] = []
					}
					data[schemas[0][i].table_name].push(schemas[0][i].column_name)
				}
				return data
			})
		} catch (e) {
			console.log(e)
		}
	}

	runQueryFromColumnData(instance, tableName, c, inserts, queryInterface, deleteTableContents, t, dontSetIdSequence) {
		return co(function*() {
			if (inserts[tableName][c].values.length > 0) {
				console.log('Query series starting, rows to execute:', inserts[tableName][c].values.length)
				if (deleteTableContents.indexOf(tableName) !== -1) {
					yield instance.db.sequelize.query('DELETE FROM "' + tableName + '";', {transaction: t})
				}

				let queryTemplate = 'INSERT INTO "' + tableName + '" (',
					query = ''
				for (let i in inserts[tableName][c].columns) {
					queryTemplate += '"' + (queryInterface.escape(inserts[tableName][c].columns[i])).replace(/'/g, '') + '",'
				}
				queryTemplate = queryTemplate.substr(0, queryTemplate.length - 1)
				queryTemplate += ') VALUES '
				query += queryTemplate

				for (let i in inserts[tableName][c].values) {
					query += ' ('
					for (let j in inserts[tableName][c].values[i]) {
						query += inserts[tableName][c].values[i][j] + ','
					}
					query = query.substr(0, query.length - 1)
					query += ')'
					if (parseInt(i, 10) % 100 === 0) {
						query += ';'
						yield instance.db.sequelize.query(query, {transaction: t})
						query = '' + queryTemplate
						continue;
					}
					query += ','
				}
				if (query[query.length - 1] === ',') {
					query = query.substr(0, query.length - 1)
					query += ';'
					yield instance.db.sequelize.query(query, {transaction: t})
				}
				console.log('All queries executed successfully.')

				if (!dontSetIdSequence) {
					yield instance.db.sequelize.query('SELECT setval(\'"' + tableName + '_id_seq"\'::regclass, (SELECT "id" FROM "' + tableName + '" ORDER BY "id" DESC LIMIT 1))', {transaction: t})
				}
			}
		})
	}

	prepareColumnData(inserts, data, tableName, tableLayout, queryInterface) {
		for (let j = 0; j < data[tableName].length; j++) {
			let columns = [], values = []
			for (let column in data[tableName][j]) {
				if (tableLayout[tableName].indexOf(column) !== -1) {
					columns.push(column)
					if ((data[tableName][j][column] instanceof Object === true) && (typeof data[tableName][j][column].length === 'undefined')) {
						values.push(queryInterface.escape(JSON.stringify(data[tableName][j][column])))
						continue
					}
					values.push(queryInterface.escape(data[tableName][j][column]))
				}
			}
			let stringifiedColumns = JSON.stringify(columns)
			if (typeof(inserts[tableName][stringifiedColumns]) === 'undefined') {
				inserts[tableName][stringifiedColumns] = {columns: columns, values: []}
			}
			inserts[tableName][stringifiedColumns].values.push(values)
		}
	}

	insertData(data, options) {
		try {
			let instance = this
			return instance.db.sequelize.transaction(function (t) {
				return co(function*() {
					let queryInterface = instance.db.sequelize.getQueryInterface(),
						dbComponents = instance.db.components,
						models = Object.keys(dbComponents),
						inserts = {},
						noSync = options && options.noSync || false,
						deleteTableContents = options && options.deleteTableContents || []

					if (!noSync) {
						yield instance.db.sequelize.sync({force: true}, {transaction: t})
					}

					let tableLayout = yield instance.getTableLayout(t)

					//seed the main tables first
					for (let i = 0; i < instance.db.seedingOrder.length; i++) {
						let modelName = instance.db.seedingOrder[i],
							tableName = dbComponents[modelName].model.getTableName()
						if (data[tableName]) {
							if (!inserts[tableName]) {
								inserts[tableName] = {}
							}
							instance.prepareColumnData(inserts, data, tableName, tableLayout, queryInterface)
							delete data[tableName]
							delete models[modelName]
						}
					}
					for (let tableName in inserts) {
						for (let c in inserts[tableName]) {
							yield instance.runQueryFromColumnData(instance, tableName, c, inserts, queryInterface, deleteTableContents, t)
						}
					}
					inserts = {}

					//seed the rest of the tables from instance.db
					for (let i = 0; i < models.length; i++) {
						let modelName = models[i],
							tableName = dbComponents[modelName].model.getTableName()
						if (data[tableName]) {
							if (typeof(inserts[tableName]) === 'undefined') {
								inserts[tableName] = {}
							}
							instance.prepareColumnData(inserts, data, tableName, tableLayout, queryInterface)
							delete data[tableName]
						}
					}
					for (let tableName in inserts) {
						for (let c in inserts[tableName]) {
							yield instance.runQueryFromColumnData(instance, tableName, c, inserts, queryInterface, deleteTableContents, t)
						}
					}
					inserts = {}

					//seed the remaining data (junction tables and other tables without sequelize models)
					for (let tableName in data) {
						if (typeof(inserts[tableName]) === 'undefined') {
							inserts[tableName] = {}
						}
						instance.prepareColumnData(inserts, data, tableName, tableLayout, queryInterface)
					}
					for (let tableName in inserts) {
						for (let c in inserts[tableName]) {
							yield instance.runQueryFromColumnData(instance, tableName, c, inserts, queryInterface, deleteTableContents, t, true)
						}
					}

					return true
				})
			})
		} catch (e) {
			console.log(e)
		}
	}

	sync() {
		let instance = this
		return co(function*() {
			let data = yield instance.getFullTableData(),
				fileDescriptor = yield fs.open(path.join(instance.config.migrations.syncHistoryPath, `${(new Date()).getTime()}.json`), 'w'),
				bytesWritten = yield fs.write(fileDescriptor, JSON.stringify(data))
			return true
			yield fs.close(fileDescriptor)
			return {
				bytesWritten,
				success: yield instance.insertData(data)
			}
		})
	}

	seed({seedFolder, seedFile}) {
		let instance = this
		return co(function*() {
			return yield instance.insertData(JSON.parse((yield fs.readFile(path.join(instance.config.migrations.baseMigrationsPath, seedFolder, `${seedFile}.json`))).toString()))
		})
	}

	generateSeed({seedFile}) {
		let instance = this
		return co(function*() {
			console.log(instance.config.migrations.seedFilesPath)
			let seed = JSON.stringify(yield instance.getFullTableData()),
				now = new Date().getTime(),
				oldFilePath = path.join(instance.config.migrations.seedFilesPath, `${seedFile}_${now}.json`)
			try {
				//write a backup copy to preserve the old seed as history, then to the file that will be used for seeding
				let fileDescriptor = yield fs.open(oldFilePath, 'w')
				yield fs.write(fileDescriptor, (yield fs.readFile(path.join(instance.config.migrations.seedFilesPath, `${seedFile}.json`))).toString())
				yield fs.close(fileDescriptor)
			} catch (e) {
				yield fs.unlink(oldFilePath)
			}
			let newFileDescriptor = yield fs.open(path.join(instance.config.migrations.seedFilesPath, `${seedFile}.json`), 'w'),
			 	result = yield fs.write(newFileDescriptor, seed)
			yield fs.close(newFileDescriptor)
			return result
		})
	}

	generateBackup() {
		let instance = this
		return co(function*() {
			let seed = JSON.stringify(yield instance.getFullTableData()),
				now = new Date().getTime(),
				fileDescriptor = yield fs.open(path.join(instance.config.migrations.backupPath, `backup_${now}.json`), 'w'),
				result = yield fs.write(fileDescriptor, seed)
			yield fs.close(fileDescriptor)
			return result
		})
	}
}

module.exports = Migrations
<commit_msg>seed fix<commit_after>'use strict'

let co = require('co'),
	fs = require('fs-promise'),
	path = require('path'),
	express = require('express'),
	wrap = require('co-express'),
	bodyParser = require('body-parser'),
	requestLogger = require('morgan'),
	getAuthMiddleware = (passKey) => (req, res, next) => {
		if (req.header('X-Auth-Passkey') !== passKey) {
			return res.status(401).end()
		}
		next()
	}

class Migrations {
	constructor(config, db) {
		let instance = this

		this.config = config
		this.db = db

		this.app = express()
		this.router = express.Router()
		this.paths = ['/seed', '/sync', '/generateSeed', '/generateBackup']

		this.app.use(requestLogger(`[Migrations Module API] :method request to :url; result: :status; completed in: :response-time; :date`))
		this.app.use(bodyParser.json())

		this.router.get('/seed', wrap(function* (req, res, next) {
			try {
				res.json({data: yield instance.seed({
					seedFolder: req.query.seedFolder && decodeURIComponent(req.query.seedFolder) || instance.config.migrations.seedFilesFolder,
					seedFile: req.query.seedFile && decodeURIComponent(req.query.seedFile) || instance.config.migrations.defaultSeedfileName
				})})
			} catch (error) {
				req.locals = {error}
				next()
			}
		}))

		this.router.get('/sync', wrap(function* (req, res, next) {
			try {
				res.json({data: yield instance.sync()})
			} catch (error) {
				req.locals = {error}
				next()
			}
		}))

		this.router.get('/generateSeed', wrap(function* (req, res, next) {
			try {
				res.json({data: yield instance.generateSeed({
					seedFile: req.query.seedFile && decodeURIComponent(req.query.seedFile) || instance.config.migrations.defaultSeedfileName
				})})
			} catch (error) {
				req.locals = {error}
				next()
			}
		}))

		this.router.get('/generateBackup', wrap(function* (req, res, next) {
			try {
				res.json({data: yield instance.generateBackup()})
			} catch (error) {
				req.locals = {error}
				next()
			}
		}))

		this.app.use('/', this.router)
		this.app.use(this.paths, (req, res) => {
			if (req.locals && req.locals.error) {
				console.log(req.locals.error)
				return res.status(500).end()
			}
			res.status(200).end()
		})
	}

	getFullTableData() {
		try {
			let instance = this
			return co(function*() {
				let data = {},
					schemas = yield instance.db.sequelize.query('SELECT "t"."table_name" FROM "information_schema"."tables" AS "t" ' +
						'WHERE "t"."table_schema"=\'' + instance.config.db.schema + '\'')
				for (let i = 0; i < schemas[0].length; i++) {
					data[schemas[0][i].table_name] = (yield instance.db.sequelize.query('SELECT * FROM "' +
						instance.config.db.schema + '"."' + schemas[0][i].table_name + '"'))[0]
				}
				return data
			})
		} catch (e) {
			console.log(e)
		}
	}

	getTableLayout(t) {
		try {
			let instance = this
			return co(function*() {
				let data = {},
					schemas = yield instance.db.sequelize.query('SELECT "t"."table_name","c"."column_name" FROM "information_schema"."tables" AS "t" ' +
						'INNER JOIN "information_schema"."columns" AS "c" ON "t"."table_name"="c"."table_name"' +
						'WHERE "t"."table_schema"=\'' + instance.config.db.schema + '\'', {transaction: t})
				for (let i = 0; i < schemas[0].length; i++) {
					if (typeof(data[schemas[0][i].table_name]) === 'undefined') {
						data[schemas[0][i].table_name] = []
					}
					data[schemas[0][i].table_name].push(schemas[0][i].column_name)
				}
				return data
			})
		} catch (e) {
			console.log(e)
		}
	}

	runQueryFromColumnData(instance, tableName, c, inserts, queryInterface, deleteTableContents, t, dontSetIdSequence) {
		return co(function*() {
			if (inserts[tableName][c].values.length > 0) {
				console.log('Query series starting, rows to execute:', inserts[tableName][c].values.length)
				if (deleteTableContents.indexOf(tableName) !== -1) {
					yield instance.db.sequelize.query('DELETE FROM "' + tableName + '";', {transaction: t})
				}

				let queryTemplate = 'INSERT INTO "' + tableName + '" (',
					query = ''
				for (let i in inserts[tableName][c].columns) {
					queryTemplate += '"' + (queryInterface.escape(inserts[tableName][c].columns[i])).replace(/'/g, '') + '",'
				}
				queryTemplate = queryTemplate.substr(0, queryTemplate.length - 1)
				queryTemplate += ') VALUES '
				query += queryTemplate

				for (let i in inserts[tableName][c].values) {
					query += ' ('
					for (let j in inserts[tableName][c].values[i]) {
						query += inserts[tableName][c].values[i][j] + ','
					}
					query = query.substr(0, query.length - 1)
					query += ')'
					if (parseInt(i, 10) % 100 === 0) {
						query += ';'
						yield instance.db.sequelize.query(query, {transaction: t})
						query = '' + queryTemplate
						continue;
					}
					query += ','
				}
				if (query[query.length - 1] === ',') {
					query = query.substr(0, query.length - 1)
					query += ';'
					yield instance.db.sequelize.query(query, {transaction: t})
				}
				console.log('All queries executed successfully.')

				if (!dontSetIdSequence) {
					yield instance.db.sequelize.query('SELECT setval(\'"' + tableName + '_id_seq"\'::regclass, (SELECT "id" FROM "' + tableName + '" ORDER BY "id" DESC LIMIT 1))', {transaction: t})
				}
			}
		})
	}

	prepareColumnData(inserts, data, tableName, tableLayout, queryInterface) {
		for (let j = 0; j < data[tableName].length; j++) {
			let columns = [], values = []
			for (let column in data[tableName][j]) {
				if (tableLayout[tableName].indexOf(column) !== -1) {
					columns.push(column)
					if ((data[tableName][j][column] instanceof Object === true) && (typeof data[tableName][j][column].length === 'undefined')) {
						values.push(queryInterface.escape(JSON.stringify(data[tableName][j][column])))
						continue
					}
					values.push(queryInterface.escape(data[tableName][j][column]))
				}
			}
			let stringifiedColumns = JSON.stringify(columns)
			if (typeof(inserts[tableName][stringifiedColumns]) === 'undefined') {
				inserts[tableName][stringifiedColumns] = {columns: columns, values: []}
			}
			inserts[tableName][stringifiedColumns].values.push(values)
		}
	}

	insertData(data, options) {
		try {
			let instance = this
			return instance.db.sequelize.transaction(function (t) {
				return co(function*() {
					let queryInterface = instance.db.sequelize.getQueryInterface(),
						dbComponents = instance.db.components,
						models = Object.keys(dbComponents),
						inserts = {},
						noSync = options && options.noSync || false,
						deleteTableContents = options && options.deleteTableContents || []

					if (!noSync) {
						yield instance.db.sequelize.sync({force: true}, {transaction: t})
					}

					let tableLayout = yield instance.getTableLayout(t)

					//seed the main tables first
					for (let i = 0; i < instance.db.seedingOrder.length; i++) {
						let modelName = instance.db.seedingOrder[i],
							tableName = dbComponents[modelName].model.getTableName()
						if (data[tableName]) {
							if (!inserts[tableName]) {
								inserts[tableName] = {}
							}
							instance.prepareColumnData(inserts, data, tableName, tableLayout, queryInterface)
							delete data[tableName]
							delete models[modelName]
						}
					}
					for (let tableName in inserts) {
						for (let c in inserts[tableName]) {
							yield instance.runQueryFromColumnData(instance, tableName, c, inserts, queryInterface, deleteTableContents, t)
						}
					}
					inserts = {}

					//seed the rest of the tables from instance.db
					for (let i = 0; i < models.length; i++) {
						let modelName = models[i],
							tableName = dbComponents[modelName].model.getTableName()
						if (data[tableName]) {
							if (typeof(inserts[tableName]) === 'undefined') {
								inserts[tableName] = {}
							}
							instance.prepareColumnData(inserts, data, tableName, tableLayout, queryInterface)
							delete data[tableName]
						}
					}
					for (let tableName in inserts) {
						for (let c in inserts[tableName]) {
							yield instance.runQueryFromColumnData(instance, tableName, c, inserts, queryInterface, deleteTableContents, t)
						}
					}
					inserts = {}

					//seed the remaining data (junction tables and other tables without sequelize models)
					for (let tableName in data) {
						if (typeof(inserts[tableName]) === 'undefined') {
							inserts[tableName] = {}
						}
						instance.prepareColumnData(inserts, data, tableName, tableLayout, queryInterface)
					}
					for (let tableName in inserts) {
						for (let c in inserts[tableName]) {
							yield instance.runQueryFromColumnData(instance, tableName, c, inserts, queryInterface, deleteTableContents, t, true)
						}
					}

					return true
				})
			})
		} catch (e) {
			console.log(e)
		}
	}

	sync() {
		let instance = this
		return co(function*() {
			let data = yield instance.getFullTableData(),
				fileDescriptor = yield fs.open(path.join(instance.config.migrations.syncHistoryPath, `${(new Date()).getTime()}.json`), 'w'),
				bytesWritten = yield fs.write(fileDescriptor, JSON.stringify(data))
			return true
			yield fs.close(fileDescriptor)
			return {
				bytesWritten,
				success: yield instance.insertData(data)
			}
		})
	}

	seed({seedFolder, seedFile}) {
		let instance = this
		return co(function*() {
			return yield instance.insertData(JSON.parse((yield fs.readFile(path.join(instance.config.migrations.baseMigrationsPath, seedFolder, `${seedFile}.json`))).toString()))
		})
	}

	generateSeed({seedFile}) {
		let instance = this
		return co(function*() {
			let seed = JSON.stringify(yield instance.getFullTableData()),
				now = new Date().getTime(),
				oldFilePath = path.join(instance.config.migrations.seedFilesPath, `${seedFile}_${now}.json`)
			try {
				//write a backup copy to preserve the old seed as history, then to the file that will be used for seeding
				let fileDescriptor = yield fs.open(oldFilePath, 'w')
				yield fs.write(fileDescriptor, (yield fs.readFile(path.join(instance.config.migrations.seedFilesPath, `${seedFile}.json`))).toString())
				yield fs.close(fileDescriptor)
			} catch (e) {
				yield fs.unlink(oldFilePath)
			}
			let newFileDescriptor = yield fs.open(path.join(instance.config.migrations.seedFilesPath, `${seedFile}.json`), 'w'),
			 	result = yield fs.write(newFileDescriptor, seed)
			yield fs.close(newFileDescriptor)
			return result
		})
	}

	generateBackup() {
		let instance = this
		return co(function*() {
			let seed = JSON.stringify(yield instance.getFullTableData()),
				now = new Date().getTime(),
				fileDescriptor = yield fs.open(path.join(instance.config.migrations.backupPath, `backup_${now}.json`), 'w'),
				result = yield fs.write(fileDescriptor, seed)
			yield fs.close(fileDescriptor)
			return result
		})
	}
}

module.exports = Migrations
<|endoftext|>