<commit_before>Ext4.define('Kwf.Ext4.Controller.Binding.BindableToGrid', {
    mixins: {
        observable: 'Ext.util.Observable'
    },
    requires: [ 'Kwf.Ext4.Data.StoreSyncQueue' ],
    gridController: null,
    constructor: function(config) {
        this.mixins.observable.constructor.call(this, config);
        this.init();
    },

    init: function()
    {
        var grid = this.gridController.grid;
        var bindable = this.bindable;
        bindable.disable();

        if (!this.saveButton && bindable.getPanel()) this.saveButton = bindable.getPanel().down('button#save');
        if (!this.addButton) this.addButton = grid.down('button#add');

        if (this.saveButton) this.saveButton.disable();

        grid.on('selectionchange', function(model, rows) {
            if (rows[0]) {
                var row = rows[0];
                if (bindable.getLoadedRecord() !== row) {
                    bindable.load(row);
                }
                bindable.enable();
                if (this.saveButton) this.saveButton.enable();
            } else {
                bindable.disable();
                if (this.saveButton) this.saveButton.disable();
            }
        }, this);

        grid.on('beforeselect', function(sm, record) {
            if (bindable.getLoadedRecord() !== record && bindable.isDirty()) {
                Ext4.Msg.show({
                    title: trlKwf('Save'),
                    msg: trlKwf('Do you want to save the changes?'),
                    buttons: Ext4.Msg.YESNOCANCEL,
                    scope: this,
                    fn: function(button) {
                        if (button == 'yes') {
                            if (this.save()) {
                                bindable.reset();
                                grid.getSelectionModel().select(record);
                            } else {
                                //validation failed re-select
                                grid.getSelectionModel().select(bindable.getLoadedRecord());
                            }
                        } else if (button == 'no') {
                            bindable.reset();
                            grid.getSelectionModel().select(record);
                        } else if (button == 'cancel') {
                            grid.getSelectionModel().select(bindable.getLoadedRecord());
                        }
                    }
                });
                return false;
            }
        }, this);

        this.gridController.on('bindstore', this.onBindStore, this);
        if (grid.getStore()) this.onBindStore(grid.getStore());

        if (this.saveButton) {
            this.saveButton.on('click', function() {
                var syncQueue = new Kwf.Ext4.Data.StoreSyncQueue();
                this.save(syncQueue);
                syncQueue.start({
                    success: function() {
                        this.fireEvent('savesuccess');
                    },
                    scope: this
                });

            }, this);
        }
        if (this.addButton) {
            this.addButton.on('click', function() {
                if (!bindable.isValid()) {
                    return false;
                }

                var s = grid.getStore();
                var row = s.model.create();
                s.add(row);
                this.fireEvent('add', row);

                grid.getSelectionModel().select(row);
                bindable.onAdd(row);

            }, this);
        }
    },

    onRefreshStore: function()
    {
        var curr = this.bindable.getLoadedRecord();
        if (curr) {
            var newRow = this.gridController.grid.getStore().getById(curr.getId());
            //A refresh that loads the current row, a new object is created.
            //Load the new row, dirty values should be kept by the bindable
            if (newRow && newRow !== curr) {
                this.bindable.load(newRow);
            }
        }
    },

    onBindStore: function(store)
    {
        store.on('refresh', this.onRefreshStore, this);
    },

    save: function(syncQueue)
    {
        if (!this.bindable.isValid()) {
            Ext4.Msg.alert(trlKwf('Save'),
                trlKwf("Can't save, please fill all red underlined fields correctly."));
            return false;
        }

        if (syncQueue) {
            syncQueue.add(this.gridController.grid.getStore()); //sync this.gridController.grid store first
            this.bindable.save(syncQueue);         //then bindables (so bindable grid is synced second)
                                                   //bindable forms can still update the row as the sync is not yet started
        } else {
            this.bindable.save();                  //bindables first to allow form updating the row before sync
            this.gridController.grid.getStore().sync({
                success: function() {
                    this.fireEvent('savesuccess');
                },
                scope: this
            });
        }

        this.fireEvent('save');

        return true;
    },

    isDirty: function()
    {
        return this.bindable.isDirty();
    },

    reset: function()
    {
        return this.bindable.reset();
    }
});
<commit_msg>Ext4: BindableToGrid: attach to syncQueue event to get success<commit_after>Ext4.define('Kwf.Ext4.Controller.Binding.BindableToGrid', {
    mixins: {
        observable: 'Ext.util.Observable'
    },
    requires: [ 'Kwf.Ext4.Data.StoreSyncQueue' ],
    gridController: null,
    constructor: function(config) {
        this.mixins.observable.constructor.call(this, config);
        this.init();
    },

    init: function()
    {
        var grid = this.gridController.grid;
        var bindable = this.bindable;
        bindable.disable();

        if (!this.saveButton && bindable.getPanel()) this.saveButton = bindable.getPanel().down('button#save');
        if (!this.addButton) this.addButton = grid.down('button#add');

        if (this.saveButton) this.saveButton.disable();

        grid.on('selectionchange', function(model, rows) {
            if (rows[0]) {
                var row = rows[0];
                if (bindable.getLoadedRecord() !== row) {
                    bindable.load(row);
                }
                bindable.enable();
                if (this.saveButton) this.saveButton.enable();
            } else {
                bindable.disable();
                if (this.saveButton) this.saveButton.disable();
            }
        }, this);

        grid.on('beforeselect', function(sm, record) {
            if (bindable.getLoadedRecord() !== record && bindable.isDirty()) {
                Ext4.Msg.show({
                    title: trlKwf('Save'),
                    msg: trlKwf('Do you want to save the changes?'),
                    buttons: Ext4.Msg.YESNOCANCEL,
                    scope: this,
                    fn: function(button) {
                        if (button == 'yes') {
                            if (this.save()) {
                                bindable.reset();
                                grid.getSelectionModel().select(record);
                            } else {
                                //validation failed re-select
                                grid.getSelectionModel().select(bindable.getLoadedRecord());
                            }
                        } else if (button == 'no') {
                            bindable.reset();
                            grid.getSelectionModel().select(record);
                        } else if (button == 'cancel') {
                            grid.getSelectionModel().select(bindable.getLoadedRecord());
                        }
                    }
                });
                return false;
            }
        }, this);

        this.gridController.on('bindstore', this.onBindStore, this);
        if (grid.getStore()) this.onBindStore(grid.getStore());

        if (this.saveButton) {
            this.saveButton.on('click', function() {
                var syncQueue = new Kwf.Ext4.Data.StoreSyncQueue();
                this.save(syncQueue);
                syncQueue.start();

            }, this);
        }
        if (this.addButton) {
            this.addButton.on('click', function() {
                if (!bindable.isValid()) {
                    return false;
                }

                var s = grid.getStore();
                var row = s.model.create();
                s.add(row);
                this.fireEvent('add', row);

                grid.getSelectionModel().select(row);
                bindable.onAdd(row);

            }, this);
        }
    },

    onRefreshStore: function()
    {
        var curr = this.bindable.getLoadedRecord();
        if (curr) {
            var newRow = this.gridController.grid.getStore().getById(curr.getId());
            //A refresh that loads the current row, a new object is created.
            //Load the new row, dirty values should be kept by the bindable
            if (newRow && newRow !== curr) {
                this.bindable.load(newRow);
            }
        }
    },

    onBindStore: function(store)
    {
        store.on('refresh', this.onRefreshStore, this);
    },

    save: function(syncQueue)
    {
        if (!this.bindable.isValid()) {
            Ext4.Msg.alert(trlKwf('Save'),
                trlKwf("Can't save, please fill all red underlined fields correctly."));
            return false;
        }

        if (syncQueue) {
            syncQueue.add(this.gridController.grid.getStore()); //sync this.gridController.grid store first
            this.bindable.save(syncQueue);         //then bindables (so bindable grid is synced second)
                                                   //bindable forms can still update the row as the sync is not yet started
            syncQueue.on('finished', function(syncQueue) {
                if (!syncQueue.hasException) {
                    this.fireEvent('savesuccess');
                }
            }, this, { single: true });
        } else {
            this.bindable.save();                  //bindables first to allow form updating the row before sync
            this.gridController.grid.getStore().sync({
                success: function() {
                    this.fireEvent('savesuccess');
                },
                scope: this
            });
        }

        this.fireEvent('save');

        return true;
    },

    isDirty: function()
    {
        return this.bindable.isDirty();
    },

    reset: function()
    {
        return this.bindable.reset();
    }
});
<|endoftext|>


<commit_before>// Home Route
Router.route('/', {
  name: 'home',
  action: function () {
    this.render('home');
    Session.set('page_name','productions');
    SEO.set({ title: 'Home - ' + Meteor.App.NAME });
  }
});

Router.route('/news', {
  name: 'news',
  action: function () {
    this.render('news');
    Session.set('page_name','news');
    SEO.set({ title: 'News - ' + Meteor.App.NAME });
  }
});

Router.route('/about', {
  name: 'about',
  action: function () {
    this.render('about');
    Session.set('page_name','about');
    SEO.set({ title: 'About - ' + Meteor.App.NAME });
  }
});

Router.route('/contact', {
  name: 'contact',
  action: function () {
    this.render('contact');
    Session.set('page_name','contact');
    SEO.set({ title: 'Contact - ' + Meteor.App.NAME });
  }
});

Router.route('/calendar', {
  name: 'calendar',
  action: function () {
    this.render('calendar');
    Session.set('page_name','calendar');
    SEO.set({ title: 'Calendar - ' + Meteor.App.NAME });
  }
});

Router.route('/gallery', {
  name: 'gallery',
  action: function () {
    this.render('gallery');
    Session.set('page_name','gallery');
    SEO.set({ title: 'Gallery - ' + Meteor.App.NAME });
  }
});

Router.route('/gallery/:id', {
  name: 'gallery.album',
  action: function () {
    this.render('album', {data: {id: this.params.id}});
    SEO.set({ title: 'Album - ' + Meteor.App.NAME });
  }
});

Router.route('/application', {
  name: 'application',
  action: function () {
    this.render('application');
    Session.set('page_name','application');
    SEO.set({ title: 'Applications - ' + Meteor.App.NAME });
  }
});

Router.route('/films', {
  name: 'Films',
  action: function () {
    this.render('films');
    Session.set('page_name','Films Application');
    SEO.set({ title: 'Films Application- ' + Meteor.App.NAME });
  }
});

Router.route('/finance', {
  name: 'Finance',
  action: function () {
    this.render('finance');
    Session.set('page_name','Finance Application');
    SEO.set({ title: 'Finance Application- ' + Meteor.App.NAME });
  }
});
Router.route('/productions', {
  name: 'Productions',
  action: function () {
    this.render('productions');
    Session.set('page_name','Productions Application');
    SEO.set({ title: 'Productions Application- ' + Meteor.App.NAME });
  }
});
Router.route('/development', {
  name: 'development',
  action: function () {
    this.render('development');
    Session.set('page_name','Development Application');
    SEO.set({ title: 'Development Application- ' + Meteor.App.NAME });
  }
});
Router.route('/speakers', {
  name: 'Speakers',
  action: function () {
    this.render('speakers');
    Session.set('page_name','Speakers Application');
    SEO.set({ title: 'Speakers Application- ' + Meteor.App.NAME });
  }
});
Router.route('/general', {
  name: 'general',
  action: function () {
    this.render('general');
    Session.set('page_name','General Application');
    SEO.set({ title: 'General Application- ' + Meteor.App.NAME });
  }
});

Router.route('/concerts', {
  name: 'concerts',
  action: function () {
    this.render('concerts');
    Session.set('page_name','concerts');
    SEO.set({ title: 'Poll - ' + Meteor.App.NAME });
  }
});
Router.route('/mnm', {
  name: 'mnm',
  action: function () {
    this.render('mandm');
    Session.set('page_name','Marketing and Media');
    SEO.set({ title: 'Marketing and Media - ' + Meteor.App.NAME });
  }
});
<commit_msg>removed routes<commit_after>// Home Route
Router.route('/', {
  name: 'home',
  action: function () {
    this.render('home');
    Session.set('page_name','productions');
    SEO.set({ title: 'Home - ' + Meteor.App.NAME });
  }
});

Router.route('/news', {
  name: 'news',
  action: function () {
    this.render('news');
    Session.set('page_name','news');
    SEO.set({ title: 'News - ' + Meteor.App.NAME });
  }
});

Router.route('/about', {
  name: 'about',
  action: function () {
    this.render('about');
    Session.set('page_name','about');
    SEO.set({ title: 'About - ' + Meteor.App.NAME });
  }
});

Router.route('/contact', {
  name: 'contact',
  action: function () {
    this.render('contact');
    Session.set('page_name','contact');
    SEO.set({ title: 'Contact - ' + Meteor.App.NAME });
  }
});

Router.route('/calendar', {
  name: 'calendar',
  action: function () {
    this.render('calendar');
    Session.set('page_name','calendar');
    SEO.set({ title: 'Calendar - ' + Meteor.App.NAME });
  }
});

Router.route('/gallery', {
  name: 'gallery',
  action: function () {
    this.render('gallery');
    Session.set('page_name','gallery');
    SEO.set({ title: 'Gallery - ' + Meteor.App.NAME });
  }
});

Router.route('/gallery/:id', {
  name: 'gallery.album',
  action: function () {
    this.render('album', {data: {id: this.params.id}});
    SEO.set({ title: 'Album - ' + Meteor.App.NAME });
  }
});
<|endoftext|>


<commit_before>/**
 * This file contains the common middleware used by your routes.
 *
 * Extend or replace these functions as your application requires.
 *
 * This structure is not enforced, and just a starting point. If
 * you have more middleware you may want to group it as separate
 * modules in your project's /lib directory.
 */

var _ = require('underscore'),
    querystring = require('querystring'),
    keystone = require('keystone');

/**
 Initialises the standard view locals

 The included layout depends on the navLinks array to generate
 the navigation in the header, you may wish to change this array
 or replace it with your own templates / logic.
 */

exports.initLocals = function (req, res, next) {

    var locals = res.locals;

    locals.navLinks = [
        { label: 'Home', key: 'home', href: '/' },
        { label: 'Contact', key: 'contact', href: '/contact' }
    ];

    locals.user = req.user;

    next();

};

/**
 Fetches and clears the flashMessages before a view is rendered
 */

exports.flashMessages = function (req, res, next) {

    var flashMessages = {
        info: req.flash('info'),
        success: req.flash('success'),
        warning: req.flash('warning'),
        error: req.flash('error')
    };

    res.locals.messages = _.any(flashMessages, function (msgs) {
        return msgs.length;
    }) ? flashMessages : false;

    next();
};

/**
 Prevents people from accessing protected pages when they're not signed in
 */
exports.requireUser = function (req, res, next) {
    if (!req.user) {
        req.flash('error', 'Please sign in to access this page.');
        res.redirect('/keystone/signin');
    } else {
        next();
    }
};
<commit_msg>remove files<commit_after>/**
 * This file contains the common middleware used by your routes.
 *
 * Extend or replace these functions as your application requires.
 *
 * This structure is not enforced, and just a starting point. If
 * you have more middleware you may want to group it as separate
 * modules in your project's /lib directory.
 */

var _ = require('underscore'),
    querystring = require('querystring'),
    keystone = require('keystone');

/**
 Initialises the standard view locals

 The included layout depends on the navLinks array to generate
 the navigation in the header, you may wish to change this array
 or replace it with your own templates / logic.
 */

exports.initLocals = function (req, res, next) {

    var locals = res.locals;

    locals.navLinks = [
        {label: 'Home', key: 'home', href: '/'},
        {label: 'Contact', key: 'contact', href: '/contact'}
    ];

    locals.user = req.user;

    next();

};

/**
 Fetches and clears the flashMessages before a view is rendered
 */

exports.flashMessages = function (req, res, next) {

    var flashMessages = {
        info: req.flash('info'),
        success: req.flash('success'),
        warning: req.flash('warning'),
        error: req.flash('error')
    };

    res.locals.messages = _.any(flashMessages, function (msgs) {
        return msgs.length;
    }) ? flashMessages : false;

    next();
};

/**
 Prevents people from accessing protected pages when they're not signed in
 */
exports.requireUser = function (req, res, next) {
    if (!req.user) {
        req.flash('error', 'Please sign in to access this page.');
        res.redirect('/keystone/signin');
    } else {
        next();
    }
};
<|endoftext|>


<commit_before>var keystone = require('keystone'),
    async = require('async');

exports = module.exports = function(req, res) {

    var view = new keystone.View(req, res),
        locals = res.locals,
        dyePopCategoryKey = ['edito', 'extraits', 'mon-oeil'];

    locals.section = 'home';
    locals.data = {
        categories: locals.categories,
        env: keystone.get('env'),
        postByCategory: []
    };

    // Load last three updated post for each category
    view.on('init', function(next) {
        async.each(locals.data.categories, function(category, callback) {

            //If we are in posts list not written by me, select more post so that we can filter
            var limit = (dyePopCategoryKey.indexOf(category.key) === -1) ? 10 : 3;

            keystone.list('Post').model.find()
                .where('state', 'published')
                .where('categories').in([category])
                .populate('author categories')
                .sort('-publishedDate')
                .limit(limit)
                .exec(function(err, documents) {
                    if (err) {
                        return callback(err);
                    }

                    //Not written by me category
                    if (dyePopCategoryKey.indexOf(category.key) === -1) {

                        //Remove posts with double category, with one category "written by me"
                        documents = documents.filter(function(post) {
                            var keepPost = true;
                            post.categories.every(function(postCategory) {
                                if (dyePopCategoryKey.indexOf(postCategory.key) !== -1) {
                                    return keepPost = false;
                                }
                                return true;
                            });
                            return keepPost;
                        });
                        documents = documents.slice(0, 3);
                    }

                    category.posts = documents;
                    locals.data.postByCategory[parseInt(category.rank) - 1] = category;
                    callback();
                });
        }, function(err) {
            if (err) {
                return next(err);
            }
            next();
        });
    });

    view.render('home');
};
<commit_msg>[remove-code-nav] Remove code category from homepage<commit_after>var keystone = require('keystone'),
    async = require('async');

exports = module.exports = function(req, res) {

    var view = new keystone.View(req, res),
        locals = res.locals,
        dyePopCategoryKey = ['edito', 'extraits', 'mon-oeil'];

    locals.section = 'home';
    locals.data = {
        categories: locals.categories,
        env: keystone.get('env'),
        postByCategory: []
    };

    // Load last three updated post for each category
    view.on('init', function(next) {
        async.each(locals.data.categories, function(category, callback) {

            //If we are in posts list not written by me, select more post so that we can filter
            var limit = (dyePopCategoryKey.indexOf(category.key) === -1) ? 10 : 3;

            keystone.list('Post').model.find()
                .where('state', 'published')
                .where('categories').in([category])
                .populate('author categories')
                .sort('-publishedDate')
                .limit(limit)
                .exec(function(err, documents) {
                    if (err) {
                        return callback(err);
                    }

                    //Remove code category from homepage
                    if (category.key === 'code') {
                        return callback();
                    }

                    //Not written by me category
                    if (dyePopCategoryKey.indexOf(category.key) === -1) {

                        //Remove posts with double category, with one category "written by me"
                        documents = documents.filter(function(post) {
                            var keepPost = true;
                            post.categories.every(function(postCategory) {
                                if (dyePopCategoryKey.indexOf(postCategory.key) !== -1) {
                                    return keepPost = false;
                                }
                                return true;
                            });
                            return keepPost;
                        });
                        documents = documents.slice(0, 3);
                    }

                    category.posts = documents;
                    locals.data.postByCategory[parseInt(category.rank) - 1] = category;
                    callback();
                });
        }, function(err) {
            if (err) {
                return next(err);
            }
            next();
        });
    });

    view.render('home');
};
<|endoftext|>


<commit_before>import { createStore } from 'redux'
import { katangapp } from '../reducers/reducers.js'

export store = createStore(katangapp)

<commit_msg>change to ES6 and do some corrections, add here initial state<commit_after>export const initialState = {
  busStopsAroundMe: {
    meters: 10,
    coors: {
      latitude: 10,
      longitude: 10
    },
    busStops: [],
    error: {}
  }
}

<|endoftext|>


<commit_before>var cookiesMap = {};
//               /////  1   ////////// 2 /////// 3 ////    4  //
var domainReg = /^(?:(https?)\:)?\/\/(.*?)(?:\/(.*?))?([\?#].*)?$/i;
var { efrontURI, cross_host = efrontURI } = this;
var location_host = location.href.replace(domainReg, '$1://$2/');
if (cross_host) {
    if (!domainReg.test(cross_host)) {
        console.error("cross_host格式不正确", cross_host);
        cross_host = "/";
    } else {
        cross_host = (/^https/.test(location_host) ? "https://" : "http://") + cross_host.replace(domainReg, '$2/');
    }
}
var base = cross_host || (domainReg.test(location.href) ? '/' : "http://efront.cc/");
var HeadersKeys = ["Content-Type"];
var cookieItemsInSessionStorageKey = "--zimoli-coms-cross";
var cookiesData = sessionStorage.getItem(cookieItemsInSessionStorageKey);
if (cookiesData) {
    try {
        extend(cookiesMap, JSON.parse(cookiesData));
    } catch (e) {
        console.warn("加载cookie出错！");
    }
}
function getDomainPath(url) {
    return url.replace(domainReg, "$2/$3");
}
function getRequestProtocol(url) {
    if (/^https:/i.test(url)) {
        return "https";
    }
    return "http";
}
function getCookies(domainPath) {
    var cookieObject = {};
    var splited = domainPath.split("/");
    var domain = splited[0];
    do {
        var copy = splited.slice(0);
        do {
            domainPath = copy.join("/");
            var cookie = cookiesMap[domainPath];
            if (cookie) {
                for (var k in cookie) {
                    if (!cookieObject[k]) {
                        cookieObject[k] = cookie[k];
                    }
                }
            }
            copy.pop();
        } while (copy.length);
        domain = domain.replace(/^.*?(\.|$)/, "");
        splited[0] = domain;
    } while (domain.length);
    return serialize(cookieObject, ";");
}
function addCookie(cookie, originDomain = "") {
    if (cookie) {
        clearTimeout(addCookie.save_timer);
        addCookie.save_timer = setTimeout(function () {
            sessionStorage.setItem(cookieItemsInSessionStorageKey, JSON.stringify(cookiesMap));
        }, 20);
        cookie.replace(/(^|;|,)\s*(expires)=(\w*),([^=]*)(;|$)/ig, "$1$2=$3.$4$5")
            .split(/,\s*/).map(function (cookie) {
                var cookieObject = {};
                var result = cookie.split(/;\s*/);
                result.slice(1).map(function (kev) {
                    var kvs = /^(.+?)\=(.+?)$/.exec(kev);
                    if (kvs) {
                        var [, k, v] = kvs;
                        cookieObject[k.toLowerCase()] = v;
                    }
                });
                var { path, domain } = cookieObject;
                if (!domain) {
                    domain = originDomain.replace(/[^\/]+$/, "");
                }
                if (/^\./.test(domain)) {
                    domain = domain.replace(/^\.+/, "");
                }
                var destPath;
                if (/^\//.test(path)) {
                    destPath = domain.replace(/\/.*$/, "") + path;
                } else {
                    destPath = domain;
                }
                destPath = destPath.replace(/\/+$/, "");
                if (originDomain.indexOf(destPath) >= 0) {
                    var cookieMap = parseKV(result[0], ";");
                    if (!cookiesMap[destPath]) {
                        cookiesMap[destPath] = cookieMap;
                    } else {
                        extend(cookiesMap[destPath], cookieMap);
                    }
                }
            });
    }
}
function isChildPath(relative, path) {
    return relative.replace(/^(.*\/)[^\/]*$/, path);
}
var digest = function () {
    if (cross.digest instanceof Function) cross.digest();
};

var getCrossUrl = function (domain, headers) {
    if (location_host === domain.slice(0, location_host.length)) return domain;
    var originDomain = getDomainPath(domain);
    var _cookies = getCookies(originDomain);
    var _headers = {};
    if (_cookies) {
        _headers.Cookie = _cookies;
    }
    extend(_headers, headers);
    var spliter = encodeURIComponent("/");
    return domain
        .replace(/^s?\/\//i, "http$&")
        .replace(domainReg, base + `%7B${/^(https\:|s\/\/)/i.test(domain) ? "s" : ""}${spliter + spliter}$2${spliter}${serialize(_headers)}%7D@$3$4`);
};
function cross(method, url, headers) {
    var originDomain = getDomainPath(url);
    if (!originDomain) throw new Error("Unsupposed url format!");
    var _cookies = getCookies(originDomain);
    var _headers = {};
    if (_cookies) {
        _headers.Cookie = _cookies;
    }
    extend(_headers, headers);
    if (/^[mc]/i.test(method)) {
        _headers["User-Agent"] = /^m/i.test(method)
            ? "Efront/1.9 (iPhone) Safari/602.1"
            : "Efront/1.9 (Windows) Chrome/77.0.3865.90";
        method = method.slice(1);
    }
    var xhr = new XMLHttpRequest;
    var abort = xhr.abort;
    xhr.abort = function () {
        xhr.onreadystatechange = null;
        abort.call(this);
    };
    HeadersKeys.map(function (k) {
        if (_headers[k]) xhr.setRequestHeader(k, _headers[k]);
        delete _headers[k];
    });

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if (xhr.getResponseHeader) {
                var cookie = xhr.getResponseHeader("efront-cookie");
                addCookie(cookie, originDomain);
            }
            switch (xhr.status) {
                case 0:
                    if (!navigator.onLine) {
                        onerror({ status: "网络断开" });
                        break;
                    }
                case 200:
                case 201:
                case 304:
                    onload(xhr);
                    break;
                case 302:
                case 301:
                    if (xhr.isRedirected > 2) break;
                    var location = xhr.getResponseHeader("efront-location");
                    if (!domainReg.test(location)) {
                        if (/^\//.test(location)) {
                            location = originDomain.replace(/\/.*$/, location);
                        } else {
                            location = originDomain.replace(/[^\/+]$/, location);
                        }
                        location = getRequestProtocol(url) + "://" + location;
                    }
                    var crs = cross("get", location, headers);
                    crs.isRedirected = (xhr.isRedirected || 0) + 1;
                    crs.done(onload, false);
                    crs.error(onerror, false);
                    break;
                default:
                    onerror(xhr);
            }
            dispatch(window, 'render');
        }
    };
    var setRequestHeader = xhr.setRequestHeader;
    var realHeaders = Object.create(null);
    xhr.setRequestHeader = function (key, value) {
        realHeaders[key] = value;
    };
    setTimeout(function () {
        if (!isEmpty(jsondata) && isEmpty(datas)) {
            if (/^(get|head|trace)$/i.test(method)) {
                url = url.replace(/#[\s\S]*/, '');
                datas = serialize(jsondata);
                if (datas) url += (/\?/.test(url) ? "&" : "?") + datas;
            } else {
                datas = JSON.stringify(jsondata);
                if (datas === "{}" || datas === "[]") {
                    datas = '';
                } else {
                    realHeaders["Content-Type"] = "application/json;charset=UTF-8";
                }
            }
        }
        xhr.open(method, getCrossUrl(url, _headers));
        Object.keys(realHeaders).forEach(key => setRequestHeader.call(xhr, key, realHeaders[key]));
        send.call(xhr, datas);
    }, 0);
    var onload = function (xhr) {
        if (xhr.decoder) {
            xhr = xhr.decoder(xhr);
        }
        onloads.map(e => e instanceof Function && e(xhr));
        digest();
    };
    var onerror = function (xhr) {
        onerrors.map(e => e instanceof Function && e(xhr));
        digest();
    };
    var onloads = [], onerrors = [];
    xhr.done = xhr.success = function (on, asqueue = true) {
        if (asqueue) {
            onloads.push(on);
        } else {
            onload = on;
        }
        return xhr;
    };
    var send = xhr.send;
    var datas = "";
    var jsondata = null;
    xhr.json = xhr.data = xhr.send = function (data, value) {
        if (!jsondata && !(isEmpty(data) && isEmpty(value))) jsondata = {};
        if (data instanceof Object && !isFile(data)) {
            extend(jsondata, data);
        } else if (value) {
            extend(jsondata, { [data]: value });
        } else if (isString(data) && value !== false) {
            var data = /^\{/.test(data) ? JSON.parse(data) : parseKV(data, "&", "=");
            extend(jsondata, data);
        } else {
            datas = data;
        }
        return xhr;
    };
    xhr.form = function (data) {
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.data(data);
        datas = serialize(jsondata, "&", "=");
    };
    xhr.fail = xhr.error = function (on, asqueue = true) {
        if (asqueue) {
            onerrors.push(on);
        } else {
            onerror = on;
        }
        onerror = on;
        return xhr;
    };
    return xhr;
}
extend(cross, {
    getCookies,
    addCookie,
    getCrossUrl
});<commit_msg>如果服务器挂了，提示服务器无响应<commit_after>var cookiesMap = {};
//               /////  1   ////////// 2 /////// 3 ////    4  //
var domainReg = /^(?:(https?)\:)?\/\/(.*?)(?:\/(.*?))?([\?#].*)?$/i;
var { efrontURI, cross_host = efrontURI } = this;
var location_host = location.href.replace(domainReg, '$1://$2/');
if (cross_host) {
    if (!domainReg.test(cross_host)) {
        console.error("cross_host格式不正确", cross_host);
        cross_host = "/";
    } else {
        cross_host = (/^https/.test(location_host) ? "https://" : "http://") + cross_host.replace(domainReg, '$2/');
    }
}
var base = cross_host || (domainReg.test(location.href) ? '/' : "http://efront.cc/");
var HeadersKeys = ["Content-Type"];
var cookieItemsInSessionStorageKey = "--zimoli-coms-cross";
var cookiesData = sessionStorage.getItem(cookieItemsInSessionStorageKey);
if (cookiesData) {
    try {
        extend(cookiesMap, JSON.parse(cookiesData));
    } catch (e) {
        console.warn("加载cookie出错！");
    }
}
function getDomainPath(url) {
    return url.replace(domainReg, "$2/$3");
}
function getRequestProtocol(url) {
    if (/^https:/i.test(url)) {
        return "https";
    }
    return "http";
}
function getCookies(domainPath) {
    var cookieObject = {};
    var splited = domainPath.split("/");
    var domain = splited[0];
    do {
        var copy = splited.slice(0);
        do {
            domainPath = copy.join("/");
            var cookie = cookiesMap[domainPath];
            if (cookie) {
                for (var k in cookie) {
                    if (!cookieObject[k]) {
                        cookieObject[k] = cookie[k];
                    }
                }
            }
            copy.pop();
        } while (copy.length);
        domain = domain.replace(/^.*?(\.|$)/, "");
        splited[0] = domain;
    } while (domain.length);
    return serialize(cookieObject, ";");
}
function addCookie(cookie, originDomain = "") {
    if (cookie) {
        clearTimeout(addCookie.save_timer);
        addCookie.save_timer = setTimeout(function () {
            sessionStorage.setItem(cookieItemsInSessionStorageKey, JSON.stringify(cookiesMap));
        }, 20);
        cookie.replace(/(^|;|,)\s*(expires)=(\w*),([^=]*)(;|$)/ig, "$1$2=$3.$4$5")
            .split(/,\s*/).map(function (cookie) {
                var cookieObject = {};
                var result = cookie.split(/;\s*/);
                result.slice(1).map(function (kev) {
                    var kvs = /^(.+?)\=(.+?)$/.exec(kev);
                    if (kvs) {
                        var [, k, v] = kvs;
                        cookieObject[k.toLowerCase()] = v;
                    }
                });
                var { path, domain } = cookieObject;
                if (!domain) {
                    domain = originDomain.replace(/[^\/]+$/, "");
                }
                if (/^\./.test(domain)) {
                    domain = domain.replace(/^\.+/, "");
                }
                var destPath;
                if (/^\//.test(path)) {
                    destPath = domain.replace(/\/.*$/, "") + path;
                } else {
                    destPath = domain;
                }
                destPath = destPath.replace(/\/+$/, "");
                if (originDomain.indexOf(destPath) >= 0) {
                    var cookieMap = parseKV(result[0], ";");
                    if (!cookiesMap[destPath]) {
                        cookiesMap[destPath] = cookieMap;
                    } else {
                        extend(cookiesMap[destPath], cookieMap);
                    }
                }
            });
    }
}
function isChildPath(relative, path) {
    return relative.replace(/^(.*\/)[^\/]*$/, path);
}
var digest = function () {
    if (cross.digest instanceof Function) cross.digest();
};

var getCrossUrl = function (domain, headers) {
    if (location_host === domain.slice(0, location_host.length)) return domain;
    var originDomain = getDomainPath(domain);
    var _cookies = getCookies(originDomain);
    var _headers = {};
    if (_cookies) {
        _headers.Cookie = _cookies;
    }
    extend(_headers, headers);
    var spliter = encodeURIComponent("/");
    return domain
        .replace(/^s?\/\//i, "http$&")
        .replace(domainReg, base + `%7B${/^(https\:|s\/\/)/i.test(domain) ? "s" : ""}${spliter + spliter}$2${spliter}${serialize(_headers)}%7D@$3$4`);
};
function cross(method, url, headers) {
    var originDomain = getDomainPath(url);
    if (!originDomain) throw new Error("Unsupposed url format!");
    var _cookies = getCookies(originDomain);
    var _headers = {};
    if (_cookies) {
        _headers.Cookie = _cookies;
    }
    extend(_headers, headers);
    if (/^[mc]/i.test(method)) {
        _headers["User-Agent"] = /^m/i.test(method)
            ? "Efront/1.9 (iPhone) Safari/602.1"
            : "Efront/1.9 (Windows) Chrome/77.0.3865.90";
        method = method.slice(1);
    }
    var xhr = new XMLHttpRequest;
    var abort = xhr.abort;
    xhr.abort = function () {
        xhr.onreadystatechange = null;
        abort.call(this);
    };
    HeadersKeys.map(function (k) {
        if (_headers[k]) xhr.setRequestHeader(k, _headers[k]);
        delete _headers[k];
    });

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if (xhr.getResponseHeader) {
                var cookie = xhr.getResponseHeader("efront-cookie");
                addCookie(cookie, originDomain);
            }
            switch (xhr.status) {
                case 0:
                    if (!navigator.onLine) {
                        onerror({ status: "网络断开" });
                        break;
                    }
                    if (!navigator.response) {
                        onerror({ status: "服务器无响应" });
                        break;
                    }
                case 200:
                case 201:
                case 304:
                    onload(xhr);
                    break;
                case 302:
                case 301:
                    if (xhr.isRedirected > 2) break;
                    var location = xhr.getResponseHeader("efront-location");
                    if (!domainReg.test(location)) {
                        if (/^\//.test(location)) {
                            location = originDomain.replace(/\/.*$/, location);
                        } else {
                            location = originDomain.replace(/[^\/+]$/, location);
                        }
                        location = getRequestProtocol(url) + "://" + location;
                    }
                    var crs = cross("get", location, headers);
                    crs.isRedirected = (xhr.isRedirected || 0) + 1;
                    crs.done(onload, false);
                    crs.error(onerror, false);
                    break;
                default:
                    onerror(xhr);
            }
            dispatch(window, 'render');
        }
    };
    var setRequestHeader = xhr.setRequestHeader;
    var realHeaders = Object.create(null);
    xhr.setRequestHeader = function (key, value) {
        realHeaders[key] = value;
    };
    setTimeout(function () {
        if (!isEmpty(jsondata) && isEmpty(datas)) {
            if (/^(get|head|trace)$/i.test(method)) {
                url = url.replace(/#[\s\S]*/, '');
                datas = serialize(jsondata);
                if (datas) url += (/\?/.test(url) ? "&" : "?") + datas;
            } else {
                datas = JSON.stringify(jsondata);
                if (datas === "{}" || datas === "[]") {
                    datas = '';
                } else {
                    realHeaders["Content-Type"] = "application/json;charset=UTF-8";
                }
            }
        }
        xhr.open(method, getCrossUrl(url, _headers));
        Object.keys(realHeaders).forEach(key => setRequestHeader.call(xhr, key, realHeaders[key]));
        send.call(xhr, datas);
    }, 0);
    var onload = function (xhr) {
        if (xhr.decoder) {
            xhr = xhr.decoder(xhr);
        }
        onloads.map(e => e instanceof Function && e(xhr));
        digest();
    };
    var onerror = function (xhr) {
        onerrors.map(e => e instanceof Function && e(xhr));
        digest();
    };
    var onloads = [], onerrors = [];
    xhr.done = xhr.success = function (on, asqueue = true) {
        if (asqueue) {
            onloads.push(on);
        } else {
            onload = on;
        }
        return xhr;
    };
    var send = xhr.send;
    var datas = "";
    var jsondata = null;
    xhr.json = xhr.data = xhr.send = function (data, value) {
        if (!jsondata && !(isEmpty(data) && isEmpty(value))) jsondata = {};
        if (data instanceof Object && !isFile(data)) {
            extend(jsondata, data);
        } else if (value) {
            extend(jsondata, { [data]: value });
        } else if (isString(data) && value !== false) {
            var data = /^\{/.test(data) ? JSON.parse(data) : parseKV(data, "&", "=");
            extend(jsondata, data);
        } else {
            datas = data;
        }
        return xhr;
    };
    xhr.form = function (data) {
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.data(data);
        datas = serialize(jsondata, "&", "=");
    };
    xhr.fail = xhr.error = function (on, asqueue = true) {
        if (asqueue) {
            onerrors.push(on);
        } else {
            onerror = on;
        }
        onerror = on;
        return xhr;
    };
    return xhr;
}
extend(cross, {
    getCookies,
    addCookie,
    getCrossUrl
});<|endoftext|>


<commit_before>function main(elem = document.createElement("radio-group")) {
    care(elem, function (field) {
        elem.innerHTML = radio;
        var { options } = field;
        if (options instanceof Array) {
            options = options.map((a, i) => {
                if (isObject(a)) return a;
                return { key: i, name: a };
            });
        } else if (isObject(options)) {
            options = Object.keys(field.options).map(k => ({ name: options[k], key: k }));
        } else {
            options = null;
        }
        render(elem, {
            a: button,
            field,
            options,
            select(a) {
                this.options.active = a;
                elem.value = a.key;
                dispatch(elem, 'change');
            }
        });
        if (elem.value) {
            elem.setValue(elem.value);
        }
    });
    elem.setValue = function (key) {
        var { options } = this.$scope;
        if (!(options instanceof Array)) return;
        var index = options.map(a => a.key).indexOf(key);
        options.active = options[index];
    };
    return elem;
}<commit_msg>兼容一些数据项<commit_after>var hasOwnProperty = {}.hasOwnProperty;
var getValue = function (o) {
    if (hasOwnProperty.call(o, 'valueOf')) return o.valueOf();
    if ("id" in o) return o.id;
    if ("key" in o) return o.key;
    if ("value" in o) return o.value;
    if (hasOwnProperty.call(o, 'toString')) return o.toString();
    return o;
};
function main(elem = document.createElement("radio-group")) {
    care(elem, function (field) {
        elem.innerHTML = radio;
        var { options } = field;
        if (options instanceof Array) {
            options = options.map((a, i) => {
                if (isObject(a)) return a;
                return { key: i, name: a };
            });
        } else if (isObject(options)) {
            options = Object.keys(field.options).map(k => ({ name: options[k], key: k }));
        } else {
            options = null;
        }
        render(elem, {
            a: button,
            field,
            options,
            select(a) {
                this.options.active = a;
                elem.value = getValue(a);
                dispatch(elem, 'change');
            }
        });
        if (!isEmpty(elem.value)) {
            elem.setValue(elem.value);
        }
    });
    elem.setValue = function (key) {
        var { options } = this.$scope;
        if (!(options instanceof Array)) return;
        var index = options.map(a => getValue(a)).indexOf(key);
        options.active = options[index];
    };
    return elem;
}<|endoftext|>


<commit_before>// Create our meeple module namespace
var meeple = angular.module('game.meeple', []);

// meeple.factory('MeepleModel', function(numMeeps) {
//   var Meeple = function(color) {
//     this.img = this.getImage(color);
//   };
//   Meeple.prototype.getImage = function(color) {
//     // Grab an image from our asset folder to set as img attribute
//     return 'assets/img/Meeples/meeple_' + Player.getColor() + '.png';
//   };
//   return Meeple;
// });

// Create our meeple controller
meeple.controller('meepleCtrl', function($scope, Player){
  angular.element(document).ready(function() {
    $scope.meepmeep = 'assets/img/Meeples/meeple_' + Player.getColor() + '.png';
    $scope.numMeeps = 0;
  });
  // $scope.meepmeep = 'assets/img/Meeples/meeple_' + Player.getColor() + '.png';
  // $scope.numMeeps = 0;

  $scope.init = function() {
    // grab current player's meeple color & num of meeples from server
    socket.on('meepDataRes', function(data) {
      $scope.numMeeps = data.numMeeps;
      console.log('~~~~~', data);
      console.log('XXX', data.numMeeps);
      console.log('>>>', $scope.numMeeps);
    });

    // send current player's username to server
    console.log("ooooo", Player.getUsername());
    socket.emit('meepDataReq', { username: Player.getUsername() });
    console.log("INIT IS RUNNING!!!!");
  };

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

  $scope.init();

});

// var Meeple = function(color, id, occupation, location){
//   this.color = color;
//   this.id = id;
//   this.occupation = occupation;
//   this.location = location; // int 0-8 based on placement on tile?
// };

// // creates a collection of all of the meeples needed for one game
// // each player's meeples are in their own array
// // i.e. var meeps = new Meeples(); meeps.blue === [{meeple},{meeple} ...]
// var Meeples = function(){
//   var colors = ['blue', 'red', 'black', 'yellow', 'green'];
//   for (var j = 0; j < colors.length; j++) {
//     var color = colors[j];
//     this[color] = [];
//     for (var k = 0; k < 8; k++) {
//       this[color].push( new Meeple(color, k) );
//     }
//   }
// };

// module.exports = Meeples;
<commit_msg>Experiment with  as numMeeps changes<commit_after>// Create our meeple module namespace
var meeple = angular.module('game.meeple', []);

// meeple.factory('MeepleModel', function(numMeeps) {
//   var Meeple = function(color) {
//     this.img = this.getImage(color);
//   };
//   Meeple.prototype.getImage = function(color) {
//     // Grab an image from our asset folder to set as img attribute
//     return 'assets/img/Meeples/meeple_' + Player.getColor() + '.png';
//   };
//   return Meeple;
// });

// Create our meeple controller
meeple.controller('meepleCtrl', function($scope, Player){
  angular.element(document).ready(function() {
    $scope.meepmeep = 'assets/img/Meeples/meeple_' + Player.getColor() + '.png';
    $scope.numMeeps = 0;
  });
  // $scope.meepmeep = 'assets/img/Meeples/meeple_' + Player.getColor() + '.png';
  // $scope.numMeeps = 0;

  // $scope.$watch(function(scope) {return scope.numMeeps}, function(scope) {
  //   console.log("Num Meeps changed...running$apply()");
  //   scope.$apply();
  // });

  $scope.init = function() {
    // grab current player's meeple color & num of meeples from server
    socket.on('meepDataRes', function(data) {
      $scope.numMeeps = data.numMeeps;
      console.log('~~~~~', data);
      console.log('XXX', data.numMeeps);
      console.log('>>>', $scope.numMeeps);
    });

    // send current player's username to server
    console.log("ooooo", Player.getUsername());
    socket.emit('meepDataReq', { username: Player.getUsername() });
    console.log("INIT IS RUNNING!!!!");
  };

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

  $scope.init();

});

// var Meeple = function(color, id, occupation, location){
//   this.color = color;
//   this.id = id;
//   this.occupation = occupation;
//   this.location = location; // int 0-8 based on placement on tile?
// };

// // creates a collection of all of the meeples needed for one game
// // each player's meeples are in their own array
// // i.e. var meeps = new Meeples(); meeps.blue === [{meeple},{meeple} ...]
// var Meeples = function(){
//   var colors = ['blue', 'red', 'black', 'yellow', 'green'];
//   for (var j = 0; j < colors.length; j++) {
//     var color = colors[j];
//     this[color] = [];
//     for (var k = 0; k < 8; k++) {
//       this[color].push( new Meeple(color, k) );
//     }
//   }
// };

// module.exports = Meeples;
<|endoftext|>


<commit_before>function serialize(mixed_value) {
  //  discuss at: http://phpjs.org/functions/serialize/
  // original by: Arpad Ray (mailto:arpad@php.net)
  // improved by: Dino
  // improved by: Le Torbi (http://www.letorbi.de/)
  // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/)
  // bugfixed by: Andrej Pavlovic
  // bugfixed by: Garagoth
  // bugfixed by: Russell Walker (http://www.nbill.co.uk/)
  // bugfixed by: Jamie Beck (http://www.terabit.ca/)
  // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/)
  // bugfixed by: Ben (http://benblume.co.uk/)
  //    input by: DtTvB (http://dt.in.th/2008-09-16.string-length-in-bytes.html)
  //    input by: Martin (http://www.erlenwiese.de/)
  //        note: We feel the main purpose of this function should be to ease the transport of data between php & js
  //        note: Aiming for PHP-compatibility, we have to translate objects to arrays
  //   example 1: serialize(['Kevin', 'van', 'Zonneveld']);
  //   returns 1: 'a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}'
  //   example 2: serialize({firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'});
  //   returns 2: 'a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}'

  var val, key, okey,
    ktype = '',
    vals = '',
    count = 0,
    _utf8Size = function (str) {
      var size = 0,
        i = 0,
        l = str.length,
        code = '';
      for (i = 0; i < l; i++) {
        code = str.charCodeAt(i);
        if (code < 0x0080) {
          size += 1;
        } else if (code < 0x0800) {
          size += 2;
        } else {
          size += 3;
        }
      }
      return size;
    };
  _getType = function (inp) {
    var match, key, cons, types, type = typeof inp;

    if (type === 'object' && !inp) {
      return 'null';
    }
    if (type === 'object') {
      if (!inp.constructor) {
        return 'object';
      }
      cons = inp.constructor.toString();
      match = cons.match(/(\w+)\(/);
      if (match) {
        cons = match[1].toLowerCase();
      }
      types = ['boolean', 'number', 'string', 'array'];
      for (key in types) {
        if (cons == types[key]) {
          type = types[key];
          break;
        }
      }
    }
    return type;
  };
  type = _getType(mixed_value);

  switch (type) {
  case 'function':
    val = '';
    break;
  case 'boolean':
    val = 'b:' + (mixed_value ? '1' : '0');
    break;
  case 'number':
    val = (Math.round(mixed_value) == mixed_value ? 'i' : 'd') + ':' + mixed_value;
    break;
  case 'string':
    val = 's:' + _utf8Size(mixed_value) + ':"' + mixed_value + '"';
    break;
  case 'array':
  case 'object':
    val = 'a';
    /*
        if (type === 'object') {
          var objname = mixed_value.constructor.toString().match(/(\w+)\(\)/);
          if (objname == undefined) {
            return;
          }
          objname[1] = this.serialize(objname[1]);
          val = 'O' + objname[1].substring(1, objname[1].length - 1);
        }
        */

    for (key in mixed_value) {
      if (mixed_value.hasOwnProperty(key)) {
        ktype = _getType(mixed_value[key]);
        if (ktype === 'function') {
          continue;
        }

        okey = (key.match(/^[0-9]+$/) ? parseInt(key, 10) : key);
        vals += this.serialize(okey) + this.serialize(mixed_value[key]);
        count++;
      }
    }
    val += ':' + count + ':{' + vals + '}';
    break;
  case 'undefined':
    // Fall-through
  default:
    // if the JS object has a property which contains a null value, the string cannot be unserialized by PHP
    val = 'N';
    break;
  }
  if (type !== 'object' && type !== 'array') {
    val += ';';
  }
  return val;
}<commit_msg>Fixes issue #151<commit_after>function serialize(mixed_value) {
  //  discuss at: http://phpjs.org/functions/serialize/
  // original by: Arpad Ray (mailto:arpad@php.net)
  // improved by: Dino
  // improved by: Le Torbi (http://www.letorbi.de/)
  // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/)
  // bugfixed by: Andrej Pavlovic
  // bugfixed by: Garagoth
  // bugfixed by: Russell Walker (http://www.nbill.co.uk/)
  // bugfixed by: Jamie Beck (http://www.terabit.ca/)
  // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/)
  // bugfixed by: Ben (http://benblume.co.uk/)
  //    input by: DtTvB (http://dt.in.th/2008-09-16.string-length-in-bytes.html)
  //    input by: Martin (http://www.erlenwiese.de/)
  //        note: We feel the main purpose of this function should be to ease the transport of data between php & js
  //        note: Aiming for PHP-compatibility, we have to translate objects to arrays
  //   example 1: serialize(['Kevin', 'van', 'Zonneveld']);
  //   returns 1: 'a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}'
  //   example 2: serialize({firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'});
  //   returns 2: 'a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}'

  var val, key, okey,
    ktype = '',
    vals = '',
    count = 0,
    _utf8Size = function (str) {
      var size = 0,
        i = 0,
        l = str.length,
        code = '';
      for (i = 0; i < l; i++) {
        code = str.charCodeAt(i);
        if (code < 0x0080) {
          size += 1;
        } else if (code < 0x0800) {
          size += 2;
        } else {
          size += 3;
        }
      }
      return size;
    },
  _getType = function (inp) {
    var match, key, cons, types, type = typeof inp;

    if (type === 'object' && !inp) {
      return 'null';
    }

    if (type === 'object') {
      if (!inp.constructor) {
        return 'object';
      }
      cons = inp.constructor.toString();
      match = cons.match(/(\w+)\(/);
      if (match) {
        cons = match[1].toLowerCase();
      }
      types = ['boolean', 'number', 'string', 'array'];
      for (key in types) {
        if (cons == types[key]) {
          type = types[key];
          break;
        }
      }
    }
    return type;
  },
  type = _getType(mixed_value);

  switch (type) {
  case 'function':
    val = '';
    break;
  case 'boolean':
    val = 'b:' + (mixed_value ? '1' : '0');
    break;
  case 'number':
    val = (Math.round(mixed_value) == mixed_value ? 'i' : 'd') + ':' + mixed_value;
    break;
  case 'string':
    val = 's:' + _utf8Size(mixed_value) + ':"' + mixed_value + '"';
    break;
  case 'array':
  case 'object':
    val = 'a';
    /*
        if (type === 'object') {
          var objname = mixed_value.constructor.toString().match(/(\w+)\(\)/);
          if (objname == undefined) {
            return;
          }
          objname[1] = this.serialize(objname[1]);
          val = 'O' + objname[1].substring(1, objname[1].length - 1);
        }
        */

    for (key in mixed_value) {
      if (mixed_value.hasOwnProperty(key)) {
        ktype = _getType(mixed_value[key]);
        if (ktype === 'function') {
          continue;
        }

        okey = (key.match(/^[0-9]+$/) ? parseInt(key, 10) : key);
        vals += this.serialize(okey) + this.serialize(mixed_value[key]);
        count++;
      }
    }
    val += ':' + count + ':{' + vals + '}';
    break;
  case 'undefined':
    // Fall-through
  default:
    // if the JS object has a property which contains a null value, the string cannot be unserialized by PHP
    val = 'N';
    break;
  }
  if (type !== 'object' && type !== 'array') {
    val += ';';
  }
  return val;
}
<|endoftext|>


<commit_before>import {
	DebugTilesRenderer as TilesRenderer,
	NONE,
	SCREEN_ERROR,
	GEOMETRIC_ERROR,
	DISTANCE,
	DEPTH,
	RELATIVE_DEPTH,
	IS_LEAF,
	RANDOM_COLOR,
} from '../src/index.js';
import {
	Scene,
	DirectionalLight,
	AmbientLight,
	WebGLRenderer,
	PerspectiveCamera,
	Box3,
	Raycaster,
	Mesh,
	MeshBasicMaterial,
	Group,
	TorusBufferGeometry,
	sRGBEncoding,
	GridHelper,
	BufferGeometry,
	Float32BufferAttribute,
	LineBasicMaterial,
	AdditiveBlending,
	Line,
	Vector3,
	RingBufferGeometry,
	Sphere,
} from 'three';
import * as dat from 'three/examples/jsm/libs/dat.gui.module.js';
import { VRButton } from 'three/examples/jsm/webxr/VRButton.js';
import { XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory.js';

let camera, scene, renderer, tiles;
let workspace;
let box, sphere, grid;
let raycaster, fwdVector, intersectRing;
let offsetParent;
let controller, controllerGrip;
let xrSession = null;
let tasks = [];

let params = {

	'displayBoxBounds': false,
	'colorMode': 0,
	'displayGrid': true,

};

init();

function init() {

	scene = new Scene();

	// primary camera view
	renderer = new WebGLRenderer( { antialias: true } );
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.setClearColor( 0x151c1f );
	renderer.outputEncoding = sRGBEncoding;
	renderer.xr.enabled = true;

	document.body.appendChild( renderer.domElement );
	renderer.domElement.tabIndex = 1;

	renderer.setAnimationLoop( frame );

	// create workspace
	workspace = new Group();
	scene.add( workspace );

	grid = new GridHelper( 10, 10, 0xffffff, 0xffffff );
	grid.material.transparent = true;
	grid.material.opacity = 0.5;
	grid.material.depthWrite = false;
	workspace.add( grid );

	camera = new PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 4000 );
	camera.position.set( 0, 1, 0 );
	workspace.add( camera );

	// lights
	const dirLight = new DirectionalLight( 0xffffff );
	dirLight.position.set( 1, 2, 3 );
	scene.add( dirLight );

	const ambLight = new AmbientLight( 0xffffff, 0.2 );
	scene.add( ambLight );

	// tile set
	box = new Box3();
	sphere = new Sphere();

	// parent for centering the tileset
	offsetParent = new Group();
	scene.add( offsetParent );

	tiles = new TilesRenderer( '../data/tileset.json' );
	offsetParent.add( tiles.group );

	// We set camera for tileset
	tiles.setCamera( camera );
	tiles.setResolutionFromRenderer( camera, renderer );

	// We define a custom scheduling callback to handle also active WebXR sessions
	const tilesSchedulingCB = func => {

		tasks.push( func );

	};

	// We set our scheduling callback for tiles downloading and parsing
	tiles.downloadQueue.schedulingCallback = tilesSchedulingCB;
	tiles.parseQueue.schedulingCallback = tilesSchedulingCB;

	// Raycasting init
	raycaster = new Raycaster();
	fwdVector = new Vector3( 0, 0, 1 );

	const rayIntersectMat = new MeshBasicMaterial( { color: 0xb2dfdb } );
	intersectRing = new Mesh( new TorusBufferGeometry( 1.5, 0.2, 16, 100 ), rayIntersectMat );
	intersectRing.visible = false;
	scene.add( intersectRing );

	// vr setup
	document.body.appendChild( VRButton.createButton( renderer ) );

	controller = renderer.xr.getController( 0 );
	controller.addEventListener( 'selectstart', () => {

		workspace.position.copy( intersectRing.position );

	} );
	controller.addEventListener( 'connected', function ( event ) {

		this.controllerActive = true;
		this.add( buildController( event.data ) );

	} );
	controller.addEventListener( 'disconnected', function () {

		this.controllerActive = false;
		this.remove( this.children[ 0 ] );

	} );
	workspace.add( controller );

	// controller models
	const controllerModelFactory = new XRControllerModelFactory();
	controllerGrip = renderer.xr.getControllerGrip( 0 );
	controllerGrip.add( controllerModelFactory.createControllerModel( controllerGrip ) );
	workspace.add( controllerGrip );

	onWindowResize();
	window.addEventListener( 'resize', onWindowResize, false );

	// GUI
	const gui = new dat.GUI();
	gui.width = 300;
	gui.add( params, 'displayGrid' );
	gui.add( params, 'displayBoxBounds' );
	gui.add( params, 'colorMode', {

		NONE,
		SCREEN_ERROR,
		GEOMETRIC_ERROR,
		DISTANCE,
		DEPTH,
		RELATIVE_DEPTH,
		IS_LEAF,
		RANDOM_COLOR,

	} );
	gui.open();

}

function buildController( data ) {

	let geometry, material;

	switch ( data.targetRayMode ) {

		case 'tracked-pointer':

			geometry = new BufferGeometry();
			geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, - 1 ], 3 ) );
			geometry.setAttribute( 'color', new Float32BufferAttribute( [ 0.5, 0.5, 0.5, 0, 0, 0 ], 3 ) );

			material = new LineBasicMaterial( {
				vertexColors: true,
				blending: AdditiveBlending,
				depthWrite: false,
				transparent: true,
			} );

			return new Line( geometry, material );

		case 'gaze':

			geometry = new RingBufferGeometry( 0.02, 0.04, 32 ).translate( 0, 0, - 1 );
			material = new MeshBasicMaterial( { opacity: 0.5, transparent: true } );
			return new Mesh( geometry, material );

	}

}

function onWindowResize() {

	camera.updateProjectionMatrix();
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );

	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();

}

function handleCamera() {

	// get the XR camera with a combined frustum for culling
	if ( renderer.xr.isPresenting ) {

		if ( xrSession === null ) { // We setup XR camera once

			// remove all cameras so we can use the VR camera instead
			tiles.cameras.forEach( c => tiles.deleteCamera( camera ) );

			const currCamera = renderer.xr.getCamera( camera );
			tiles.setCamera( currCamera );

			const leftCam = currCamera.cameras[ 0 ];
			if ( leftCam ) {

				tiles.setResolution( currCamera, leftCam.viewport.z, leftCam.viewport.w );

			}

			xrSession = renderer.xr.getSession();

		}

	} else {

		// Reset default camera (exiting WebXR session)
		if ( xrSession !== null ) {

			tiles.cameras.forEach( c => tiles.deleteCamera( camera ) );

			tiles.setCamera( camera );
			tiles.setResolutionFromRenderer( camera, renderer );

			camera.position.set( 0, 1, 0 );

			xrSession = null;

		}

	}

}

function handleTasks() {

	if ( tasks.length < 1 ) return;

	const tt = tasks;
	let tlen = tt.length;

	for ( let t = 0; t < tlen; t ++ ) tt[ t ]();
	tasks = [];

}

function frame() {

	grid.visible = params.displayGrid;

	// update options
	tiles.displayBoxBounds = params.displayBoxBounds;
	tiles.colorMode = parseFloat( params.colorMode );

	// update tiles center
	if ( tiles.getBounds( box ) ) {

		box.getCenter( tiles.group.position );
		tiles.group.position.multiplyScalar( - 1 );

	} else if ( tiles.getBoundingSphere( sphere ) ) {

		tiles.group.position.copy( sphere.center );
		tiles.group.position.multiplyScalar( - 1 );

	}

	// We check for tiles camera setup (default and XR sessions)
	handleCamera();

	// We handle pending tasks
	handleTasks();

	tiles.update();

	if ( controller.controllerActive ) {

		const { ray } = raycaster;
		raycaster.firstHitOnly = true;

		// get the controller ray
		ray.origin
			.copy( controller.position )
			.applyMatrix4( workspace.matrixWorld );
		controller
			.getWorldDirection( ray.direction )
			.multiplyScalar( - 1 );

		const results = raycaster.intersectObject( tiles.group, true );
		if ( results.length ) {

			const hit = results[ 0 ];

			hit.face.normal.transformDirection( tiles.group.matrixWorld );
			intersectRing.position.copy( hit.point );
			intersectRing.quaternion.setFromUnitVectors(
				fwdVector,
				hit.face.normal,
			);
			intersectRing.visible = true;

			// scale ring based on distance
			const scale = workspace.position.distanceTo( intersectRing.position ) * camera.fov / 4000;
			intersectRing.scale.setScalar( scale );

		} else {

			intersectRing.visible = false;

		}

	} else {

		intersectRing.visible = false;

	}

	// render primary view
	renderer.render( scene, camera );

}
<commit_msg>Update vr.js<commit_after>import {
	DebugTilesRenderer as TilesRenderer,
	NONE,
	SCREEN_ERROR,
	GEOMETRIC_ERROR,
	DISTANCE,
	DEPTH,
	RELATIVE_DEPTH,
	IS_LEAF,
	RANDOM_COLOR,
} from '../src/index.js';
import {
	Scene,
	DirectionalLight,
	AmbientLight,
	WebGLRenderer,
	PerspectiveCamera,
	Box3,
	Raycaster,
	Mesh,
	MeshBasicMaterial,
	Group,
	TorusBufferGeometry,
	sRGBEncoding,
	GridHelper,
	BufferGeometry,
	Float32BufferAttribute,
	LineBasicMaterial,
	AdditiveBlending,
	Line,
	Vector3,
	RingBufferGeometry,
	Sphere,
} from 'three';
import * as dat from 'three/examples/jsm/libs/dat.gui.module.js';
import { VRButton } from 'three/examples/jsm/webxr/VRButton.js';
import { XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory.js';

let camera, scene, renderer, tiles;
let workspace;
let box, sphere, grid;
let raycaster, fwdVector, intersectRing;
let offsetParent;
let controller, controllerGrip;
let xrSession = null;
let tasks = [];

let params = {

	'displayBoxBounds': false,
	'colorMode': 0,
	'displayGrid': true,

};

init();

function init() {

	scene = new Scene();

	// primary camera view
	renderer = new WebGLRenderer( { antialias: true } );
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.setClearColor( 0x151c1f );
	renderer.outputEncoding = sRGBEncoding;
	renderer.xr.enabled = true;

	document.body.appendChild( renderer.domElement );
	renderer.domElement.tabIndex = 1;

	renderer.setAnimationLoop( animate );

	// create workspace
	workspace = new Group();
	scene.add( workspace );

	grid = new GridHelper( 10, 10, 0xffffff, 0xffffff );
	grid.material.transparent = true;
	grid.material.opacity = 0.5;
	grid.material.depthWrite = false;
	workspace.add( grid );

	camera = new PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 4000 );
	camera.position.set( 0, 1, 0 );
	workspace.add( camera );

	// lights
	const dirLight = new DirectionalLight( 0xffffff );
	dirLight.position.set( 1, 2, 3 );
	scene.add( dirLight );

	const ambLight = new AmbientLight( 0xffffff, 0.2 );
	scene.add( ambLight );

	// tile set
	box = new Box3();
	sphere = new Sphere();

	// parent for centering the tileset
	offsetParent = new Group();
	scene.add( offsetParent );

	tiles = new TilesRenderer( '../data/tileset.json' );
	offsetParent.add( tiles.group );

	// We set camera for tileset
	tiles.setCamera( camera );
	tiles.setResolutionFromRenderer( camera, renderer );

	// We define a custom scheduling callback to handle also active WebXR sessions
	const tilesSchedulingCB = func => {

		tasks.push( func );

	};

	// We set our scheduling callback for tiles downloading and parsing
	tiles.downloadQueue.schedulingCallback = tilesSchedulingCB;
	tiles.parseQueue.schedulingCallback = tilesSchedulingCB;

	// Raycasting init
	raycaster = new Raycaster();
	fwdVector = new Vector3( 0, 0, 1 );

	const rayIntersectMat = new MeshBasicMaterial( { color: 0xb2dfdb } );
	intersectRing = new Mesh( new TorusBufferGeometry( 1.5, 0.2, 16, 100 ), rayIntersectMat );
	intersectRing.visible = false;
	scene.add( intersectRing );

	// vr setup
	document.body.appendChild( VRButton.createButton( renderer ) );

	controller = renderer.xr.getController( 0 );
	controller.addEventListener( 'selectstart', () => {

		workspace.position.copy( intersectRing.position );

	} );
	controller.addEventListener( 'connected', function ( event ) {

		this.controllerActive = true;
		this.add( buildController( event.data ) );

	} );
	controller.addEventListener( 'disconnected', function () {

		this.controllerActive = false;
		this.remove( this.children[ 0 ] );

	} );
	workspace.add( controller );

	// controller models
	const controllerModelFactory = new XRControllerModelFactory();
	controllerGrip = renderer.xr.getControllerGrip( 0 );
	controllerGrip.add( controllerModelFactory.createControllerModel( controllerGrip ) );
	workspace.add( controllerGrip );

	onWindowResize();
	window.addEventListener( 'resize', onWindowResize, false );

	// GUI
	const gui = new dat.GUI();
	gui.width = 300;
	gui.add( params, 'displayGrid' );
	gui.add( params, 'displayBoxBounds' );
	gui.add( params, 'colorMode', {

		NONE,
		SCREEN_ERROR,
		GEOMETRIC_ERROR,
		DISTANCE,
		DEPTH,
		RELATIVE_DEPTH,
		IS_LEAF,
		RANDOM_COLOR,

	} );
	gui.open();

}

function buildController( data ) {

	let geometry, material;

	switch ( data.targetRayMode ) {

		case 'tracked-pointer':

			geometry = new BufferGeometry();
			geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, - 1 ], 3 ) );
			geometry.setAttribute( 'color', new Float32BufferAttribute( [ 0.5, 0.5, 0.5, 0, 0, 0 ], 3 ) );

			material = new LineBasicMaterial( {
				vertexColors: true,
				blending: AdditiveBlending,
				depthWrite: false,
				transparent: true,
			} );

			return new Line( geometry, material );

		case 'gaze':

			geometry = new RingBufferGeometry( 0.02, 0.04, 32 ).translate( 0, 0, - 1 );
			material = new MeshBasicMaterial( { opacity: 0.5, transparent: true } );
			return new Mesh( geometry, material );

	}

}

function onWindowResize() {

	camera.updateProjectionMatrix();
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );

	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();

}

function handleCamera() {

	// get the XR camera with a combined frustum for culling
	if ( renderer.xr.isPresenting ) {

		if ( xrSession === null ) { // We setup XR camera once

			// remove all cameras so we can use the VR camera instead
			tiles.cameras.forEach( c => tiles.deleteCamera( camera ) );

			const currCamera = renderer.xr.getCamera( camera );
			tiles.setCamera( currCamera );

			const leftCam = currCamera.cameras[ 0 ];
			if ( leftCam ) {

				tiles.setResolution( currCamera, leftCam.viewport.z, leftCam.viewport.w );

			}

			xrSession = renderer.xr.getSession();

		}

	} else {

		// Reset default camera (exiting WebXR session)
		if ( xrSession !== null ) {

			tiles.cameras.forEach( c => tiles.deleteCamera( camera ) );

			tiles.setCamera( camera );
			tiles.setResolutionFromRenderer( camera, renderer );

			camera.position.set( 0, 1, 0 );

			xrSession = null;

		}

	}

}

function handleTasks() {

	for ( let t = 0, l = tasks.length; t < l; t ++ ) {

		tasks[ t ]();

	}
	tasks.length = 0;

}

function animate() {

	grid.visible = params.displayGrid;

	// update options
	tiles.displayBoxBounds = params.displayBoxBounds;
	tiles.colorMode = parseFloat( params.colorMode );

	// update tiles center
	if ( tiles.getBounds( box ) ) {

		box.getCenter( tiles.group.position );
		tiles.group.position.multiplyScalar( - 1 );

	} else if ( tiles.getBoundingSphere( sphere ) ) {

		tiles.group.position.copy( sphere.center );
		tiles.group.position.multiplyScalar( - 1 );

	}

	// We check for tiles camera setup (default and XR sessions)
	handleCamera();

	// We handle pending tasks
	handleTasks();

	tiles.update();

	if ( controller.controllerActive ) {

		const { ray } = raycaster;
		raycaster.firstHitOnly = true;

		// get the controller ray
		ray.origin
			.copy( controller.position )
			.applyMatrix4( workspace.matrixWorld );
		controller
			.getWorldDirection( ray.direction )
			.multiplyScalar( - 1 );

		const results = raycaster.intersectObject( tiles.group, true );
		if ( results.length ) {

			const hit = results[ 0 ];

			hit.face.normal.transformDirection( tiles.group.matrixWorld );
			intersectRing.position.copy( hit.point );
			intersectRing.quaternion.setFromUnitVectors(
				fwdVector,
				hit.face.normal,
			);
			intersectRing.visible = true;

			// scale ring based on distance
			const scale = workspace.position.distanceTo( intersectRing.position ) * camera.fov / 4000;
			intersectRing.scale.setScalar( scale );

		} else {

			intersectRing.visible = false;

		}

	} else {

		intersectRing.visible = false;

	}

	// render primary view
	renderer.render( scene, camera );

}
<|endoftext|>


<commit_before>'use strict';

var util = require('../../utilities');

function saveMsg(db,from,channel,message) {
  return (!/^@.*/.test(message) &&
          from != util.bot() &&
          !/\s*s\/(.*)\/(.*)\//.test(message));
}
function messageListener(db, from, channel, message) {

  var messages = [];
  //save the last message the person said
  db.lastsaid = db.lastsaid || {};
  db.lastsaid[from] = db.lastsaid[from] || '';
  if (saveMsg(db,from,channel,message)) {
    db.lastsaid[from] = message;
  }
  if (/^@grab/.test(message)) {
    var match = /^@grab\s+([.-_|\w]+)$/.exec(message);
    db.quotes = db.quotes || {};

    if (match) {
      var sayer = match[1];
      if (sayer != from) {
        db.quotes[sayer] = db.quotes[sayer] || [];
        if (db.lastsaid[sayer] && db.lastsaid[sayer] !== '') {
          db.quotes[sayer].push(db.lastsaid[sayer] + ' at ' + util.now());
          messages.push({ to: channel, message: from + ': OK - message grabbed.' });
        } else {
          messages.push({ to: channel, message: from + ': Sorry, ' + util.bot() + ' has not recorded anything for ' + sayer +'.'});
        }
      } else {
        messages.push({ to: channel, message: from + ': Sorry, you can\'t grab yourself.'});
      }
    } else {
      messages.push({ to: channel, message: 'Usage: @grab <username>' });
    }
  }
  return messages;
}

module.exports = messageListener;
module.exports.help = [{ cmd:'@grab',
                         syntax: '@grab <username>',
                         output: {success: ['<user>: OK - message grabbed.'],
                                  failure: ['<user>: Sorry, <botname> has not recored anything for <username>.',
                                            '<user>: Sorry, you can\'t grab yourself.']}
                       }];

<commit_msg>Drop trailing spaces<commit_after>'use strict';

var util = require('../../utilities');

function saveMsg(db,from,channel,message) {
  return (!/^@.*/.test(message) &&
          from != util.bot() &&
          !/\s*s\/(.*)\/(.*)\//.test(message));
}
function messageListener(db, from, channel, message) {

  var messages = [];
  //save the last message the person said
  db.lastsaid = db.lastsaid || {};
  db.lastsaid[from] = db.lastsaid[from] || '';
  if (saveMsg(db,from,channel,message)) {
    db.lastsaid[from] = message;
  }
  if (/^@grab/.test(message)) {
    var match = /^@grab\s+([.-_|\w]+)\s*$/.exec(message);
    db.quotes = db.quotes || {};

    if (match) {
      var sayer = match[1];
      if (sayer != from) {
        db.quotes[sayer] = db.quotes[sayer] || [];
        if (db.lastsaid[sayer] && db.lastsaid[sayer] !== '') {
          db.quotes[sayer].push(db.lastsaid[sayer] + ' at ' + util.now());
          messages.push({ to: channel, message: from + ': OK - message grabbed.' });
        } else {
          messages.push({ to: channel, message: from + ': Sorry, ' + util.bot() + ' has not recorded anything for ' + sayer +'.'});
        }
      } else {
        messages.push({ to: channel, message: from + ': Sorry, you can\'t grab yourself.'});
      }
    } else {
      messages.push({ to: channel, message: 'Usage: @grab <username>' });
    }
  }
  return messages;
}

module.exports = messageListener;
module.exports.help = [{ cmd:'@grab',
                         syntax: '@grab <username>',
                         output: {success: ['<user>: OK - message grabbed.'],
                                  failure: ['<user>: Sorry, <botname> has not recored anything for <username>.',
                                            '<user>: Sorry, you can\'t grab yourself.']}
                       }];

<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.define('options', function() {
  var OptionsPage = options.OptionsPage;

  /**
   * ImportDataOverlay class
   * Encapsulated handling of the 'Import Data' overlay page.
   * @class
   */
  function ImportDataOverlay() {
    OptionsPage.call(this,
                     'importData',
                     loadTimeData.getString('importDataOverlayTabTitle'),
                     'import-data-overlay');
  }

  cr.addSingletonGetter(ImportDataOverlay);

  ImportDataOverlay.prototype = {
    // Inherit from OptionsPage.
    __proto__: OptionsPage.prototype,

    /**
     * Initialize the page.
     */
    initializePage: function() {
      // Call base class implementation to start preference initialization.
      OptionsPage.prototype.initializePage.call(this);

      var self = this;
      var checkboxes =
          document.querySelectorAll('#import-checkboxes input[type=checkbox]');
      for (var i = 0; i < checkboxes.length; i++) {
        checkboxes[i].onchange = function() {
          self.validateCommitButton_();
        };
      }

      $('import-browsers').onchange = function() {
        self.updateCheckboxes_();
        self.validateCommitButton_();
        self.updateBottomBar_();
      };

      $('import-data-commit').onclick = function() {
        chrome.send('importData', [
            String($('import-browsers').selectedIndex),
            String($('import-history').checked),
            String($('import-favorites').checked),
            String($('import-passwords').checked),
            String($('import-search').checked)]);
      };

      $('import-data-cancel').onclick = function() {
        ImportDataOverlay.dismiss();
      };

      $('import-choose-file').onclick = function() {
        chrome.send('chooseBookmarksFile');
      };

      $('import-data-show-bookmarks-bar').onchange = function() {
        // Note: The callback 'toggleShowBookmarksBar' is handled within the
        // browser options handler -- rather than the import data handler --
        // as the implementation is shared by several clients.
        chrome.send('toggleShowBookmarksBar');
      }

      $('import-data-confirm').onclick = function() {
        ImportDataOverlay.dismiss();
      };

      // Form controls are disabled until the profile list has been loaded.
      self.setAllControlsEnabled_(false);
    },

    /**
     * Sets the enabled and checked state of the commit button.
     * @private
     */
    validateCommitButton_: function() {
      var somethingToImport =
          $('import-history').checked || $('import-favorites').checked ||
          $('import-passwords').checked || $('import-search').checked;
      $('import-data-commit').disabled = !somethingToImport;
    },

    /**
     * Sets the enabled state of all the checkboxes and the commit button.
     * @private
     */
    setAllControlsEnabled_: function(enabled) {
      var checkboxes =
          document.querySelectorAll('#import-checkboxes input[type=checkbox]');
      for (var i = 0; i < checkboxes.length; i++)
        this.setUpCheckboxState_(checkboxes[i], enabled);
      $('import-data-commit').disabled = !enabled;
      $('mac-password-keychain').hidden = !enabled;
    },

    /**
     * Sets the enabled and checked states of a checkbox element.
     * @param {Object} checkbox A checkbox element.
     * @param {boolean} enabled The enabled state of the checkbox. If false,
     * the checkbox is disabled and unchecked. If true, the checkbox is enabled
     * and checked.
     * @param {boolean} visible The visible state of the checkbox.
     * @private
     */
    setUpCheckboxState_: function(checkbox, enabled) {
      checkbox.setDisabled('noProfileData', !enabled);
      checkbox.checked = enabled;
    },

    /**
     * Update the enabled and checked states of all checkboxes.
     * @private
     */
    updateCheckboxes_: function() {
      var index = $('import-browsers').selectedIndex;
      var bookmarksFileSelected = index == this.browserProfiles.length - 1;
      $('import-choose-file').hidden = !bookmarksFileSelected;
      $('import-data-commit').hidden = bookmarksFileSelected;

      var browserProfile;
      if (this.browserProfiles.length > index)
        browserProfile = this.browserProfiles[index];
      var importOptions = ['history', 'favorites', 'passwords', 'search'];
      for (var i = 0; i < importOptions.length; i++) {
        var checkbox = $('import-' + importOptions[i]);
        var enable = browserProfile && browserProfile[importOptions[i]];
        checkbox.checked = enable;
        this.setUpCheckboxState_(checkbox, enable);
        var checkboxWithLabel = $('import-' + importOptions[i] + '-with-label');
        checkboxWithLabel.style.display = enable ? '' : 'none';
      }
    },

    /**
     * Show or hide gray message at the bottom.
     * @private
     */
    updateBottomBar_: function() {
      var index = $('import-browsers').selectedIndex;
      var browserProfile;
      if (this.browserProfiles.length > index)
        browserProfile = this.browserProfiles[index];
      var enable = browserProfile && browserProfile['show_bottom_bar'];
      $('mac-password-keychain').hidden = !enable;
    },

    /**
     * Update the supported browsers popup with given entries.
     * @param {array} browsers List of supported browsers name.
     * @private
     */
    updateSupportedBrowsers_: function(browsers) {
      this.browserProfiles = browsers;
      var browserSelect = $('import-browsers');
      browserSelect.remove(0);  // Remove the 'Loading...' option.
      browserSelect.textContent = '';
      var browserCount = browsers.length;

      if (browserCount == 0) {
        var option = new Option(loadTimeData.getString('noProfileFound'), 0);
        browserSelect.appendChild(option);

        this.setAllControlsEnabled_(false);
      } else {
        this.setAllControlsEnabled_(true);
        for (var i = 0; i < browserCount; i++) {
          var browser = browsers[i];
          var option = new Option(browser.name, browser.index);
          browserSelect.appendChild(option);
        }

        this.updateCheckboxes_();
        this.validateCommitButton_();
        this.updateBottomBar_();
      }
    },

    /**
     * Clear import prefs set when user checks/unchecks a checkbox so that each
     * checkbox goes back to the default "checked" state (or alternatively, to
     * the state set by a recommended policy).
     * @private
     */
    clearUserPrefs_: function() {
      var importPrefs = ['import_history',
                         'import_bookmarks',
                         'import_saved_passwords',
                         'import_search_engine'];
      for (var i = 0; i < importPrefs.length; i++)
        Preferences.clearPref(importPrefs[i], true);
    },

    /**
     * Update the dialog layout to reflect success state.
     * @param {boolean} success If true, show success dialog elements.
     * @private
     */
    updateSuccessState_: function(success) {
      var sections = document.querySelectorAll('.import-data-configure');
      for (var i = 0; i < sections.length; i++)
        sections[i].hidden = success;

      sections = document.querySelectorAll('.import-data-success');
      for (var i = 0; i < sections.length; i++)
        sections[i].hidden = !success;
    },
  };

  ImportDataOverlay.clearUserPrefs = function() {
    ImportDataOverlay.getInstance().clearUserPrefs_();
  };

  /**
   * Update the supported browsers popup with given entries.
   * @param {array} list of supported browsers name.
   */
  ImportDataOverlay.updateSupportedBrowsers = function(browsers) {
    ImportDataOverlay.getInstance().updateSupportedBrowsers_(browsers);
  };

  /**
   * Update the UI to reflect whether an import operation is in progress.
   * @param {boolean} state True if an import operation is in progress.
   */
  ImportDataOverlay.setImportingState = function(state) {
    var checkboxes =
        document.querySelectorAll('#import-checkboxes input[type=checkbox]');
    for (var i = 0; i < checkboxes.length; i++)
        checkboxes[i].setDisabled('Importing', state);
    if (!state)
      ImportDataOverlay.getInstance().updateCheckboxes_();
    $('import-browsers').disabled = state;
    $('import-throbber').style.visibility = state ? 'visible' : 'hidden';
    ImportDataOverlay.getInstance().validateCommitButton_();
  };

  /**
   * Remove the import overlay from display.
   */
  ImportDataOverlay.dismiss = function() {
    ImportDataOverlay.clearUserPrefs();
    OptionsPage.closeOverlay();
  };

  /**
   * Show a message confirming the success of the import operation.
   */
  ImportDataOverlay.confirmSuccess = function() {
    var showBookmarksMessage = $('import-favorites').checked;
    ImportDataOverlay.setImportingState(false);
    $('import-find-your-bookmarks').hidden = !showBookmarksMessage;
    ImportDataOverlay.getInstance().updateSuccessState_(true);
  };

  /**
   * Show the import data overlay.
   */
  ImportDataOverlay.show = function() {
    // Make sure that any previous import success message is hidden, and
    // we're showing the UI to import further data.
    ImportDataOverlay.getInstance().updateSuccessState_(false);
    ImportDataOverlay.getInstance().validateCommitButton_();

    OptionsPage.navigateToPage('importData');
  };

  // Export
  return {
    ImportDataOverlay: ImportDataOverlay
  };
});
<commit_msg>Remove the resetting of the checked state on import dialog.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.define('options', function() {
  var OptionsPage = options.OptionsPage;

  /**
   * ImportDataOverlay class
   * Encapsulated handling of the 'Import Data' overlay page.
   * @class
   */
  function ImportDataOverlay() {
    OptionsPage.call(this,
                     'importData',
                     loadTimeData.getString('importDataOverlayTabTitle'),
                     'import-data-overlay');
  }

  cr.addSingletonGetter(ImportDataOverlay);

  ImportDataOverlay.prototype = {
    // Inherit from OptionsPage.
    __proto__: OptionsPage.prototype,

    /**
     * Initialize the page.
     */
    initializePage: function() {
      // Call base class implementation to start preference initialization.
      OptionsPage.prototype.initializePage.call(this);

      var self = this;
      var checkboxes =
          document.querySelectorAll('#import-checkboxes input[type=checkbox]');
      for (var i = 0; i < checkboxes.length; i++) {
        checkboxes[i].onchange = function() {
          self.validateCommitButton_();
        };
      }

      $('import-browsers').onchange = function() {
        self.updateCheckboxes_();
        self.validateCommitButton_();
        self.updateBottomBar_();
      };

      $('import-data-commit').onclick = function() {
        chrome.send('importData', [
            String($('import-browsers').selectedIndex),
            String($('import-history').checked),
            String($('import-favorites').checked),
            String($('import-passwords').checked),
            String($('import-search').checked)]);
      };

      $('import-data-cancel').onclick = function() {
        ImportDataOverlay.dismiss();
      };

      $('import-choose-file').onclick = function() {
        chrome.send('chooseBookmarksFile');
      };

      $('import-data-show-bookmarks-bar').onchange = function() {
        // Note: The callback 'toggleShowBookmarksBar' is handled within the
        // browser options handler -- rather than the import data handler --
        // as the implementation is shared by several clients.
        chrome.send('toggleShowBookmarksBar');
      }

      $('import-data-confirm').onclick = function() {
        ImportDataOverlay.dismiss();
      };

      // Form controls are disabled until the profile list has been loaded.
      self.setAllControlsEnabled_(false);
    },

    /**
     * Sets the enabled and checked state of the commit button.
     * @private
     */
    validateCommitButton_: function() {
      var somethingToImport =
          $('import-history').checked || $('import-favorites').checked ||
          $('import-passwords').checked || $('import-search').checked;
      $('import-data-commit').disabled = !somethingToImport;
    },

    /**
     * Sets the enabled state of all the checkboxes and the commit button.
     * @private
     */
    setAllControlsEnabled_: function(enabled) {
      var checkboxes =
          document.querySelectorAll('#import-checkboxes input[type=checkbox]');
      for (var i = 0; i < checkboxes.length; i++)
        this.setUpCheckboxState_(checkboxes[i], enabled);
      $('import-data-commit').disabled = !enabled;
      $('mac-password-keychain').hidden = !enabled;
    },

    /**
     * Sets the enabled state of a checkbox element.
     * @param {Object} checkbox A checkbox element.
     * @param {boolean} enabled The enabled state of the checkbox. If false,
     *     the checkbox is disabled. If true, the checkbox is enabled.
     * @private
     */
    setUpCheckboxState_: function(checkbox, enabled) {
      checkbox.setDisabled('noProfileData', !enabled);
    },

    /**
     * Update the enabled and visible states of all the checkboxes.
     * @private
     */
    updateCheckboxes_: function() {
      var index = $('import-browsers').selectedIndex;
      var bookmarksFileSelected = index == this.browserProfiles.length - 1;
      $('import-choose-file').hidden = !bookmarksFileSelected;
      $('import-data-commit').hidden = bookmarksFileSelected;

      var browserProfile;
      if (this.browserProfiles.length > index)
        browserProfile = this.browserProfiles[index];
      var importOptions = ['history', 'favorites', 'passwords', 'search'];
      for (var i = 0; i < importOptions.length; i++) {
        var checkbox = $('import-' + importOptions[i]);
        var enable = browserProfile && browserProfile[importOptions[i]];
        this.setUpCheckboxState_(checkbox, enable);
        var checkboxWithLabel = $('import-' + importOptions[i] + '-with-label');
        checkboxWithLabel.style.display = enable ? '' : 'none';
      }
    },

    /**
     * Show or hide gray message at the bottom.
     * @private
     */
    updateBottomBar_: function() {
      var index = $('import-browsers').selectedIndex;
      var browserProfile;
      if (this.browserProfiles.length > index)
        browserProfile = this.browserProfiles[index];
      var enable = browserProfile && browserProfile['show_bottom_bar'];
      $('mac-password-keychain').hidden = !enable;
    },

    /**
     * Update the supported browsers popup with given entries.
     * @param {array} browsers List of supported browsers name.
     * @private
     */
    updateSupportedBrowsers_: function(browsers) {
      this.browserProfiles = browsers;
      var browserSelect = $('import-browsers');
      browserSelect.remove(0);  // Remove the 'Loading...' option.
      browserSelect.textContent = '';
      var browserCount = browsers.length;

      if (browserCount == 0) {
        var option = new Option(loadTimeData.getString('noProfileFound'), 0);
        browserSelect.appendChild(option);

        this.setAllControlsEnabled_(false);
      } else {
        this.setAllControlsEnabled_(true);
        for (var i = 0; i < browserCount; i++) {
          var browser = browsers[i];
          var option = new Option(browser.name, browser.index);
          browserSelect.appendChild(option);
        }

        this.updateCheckboxes_();
        this.validateCommitButton_();
        this.updateBottomBar_();
      }
    },

    /**
     * Clear import prefs set when user checks/unchecks a checkbox so that each
     * checkbox goes back to the default "checked" state (or alternatively, to
     * the state set by a recommended policy).
     * @private
     */
    clearUserPrefs_: function() {
      var importPrefs = ['import_history',
                         'import_bookmarks',
                         'import_saved_passwords',
                         'import_search_engine'];
      for (var i = 0; i < importPrefs.length; i++)
        Preferences.clearPref(importPrefs[i], true);
    },

    /**
     * Update the dialog layout to reflect success state.
     * @param {boolean} success If true, show success dialog elements.
     * @private
     */
    updateSuccessState_: function(success) {
      var sections = document.querySelectorAll('.import-data-configure');
      for (var i = 0; i < sections.length; i++)
        sections[i].hidden = success;

      sections = document.querySelectorAll('.import-data-success');
      for (var i = 0; i < sections.length; i++)
        sections[i].hidden = !success;
    },
  };

  ImportDataOverlay.clearUserPrefs = function() {
    ImportDataOverlay.getInstance().clearUserPrefs_();
  };

  /**
   * Update the supported browsers popup with given entries.
   * @param {array} list of supported browsers name.
   */
  ImportDataOverlay.updateSupportedBrowsers = function(browsers) {
    ImportDataOverlay.getInstance().updateSupportedBrowsers_(browsers);
  };

  /**
   * Update the UI to reflect whether an import operation is in progress.
   * @param {boolean} state True if an import operation is in progress.
   */
  ImportDataOverlay.setImportingState = function(state) {
    var checkboxes =
        document.querySelectorAll('#import-checkboxes input[type=checkbox]');
    for (var i = 0; i < checkboxes.length; i++)
        checkboxes[i].setDisabled('Importing', state);
    if (!state)
      ImportDataOverlay.getInstance().updateCheckboxes_();
    $('import-browsers').disabled = state;
    $('import-throbber').style.visibility = state ? 'visible' : 'hidden';
    ImportDataOverlay.getInstance().validateCommitButton_();
  };

  /**
   * Remove the import overlay from display.
   */
  ImportDataOverlay.dismiss = function() {
    ImportDataOverlay.clearUserPrefs();
    OptionsPage.closeOverlay();
  };

  /**
   * Show a message confirming the success of the import operation.
   */
  ImportDataOverlay.confirmSuccess = function() {
    var showBookmarksMessage = $('import-favorites').checked;
    ImportDataOverlay.setImportingState(false);
    $('import-find-your-bookmarks').hidden = !showBookmarksMessage;
    ImportDataOverlay.getInstance().updateSuccessState_(true);
  };

  /**
   * Show the import data overlay.
   */
  ImportDataOverlay.show = function() {
    // Make sure that any previous import success message is hidden, and
    // we're showing the UI to import further data.
    ImportDataOverlay.getInstance().updateSuccessState_(false);
    ImportDataOverlay.getInstance().validateCommitButton_();

    OptionsPage.navigateToPage('importData');
  };

  // Export
  return {
    ImportDataOverlay: ImportDataOverlay
  };
});
<|endoftext|>


<commit_before>var exec = require('child_process').exec;
var fs = require('fs');
var path = require('path');

var packages;
var currentPackageIndex = 0;
var original_cwd = process.cwd();
var outDir = path.join(original_cwd, 'captures', 'apks');

if(!fs.existsSync(outDir)) {
    fs.mkdirSync(outDir);
}

process.chdir(outDir);

exec('adb shell pm list packages', function(error, stdout, stderr) {

    packages = stdout.split('\r\n');

    processNext();

});

function processNext() {
    var pk = packages[currentPackageIndex];

    console.log('this', pk);

    var f = pk.replace('package:', '');
    f = f + '-1.apk';

    console.log('pull', f);

    exec('adb pull /data/app/' + f, function(er, sout, serr) {

        currentPackageIndex++;

        if(currentPackageIndex < packages.length) {
            process.nextTick(processNext);
        } else {
            finish();
        }
    });
}

function finish() {
    console.log('done');
    exec('cd ' + original_cwd);
}

<commit_msg>make apk-bck use the settings too<commit_after>var exec = require('child_process').exec;
var fs = require('fs');
var path = require('path');
var settings = require('./settings');

var packages;
var currentPackageIndex = 0;
var original_cwd = process.cwd();
var outDir = path.join(original_cwd, settings.get('outputDir'), settings.get('apksDir'));

console.log('apk-bck out dir=' + outDir);

if(!fs.existsSync(outDir)) {
    fs.mkdirSync(outDir);
}

process.chdir(outDir);

exec('adb shell pm list packages', function(error, stdout, stderr) {

    if(error) {
        var errorMsg = error.toString();
        console.error(errorMsg);
        if(errorMsg.search('device not found')) {
            console.log('>>> hint hint: IS THE DEVICE CONNECTED TO THE COMPUTER?');
        }
    } else {

        packages = stdout.split('\r\n');
        processNext();

    }

});

function processNext() {
    var pk = packages[currentPackageIndex];
    currentPackageIndex++;

    var f = pk.replace('package:', '');
    f = f + '-1.apk';

    console.log(f);

    if(fs.existsSync(f)) {

        console.log('\t=> already exists');
        nextStep();

    } else {

        exec('adb pull /data/app/' + f, function(er, sout, serr) {
            nextStep();
        });

    }
}

function nextStep() {
    if(currentPackageIndex < packages.length) {
        process.nextTick(processNext);
    } else {
        finish();
    }
}

function finish() {
    console.log('done');
    exec('cd ' + original_cwd);
}

<|endoftext|>