<commit_before>const moment             = require('moment');
const CookieStorage      = require('./storage').CookieStorage;
const LocalStore         = require('./storage').LocalStore;
const State              = require('./storage').State;
const defaultRedirectUrl = require('./url').defaultRedirectUrl;
const getLoginToken      = require('../common_functions/common_functions').getLoginToken;
const jpClient           = require('../common_functions/country_base').jpClient;
const BinarySocket       = require('../websocket_pages/socket');
const RealityCheckData   = require('../websocket_pages/user/reality_check/reality_check.data');
const Cookies            = require('../../lib/js-cookie');

const Client = (() => {
    'use strict';

    const client_object = {};

    const parseLoginIDList = (string) => {
        if (!string) return [];
        return string.split('+').sort().map((str) => {
            const items = str.split(':');
            const id = items[0];
            const is_real = items[1] === 'R';
            const is_financial = /^MF/.test(id);
            const is_gaming = /^MLT/.test(id);

            if (is_real) client_object.has_real = is_real;
            if (is_financial) client_object.has_financial = is_financial;
            if (is_gaming) client_object.has_gaming = is_gaming;

            return {
                id           : id,
                real         : is_real,
                disabled     : items[2] === 'D',
                financial    : is_financial,
                non_financial: is_gaming,
            };
        });
    };

    const init = () => {
        client_object.loginid_array = parseLoginIDList(Cookies.get('loginid_list') || '');

        set('email',     Cookies.get('email'));
        set('loginid',   Cookies.get('loginid'));
        set('residence', Cookies.get('residence'));
    };

    const isLoggedIn = () => (
        get('tokens') &&
        getLoginToken() &&
        Cookies.get('loginid') &&
        client_object.loginid_array.length > 0
    );

    const validateLoginid = () => {
        const loginid_list = Cookies.get('loginid_list');
        const client_id    = Cookies.get('loginid');
        if (!client_id || !loginid_list) return;

        const valid_login_ids = new RegExp('^(MX|MF|VRTC|MLT|CR|FOG|VRTJ|JP)[0-9]+$', 'i');

        if (!valid_login_ids.test(client_id)) {
            sendLogoutRequest();
        }

        loginid_list.split('+').forEach((acc_id) => {
            if (!valid_login_ids.test(acc_id.split(':')[0])) {
                sendLogoutRequest();
            }
        });
    };

    const set = (key, value) => {
        client_object[key] = value;
        return LocalStore.set(`client.${key}`, value);
    };

    // use this function to get variables that have values
    const get = (key) => {
        let value = client_object[key] || LocalStore.get(`client.${key}`) || '';
        if (!Array.isArray(value) && (+value === 1 || +value === 0 || value === 'true' || value === 'false')) {
            value = JSON.parse(value || false);
        }
        return value;
    };

    const responseAuthorize = (response) => {
        const authorize = response.authorize;
        if (!Cookies.get('email')) {
            setCookie('email', authorize.email);
            set('email', authorize.email);
        }
        set('session_start', parseInt(moment().valueOf() / 1000));
        set('is_virtual', authorize.is_virtual);
        set('landing_company_name', authorize.landing_company_name);
        set('landing_company_fullname', authorize.landing_company_fullname);
        setCurrency(authorize.currency);
    };

    const shouldAcceptTnc = () => {
        if (get('is_virtual')) return false;
        const website_tnc_version = State.get(['response', 'website_status', 'website_status', 'terms_conditions_version']);
        const get_settings = State.get(['response', 'get_settings', 'get_settings']);
        return get_settings.hasOwnProperty('client_tnc_status') && get_settings.client_tnc_status !== website_tnc_version;
    };

    const clear = () => {
        // clear all client values from local storage
        Object.keys(localStorage).forEach((c) => {
            if (/^client\.(?!(tokens$))/.test(c)) {
                LocalStore.set(c, '');
            }
        });
        const hash = window.location.hash;
        if (/no-reality-check/.test(hash)) {
            window.location.hash = hash.replace('no-reality-check', '');
        }
    };

    const getToken = (client_loginid) => {
        let token;
        const tokens = get('tokens');
        if (client_loginid && tokens) {
            const tokens_obj = JSON.parse(tokens);
            if (tokens_obj.hasOwnProperty(client_loginid) && tokens_obj[client_loginid]) {
                token = tokens_obj[client_loginid].token;
            }
        }
        return token;
    };

    const addToken = (client_loginid, token) => {
        if (!client_loginid || !token || getToken(client_loginid)) {
            return false;
        }
        const tokens = get('tokens');
        const tokens_obj = tokens && tokens.length > 0 ? JSON.parse(tokens) : {};
        tokens_obj[client_loginid] = { token: token, currency: '' };
        set('tokens', JSON.stringify(tokens_obj));
        return true;
    };

    const setCookie = (cookie_name, Value, domain) => {
        const cookie_expire = new Date();
        cookie_expire.setDate(cookie_expire.getDate() + 60);
        const cookie = new CookieStorage(cookie_name, domain);
        cookie.write(Value, cookie_expire, true);
    };

    const processNewAccount = (client_email, client_loginid, token, virtual_client) => {
        if (!client_email || !client_loginid || !token) {
            return;
        }
        // save token
        addToken(client_loginid, token);
        // set cookies
        setCookie('email',        client_email);
        setCookie('login',        token);
        setCookie('loginid',      client_loginid);
        setCookie('loginid_list', virtual_client ? `${client_loginid}:V:E` : `${client_loginid}:R:E+${Cookies.get('loginid_list')}`);
        // set local storage
        localStorage.setItem('GTM_new_account', '1');
        localStorage.setItem('active_loginid', client_loginid);
        RealityCheckData.clear();
        window.location.href = defaultRedirectUrl(); // need to redirect not using pjax
    };

    const hasShortCode = (data, code) => ((data || {}).shortcode === code);

    const canUpgradeGamingToFinancial = data => (hasShortCode(data.financial_company, 'maltainvest'));

    const canUpgradeVirtualToFinancial = data => (!data.gaming_company && hasShortCode(data.financial_company, 'maltainvest'));

    const canUpgradeVirtualToJapan = data => (!data.gaming_company && hasShortCode(data.financial_company, 'japan'));

    const hasGamingFinancialEnabled = () => {
        let has_financial = false,
            has_gaming = false;

        client_object.loginid_array.forEach((client) => {
            if (!client.disabled) {
                if (client.financial) {
                    has_financial = true;
                } else if (client.non_financial) {
                    has_gaming = true;
                }
            }
        });

        return has_gaming && has_financial;
    };

    const activateByClientType = (section = 'body') => {
        if (isLoggedIn()) {
            BinarySocket.wait('authorize', 'website_status').then(() => {
                $('#client-logged-in').addClass('gr-centered');
                $('.client_logged_in').setVisibility(1);
                if (get('is_virtual')) {
                    $(section).find('.client_virtual').setVisibility(1);
                    $('#topbar').addClass('secondary-bg-color').removeClass('primary-color-dark');
                } else {
                    $(section).find('.client_real').not((jpClient() ? '.ja-hide' : '')).setVisibility(1);
                    $('#topbar').addClass('primary-color-dark').removeClass('secondary-bg-color');
                }
            });
        } else {
            $(section).find('.client_logged_out').setVisibility(1);
            $('#topbar').addClass('primary-color-dark').removeClass('secondary-bg-color');
        }
    };

    const sendLogoutRequest = (show_login_page) => {
        if (show_login_page) {
            sessionStorage.setItem('showLoginPage', 1);
        }
        BinarySocket.send({ logout: '1' });
    };

    const doLogout = (response) => {
        if (response.logout !== 1) return;
        clear();
        LocalStore.remove('client.tokens');
        const cookies = ['login', 'loginid', 'loginid_list', 'email', 'settings', 'reality_check', 'affiliate_token', 'affiliate_tracking', 'residence'];
        const domains = [
            `.${document.domain.split('.').slice(-2).join('.')}`,
            `.${document.domain}`,
        ];

        let parent_path = window.location.pathname.split('/', 2)[1];
        if (parent_path !== '') {
            parent_path = `/${parent_path}`;
        }

        cookies.forEach((c) => {
            const regex = new RegExp(c);
            Cookies.remove(c, { path: '/', domain: domains[0] });
            Cookies.remove(c, { path: '/', domain: domains[1] });
            Cookies.remove(c);
            if (regex.test(document.cookie) && parent_path) {
                Cookies.remove(c, { path: parent_path, domain: domains[0] });
                Cookies.remove(c, { path: parent_path, domain: domains[1] });
                Cookies.remove(c, { path: parent_path });
            }
        });
        window.location.reload();
    };

    const currentLandingCompany = () => {
        const landing_company_response = State.get(['response', 'landing_company', 'landing_company']) || {};
        let client_landing_company = {};
        Object.keys(landing_company_response).forEach((key) => {
            if (client_object.landing_company_name === landing_company_response[key].shortcode) {
                client_landing_company = landing_company_response[key];
            }
        });
        return client_landing_company;
    };

    const isFinancial = () => (client_object.loginid_array.find(obj => (obj.id === get('loginid'))) || {}).financial;

    const shouldCompleteTax = () => isFinancial() && !/crs_tin_information/.test((State.get(['response', 'get_account_status', 'get_account_status']) || {}).status);

    const getMT5AccountType = group => (group ? group.replace('\\', '_') : '');

    const setCurrency = (currency) => {
        const tokens = get('tokens');
        const tokens_obj = tokens && tokens.length > 0 ? JSON.parse(tokens) : {};
        const loginid = tokens_obj[get('loginid')];
        if (!loginid.currency) {
            loginid.currency = currency;
            set('tokens', JSON.stringify(tokens_obj));
        }
        set('currency', currency);
    };

    return {
        init             : init,
        validateLoginid  : validateLoginid,
        set              : set,
        get              : get,
        responseAuthorize: responseAuthorize,
        shouldAcceptTnc  : shouldAcceptTnc,
        clear            : clear,
        getToken         : getToken,
        setCookie        : setCookie,
        processNewAccount: processNewAccount,
        isLoggedIn       : isLoggedIn,
        sendLogoutRequest: sendLogoutRequest,
        doLogout         : doLogout,
        isFinancial      : isFinancial,
        shouldCompleteTax: shouldCompleteTax,
        getMT5AccountType: getMT5AccountType,
        setCurrency      : setCurrency,

        canUpgradeGamingToFinancial : canUpgradeGamingToFinancial,
        canUpgradeVirtualToFinancial: canUpgradeVirtualToFinancial,
        canUpgradeVirtualToJapan    : canUpgradeVirtualToJapan,
        hasGamingFinancialEnabled   : hasGamingFinancialEnabled,
        activateByClientType        : activateByClientType,
        currentLandingCompany       : currentLandingCompany,
    };
})();

module.exports = Client;
<commit_msg>Backward compatibility for client.tokens<commit_after>const moment             = require('moment');
const CookieStorage      = require('./storage').CookieStorage;
const LocalStore         = require('./storage').LocalStore;
const State              = require('./storage').State;
const defaultRedirectUrl = require('./url').defaultRedirectUrl;
const getPropertyValue   = require('./utility').getPropertyValue;
const getLoginToken      = require('../common_functions/common_functions').getLoginToken;
const jpClient           = require('../common_functions/country_base').jpClient;
const BinarySocket       = require('../websocket_pages/socket');
const RealityCheckData   = require('../websocket_pages/user/reality_check/reality_check.data');
const Cookies            = require('../../lib/js-cookie');

const Client = (() => {
    'use strict';

    const client_object = {};

    const parseLoginIDList = (string) => {
        if (!string) return [];
        return string.split('+').sort().map((str) => {
            const items = str.split(':');
            const id = items[0];
            const is_real = items[1] === 'R';
            const is_financial = /^MF/.test(id);
            const is_gaming = /^MLT/.test(id);

            if (is_real) client_object.has_real = is_real;
            if (is_financial) client_object.has_financial = is_financial;
            if (is_gaming) client_object.has_gaming = is_gaming;

            return {
                id           : id,
                real         : is_real,
                disabled     : items[2] === 'D',
                financial    : is_financial,
                non_financial: is_gaming,
            };
        });
    };

    const init = () => {
        client_object.loginid_array = parseLoginIDList(Cookies.get('loginid_list') || '');

        set('email',     Cookies.get('email'));
        set('loginid',   Cookies.get('loginid'));
        set('residence', Cookies.get('residence'));

        backwardCompatibility();
    };

    const isLoggedIn = () => (
        get('tokens') &&
        getLoginToken() &&
        Cookies.get('loginid') &&
        client_object.loginid_array.length > 0
    );

    const validateLoginid = () => {
        const loginid_list = Cookies.get('loginid_list');
        const client_id    = Cookies.get('loginid');
        if (!client_id || !loginid_list) return;

        const valid_login_ids = new RegExp('^(MX|MF|VRTC|MLT|CR|FOG|VRTJ|JP)[0-9]+$', 'i');

        if (!valid_login_ids.test(client_id)) {
            sendLogoutRequest();
        }

        loginid_list.split('+').forEach((acc_id) => {
            if (!valid_login_ids.test(acc_id.split(':')[0])) {
                sendLogoutRequest();
            }
        });
    };

    const set = (key, value) => {
        client_object[key] = value;
        return LocalStore.set(`client.${key}`, value);
    };

    // use this function to get variables that have values
    const get = (key) => {
        let value = client_object[key] || LocalStore.get(`client.${key}`) || '';
        if (!Array.isArray(value) && (+value === 1 || +value === 0 || value === 'true' || value === 'false')) {
            value = JSON.parse(value || false);
        }
        return value;
    };

    const responseAuthorize = (response) => {
        const authorize = response.authorize;
        if (!Cookies.get('email')) {
            setCookie('email', authorize.email);
            set('email', authorize.email);
        }
        set('session_start', parseInt(moment().valueOf() / 1000));
        set('is_virtual', authorize.is_virtual);
        set('landing_company_name', authorize.landing_company_name);
        set('landing_company_fullname', authorize.landing_company_fullname);
        setCurrency(authorize.currency);
    };

    const shouldAcceptTnc = () => {
        if (get('is_virtual')) return false;
        const website_tnc_version = State.get(['response', 'website_status', 'website_status', 'terms_conditions_version']);
        const get_settings = State.get(['response', 'get_settings', 'get_settings']);
        return get_settings.hasOwnProperty('client_tnc_status') && get_settings.client_tnc_status !== website_tnc_version;
    };

    const clear = () => {
        // clear all client values from local storage
        Object.keys(localStorage).forEach((c) => {
            if (/^client\.(?!(tokens$))/.test(c)) {
                LocalStore.set(c, '');
            }
        });
        const hash = window.location.hash;
        if (/no-reality-check/.test(hash)) {
            window.location.hash = hash.replace('no-reality-check', '');
        }
    };

    const getAccountObj = client_loginid => (getPropertyValue(JSON.parse(get('tokens') || '{}'), [client_loginid]) || {});

    const getToken = client_loginid => getPropertyValue(getAccountObj(client_loginid), ['token']);

    const setCurrency = (currency) => {
        const tokens = get('tokens');
        const tokens_obj = tokens && tokens.length > 0 ? JSON.parse(tokens) : {};
        const account_obj = tokens_obj[get('loginid')];
        if (!account_obj.currency) {
            account_obj.currency = currency;
            set('tokens', JSON.stringify(tokens_obj));
        }
        set('currency', currency);
    };

    const backwardCompatibility = () => {
        // upgrade client.tokens structure to the new one (for clients which already are logged-in with the old version)
        const account_obj = getAccountObj(get('loginid'));
        if (typeof account_obj !== 'object') {
            const tokens = get('tokens');
            const tokens_obj = tokens && tokens.length > 0 ? JSON.parse(tokens) : {};
            Object.keys(tokens_obj).forEach((loginid) => {
                tokens_obj[loginid] = { token: tokens_obj[loginid] };
            });
            set('tokens', JSON.stringify(tokens_obj));
        }
    };

    const addToken = (client_loginid, token) => {
        if (!client_loginid || !token || getToken(client_loginid)) {
            return false;
        }
        const tokens = get('tokens');
        const tokens_obj = tokens && tokens.length > 0 ? JSON.parse(tokens) : {};
        tokens_obj[client_loginid] = { token: token, currency: '' };
        set('tokens', JSON.stringify(tokens_obj));
        return true;
    };

    const setCookie = (cookie_name, Value, domain) => {
        const cookie_expire = new Date();
        cookie_expire.setDate(cookie_expire.getDate() + 60);
        const cookie = new CookieStorage(cookie_name, domain);
        cookie.write(Value, cookie_expire, true);
    };

    const processNewAccount = (client_email, client_loginid, token, virtual_client) => {
        if (!client_email || !client_loginid || !token) {
            return;
        }
        // save token
        addToken(client_loginid, token);
        // set cookies
        setCookie('email',        client_email);
        setCookie('login',        token);
        setCookie('loginid',      client_loginid);
        setCookie('loginid_list', virtual_client ? `${client_loginid}:V:E` : `${client_loginid}:R:E+${Cookies.get('loginid_list')}`);
        // set local storage
        localStorage.setItem('GTM_new_account', '1');
        localStorage.setItem('active_loginid', client_loginid);
        RealityCheckData.clear();
        window.location.href = defaultRedirectUrl(); // need to redirect not using pjax
    };

    const hasShortCode = (data, code) => ((data || {}).shortcode === code);

    const canUpgradeGamingToFinancial = data => (hasShortCode(data.financial_company, 'maltainvest'));

    const canUpgradeVirtualToFinancial = data => (!data.gaming_company && hasShortCode(data.financial_company, 'maltainvest'));

    const canUpgradeVirtualToJapan = data => (!data.gaming_company && hasShortCode(data.financial_company, 'japan'));

    const hasGamingFinancialEnabled = () => {
        let has_financial = false,
            has_gaming = false;

        client_object.loginid_array.forEach((client) => {
            if (!client.disabled) {
                if (client.financial) {
                    has_financial = true;
                } else if (client.non_financial) {
                    has_gaming = true;
                }
            }
        });

        return has_gaming && has_financial;
    };

    const activateByClientType = (section = 'body') => {
        if (isLoggedIn()) {
            BinarySocket.wait('authorize', 'website_status').then(() => {
                $('#client-logged-in').addClass('gr-centered');
                $('.client_logged_in').setVisibility(1);
                if (get('is_virtual')) {
                    $(section).find('.client_virtual').setVisibility(1);
                    $('#topbar').addClass('secondary-bg-color').removeClass('primary-color-dark');
                } else {
                    $(section).find('.client_real').not((jpClient() ? '.ja-hide' : '')).setVisibility(1);
                    $('#topbar').addClass('primary-color-dark').removeClass('secondary-bg-color');
                }
            });
        } else {
            $(section).find('.client_logged_out').setVisibility(1);
            $('#topbar').addClass('primary-color-dark').removeClass('secondary-bg-color');
        }
    };

    const sendLogoutRequest = (show_login_page) => {
        if (show_login_page) {
            sessionStorage.setItem('showLoginPage', 1);
        }
        BinarySocket.send({ logout: '1' });
    };

    const doLogout = (response) => {
        if (response.logout !== 1) return;
        clear();
        LocalStore.remove('client.tokens');
        const cookies = ['login', 'loginid', 'loginid_list', 'email', 'settings', 'reality_check', 'affiliate_token', 'affiliate_tracking', 'residence'];
        const domains = [
            `.${document.domain.split('.').slice(-2).join('.')}`,
            `.${document.domain}`,
        ];

        let parent_path = window.location.pathname.split('/', 2)[1];
        if (parent_path !== '') {
            parent_path = `/${parent_path}`;
        }

        cookies.forEach((c) => {
            const regex = new RegExp(c);
            Cookies.remove(c, { path: '/', domain: domains[0] });
            Cookies.remove(c, { path: '/', domain: domains[1] });
            Cookies.remove(c);
            if (regex.test(document.cookie) && parent_path) {
                Cookies.remove(c, { path: parent_path, domain: domains[0] });
                Cookies.remove(c, { path: parent_path, domain: domains[1] });
                Cookies.remove(c, { path: parent_path });
            }
        });
        window.location.reload();
    };

    const currentLandingCompany = () => {
        const landing_company_response = State.get(['response', 'landing_company', 'landing_company']) || {};
        let client_landing_company = {};
        Object.keys(landing_company_response).forEach((key) => {
            if (client_object.landing_company_name === landing_company_response[key].shortcode) {
                client_landing_company = landing_company_response[key];
            }
        });
        return client_landing_company;
    };

    const isFinancial = () => (client_object.loginid_array.find(obj => (obj.id === get('loginid'))) || {}).financial;

    const shouldCompleteTax = () => isFinancial() && !/crs_tin_information/.test((State.get(['response', 'get_account_status', 'get_account_status']) || {}).status);

    const getMT5AccountType = group => (group ? group.replace('\\', '_') : '');

    return {
        init             : init,
        validateLoginid  : validateLoginid,
        set              : set,
        get              : get,
        responseAuthorize: responseAuthorize,
        shouldAcceptTnc  : shouldAcceptTnc,
        clear            : clear,
        getToken         : getToken,
        setCurrency      : setCurrency,
        setCookie        : setCookie,
        processNewAccount: processNewAccount,
        isLoggedIn       : isLoggedIn,
        sendLogoutRequest: sendLogoutRequest,
        doLogout         : doLogout,
        isFinancial      : isFinancial,
        shouldCompleteTax: shouldCompleteTax,
        getMT5AccountType: getMT5AccountType,

        canUpgradeGamingToFinancial : canUpgradeGamingToFinancial,
        canUpgradeVirtualToFinancial: canUpgradeVirtualToFinancial,
        canUpgradeVirtualToJapan    : canUpgradeVirtualToJapan,
        hasGamingFinancialEnabled   : hasGamingFinancialEnabled,
        activateByClientType        : activateByClientType,
        currentLandingCompany       : currentLandingCompany,
    };
})();

module.exports = Client;
<|endoftext|>


<commit_before>var React = require('react');
var Link = require('react-router').Link

var SideNav = React.createClass({

  componentDidMount () {
    $(".button-collapse").sideNav({
      menuWidth: 200,
      closeOnClick: true
    });
  },

  render: function(){
    var navArray = this.props.navArray;
    var NavItems = navArray.map(function(elem) {
      return (
<Link to={elem.url}>{elem.name}{elem.icon}</Link>
);
    });

    return (

<Link to='/' className="logo-our">{this.props.interface}</Link>

            {NavItems}

    );
  }
});

module.exports = SideNav;
<commit_msg>And this... #67<commit_after>var React = require('react');
var Link = require('react-router').Link

var SideNav = React.createClass({

  componentDidMount () {
    $(".button-collapse").sideNav({
      menuWidth: 200,
      closeOnClick: true
    });
  },

  render: function(){
    var navArray = this.props.navArray;
    var NavItems = navArray.map(function(elem) {
      return (
<Link to={elem.url}>{elem.name}{elem.icon}</Link>
);
    });

    return (

<Link to='/' className="logo-our">{this.props.interface}</Link>

            {NavItems}

<Link to='/' className="logo-our">{this.props.interface}</Link>

            {NavItems}

    );
  }
});

module.exports = SideNav;
<|endoftext|>


<commit_before>angular
    .module('teamform')
    .controller("DashboardCtrl", ['$scope', 'Events', 'Auth', 'Teams', '$stateParams', '$timeout', '$state', DashboardCtrl]);

function DashboardCtrl($scope, Events, Auth, Teams, $stateParams, $timeout, $state) {

    var uid = Auth.$getAuth().uid;
    $scope.events = Events.arr();

    $scope.tickInterval = 1000 //ms

    var tick = function() {
        $scope.dateTime = Date.now() // get the current time
        $timeout(tick, $scope.tickInterval); // reset the timer
    }

    // Start the timer
    $timeout(tick, $scope.tickInterval);
}
<commit_msg>add ";"<commit_after>angular
    .module('teamform')
    .controller("DashboardCtrl", ['$scope', 'Events', 'Auth', 'Teams', '$stateParams', '$timeout', '$state', DashboardCtrl]);

function DashboardCtrl($scope, Events, Auth, Teams, $stateParams, $timeout, $state) {

    var uid = Auth.$getAuth().uid;
    $scope.events = Events.arr();

    $scope.tickInterval = 1000; //ms

    var tick = function() {
        $scope.dateTime = Date.now(); // get the current time
        $timeout(tick, $scope.tickInterval); // reset the timer
    };

    // Start the timer
    $timeout(tick, $scope.tickInterval);
}
<|endoftext|>


<commit_before>YUI.add("model-timeline-base", function(Y) {
    "use strict";

    var models = Y.namespace("Falco.Models"),

        TimelineBase;

    TimelineBase = Y.Base.create("timeline", Y.Model, [], {
        initializer : function(config) {
            var tweets;

            config || (config = {});

            tweets = new models.Tweets({
                items : config.tweets || []
            });

            this.set("tweets", tweets);

            this._handles = [
                tweets.after([ "more", "add" ], this._tweetAdd, this)
            ];

            this.publish("tweets", { preventable : false });
        },

        destructor : function() {
            new Y.EventTarget(this._handles).detach();

            this._handles = null;

            this.get("tweets").destroy();
        },

        // Override .toJSON() to make sure tweets are included
        toJSON : function() {
            var json = TimelineBase.superclass.toJSON.apply(this);

            json.tweets = json.tweets.toJSON();

            return json;
        },

        _tweetAdd : function(e) {
            var count = 1;

            // Don't notify for tweets from cache
            if(e.cached) {
                return;
            }

            if(e.response || e.models) {
                count = (e.response || e.models).length;
            }

            this.fire("tweets", {
                count : count
            });
        }
    });

    models.TimelineBase = TimelineBase;

}, "@VERSION@", {
    requires : [
        // YUI
        "base-build",
        "model",

        // Models
        "model-list-tweets"
    ]
});
<commit_msg>Fix counts for search timeline updates<commit_after>YUI.add("model-timeline-base", function(Y) {
    "use strict";

    var models = Y.namespace("Falco.Models"),

        TimelineBase;

    TimelineBase = Y.Base.create("timeline", Y.Model, [], {
        initializer : function(config) {
            var tweets;

            config || (config = {});

            tweets = new models.Tweets({
                items : config.tweets || []
            });

            this.set("tweets", tweets);

            this._handles = [
                tweets.after([ "more", "add" ], this._tweetAdd, this)
            ];

            this.publish("tweets", { preventable : false });
        },

        destructor : function() {
            new Y.EventTarget(this._handles).detach();

            this._handles = null;

            this.get("tweets").destroy();
        },

        // Override .toJSON() to make sure tweets are included
        toJSON : function() {
            var json = TimelineBase.superclass.toJSON.apply(this);

            json.tweets = json.tweets.toJSON();

            return json;
        },

        _tweetAdd : function(e) {
            var count = 1;

            // Don't notify for tweets from cache
            if(e.cached) {
                return;
            }

            if(e.parsed || e.models) {
                count = (e.parsed || e.models).length;
            }

            this.fire("tweets", {
                count : count
            });
        }
    });

    models.TimelineBase = TimelineBase;

}, "@VERSION@", {
    requires : [
        // YUI
        "base-build",
        "model",

        // Models
        "model-list-tweets"
    ]
});
<|endoftext|>


<commit_before>import React from 'react'
import Header from '../../components/Header'
import '../styles/index.scss'

// export const CoreLayout = ({ children }) => (
//

//
//

//       {children}
//

//

// )

class CoreLayout extends React.Component {

  render () {
    return (

        {this.props.children}

    )
  }
}

CoreLayout.propTypes = {
  children : React.PropTypes.element.isRequired
}

export default CoreLayout
<commit_msg>Remove relative-position class<commit_after>import React from 'react'
import Header from '../../components/Header'
import '../styles/index.scss'

// export const CoreLayout = ({ children }) => (
//

//
//

//       {children}
//

//

// )

class CoreLayout extends React.Component {

  render () {
    return (

        {this.props.children}

    )
  }
}

CoreLayout.propTypes = {
  children : React.PropTypes.element.isRequired
}

export default CoreLayout
<|endoftext|>


<commit_before>/**
 * This is a wrapper around the interface for the LMDB.
 * It manages the access to a single table/object store.
 * @implements {IBackend}
 * @implements {ISynchronousObjectStore}
 */
class LMDBBackend extends LMDBBaseBackend {
    /**
     * Creates a wrapper given a JungleDB, the table's name, the database directory and an encoding.
     * @param {JungleDB} db The JungleDB object managing the connection.
     * @param {string} tableName The table name this object store represents.
     * @param {ICodec} [codec] A default codec for the object store.
     * @param {object} [options] Advanced options.
     */
    constructor(db, tableName, codec = null, options = {}) {
        super(db, tableName, codec, options);

        /** @type {Map.<string,PersistentIndex>} */
        this._indices = new Map();
        this._indicesToCreate = new Map();
        this._indicesToDelete = [];
    }

    /**
     * A map of index names to indices.
     * The index names can be used to access an index.
     * @type {Map.<string,IIndex>}
     */
    get indices() {
        return this._indices;
    }

    /**
     * Initialises the persisted indices of the object store.
     * @param {number} oldVersion
     * @param {number} newVersion
     * @returns {Array.<PersistentIndex>} The list of indices.
     */
    init(oldVersion, newVersion) {
        super.init(oldVersion, newVersion);

        // Delete indices.
        for (const { indexName, upgradeCondition } of this._indicesToDelete) {
            if (upgradeCondition === null || upgradeCondition === true || (typeof upgradeCondition === 'function' && upgradeCondition(oldVersion, newVersion))) {
                const index = new PersistentIndex(this, indexName, '');
                LMDBBaseBackend.truncate(this._env, index.tableName);
            }
        }
        this._indicesToDelete = [];

        const indices = [];
        for (const [indexName, { index, upgradeCondition }] of this._indicesToCreate) {
            indices.push(index.init(oldVersion, newVersion, upgradeCondition));
        }
        return indices;
    }

    /**
     * Returns the object stored under the given primary key.
     * Resolves to undefined if the key is not present in the object store.
     * @param {string} key The primary key to look for.
     * @returns {*} The object stored under the given key, or undefined if not present.
     */
    getSync(key) {
        const txn = this._env.beginTxn({ readOnly: true });
        const value = this._get(txn, key);
        txn.commit();
        return value;
    }

    /**
     * A check whether a certain key is cached.
     * @param {string} key The key to check.
     * @return {boolean} A boolean indicating whether the key is already in the cache.
     */
    isCached(key) {
        return true;
    }

    /**
     * Returns a promise of the object stored under the given primary key.
     * Resolves to undefined if the key is not present in the object store.
     * @param {string} key The primary key to look for.
     * @returns {Promise.<*>} A promise of the object stored under the given key, or undefined if not present.
     */
    async get(key) {
        return this.getSync(key);
    }

    /**
     * Returns a promise of an array of objects whose primary keys fulfill the given query.
     * If the optional query is not given, it returns all objects in the object store.
     * If the query is of type KeyRange, it returns all objects whose primary keys are within this range.
     * If the query is of type Query, it returns all objects whose primary keys fulfill the query.
     * @param {Query|KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<Array.<*>>} A promise of the array of objects relevant to the query.
     */
    async values(query=null) {
        if (query !== null && query instanceof Query) {
            return query.values(this);
        }

        let result = [];
        this._readStream((value, key) => {
            result.push(value);
        }, true, query);
        return result;
    }

    /**
     * Returns a promise of a set of keys fulfilling the given query.
     * If the optional query is not given, it returns all keys in the object store.
     * If the query is of type KeyRange, it returns all keys of the object store being within this range.
     * If the query is of type Query, it returns all keys fulfilling the query.
     * @param {Query|KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<Set.<string>>} A promise of the set of keys relevant to the query.
     */
    async keys(query = null) {
        if (query !== null && query instanceof Query) {
            return query.keys(this);
        }
        let resultSet = new Set();
        this._readStream((value, key) => {
            resultSet.add(key);
        }, true, query, true);
        return resultSet;
    }

    /**
     * Iterates over the keys in a given range and direction.
     * The callback is called for each primary key fulfilling the query
     * until it returns false and stops the iteration.
     * @param {function(key:string):boolean} callback A predicate called for each key until returning false.
     * @param {boolean} ascending Determines the direction of traversal.
     * @param {KeyRange} query An optional KeyRange to narrow down the iteration space.
     * @returns {Promise} The promise resolves after all elements have been streamed.
     */
    async keyStream(callback, ascending=true, query=null) {
        this._readStream((value, key) => {
            return callback(key);
        }, ascending, query, true);
    }

    /**
     * Iterates over the keys and values in a given range and direction.
     * The callback is called for each value and primary key fulfilling the query
     * until it returns false and stops the iteration.
     * @param {function(value:*, key:string):boolean} callback A predicate called for each value and key until returning false.
     * @param {boolean} ascending Determines the direction of traversal.
     * @param {KeyRange} query An optional KeyRange to narrow down the iteration space.
     * @returns {Promise} The promise resolves after all elements have been streamed.
     */
    async valueStream(callback, ascending=true, query=null) {
        this._readStream((value, key) => {
            return callback(value, key);
        }, ascending, query);
    }

    /**
     * Returns a promise of the object whose primary key is maximal for the given range.
     * If the optional query is not given, it returns the object whose key is maximal.
     * If the query is of type KeyRange, it returns the object whose primary key is maximal for the given range.
     * @param {KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<*>} A promise of the object relevant to the query.
     */
    async maxValue(query=null) {
        let maxValue = null;
        this._readStream((value, key) => {
            maxValue = value;
            return false;
        }, false, query);
        return maxValue;
    }

    /**
     * Returns a promise of the key being maximal for the given range.
     * If the optional query is not given, it returns the maximal key.
     * If the query is of type KeyRange, it returns the key being maximal for the given range.
     * @param {KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<string>} A promise of the key relevant to the query.
     */
    async maxKey(query=null) {
        let maxKey = null;
        this._readStream((value, key) => {
            maxKey = key;
            return false;
        }, false, query, true);
        return maxKey;
    }

    /**
     * Returns a promise of the object whose primary key is minimal for the given range.
     * If the optional query is not given, it returns the object whose key is minimal.
     * If the query is of type KeyRange, it returns the object whose primary key is minimal for the given range.
     * @param {KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<*>} A promise of the object relevant to the query.
     */
    async minValue(query=null) {
        let minValue = null;
        this._readStream((value, key) => {
            minValue = value;
            return false;
        }, true, query);
        return minValue;
    }

    /**
     * Returns a promise of the key being minimal for the given range.
     * If the optional query is not given, it returns the minimal key.
     * If the query is of type KeyRange, it returns the key being minimal for the given range.
     * @param {KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<string>} A promise of the key relevant to the query.
     */
    async minKey(query=null) {
        let minKey = null;
        this._readStream((value, key) => {
            minKey = key;
            return false;
        }, true, query, true);
        return minKey;
    }

    /**
     * Returns the count of entries in the given range.
     * If the optional query is not given, it returns the count of entries in the object store.
     * If the query is of type KeyRange, it returns the count of entries within the given range.
     * @param {KeyRange} [query]
     * @returns {Promise.<number>}
     */
    async count(query=null) {
        let i = 0;
        this._readStream((value, key) => {
            i++;
        }, true, query, true);
        return i;
    }

    /**
     * Returns the index of the given name.
     * If the index does not exist, it returns undefined.
     * @param {string} indexName The name of the requested index.
     * @returns {IIndex} The index associated with the given name.
     */
    index(indexName) {
        return this._indices.get(indexName);
    }

    /**
     * Internally applies a transaction to the store's state.
     * This needs to be done in batch (as a db level transaction), i.e., either the full state is updated
     * or no changes are applied.
     * @param {EncodedLMDBTransaction} tx The transaction to apply.
     * @param txn
     */
    applyEncodedTransaction(tx, txn) {
        if (tx._truncated) {
            this._truncate(txn);
        }

        for (const key of tx._removed) {
            this._remove(txn, key, undefined, true);
        }
        for (const [key, value] of tx._modified) {
            this._put(txn, key, value, undefined, true);
        }

        for (const [indexName, index] of this._indices) {
            index.applyEncodedTransaction(tx.getIndex(indexName), txn);
        }
    }

    /**
     * Encode transaction and estimate the encoded size of a transaction.
     * @param {Transaction} tx The transaction to encode.
     * @returns {EncodedLMDBTransaction}
     */
    encodeTransaction(tx) {
        const encodedTx = new EncodedLMDBTransaction(this);

        if (tx._truncated) {
            encodedTx.truncate();
        }

        for (const key of tx._removed) {
            this._remove(encodedTx, key);
        }
        for (const [key, value] of tx._modified) {
            this._put(encodedTx, key, value);
        }

        for (const [indexName, index] of this._indices) {
            encodedTx.setIndex(indexName, index.encodeTransaction(tx));
        }

        return encodedTx;
    }

    /**
     * Returns the necessary information in order to flush a combined transaction.
     * @param {Transaction} tx The transaction that should be applied to this backend.
     * @returns {Promise.<Array>} An array containing the batch operations.
     */
    async applyCombined(tx) {
        return this.encodeTransaction(tx);
    }

    /**
     * Applies a function on all key-value pairs in the database.
     * @param {function(key:string, value:*)} func The function to apply.
     * @returns {Promise} The promise resolves after applying the function to all entries.
     */
    async map(func) {
        this._readStream(func);
    }

    /**
     * Creates a new secondary index on the object store.
     * Currently, all secondary indices are non-unique.
     * They are defined by a key within the object or alternatively a path through the object to a specific subkey.
     * For example, ['a', 'b'] could be used to use 'key' as the key in the following object:
     * { 'a': { 'b': 'key' } }
     * Secondary indices may be multiEntry, i.e., if the keyPath resolves to an iterable object, each item within can
     * be used to find this entry.
     * If a new object does not possess the key path associated with that index, it is simply ignored.
     *
     * This function may only be called before the database is connected.
     * Moreover, it is only executed on database version updates or on first creation.
     * @param {string} indexName The name of the index.
     * @param {string|Array.<string>} [keyPath] The path to the key within the object. May be an array for multiple levels.
     * @param {{multiEntry:?boolean, unique:?boolean, upgradeCondition:?boolean|?function(oldVersion:number, newVersion:number):boolean, keyEncoding:?ILMDBEncoding|?ILevelDBEncoding, lmdbKeyEncoding:?ILMDBEncoding, leveldbKeyEncoding:?ILevelDBEncoding}} [options] An options object.
     */
    createIndex(indexName, keyPath, options = {}) {
        let { multiEntry = false, upgradeCondition = null, unique = false, keyEncoding = null, lmdbKeyEncoding = null } = options || {};

        if (this._db.connected) throw new Error('Cannot create index while connected');
        keyPath = keyPath || indexName;
        const index = new PersistentIndex(this, this._db, indexName, keyPath, multiEntry, unique, lmdbKeyEncoding || keyEncoding);
        this._indices.set(indexName, index);
        this._indicesToCreate.set(indexName, { index, upgradeCondition });
    }

    /**
     * Deletes a secondary index from the object store.
     * @param indexName
     * @param {{upgradeCondition:?boolean|?function(oldVersion:number, newVersion:number):boolean}} [options]
     */
    deleteIndex(indexName, options = {}) {
        let { upgradeCondition = null } = options || {};

        if (this._db.connected) throw new Error('Cannot delete index while connected');
        this._indicesToDelete.push({ indexName, upgradeCondition });
    }

    /**
     * Closes the object store and potential connections.
     * @returns {Promise} The promise resolves after closing the object store.
     */
    close() {
        this._close();
        const indexPromises = [];
        for (const index of this._indices.values()) {
            indexPromises.close(index.close());
        }
        return Promise.all(indexPromises);
    }

    /**
     * Checks whether an object store implements the ISynchronousObjectStore interface.
     * @returns {boolean} The transaction object.
     */
    isSynchronous() {
        return true;
    }

    /**
     * Internally applies a transaction to the store's state.
     * This needs to be done in batch (as a db level transaction), i.e., either the full state is updated
     * or no changes are applied.
     * @param {Transaction} tx The transaction to apply.
     * @returns {Promise} The promise resolves after applying the transaction.
     * @protected
     */
    async _apply(tx) {
        // Check database size before applying transaction.
        const encodedTx = this.encodeTransaction(tx);
        if (this._db.autoResize) {
            const estimatedSize = encodedTx.byteSize * 2;
            if (this._db.needsResize(estimatedSize)) {
                this._db.doResize(estimatedSize);
            }
        }

        const txn = this._env.beginTxn();
        try {
            this.applyEncodedTransaction(encodedTx, txn);
        } catch (e) {
            txn.abort();
            throw e;
        }
        txn.commit();
    }
}
Class.register(LMDBBackend);
<commit_msg>Comment code.<commit_after>/**
 * This is a wrapper around the interface for the LMDB.
 * It manages the access to a single table/object store.
 * @implements {IBackend}
 * @implements {ISynchronousObjectStore}
 */
class LMDBBackend extends LMDBBaseBackend {
    /**
     * Creates a wrapper given a JungleDB, the table's name, the database directory and an encoding.
     * @param {JungleDB} db The JungleDB object managing the connection.
     * @param {string} tableName The table name this object store represents.
     * @param {ICodec} [codec] A default codec for the object store.
     * @param {object} [options] Advanced options.
     */
    constructor(db, tableName, codec = null, options = {}) {
        super(db, tableName, codec, options);

        /** @type {Map.<string,PersistentIndex>} */
        this._indices = new Map();
        this._indicesToCreate = new Map();
        this._indicesToDelete = [];
    }

    /**
     * A map of index names to indices.
     * The index names can be used to access an index.
     * @type {Map.<string,IIndex>}
     */
    get indices() {
        return this._indices;
    }

    /**
     * Initialises the persisted indices of the object store.
     * @param {number} oldVersion
     * @param {number} newVersion
     * @returns {Array.<PersistentIndex>} The list of indices.
     */
    init(oldVersion, newVersion) {
        super.init(oldVersion, newVersion);

        // Delete indices.
        for (const { indexName, upgradeCondition } of this._indicesToDelete) {
            if (upgradeCondition === null || upgradeCondition === true || (typeof upgradeCondition === 'function' && upgradeCondition(oldVersion, newVersion))) {
                const index = new PersistentIndex(this, indexName, '');
                LMDBBaseBackend.truncate(this._env, index.tableName);
            }
        }
        this._indicesToDelete = [];

        const indices = [];
        for (const [indexName, { index, upgradeCondition }] of this._indicesToCreate) {
            indices.push(index.init(oldVersion, newVersion, upgradeCondition));
        }
        return indices;
    }

    /**
     * Returns the object stored under the given primary key.
     * Resolves to undefined if the key is not present in the object store.
     * @param {string} key The primary key to look for.
     * @returns {*} The object stored under the given key, or undefined if not present.
     */
    getSync(key) {
        const txn = this._env.beginTxn({ readOnly: true });
        const value = this._get(txn, key);
        txn.commit();
        return value;
    }

    /**
     * A check whether a certain key is cached.
     * @param {string} key The key to check.
     * @return {boolean} A boolean indicating whether the key is already in the cache.
     */
    isCached(key) {
        return true;
    }

    /**
     * Returns a promise of the object stored under the given primary key.
     * Resolves to undefined if the key is not present in the object store.
     * @param {string} key The primary key to look for.
     * @returns {Promise.<*>} A promise of the object stored under the given key, or undefined if not present.
     */
    async get(key) {
        return this.getSync(key);
    }

    /**
     * Returns a promise of an array of objects whose primary keys fulfill the given query.
     * If the optional query is not given, it returns all objects in the object store.
     * If the query is of type KeyRange, it returns all objects whose primary keys are within this range.
     * If the query is of type Query, it returns all objects whose primary keys fulfill the query.
     * @param {Query|KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<Array.<*>>} A promise of the array of objects relevant to the query.
     */
    async values(query=null) {
        if (query !== null && query instanceof Query) {
            return query.values(this);
        }

        let result = [];
        this._readStream((value, key) => {
            result.push(value);
        }, true, query);
        return result;
    }

    /**
     * Returns a promise of a set of keys fulfilling the given query.
     * If the optional query is not given, it returns all keys in the object store.
     * If the query is of type KeyRange, it returns all keys of the object store being within this range.
     * If the query is of type Query, it returns all keys fulfilling the query.
     * @param {Query|KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<Set.<string>>} A promise of the set of keys relevant to the query.
     */
    async keys(query = null) {
        if (query !== null && query instanceof Query) {
            return query.keys(this);
        }
        let resultSet = new Set();
        this._readStream((value, key) => {
            resultSet.add(key);
        }, true, query, true);
        return resultSet;
    }

    /**
     * Iterates over the keys in a given range and direction.
     * The callback is called for each primary key fulfilling the query
     * until it returns false and stops the iteration.
     * @param {function(key:string):boolean} callback A predicate called for each key until returning false.
     * @param {boolean} ascending Determines the direction of traversal.
     * @param {KeyRange} query An optional KeyRange to narrow down the iteration space.
     * @returns {Promise} The promise resolves after all elements have been streamed.
     */
    async keyStream(callback, ascending=true, query=null) {
        this._readStream((value, key) => {
            return callback(key);
        }, ascending, query, true);
    }

    /**
     * Iterates over the keys and values in a given range and direction.
     * The callback is called for each value and primary key fulfilling the query
     * until it returns false and stops the iteration.
     * @param {function(value:*, key:string):boolean} callback A predicate called for each value and key until returning false.
     * @param {boolean} ascending Determines the direction of traversal.
     * @param {KeyRange} query An optional KeyRange to narrow down the iteration space.
     * @returns {Promise} The promise resolves after all elements have been streamed.
     */
    async valueStream(callback, ascending=true, query=null) {
        this._readStream((value, key) => {
            return callback(value, key);
        }, ascending, query);
    }

    /**
     * Returns a promise of the object whose primary key is maximal for the given range.
     * If the optional query is not given, it returns the object whose key is maximal.
     * If the query is of type KeyRange, it returns the object whose primary key is maximal for the given range.
     * @param {KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<*>} A promise of the object relevant to the query.
     */
    async maxValue(query=null) {
        let maxValue = null;
        this._readStream((value, key) => {
            maxValue = value;
            return false;
        }, false, query);
        return maxValue;
    }

    /**
     * Returns a promise of the key being maximal for the given range.
     * If the optional query is not given, it returns the maximal key.
     * If the query is of type KeyRange, it returns the key being maximal for the given range.
     * @param {KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<string>} A promise of the key relevant to the query.
     */
    async maxKey(query=null) {
        let maxKey = null;
        this._readStream((value, key) => {
            maxKey = key;
            return false;
        }, false, query, true);
        return maxKey;
    }

    /**
     * Returns a promise of the object whose primary key is minimal for the given range.
     * If the optional query is not given, it returns the object whose key is minimal.
     * If the query is of type KeyRange, it returns the object whose primary key is minimal for the given range.
     * @param {KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<*>} A promise of the object relevant to the query.
     */
    async minValue(query=null) {
        let minValue = null;
        this._readStream((value, key) => {
            minValue = value;
            return false;
        }, true, query);
        return minValue;
    }

    /**
     * Returns a promise of the key being minimal for the given range.
     * If the optional query is not given, it returns the minimal key.
     * If the query is of type KeyRange, it returns the key being minimal for the given range.
     * @param {KeyRange} [query] Optional query to check keys against.
     * @returns {Promise.<string>} A promise of the key relevant to the query.
     */
    async minKey(query=null) {
        let minKey = null;
        this._readStream((value, key) => {
            minKey = key;
            return false;
        }, true, query, true);
        return minKey;
    }

    /**
     * Returns the count of entries in the given range.
     * If the optional query is not given, it returns the count of entries in the object store.
     * If the query is of type KeyRange, it returns the count of entries within the given range.
     * @param {KeyRange} [query]
     * @returns {Promise.<number>}
     */
    async count(query=null) {
        let i = 0;
        this._readStream((value, key) => {
            i++;
        }, true, query, true);
        return i;
    }

    /**
     * Returns the index of the given name.
     * If the index does not exist, it returns undefined.
     * @param {string} indexName The name of the requested index.
     * @returns {IIndex} The index associated with the given name.
     */
    index(indexName) {
        return this._indices.get(indexName);
    }

    /**
     * Internally applies a transaction to the store's state.
     * This needs to be done in batch (as a db level transaction), i.e., either the full state is updated
     * or no changes are applied.
     * @param {EncodedLMDBTransaction} tx The transaction to apply.
     * @param txn
     */
    applyEncodedTransaction(tx, txn) {
        if (tx._truncated) {
            this._truncate(txn);
        }

        for (const key of tx._removed) {
            this._remove(txn, key, /*value*/ undefined, /*alreadyEncoded*/ true);
        }
        for (const [key, value] of tx._modified) {
            this._put(txn, key, value, /*allowOverwrite*/ true, /*alreadyEncoded*/ true);
        }

        for (const [indexName, index] of this._indices) {
            index.applyEncodedTransaction(tx.getIndex(indexName), txn);
        }
    }

    /**
     * Encode transaction and estimate the encoded size of a transaction.
     * @param {Transaction} tx The transaction to encode.
     * @returns {EncodedLMDBTransaction}
     */
    encodeTransaction(tx) {
        const encodedTx = new EncodedLMDBTransaction(this);

        if (tx._truncated) {
            encodedTx.truncate();
        }

        for (const key of tx._removed) {
            this._remove(encodedTx, key);
        }
        for (const [key, value] of tx._modified) {
            this._put(encodedTx, key, value);
        }

        for (const [indexName, index] of this._indices) {
            encodedTx.setIndex(indexName, index.encodeTransaction(tx));
        }

        return encodedTx;
    }

    /**
     * Returns the necessary information in order to flush a combined transaction.
     * @param {Transaction} tx The transaction that should be applied to this backend.
     * @returns {Promise.<Array>} An array containing the batch operations.
     */
    async applyCombined(tx) {
        return this.encodeTransaction(tx);
    }

    /**
     * Applies a function on all key-value pairs in the database.
     * @param {function(key:string, value:*)} func The function to apply.
     * @returns {Promise} The promise resolves after applying the function to all entries.
     */
    async map(func) {
        this._readStream(func);
    }

    /**
     * Creates a new secondary index on the object store.
     * Currently, all secondary indices are non-unique.
     * They are defined by a key within the object or alternatively a path through the object to a specific subkey.
     * For example, ['a', 'b'] could be used to use 'key' as the key in the following object:
     * { 'a': { 'b': 'key' } }
     * Secondary indices may be multiEntry, i.e., if the keyPath resolves to an iterable object, each item within can
     * be used to find this entry.
     * If a new object does not possess the key path associated with that index, it is simply ignored.
     *
     * This function may only be called before the database is connected.
     * Moreover, it is only executed on database version updates or on first creation.
     * @param {string} indexName The name of the index.
     * @param {string|Array.<string>} [keyPath] The path to the key within the object. May be an array for multiple levels.
     * @param {{multiEntry:?boolean, unique:?boolean, upgradeCondition:?boolean|?function(oldVersion:number, newVersion:number):boolean, keyEncoding:?ILMDBEncoding|?ILevelDBEncoding, lmdbKeyEncoding:?ILMDBEncoding, leveldbKeyEncoding:?ILevelDBEncoding}} [options] An options object.
     */
    createIndex(indexName, keyPath, options = {}) {
        let { multiEntry = false, upgradeCondition = null, unique = false, keyEncoding = null, lmdbKeyEncoding = null } = options || {};

        if (this._db.connected) throw new Error('Cannot create index while connected');
        keyPath = keyPath || indexName;
        const index = new PersistentIndex(this, this._db, indexName, keyPath, multiEntry, unique, lmdbKeyEncoding || keyEncoding);
        this._indices.set(indexName, index);
        this._indicesToCreate.set(indexName, { index, upgradeCondition });
    }

    /**
     * Deletes a secondary index from the object store.
     * @param indexName
     * @param {{upgradeCondition:?boolean|?function(oldVersion:number, newVersion:number):boolean}} [options]
     */
    deleteIndex(indexName, options = {}) {
        let { upgradeCondition = null } = options || {};

        if (this._db.connected) throw new Error('Cannot delete index while connected');
        this._indicesToDelete.push({ indexName, upgradeCondition });
    }

    /**
     * Closes the object store and potential connections.
     * @returns {Promise} The promise resolves after closing the object store.
     */
    close() {
        this._close();
        const indexPromises = [];
        for (const index of this._indices.values()) {
            indexPromises.close(index.close());
        }
        return Promise.all(indexPromises);
    }

    /**
     * Checks whether an object store implements the ISynchronousObjectStore interface.
     * @returns {boolean} The transaction object.
     */
    isSynchronous() {
        return true;
    }

    /**
     * Internally applies a transaction to the store's state.
     * This needs to be done in batch (as a db level transaction), i.e., either the full state is updated
     * or no changes are applied.
     * @param {Transaction} tx The transaction to apply.
     * @returns {Promise} The promise resolves after applying the transaction.
     * @protected
     */
    async _apply(tx) {
        // Check database size before applying transaction.
        const encodedTx = this.encodeTransaction(tx);
        if (this._db.autoResize) {
            const estimatedSize = encodedTx.byteSize * 2;
            if (this._db.needsResize(estimatedSize)) {
                this._db.doResize(estimatedSize);
            }
        }

        const txn = this._env.beginTxn();
        try {
            this.applyEncodedTransaction(encodedTx, txn);
        } catch (e) {
            txn.abort();
            throw e;
        }
        txn.commit();
    }
}
Class.register(LMDBBackend);
<|endoftext|>


<commit_before>// Copyright 2016 Foxysoft GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/* global fx_trace, fx_bobj_Session, IUserGroup, fx_JavaUtils, IUser */

/**
 * Data manipulation functions for BOBJ groups
 * @class
 * @requires fx_trace
 * @requires fx_bobj_Session
 * @requires fx_JavaUtils
 * @since 1.0.0
 */
var fx_bobj_Group = (function() {
    /**
     * Indicates whether static class members have been initialized
     * or not. Each public method must first check this and call
     * class_init() if it's false. Set to true by class_init().
     */
    var gv_initialized = false;

    var go_result = {
        /**
         * Add/remove user members to a BOBJ group.
         * @public
         * @function
         * @name fx_bobj_Group.modifyGroupMembers
         * @param {com.sap.idm.ic.DSEEntry} io_entry - IDM entry
         *
IO_ENTRY ::= {
         * SI_NAME:             Group name (mandatory)
         * SI_GROUP_MEMBERS:    <DELTA_STRING>
         * }
         *
         * <DELTA_STRING>  ::= [<OPERATOR_SPEC>]<USER_ID>
         *                     [|[<OPERATOR_SPEC>]<USER_ID>]...
         * <USER_ID>       ::= User login ID (=SI_NAME of user)
         * <OPERATOR_SPEC> ::= {<OPERATOR>}
         * <OPERATOR>      ::= A|D
         *

         *
As usual, {A} means "add member", {D} means "remove member".
         * If <OPERATOR_SPEC> is omitted, the default is {A}.

         *
Example:

         *

         * IO_ENTRY ::= {
         * SI_NAME: Cryptographic Officers
         * SI_GROUP_MEMBERS: {D}JOHNDOE|{A}JANEDOE
         *

         * will remove the user whose login ID (SI_NAME) is JOHNDOE
         * from group Cryptographic Officers, and add user JANEDOE
         * to that group.
         * @throws {java.lang.Exception}
         */
        modifyMembers: function(io_entry)
        {
            if(!gv_initialized)
            {
                class_init();
            }
            var SCRIPT = "fx_bobj_Group=>modifyMembers: ";
            fx_trace(SCRIPT+"Entering io_entry="+io_entry);

            var lo_si_name = io_entry.get("SI_NAME");
            if(lo_si_name == null)
            {
                throw new java.lang.Exception(
                    "Missing mandatory parameter SI_NAME"
                );
            }

            /**
             * @type {com.crystaldecisions.sdk.occa.infostore.IInfoObjects}
             */
            var lo_to_modify_info_objects
                    = fx_bobj_Session.lookupSingleInfoObject(
                        lo_si_name
                        ,IUserGroup.KIND
                        ,"SI_GROUP_MEMBERS"
                    );

            /**
             * @type {
             * com.crystaldecisions.sdk.plugin.desktop.usergroup.IUserGroup
             * }
             */
            var lo_to_modify = lo_to_modify_info_objects.get(0);

            /** @type {java.lang.String} */
            var lo_si_group_members
                    = io_entry.get("SI_GROUP_MEMBERS");

            if(lo_si_group_members != null)
            {
                /** @type {java.util.Set<java.lang.Integer>} */
                var lo_current_members = fx_JavaUtils.callByReflection(
                    lo_to_modify
                    ,"getUsers"
                );

                fx_trace(SCRIPT
                         + "Have current members? "
                         + (lo_current_members != null));

                /** @type {string[]}*/
                var lt_si_group_members
                        = ("" + lo_si_group_members).split("|");

                for(var i=0;i<lt_si_group_members.length;++i)
                {
                    var lv_si_group_member   = lt_si_group_members[i];
                    var lv_operation         = null;
                    var lv_group_member_name = null;
                    var lv_operation_result  = null;

                    if(lv_si_group_member.indexOf("{A}") == 0)
                    {
                        lv_operation = "{A}";
                        lv_group_member_name
                            = lv_si_group_member
                            .substring("{A}".length);

                        fx_trace(SCRIPT
                                 + "Will ADD group member "
                                 + lv_group_member_name
                                 + " to "
                                 + lo_si_name);
                    }
                    else if(lv_si_group_member.indexOf("{D}") == 0)
                    {
                        lv_operation = "{D}";
                        lv_group_member_name
                            = lv_si_group_member
                            .substring("{D}".length);

                        fx_trace(SCRIPT
                                 + "Will REMOVE group member "
                                 + lv_group_member_name
                                 + " from "
                                 + lo_si_name);
                    }
                    else
                    {
                        // Default operation is ADD {A}
                        lv_operation = "{A}";
                        lv_group_member_name = lv_si_group_member;
                        fx_trace(SCRIPT
                                 + "Will ADD group member "
                                 + lv_group_member_name
                                 + " to "
                                 + lo_si_name);
                    }

                    /**
                     * @type {
                     * com.crystaldecisions.sdk.occa.infostore.IInfoObjects
                     * }
                     */
                    var lo_group_member_info_objects
                            = fx_bobj_Session.lookupSingleInfoObject(
                                lv_group_member_name
                                ,IUser.KIND
                            );

                    /**
                     * @type {
                     * com.crystaldecisions.sdk.plugin.desktop.user.IUser
                     * }
                     */
                    var lo_group_member
                            = lo_group_member_info_objects.get(0);

                    fx_trace(SCRIPT
                             + "Have group member object? "
                             + (lo_group_member != null));

                    var lo_group_member_id = fx_JavaUtils.callByReflection(
                        lo_group_member
                        ,"getID"
                    );

                    fx_trace(SCRIPT
                             + "lo_group_member_id="
                             + lo_group_member_id);

                    if(lv_operation == "{A}")
                    {
                        // ========== IMPORTANT ==========
                        // must pass ID to add() method,
                        // not user object as a whole
                        // ===============================
                        lv_operation_result
                            = lo_current_members.add(lo_group_member_id);
                    }
                    else
                    {
                        // ========== IMPORTANT ==========
                        // must pass ID to remove() method,
                        // not user object as a whole
                        // ===============================
                        lv_operation_result
                            = lo_current_members.remove(lo_group_member_id);
                    }
                    fx_trace(SCRIPT
                             + lo_si_name
                             + ": "
                             + lv_operation
                             + lv_group_member_name
                             + " returned "
                             + lv_operation_result);

                }//for(var i=0;i<lt_si_group_members.length;++i)

            }//if(lo_si_group_members != null)

            fx_trace(SCRIPT + "Before commit");

            fx_bobj_Session.getInfoStore().commit(lo_to_modify_info_objects);

            fx_trace(SCRIPT+"Returning");

        }//modifyMembers
    }//go_result
    ;

    function class_init()
    {
        importClass(Packages
                    .com.crystaldecisions.sdk.plugin.desktop.user
                    .IUser);
        importClass(Packages
                    .com.crystaldecisions.sdk.plugin.desktop.usergroup
                    .IUserGroup);

        gv_initialized = true;
    }//class_init

    class_init();
    return go_result;

})();
<commit_msg>Fix #7<commit_after>// Copyright 2016 Foxysoft GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/* global fx_trace, fx_bobj_Session, IUserGroup, fx_JavaUtils, IUser */

/**
 * Data manipulation functions for BOBJ groups
 * @class
 * @requires fx_trace
 * @requires fx_bobj_Session
 * @requires fx_JavaUtils
 * @since 1.0.0
 */
var fx_bobj_Group = (function() {
    /**
     * Indicates whether static class members have been initialized
     * or not. Each public method must first check this and call
     * class_init() if it's false. Set to true by class_init().
     */
    var gv_initialized = false;

    var go_result = {
        /**
         * Add/remove user members to a BOBJ group.
         * @public
         * @function
         * @name fx_bobj_Group.modifyGroupMembers
         * @param {com.sap.idm.ic.DSEEntry} io_entry - IDM entry
         *
IO_ENTRY ::= {
         * SI_NAME:             Group name (mandatory)
         * SI_GROUP_MEMBERS:    <DELTA_STRING>
         * }
         *
         * <DELTA_STRING>  ::= [<OPERATOR_SPEC>]<USER_ID>
         *                     [|[<OPERATOR_SPEC>]<USER_ID>]...
         * <USER_ID>       ::= User login ID (=SI_NAME of user)
         * <OPERATOR_SPEC> ::= {<OPERATOR>}
         * <OPERATOR>      ::= A|D
         *

         *
As usual, {A} means "add member", {D} means "remove member".
         * If <OPERATOR_SPEC> is omitted, the default is {A}.

         *
Example:

         *

         * IO_ENTRY ::= {
         * SI_NAME: Cryptographic Officers
         * SI_GROUP_MEMBERS: {D}JOHNDOE|{A}JANEDOE
         *

         * will remove the user whose login ID (SI_NAME) is JOHNDOE
         * from group Cryptographic Officers, and add user JANEDOE
         * to that group.
         * @throws {java.lang.Exception}
         */
        modifyMembers: function(io_entry)
        {
            if(!gv_initialized)
            {
                class_init();
            }
            var SCRIPT = "fx_bobj_Group=>modifyMembers: ";
            fx_trace(SCRIPT+"Entering io_entry="+io_entry);

            var lo_si_name = io_entry.get("SI_NAME");
            if(lo_si_name == null)
            {
                throw new java.lang.Exception(
                    "Missing mandatory parameter SI_NAME"
                );
            }

            /**
             * @type {com.crystaldecisions.sdk.occa.infostore.IInfoObjects}
             */
            var lo_to_modify_info_objects
                    = fx_bobj_Session.lookupSingleInfoObject(
                        lo_si_name
                        ,IUserGroup.KIND
                        ,"SI_GROUP_MEMBERS"
                    );

            /**
             * @type {
             * com.crystaldecisions.sdk.plugin.desktop.usergroup.IUserGroup
             * }
             */
            var lo_to_modify = lo_to_modify_info_objects.get(0);

            /** @type {java.lang.String} */
            var lo_si_group_members
                    = io_entry.get("SI_GROUP_MEMBERS");

            if(lo_si_group_members != null)
            {
                /** @type {java.util.Set<java.lang.Integer>} */
                var lo_current_members = fx_JavaUtils.callByReflection(
                    lo_to_modify
                    ,"getUsers"
                );

                fx_trace(SCRIPT
                         + "Have current members? "
                         + (lo_current_members != null));

                /** @type {string[]}*/
                var lt_si_group_members
                        = ("" + lo_si_group_members).split("|");

                for(var i=0;i<lt_si_group_members.length;++i)
                {
                    var lv_si_group_member   = lt_si_group_members[i];
                    var lv_operation         = null;
                    var lv_group_member_name = null;
                    var lv_operation_result  = null;

                    if(lv_si_group_member.indexOf("{A}") == 0)
                    {
                        lv_operation = "{A}";
                        lv_group_member_name
                            = lv_si_group_member
                            .substring("{A}".length);

                        fx_trace(SCRIPT
                                 + "Will ADD group member "
                                 + lv_group_member_name
                                 + " to "
                                 + lo_si_name);
                    }
                    else if(lv_si_group_member.indexOf("{D}") == 0)
                    {
                        lv_operation = "{D}";
                        lv_group_member_name
                            = lv_si_group_member
                            .substring("{D}".length);

                        fx_trace(SCRIPT
                                 + "Will REMOVE group member "
                                 + lv_group_member_name
                                 + " from "
                                 + lo_si_name);
                    }
                    else
                    {
                        // Default operation is ADD {A}
                        lv_operation = "{A}";
                        lv_group_member_name = lv_si_group_member;
                        fx_trace(SCRIPT
                                 + "Will ADD group member "
                                 + lv_group_member_name
                                 + " to "
                                 + lo_si_name);
                    }

                    /**
                     * @type {
                     * com.crystaldecisions.sdk.occa.infostore.IInfoObjects
                     * }
                     */
                    var lo_group_member_info_objects
                            = fx_bobj_Session.lookupSingleInfoObject(
                                lv_group_member_name
                                ,IUser.KIND
                            );

                    /**
                     * @type {
                     * com.crystaldecisions.sdk.plugin.desktop.user.IUser
                     * }
                     */
                    var lo_group_member
                            = lo_group_member_info_objects.get(0);

                    fx_trace(SCRIPT
                             + "Have group member object? "
                             + (lo_group_member != null));

                    var lo_group_member_id = fx_JavaUtils.callByReflection(
                        lo_group_member
                        ,"getID"
                    );

                    fx_trace(SCRIPT
                             + "lo_group_member_id="
                             + lo_group_member_id);

                    if(lv_operation == "{A}")
                    {
                        // ========== IMPORTANT ==========
                        // must pass ID to add() method,
                        // not user object as a whole
                        // ===============================
                        lv_operation_result
                            = lo_current_members.add(lo_group_member_id);
                    }
                    else
                    {
                        // ========== IMPORTANT ==========
                        // must pass ID to remove() method,
                        // not user object as a whole
                        // ===============================
                        lv_operation_result
                            = lo_current_members.remove(lo_group_member_id);
                    }
                    fx_trace(SCRIPT
                             + lo_si_name
                             + ": "
                             + lv_operation
                             + lv_group_member_name
                             + " returned "
                             + lv_operation_result);

                }//for(var i=0;i<lt_si_group_members.length;++i)

            }//if(lo_si_group_members != null)

            fx_trace(SCRIPT + "Before commit");

            fx_bobj_Session.getInfoStore().commit(lo_to_modify_info_objects);

            fx_trace(SCRIPT+"Returning");

        }//modifyMembers
    }//go_result
    ;

    function class_init()
    {
        importClass(Packages
                    .com.crystaldecisions.sdk.plugin.desktop.user
                    .IUser);
        importClass(Packages
                    .com.crystaldecisions.sdk.plugin.desktop.usergroup
                    .IUserGroup);

        gv_initialized = true;
    }//class_init

    // Static initialization at script load time has issues in SAP IDM.
    // Avoid it where possible, and use lazy initialization instead.
    // ===== DON'T TRY THIS =====
    // class_init()
    // ==========================
    return go_result;

})();
<|endoftext|>


<commit_before>var allOptions = document.querySelectorAll('.poll--option');
var lastOption = allOptions[allOptions.length - 2];
var lastInput = lastOption.querySelector('input');
var form = document.getElementById('createPollForm');
var i = 2; // optionI

function addNewPollInput() {
	var newOption = document.createElement('div');
	newOption.classList.add('poll--option');
	newOption.innerHTML = `<label for="option${i}">Option ${i + 1}</label><input type="text" name="option${i}" id="option${i}" />`;

	form.insertBefore(newOption,lastOption.nextSibling);
	lastInput.removeEventListener('focus',addNewPollInput);

	allOptions = document.querySelectorAll('.poll--option');
	lastOption = allOptions[allOptions.length - 2];
	lastInput = lastOption.querySelector('input');

	lastInput.addEventListener('focus', addNewPollInput);
	i++;
}

addNewPollInput();
<commit_msg>Change event to input<commit_after>var allOptions = document.querySelectorAll('.poll--option');
var lastOption = allOptions[allOptions.length - 2];
var lastInput = lastOption.querySelector('input');
var form = document.getElementById('createPollForm');
var i = 2; // optionI

function addNewPollInput() {
	var newOption = document.createElement('div');
	newOption.classList.add('poll--option');
	newOption.innerHTML = `<label for="option${i}">Option ${i + 1}</label><input type="text" name="option${i}" id="option${i}" />`;

	form.insertBefore(newOption,lastOption.nextSibling);
	lastInput.removeEventListener('input',addNewPollInput);

	allOptions = document.querySelectorAll('.poll--option');
	lastOption = allOptions[allOptions.length - 2];
	lastInput = lastOption.querySelector('input');

	lastInput.addEventListener('input', addNewPollInput);
	i++;
}

addNewPollInput();
<|endoftext|>