<commit_before>var gulp = require('gulp'),
    gutil = require('gulp-util'),
    jshint = require('gulp-jshint'),
    cached = require('gulp-cached'),
    coverage = require('gulp-jsx-coverage'),
    fs = require('fs'),
    React = require('react-tools'),
    through = require('through2'),
    buffer = require('vinyl-buffer'),
    source = require('vinyl-source-stream'),
    aliasify = require('aliasify'),
    browserify = require('browserify'),
    uglify = require('gulp-uglify'),
    nodemon = require('nodemon'),
    browserSync = require('browser-sync'),
    serverStarted = false,

// If you use vim and watch tasks be triggered 2 times when saving
// You can :set nowritebackup in vim to prevent this
// Reference: https://github.com/joyent/node/issues/3172
configs = {
    static_dir: 'static/',
    mainjs: require(process.cwd() + '/package.json').main,
    appjs: process.cwd() + '/fluxexapp.js',
    nodemon_restart_delay: 200,
    nodemon_delay: 2000,
    gulp_watch: {debounceDelay: 500},
    watchify: {debug: true, delay: 500},
    jshint_jsx: {quotmark: false},
    jslint_fail: false,
    aliasify: {
        aliases: {
            request: 'browser-request'
        }
    },
    test_coverage: {
        default: {
            src: ['test/**/*.js', 'test/components/*.js*'],
            istanbul: {
                coverageVariable: '__FLUXEX_COVERAGE__',
                exclude: /node_modules\/|test\//
            },
            coverage: {
                directory: 'coverage'
            },
            mocha: {},
            react: {
                sourceMap: true
            },
            coffee: {
                sourceMap: true
            }
        },
        console: {
            coverage: {
                reporters: ['text-summary']
            },
            mocha: {
                reporter: 'spec'
            }
        },
        report: {
            coverage: {
                reporters: ['lcov', 'json']
            },
            mocha: {
                reporter: 'tap'
            }
        }
    }
},

build_files = {
    js: ['actions/*.js', 'stores/*.js'],
    jsx: ['components/*.jsx']
},

restart_nodemon = function () {
    setTimeout(function () {
        nodemon.emit('restart');
    }, configs.nodemon_restart_delay);
},

lint_chain = function (task) {
    task = task.pipe(jshint.reporter('jshint-stylish'));

    if (configs.jslint_fail) {
        task = task.pipe(jshint.reporter('fail'));
    }

    return task;
},

// Stop using gulp-react because it do not keep original file name
react_compiler = function (options) {
    return through.obj(function (file, enc, callback) {
        try {
            file.contents = new Buffer(React.transform(file.contents.toString(), options));
            this.push(file);
        } catch (E) {
            gutil.log('[jsx ERROR]', gutil.colors.red(file.path));
            gutil.log('[jsx ERROR]', gutil.colors.red(E.message));
        }
        callback();
    });
},

// Do testing tasks
get_testing_task = function (options) {
    var cfg = JSON.parse(JSON.stringify(configs.test_coverage.default));

    cfg.istanbul.exclude = configs.test_coverage.default.istanbul.exclude;
    cfg.coverage.reporters = options.coverage.reporters;
    cfg.mocha = options.mocha;

    return coverage.createTask(cfg);
},

bundleAll = function (b, noSave) {
    var B = b.bundle()
    .on('error', function (E) {
        gutil.log('[browserify ERROR]', gutil.colors.red(E));
    });

    if (!noSave) {
        B.pipe(source('main.js'))
        .pipe(gulp.dest(configs.static_dir + 'js/'))
        .on('end', restart_nodemon);
    }

    return B;
},

buildApp = function (watch, fullpath, nosave, disc) {
    var b = browserify(configs.appjs, {
        cache: {},
        packageCache: {},
        require: (disc ? process.cwd() : '.') + '/components/Html.jsx',
        standalone: 'Fluxex',
        fullPaths: fullpath ? true: false,
        debug: watch
    });

    b.transform('reactify');
    b.transform(aliasify.configure(configs.aliasify), {global: true});

    if (watch) {
        b = require('watchify')(b, configs.watchify);
        b.on('update', function (F) {
            gutil.log('[browserify] ' + F[0] + ' updated');
            bundleAll(b);
        });
    }

    return bundleAll(b, nosave);
};

gulp.task('build_app', function () {
    return buildApp(false, false, true)
        .pipe(source('main.js'))
        .pipe(buffer())
        .pipe(uglify())
        .pipe(gulp.dest(configs.static_dir + 'js/'));
});

gulp.task('disc_app', function () {
    return buildApp(false, true, true, true)
        .pipe(require('disc')())
        .pipe(fs.createWriteStream(configs.static_dir + 'disc.html'));
});

gulp.task('watch_app', function () {
    return buildApp(true, true);
});

gulp.task('watch_flux_js', ['lint_flux_js'], function () {
    gulp.watch(build_files.js, configs.gulp_watch, ['lint_flux_js']);
});

gulp.task('lint_flux_js', function () {
    return lint_chain(
        gulp.src(build_files.js)
        .pipe(cached('jshint'))
        .pipe(jshint())
    );
});

gulp.task('watch_jsx', ['lint_jsx'], function () {
    gulp.watch(build_files.jsx, configs.gulp_watch, ['lint_jsx']);
});

gulp.task('lint_jsx', function () {
    return lint_chain(
        gulp.src(build_files.jsx)
        .pipe(cached('jshint'))
        .pipe(react_compiler({sourceMap: true}))
        .pipe(jshint(configs.jshint_jsx))
    );
});

gulp.task('watch_server', ['lint_server'], function () {
    gulp.watch(configs.mainjs, configs.gulp_watch, ['lint_server'])
    .on('change', function () {
        nodemon.emit('restart');
    });
});

gulp.task('lint_server', function () {
    return gulp.src(configs.mainjs)
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'));
});

gulp.task('nodemon_server', ['watch_flux_js', 'watch_jsx', 'watch_app', 'watch_server'], function () {
    nodemon({
        ignore: '*',
        script: configs.mainjs,
        ext: 'do_not_watch'
    })
    .on('log', function (log) {
        gutil.log(log.colour);
    })
    .on('start', function () {
        if (serverStarted) {
            setTimeout(browserSync.reload, configs.nodemon_delay);
        } else {
            browserSync.init(null, {
                proxy: 'http://localhost:3000',
                files: [configs.static_dir + 'css/*.css'],
                port: 3001,
                online: false,
                open: false
            });

            serverStarted = true;
        }
    });
});

gulp.task('test_app', get_testing_task(configs.test_coverage.console));
gulp.task('save_test_app', get_testing_task(configs.test_coverage.report));
gulp.task('develop', ['nodemon_server']);
gulp.task('lint_all', ['lint_server', 'lint_flux_js', 'lint_jsx']);
gulp.task('buildall', ['lint_all', 'build_app']);
gulp.task('default',['buildall']);

module.exports = configs;
<commit_msg>pipe to gulp-github when enabled setting<commit_after>var gulp = require('gulp'),
    gutil = require('gulp-util'),
    jshint = require('gulp-jshint'),
    cached = require('gulp-cached'),
    coverage = require('gulp-jsx-coverage'),
    fs = require('fs'),
    React = require('react-tools'),
    through = require('through2'),
    buffer = require('vinyl-buffer'),
    source = require('vinyl-source-stream'),
    aliasify = require('aliasify'),
    browserify = require('browserify'),
    uglify = require('gulp-uglify'),
    nodemon = require('nodemon'),
    browserSync = require('browser-sync'),
    serverStarted = false,

// If you use vim and watch tasks be triggered 2 times when saving
// You can :set nowritebackup in vim to prevent this
// Reference: https://github.com/joyent/node/issues/3172
configs = {
    static_dir: 'static/',
    mainjs: require(process.cwd() + '/package.json').main,
    appjs: process.cwd() + '/fluxexapp.js',
    nodemon_restart_delay: 200,
    nodemon_delay: 2000,
    gulp_watch: {debounceDelay: 500},
    watchify: {debug: true, delay: 500},
    jshint_jsx: {quotmark: false},
    jslint_fail: false,
    aliasify: {
        aliases: {
            request: 'browser-request'
        }
    },
    test_coverage: {
        default: {
            src: ['test/**/*.js', 'test/components/*.js*'],
            istanbul: {
                coverageVariable: '__FLUXEX_COVERAGE__',
                exclude: /node_modules\/|test\//
            },
            coverage: {
                directory: 'coverage'
            },
            mocha: {},
            react: {
                sourceMap: true
            },
            coffee: {
                sourceMap: true
            }
        },
        console: {
            coverage: {
                reporters: ['text-summary']
            },
            mocha: {
                reporter: 'spec'
            }
        },
        report: {
            coverage: {
                reporters: ['lcov', 'json']
            },
            mocha: {
                reporter: 'tap'
            }
        }
    }
},

build_files = {
    js: ['actions/*.js', 'stores/*.js'],
    jsx: ['components/*.jsx']
},

restart_nodemon = function () {
    setTimeout(function () {
        nodemon.emit('restart');
    }, configs.nodemon_restart_delay);
},

lint_chain = function (task) {
    task = task.pipe(jshint.reporter('jshint-stylish'));

    if (configs.jslint_fail) {
        task = task.pipe(jshint.reporter('fail'));
    }

    if (configs.github) {
        task = task.pipe(require('gulp-github')(configs.github));
    }

    return task;
},

// Stop using gulp-react because it do not keep original file name
react_compiler = function (options) {
    return through.obj(function (file, enc, callback) {
        try {
            file.contents = new Buffer(React.transform(file.contents.toString(), options));
            this.push(file);
        } catch (E) {
            gutil.log('[jsx ERROR]', gutil.colors.red(file.path));
            gutil.log('[jsx ERROR]', gutil.colors.red(E.message));
        }
        callback();
    });
},

// Do testing tasks
get_testing_task = function (options) {
    var cfg = JSON.parse(JSON.stringify(configs.test_coverage.default));

    cfg.istanbul.exclude = configs.test_coverage.default.istanbul.exclude;
    cfg.coverage.reporters = options.coverage.reporters;
    cfg.mocha = options.mocha;

    return coverage.createTask(cfg);
},

bundleAll = function (b, noSave) {
    var B = b.bundle()
    .on('error', function (E) {
        gutil.log('[browserify ERROR]', gutil.colors.red(E));
    });

    if (!noSave) {
        B.pipe(source('main.js'))
        .pipe(gulp.dest(configs.static_dir + 'js/'))
        .on('end', restart_nodemon);
    }

    return B;
},

buildApp = function (watch, fullpath, nosave, disc) {
    var b = browserify(configs.appjs, {
        cache: {},
        packageCache: {},
        require: (disc ? process.cwd() : '.') + '/components/Html.jsx',
        standalone: 'Fluxex',
        fullPaths: fullpath ? true: false,
        debug: watch
    });

    b.transform('reactify');
    b.transform(aliasify.configure(configs.aliasify), {global: true});

    if (watch) {
        b = require('watchify')(b, configs.watchify);
        b.on('update', function (F) {
            gutil.log('[browserify] ' + F[0] + ' updated');
            bundleAll(b);
        });
    }

    return bundleAll(b, nosave);
};

gulp.task('build_app', function () {
    return buildApp(false, false, true)
        .pipe(source('main.js'))
        .pipe(buffer())
        .pipe(uglify())
        .pipe(gulp.dest(configs.static_dir + 'js/'));
});

gulp.task('disc_app', function () {
    return buildApp(false, true, true, true)
        .pipe(require('disc')())
        .pipe(fs.createWriteStream(configs.static_dir + 'disc.html'));
});

gulp.task('watch_app', function () {
    return buildApp(true, true);
});

gulp.task('watch_flux_js', ['lint_flux_js'], function () {
    gulp.watch(build_files.js, configs.gulp_watch, ['lint_flux_js']);
});

gulp.task('lint_flux_js', function () {
    return lint_chain(
        gulp.src(build_files.js)
        .pipe(cached('jshint'))
        .pipe(jshint())
    );
});

gulp.task('watch_jsx', ['lint_jsx'], function () {
    gulp.watch(build_files.jsx, configs.gulp_watch, ['lint_jsx']);
});

gulp.task('lint_jsx', function () {
    return lint_chain(
        gulp.src(build_files.jsx)
        .pipe(cached('jshint'))
        .pipe(react_compiler({sourceMap: true}))
        .pipe(jshint(configs.jshint_jsx))
    );
});

gulp.task('watch_server', ['lint_server'], function () {
    gulp.watch(configs.mainjs, configs.gulp_watch, ['lint_server'])
    .on('change', function () {
        nodemon.emit('restart');
    });
});

gulp.task('lint_server', function () {
    return gulp.src(configs.mainjs)
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'));
});

gulp.task('nodemon_server', ['watch_flux_js', 'watch_jsx', 'watch_app', 'watch_server'], function () {
    nodemon({
        ignore: '*',
        script: configs.mainjs,
        ext: 'do_not_watch'
    })
    .on('log', function (log) {
        gutil.log(log.colour);
    })
    .on('start', function () {
        if (serverStarted) {
            setTimeout(browserSync.reload, configs.nodemon_delay);
        } else {
            browserSync.init(null, {
                proxy: 'http://localhost:3000',
                files: [configs.static_dir + 'css/*.css'],
                port: 3001,
                online: false,
                open: false
            });

            serverStarted = true;
        }
    });
});

gulp.task('test_app', get_testing_task(configs.test_coverage.console));
gulp.task('save_test_app', get_testing_task(configs.test_coverage.report));
gulp.task('develop', ['nodemon_server']);
gulp.task('lint_all', ['lint_server', 'lint_flux_js', 'lint_jsx']);
gulp.task('buildall', ['lint_all', 'build_app']);
gulp.task('default',['buildall']);

module.exports = configs;
<|endoftext|>


<commit_before>let mod = new ActionObj('Back');
module.exports = mod;

mod.nextTarget = function() {
    const creep = this.creep;
    if(creep.room.name === creep.memory.homeRoom) {
        const pos = creep.pos;
        if(pos.x === 0 || pos.x === 49 || pos.y === 0 || pos.y === 49) {
            //Don't stay at exit, creep will loop between room
            return creep.room.controller;
        } else {
            return false;
        }
    }

    const homeRoom = Game.rooms[creep.memory.homeRoom];
    return homeRoom.controller;
};

mod.word = '🕵 Back';

mod.loop = function(creep) {
    return this.loop0(creep, (creep, target) => {
        creep.moveTo(target, {
            reusePath: 15,
            visualizePathStyle: {stroke: '#ffffff'}
        });
    });
};
<commit_msg>remove edge case in action.travel<commit_after>let mod = new ActionObj('Back');
module.exports = mod;

mod.nextTarget = function() {
    const creep = this.creep;
    if(creep.room.name === creep.memory.homeRoom) {
        return false;
        /*
        const pos = creep.pos;
        if(pos.x === 0 || pos.x === 49 || pos.y === 0 || pos.y === 49) {
            //Don't stay at exit, creep will loop between room
            return creep.room.controller;
        } else {
            return false;
        }
        */
    }

    const homeRoom = Game.rooms[creep.memory.homeRoom];
    return homeRoom.controller;
};

mod.word = '🕵 Back';

mod.loop = function(creep) {
    return this.loop0(creep, (creep, target) => {
        creep.moveTo(target, {
            reusePath: 15,
            visualizePathStyle: {stroke: '#ffffff'}
        });
    });
};
<|endoftext|>


<commit_before>import t from "tcomb"
import alt from "alt-instance"
import iDB from "idb-instance"
import idb_helper from "../idb-helper"
import v from "chain/serializer_validation"

import Apis from "rpc_api/ApiInstances"
import WalletDb from "stores/WalletDb"
import AccountStore from "stores/AccountStore";
import PrivateKeyStore from "stores/PrivateKeyStore"
import ImportKeysActions from "actions/ImportKeysActions"
import TransactionConfirmActions from "actions/TransactionConfirmActions"
import BalanceClaimActions from "actions/BalanceClaimActions"
import WalletUnlockActions from "actions/WalletUnlockActions"

import chain_api from "api/ChainStore";
import ApplicationApi from "rpc_api/ApplicationApi"
import AssetTcomb from "stores/tcomb_structs"
import ops from 'chain/signed_transaction'

var application_api = new ApplicationApi()
var api = Apis.instance()

let AssetTypeTcomb = t.struct({
    amount: t.Any, //string or number, TODO fix in c++
    asset_id: t.Str
}, 'AssetTypeTcomb')

export var BalanceClaimTcomb = t.struct({
    chain_balance_record: t.Obj,
    pubkey: t.Str,
    is_claimed: t.maybe(t.Bool),
    vested_balance: t.maybe(AssetTypeTcomb)
}, 'BalanceClaimTcomb')

var TRACE = true

class BalanceClaimStore {

    constructor() {
        this.bindActions(BalanceClaimActions)
        this.bindListeners({
            onRefreshBalanceClaims: TransactionConfirmActions.wasBroadcast,
            onLoadMyAccounts: [
                WalletUnlockActions.change//, ImportKeysActions.saved
            ]
        })
        this.balances_saving = 0
        this.pending_add_promises = []
        this.state = {
            balance_by_account_asset: [],
            my_accounts: [],
            my_account_private_key_tcombs: {},
            my_accounts_loading: false,
            balance_claims: [],
            balance_ids: [],
            balances_saving: 0,
            balances_error: null
        }
    }

    onWillMount() {
        this.mounted = true
    }

    onWillUnmount() {
        this.mounted = false
    }

    /**
        No need to wait on the promises returned by this method as long
        as this.state.balances_error == null and this.state.balances_saving == 0
        are both true before performing any important operations.
    */
    onAdd({balance_claim, transaction}) {
        BalanceClaimTcomb(balance_claim)
        this.indexBalanceClaim(balance_claim)
        var p1 = idb_helper.add(
            transaction.objectStore("balance_claims"),
            balance_claim
        )
        this.pending_add_promises.push(p1)
        return p1
    }

    loadBalanceClaims() {
        if(this.loadBalanceClaimsLoaded) return Promise.resolve()
        return idb_helper.cursor("balance_claims", cursor => {
            if( ! cursor) return
            var balance_claim = cursor.value
            this.indexBalanceClaim(balance_claim)
            cursor.continue()
        }).then(()=>{
            this.loadBalanceClaimsLoaded = true
            this.forceUpdate()
        }).catch( balances_error => {
            this.setState({balances_error})
        })
    }

    indexBalanceClaim(balance_claim) {
        this.state.balance_claims.push( balance_claim )
        this.state.balance_ids.push( balance_claim.chain_balance_record.id )
        //this.setBalanceClaims(this.state.balance_claims)
    }

    /** Called both on initial import and display of balance claims and then
    again anytime the balance claim UI is mounted.  This is to ensure the data
    being viewed is accurate.
    */
    onRefreshBalanceClaims() {
        if( ! this.mounted) return
        if(TRACE) console.log('... BalanceClaimStore.onRefreshBalanceClaims START')
        var balance_claims = this.state.balance_claims
        var balance_ids = this.state.balance_ids
        this.loadBalanceClaims().then( ()=> {
            //DEBUG console.log('... refresh')
            if( ! balance_claims.length) {
                this.setBalanceClaims( [] )
                if(TRACE) console.log('... BalanceClaimStore.onRefreshBalanceClaims done, no claims import keys first')
                return
            }
            if(TRACE) console.log('... BalanceClaimStore.onRefreshBalanceClaims get_objects start')
            var db = api.db_api()

            //DEBUG console.log("get_vested_balances",result)

            var get_objects_promise
            //if(this.pending_add_promises.length)
            //    get_objects_promise = Promise.resolve(balance_claims)
            //else
                get_objects_promise = db.exec("get_objects", [balance_ids])

            return get_objects_promise.then( result => {
                if(TRACE) console.log('... BalanceClaimStore.onRefreshBalanceClaims get_objects DONE')
                var ps = []
                for(let i = 0; i < result.length; i++) {
                    var balance_claim = balance_claims[i]
                    var chain_balance_record = result[i]
                    //DEBUG console.log('... chain_balance_record',chain_balance_record)
                    if( ! chain_balance_record) {
                        balance_claims[i] = BalanceClaimTcomb.update(
                            BalanceClaimTcomb(balance_claim), {
                                is_claimed: { '$set': true }
                            }
                        )
                    } else {
                        balance_claims[i] = BalanceClaimTcomb.update(
                            BalanceClaimTcomb(balance_claim), {
                                chain_balance_record: { '$set': chain_balance_record }
                            }
                        )
                        if(chain_balance_record.vesting_policy) { (i => {
                            ps.push(db.exec("get_vested_balances",
                                [[chain_balance_record.id]]).then( vested_balances => {
                                var vested_balance = vested_balances[0]
                                balance_claims[i] = BalanceClaimTcomb.update(
                                    BalanceClaimTcomb(balance_claims[i]), {
                                        vested_balance: {'$set': vested_balance}
                                    }
                                )
                            }))
                        })(i) }
                    }
                }
                Promise.all(ps).then(()=> this.setBalanceClaims(balance_claims))
                return Promise.all(this.pending_add_promises).then( ()=> {
                    this.pending_add_promises = []
                    var transaction = this.transaction_update()
                    var store = transaction.objectStore("balance_claims")

                    for(let balance_claim of balance_claims) {
                        var request = store.put(balance_claim)
                        ps.push(idb_helper.on_request_end(request))
                    }
                    return Promise.all(ps).then( ()=> {
                        this.setBalanceClaims(balance_claims)
                        if(TRACE) console.log('... BalanceClaimStore.onRefreshBalanceClaims DONE')
                    })
                })
            })
        }).catch( balance_claim_error => this.setState({balance_claim_error}) )
    }

    /** Populate this.state.my_accounts with only account where the wallet
    has full transaction signing authority.  This needs to be done until
    the user needs more flexibility and can be warned that they could not spend
    the claimed balance in this wallet.

    Blocks the case where the import file may have an account name registered to
    someone else.
    */
    onLoadMyAccounts() {
        if( ! this.mounted) return
        if(TRACE) console.log('... BalanceClaimStore.onLoadMyAccounts')
        if( WalletDb.isLocked()) return
        if(TRACE) console.log('... BalanceClaimStore.loadMyAccounts START')
        this.setState({my_accounts_loading:true})
        var account_names = AccountStore.getState().linkedAccounts.toArray()
        var promises = []
        for(let account_name of account_names) {

            var found = false
            for(let account of this.state.my_accounts)
                if(account_name == account)
                    found = true
            if(found)
                continue

            var db = api.db_api()
            if(TRACE) console.log('... BalanceClaimStore.onLoadMyAccounts lookupAccountByName')
            var p = db.exec("get_account_by_name", [account_name]).then ( account => {

                if( ! account) return
                //DEBUG console.log('... account lookupAccountByName',account.get("id"),account.get("name"))

                // todo, move to ChainStore
                // the fake transfer will check for required auths
                var tr = new ops.signed_transaction()
                tr.add_type_operation("transfer", {
                    fee: { amount: 0, asset_id: 0 },
                    from: account.id,
                    to: account.id,
                    amount: { amount: 1, asset_id: 0},
                    null//memo
                })
                return tr.get_potential_signatures().then((public_keys)=>{
                    //var pubkeys = PrivateKeyStore.getPubkeys()
                    var pubkeys = PrivateKeyStore.getPubkeys_having_PrivateKey(public_keys)
                    if( ! pubkeys.length)
                        return {account_name:null, private_key_tcombs: []}

                    return tr.get_required_signatures(pubkeys).then(
                        pubkey_strings => {
                        //DEBUG console.log('... get_required_signatures',pubkey_strings)//,tr.serialize())
                        var private_key_tcombs = []
                        for(let pubkey_string of pubkey_strings) {
                            //var private_key = WalletDb.getPrivateKey(pubkey_string)
                            var private_key_tcomb = PrivateKeyStore.getTcomb_byPubkey(pubkey_string)
                            if( private_key_tcomb )
                                private_key_tcombs.push(private_key_tcomb[0])
                            else {
                                // Missing signing key
                                console.log('... BalanceClaimStore NOT my account1', account.name)
                                return null
                            }
                        }
                        return {
                            account_name: account.name,
                            private_key_tcombs
                        }
                    })
                })

            }).catch( error => {
                //DEBUG Account not found console.log('... error1',error)
            })
            promises.push(p)
        }
        if(TRACE) console.log('... done..');

        Promise.all(promises).then( account_names => {
            var my_accounts = this.state.my_accounts
            var my_account_private_key_tcombs = this.state.my_account_private_key_tcombs
            for(let obj of account_names) {
                if( ! obj) {
                    if(TRACE) console.log('... BalanceClaimStore NOT my account2',
                        obj.account_name,error)
                    continue
                }
                if(TRACE) console.log('... BalanceClaimStore my account')
                var {account_name, private_key_tcombs} = obj
                my_accounts.push(account_name)
                my_account_private_key_tcombs[account_name] = private_key_tcombs
            }
            //DEBUG console.log('... my_accounts',my_accounts)
            this.setState({my_accounts, my_account_private_key_tcombs,
                my_accounts_loading:false})
            if(TRACE) console.log('... BalanceClaimStore.onLoadMyAccounts DONE')
        }).catch( balance_claim_error => {
            console.log('BalanceClaimStore.onLoadMyAccounts', balance_claim_error)
            this.setState({balance_claim_error})
        })
    }

    setBalanceClaims(balance_claims) {
        var balance_by_account_asset = this.balanceByAssetName(balance_claims)
        this.setState({balance_claims, balance_by_account_asset, loading: false,
            balance_claim_error:null})
    }

    transaction_update() {
        var transaction = iDB.instance().db().transaction(
            ["balance_claims"], "readwrite"
        )
        return transaction
    }

    /** group things for reporting purposes */
    balanceByAssetName(balance_claims) {
        var asset_totals = {}
        for(let balance_claim of balance_claims) {
            var b = balance_claim.chain_balance_record
            var vested_balance = balance_claim.vested_balance

            var pubkey = balance_claim.pubkey
            var private_key_tcomb = PrivateKeyStore.getTcomb_byPubkey(pubkey)
            if(! private_key_tcomb) {
                console.error("balance claim has no coresponding private key")
                continue
            }
            var import_account_names =
                private_key_tcomb.import_account_names

            var group_by =
                import_account_names.join("\t") +
                b.balance.asset_id + "\t"

            var total =
                asset_totals[group_by] || (
                asset_totals[group_by] =
            {
                vesting: {claimed:0, unclaimed:0, total:0},
                unvested: {claimed:0, unclaimed:0},
                accounts: import_account_names,
                balance_claims: [],
                asset_id: b.balance.asset_id
            })
            if(b.vesting_policy) {
                if(balance_claim.is_claimed)
                    total.vesting.claimed += v.to_number(b.balance.amount)
                else {
                    //DEBUG console.log('... b.balance.amount',b.balance.amount,vested_balance.amount)
                    total.vesting.total += v.to_number(b.balance.amount)
                    if(vested_balance)
                        total.vesting.unclaimed += v.to_number(vested_balance.amount)
                }
            } else {
                if(balance_claim.is_claimed)
                    total.unvested.claimed += v.to_number(b.balance.amount)
                else
                    total.unvested.unclaimed += v.to_number(b.balance.amount)
            }
            total.balance_claims.push(balance_claim)
        }
        var balance_by_account_asset = []
        for(let key of Object.keys(asset_totals).sort()) {
            var total_record = asset_totals[key]
            var accounts = total_record.accounts
            var balance = {
                vesting: total_record.vesting,
                unvested: total_record.unvested
            }
            var balance_claims = total_record.balance_claims
            balance_by_account_asset.push({
                accounts, asset_id:total_record.asset_id,
                balance, balance_claims})
        }
        return balance_by_account_asset
    }

}

export var BalanceClaimStoreWrapped = alt.createStore(BalanceClaimStore, "BalanceClaimStore");
export default BalanceClaimStoreWrapped
<commit_msg>Fixed null ptr in balance claim, turned trace off<commit_after>import t from "tcomb"
import alt from "alt-instance"
import iDB from "idb-instance"
import idb_helper from "../idb-helper"
import v from "chain/serializer_validation"

import Apis from "rpc_api/ApiInstances"
import WalletDb from "stores/WalletDb"
import AccountStore from "stores/AccountStore";
import PrivateKeyStore from "stores/PrivateKeyStore"
import ImportKeysActions from "actions/ImportKeysActions"
import TransactionConfirmActions from "actions/TransactionConfirmActions"
import BalanceClaimActions from "actions/BalanceClaimActions"
import WalletUnlockActions from "actions/WalletUnlockActions"

import chain_api from "api/ChainStore";
import ApplicationApi from "rpc_api/ApplicationApi"
import AssetTcomb from "stores/tcomb_structs"
import ops from 'chain/signed_transaction'

var application_api = new ApplicationApi()
var api = Apis.instance()

let AssetTypeTcomb = t.struct({
    amount: t.Any, //string or number, TODO fix in c++
    asset_id: t.Str
}, 'AssetTypeTcomb')

export var BalanceClaimTcomb = t.struct({
    chain_balance_record: t.Obj,
    pubkey: t.Str,
    is_claimed: t.maybe(t.Bool),
    vested_balance: t.maybe(AssetTypeTcomb)
}, 'BalanceClaimTcomb')

var TRACE = false

class BalanceClaimStore {

    constructor() {
        this.bindActions(BalanceClaimActions)
        this.bindListeners({
            onRefreshBalanceClaims: TransactionConfirmActions.wasBroadcast,
            onLoadMyAccounts: [
                WalletUnlockActions.change//, ImportKeysActions.saved
            ]
        })
        this.balances_saving = 0
        this.pending_add_promises = []
        this.state = {
            balance_by_account_asset: [],
            my_accounts: [],
            my_account_private_key_tcombs: {},
            my_accounts_loading: false,
            balance_claims: [],
            balance_ids: [],
            balances_saving: 0,
            balances_error: null
        }
    }

    onWillMount() {
        this.mounted = true
    }

    onWillUnmount() {
        this.mounted = false
    }

    /**
        No need to wait on the promises returned by this method as long
        as this.state.balances_error == null and this.state.balances_saving == 0
        are both true before performing any important operations.
    */
    onAdd({balance_claim, transaction}) {
        BalanceClaimTcomb(balance_claim)
        this.indexBalanceClaim(balance_claim)
        var p1 = idb_helper.add(
            transaction.objectStore("balance_claims"),
            balance_claim
        )
        this.pending_add_promises.push(p1)
        return p1
    }

    loadBalanceClaims() {
        if(this.loadBalanceClaimsLoaded) return Promise.resolve()
        return idb_helper.cursor("balance_claims", cursor => {
            if( ! cursor) return
            var balance_claim = cursor.value
            this.indexBalanceClaim(balance_claim)
            cursor.continue()
        }).then(()=>{
            this.loadBalanceClaimsLoaded = true
            this.forceUpdate()
        }).catch( balances_error => {
            this.setState({balances_error})
        })
    }

    indexBalanceClaim(balance_claim) {
        this.state.balance_claims.push( balance_claim )
        this.state.balance_ids.push( balance_claim.chain_balance_record.id )
        //this.setBalanceClaims(this.state.balance_claims)
    }

    /** Called both on initial import and display of balance claims and then
    again anytime the balance claim UI is mounted.  This is to ensure the data
    being viewed is accurate.
    */
    onRefreshBalanceClaims() {
        if( ! this.mounted) return
        if(TRACE) console.log('... BalanceClaimStore.onRefreshBalanceClaims START')
        var balance_claims = this.state.balance_claims
        var balance_ids = this.state.balance_ids
        this.loadBalanceClaims().then( ()=> {
            //DEBUG console.log('... refresh')
            if( ! balance_claims.length) {
                this.setBalanceClaims( [] )
                if(TRACE) console.log('... BalanceClaimStore.onRefreshBalanceClaims done, no claims import keys first')
                return
            }
            if(TRACE) console.log('... BalanceClaimStore.onRefreshBalanceClaims get_objects start')
            var db = api.db_api()

            //DEBUG console.log("get_vested_balances",result)

            var get_objects_promise
            //if(this.pending_add_promises.length)
            //    get_objects_promise = Promise.resolve(balance_claims)
            //else
                get_objects_promise = db.exec("get_objects", [balance_ids])

            return get_objects_promise.then( result => {
                if(TRACE) console.log('... BalanceClaimStore.onRefreshBalanceClaims get_objects DONE')
                var ps = []
                for(let i = 0; i < result.length; i++) {
                    var balance_claim = balance_claims[i]
                    var chain_balance_record = result[i]
                    //DEBUG console.log('... chain_balance_record',chain_balance_record)
                    if( ! chain_balance_record) {
                        balance_claims[i] = BalanceClaimTcomb.update(
                            BalanceClaimTcomb(balance_claim), {
                                is_claimed: { '$set': true }
                            }
                        )
                    } else {
                        balance_claims[i] = BalanceClaimTcomb.update(
                            BalanceClaimTcomb(balance_claim), {
                                chain_balance_record: { '$set': chain_balance_record }
                            }
                        )
                        if(chain_balance_record.vesting_policy) { (i => {
                            ps.push(db.exec("get_vested_balances",
                                [[chain_balance_record.id]]).then( vested_balances => {
                                var vested_balance = vested_balances[0]
                                balance_claims[i] = BalanceClaimTcomb.update(
                                    BalanceClaimTcomb(balance_claims[i]), {
                                        vested_balance: {'$set': vested_balance}
                                    }
                                )
                            }))
                        })(i) }
                    }
                }
                Promise.all(ps).then(()=> this.setBalanceClaims(balance_claims))
                return Promise.all(this.pending_add_promises).then( ()=> {
                    this.pending_add_promises = []
                    var transaction = this.transaction_update()
                    var store = transaction.objectStore("balance_claims")

                    for(let balance_claim of balance_claims) {
                        var request = store.put(balance_claim)
                        ps.push(idb_helper.on_request_end(request))
                    }
                    return Promise.all(ps).then( ()=> {
                        this.setBalanceClaims(balance_claims)
                        if(TRACE) console.log('... BalanceClaimStore.onRefreshBalanceClaims DONE')
                    })
                })
            })
        }).catch( balance_claim_error => this.setState({balance_claim_error}) )
    }

    /** Populate this.state.my_accounts with only account where the wallet
    has full transaction signing authority.  This needs to be done until
    the user needs more flexibility and can be warned that they could not spend
    the claimed balance in this wallet.

    Blocks the case where the import file may have an account name registered to
    someone else.
    */
    onLoadMyAccounts() {
        if( ! this.mounted) return
        if(TRACE) console.log('... BalanceClaimStore.onLoadMyAccounts')
        if( WalletDb.isLocked()) return
        if(TRACE) console.log('... BalanceClaimStore.loadMyAccounts START')
        this.setState({my_accounts_loading:true})
        var account_names = AccountStore.getState().linkedAccounts.toArray()
        var promises = []
        for(let account_name of account_names) {

            var found = false
            for(let account of this.state.my_accounts)
                if(account_name == account)
                    found = true
            if(found)
                continue

            var db = api.db_api()
            if(TRACE) console.log('... BalanceClaimStore.onLoadMyAccounts lookupAccountByName')
            var p = db.exec("get_account_by_name", [account_name]).then ( account => {

                if( ! account) return
                //DEBUG console.log('... account lookupAccountByName',account.get("id"),account.get("name"))

                // todo, move to ChainStore
                // the fake transfer will check for required auths
                var tr = new ops.signed_transaction()
                tr.add_type_operation("transfer", {
                    fee: { amount: 0, asset_id: 0 },
                    from: account.id,
                    to: account.id,
                    amount: { amount: 1, asset_id: 0},
                    null//memo
                })
                return tr.get_potential_signatures().then((public_keys)=>{
                    //var pubkeys = PrivateKeyStore.getPubkeys()
                    var pubkeys = PrivateKeyStore.getPubkeys_having_PrivateKey(public_keys)
                    if( ! pubkeys.length)
                        return {account_name:null, private_key_tcombs: []}

                    return tr.get_required_signatures(pubkeys).then(
                        pubkey_strings => {
                        //DEBUG console.log('... get_required_signatures',pubkey_strings)//,tr.serialize())
                        var private_key_tcombs = []
                        for(let pubkey_string of pubkey_strings) {
                            //var private_key = WalletDb.getPrivateKey(pubkey_string)
                            var private_key_tcomb = PrivateKeyStore.getTcomb_byPubkey(pubkey_string)
                            if( private_key_tcomb )
                                private_key_tcombs.push(private_key_tcomb[0])
                            else {
                                // Missing signing key
                                console.log('... BalanceClaimStore NOT my account1', account.name)
                                return null
                            }
                        }
                        return {
                            account_name: account.name,
                            private_key_tcombs
                        }
                    })
                })

            }).catch( error => {
                //DEBUG Account not found console.log('... error1',error)
            })
            promises.push(p)
        }
        if(TRACE) console.log('... done..');

        Promise.all(promises).then( account_names => {
            var my_accounts = this.state.my_accounts
            var my_account_private_key_tcombs = this.state.my_account_private_key_tcombs
            for(let obj of account_names) {
                if( ! obj) {
                    if(TRACE) console.log('... BalanceClaimStore NOT my account2',
                        obj,error)
                    continue
                }
                if(TRACE) console.log('... BalanceClaimStore my account')
                var {account_name, private_key_tcombs} = obj
                my_accounts.push(account_name)
                my_account_private_key_tcombs[account_name] = private_key_tcombs
            }
            //DEBUG console.log('... my_accounts',my_accounts)
            this.setState({my_accounts, my_account_private_key_tcombs,
                my_accounts_loading:false})
            if(TRACE) console.log('... BalanceClaimStore.onLoadMyAccounts DONE')
        }).catch( balance_claim_error => {
            console.log('BalanceClaimStore.onLoadMyAccounts', balance_claim_error)
            this.setState({balance_claim_error})
        })
    }

    setBalanceClaims(balance_claims) {
        var balance_by_account_asset = this.balanceByAssetName(balance_claims)
        this.setState({balance_claims, balance_by_account_asset, loading: false,
            balance_claim_error:null})
    }

    transaction_update() {
        var transaction = iDB.instance().db().transaction(
            ["balance_claims"], "readwrite"
        )
        return transaction
    }

    /** group things for reporting purposes */
    balanceByAssetName(balance_claims) {
        var asset_totals = {}
        for(let balance_claim of balance_claims) {
            var b = balance_claim.chain_balance_record
            var vested_balance = balance_claim.vested_balance

            var pubkey = balance_claim.pubkey
            var private_key_tcomb = PrivateKeyStore.getTcomb_byPubkey(pubkey)
            if(! private_key_tcomb) {
                console.error("balance claim has no coresponding private key")
                continue
            }
            var import_account_names =
                private_key_tcomb.import_account_names

            var group_by =
                import_account_names.join("\t") +
                b.balance.asset_id + "\t"

            var total =
                asset_totals[group_by] || (
                asset_totals[group_by] =
            {
                vesting: {claimed:0, unclaimed:0, total:0},
                unvested: {claimed:0, unclaimed:0},
                accounts: import_account_names,
                balance_claims: [],
                asset_id: b.balance.asset_id
            })
            if(b.vesting_policy) {
                if(balance_claim.is_claimed)
                    total.vesting.claimed += v.to_number(b.balance.amount)
                else {
                    //DEBUG console.log('... b.balance.amount',b.balance.amount,vested_balance.amount)
                    total.vesting.total += v.to_number(b.balance.amount)
                    if(vested_balance)
                        total.vesting.unclaimed += v.to_number(vested_balance.amount)
                }
            } else {
                if(balance_claim.is_claimed)
                    total.unvested.claimed += v.to_number(b.balance.amount)
                else
                    total.unvested.unclaimed += v.to_number(b.balance.amount)
            }
            total.balance_claims.push(balance_claim)
        }
        var balance_by_account_asset = []
        for(let key of Object.keys(asset_totals).sort()) {
            var total_record = asset_totals[key]
            var accounts = total_record.accounts
            var balance = {
                vesting: total_record.vesting,
                unvested: total_record.unvested
            }
            var balance_claims = total_record.balance_claims
            balance_by_account_asset.push({
                accounts, asset_id:total_record.asset_id,
                balance, balance_claims})
        }
        return balance_by_account_asset
    }

}

export var BalanceClaimStoreWrapped = alt.createStore(BalanceClaimStore, "BalanceClaimStore");
export default BalanceClaimStoreWrapped
<|endoftext|>


<commit_before>export const UPDATE_CONFIG = 'UPDATE_CONFIG';

import { updateConfig as updateHglConfig } from 'components/higlass/actions';
import { updateConfig as updateFgmConfig } from 'components/fragments/actions';

export const updateConfigs = (config) => {
  return function (dispath) {
    dispath(updateHglConfig(config.hgl));
    dispath(updateFgmConfig(config.fgm));
  };
};
<commit_msg>More eslint fixes<commit_after>import { updateConfig as updateHglConfig } from 'components/higlass/actions';
import { updateConfig as updateFgmConfig } from 'components/fragments/actions';

export const UPDATE_CONFIG = 'UPDATE_CONFIG';

export const updateConfigs = config => (dispath) => {
  dispath(updateHglConfig(config.hgl));
  dispath(updateFgmConfig(config.fgm));
};
<|endoftext|>


<commit_before>(function(mask) {
	if (typeof DEBUG === 'undefined' || DEBUG === false) {
		return;
	}

	var _cache = {},
		_mask_Component = mask.Dom.Component,
		_mask_getHandler = mask.getHandler,
		_mask_render = mask.render,
		_signal_emitIn = (Compo || mask.Compo)
			.signal.emitIn;

	mask.Module.reload = function (path) {
		var filename = mask.Module.resolvePath({ path: path });
		var endpoint = new mask.Module.Endpoint(filename);
		var module = mask.Module.getCache(endpoint);
		if (module == null) {
			return false;
		}
		var compos = Object.keys(module.exports.__handlers__);
		module.state = 0;
		module.defer();
		module.loadModule().then(function(){
			compos.forEach(function (name, index) {
				reload(name, compos.slice(0, index));
			})
		});
		return true;
	};

	function reload(compoName, reloadedCompoNames) {
		var cache = _cache[compoName];

		_cache[compoName] = [];

		if (!cache) {
			console.log('No compos', compoName, _cache);
			window.location.reload();
			return;
		}

		var imax = cache.length,
			i = -1;
		while (++i < imax) {

			var x = cache[i],
				_instance = x.instance;
				_parent = _instance.parent,
				_stateTree = null;

			if (_instance == null || !_instance.$) {
				console.error('Mask.Reload - no instance', x);
				continue;
			}

			if (wasReloadedViaParent(_instance, reloadedCompoNames)) {
				_cache[compoName].push(x);
				continue;
			}
			_stateTree = serializeStateTree(_instance);

			var $placeholder = dom_createPlaceholder(_instance);
			compo_remove(_instance);

			var frag = _mask_render(x.node, x.model, x.ctx, $placeholder && $placeholder.container, _parent);
			compo_insert(frag, $placeholder, _parent, _stateTree);
		}
	}

	function serializeStateTree (compo) {
		return mask.TreeWalker.map(compo, function (x) {
			return {
				compoName: x.compoName,
				state: x.serializeState && (x.serializeState() || {}),
				components: null
			};
		});
	}
	function deserializeStateTree (compo, stateTree) {
		var ctx = {};
		mask.TreeWalker.superpose(compo, stateTree, function (x, stateNode) {
			if (stateNode.state != null && x.deserializeState) {
				x.deserializeState(stateNode.state, ctx, compo);
			}
		});
	}

	function wasReloadedViaParent (compo, names) {
		var parent = compo.parent;
		while(parent != null) {
			if (names.indexOf(parent.compoName) !== -1) {
				return true;
			}
			parent = parent.parent;
		}
		return false;
	}

	/** Reload Helpers > */

	function compo_remove(instance) {
		cache_remove(instance);
		if (instance.remove) {
			instance.remove();
			return;
		}
		instance.$ && instance.$.remove();
	}

	function dom_createPlaceholder(instance) {
		var element = instance.$[0];
		if (element == null) {
			return null;
		}
		var parentNode = element.parentNode;
		if (parentNode == null) {
			return null;
		}
		if (parentNode.lastElementChild === element) {
			return { container: parentNode, anchor: null };
		}

		var anchor = document.createComment('');
		parentNode.insertBefore(anchor, element);
		return { container: null, anchor: anchor };
	}

	function compo_insert(fragment, placeholder, parentController, stateTree) {
		if (placeholder && placeholder.anchor) {
			placeholder.parentNode.insertBefore(fragment, placeholder);
		}

		var last = parentController.components[parentController.components.length - 1];
		if (last) {
			_signal_emitIn(last, 'domInsert');
			if (stateTree) {
				deserializeStateTree(last, stateTree);
			}
		}
	}

	function cache_remove (compo) {
		var arr = _cache[compo.compoName];
		var i = arr.indexOf(compo);
		arr.splice(i, 1);
	}

	/* < Reload Helpers */

	mask.on('compoCreated', function(custom, model, ctx, container, node) {
		(_cache[custom.compoName] || (_cache[custom.compoName] = []))
			.push({
				node: node,
				nodes: custom.nodes,
				attr: custom.attr,
				model: model,
				instance: custom,
				ctx: ctx
			});

		var dispose = custom.dispose;
		custom.dispose = function () {
			cache_remove(custom);
			if (dispose) {
				dispose.apply(custom, arguments);
			}
		};
	});

	mask.delegateReload = function() {
		var compos = arguments,
			length = arguments.length;

		return function(source) {
			eval(source);
			for (var i = 0; i < length; i++) {
				reload(compos[i]);
			}
		};
	};

	var _mask_registerHandler = mask.registerHandler,
		_reloadersCache = {};

	mask.registerHandler = function(compoName, handler) {
		_mask_registerHandler(compoName, handler);

		var url = include.url,
			reloader = _reloadersCache[url];

		if (reloader && include.reload && include.reload != reloader) {
			// resource already has reloader, and this is custom
			console.log(' - custom reloader registered. Mask compo reload dropped');
			return;
		}

		if (!reloader) {
			reloader = _reloadersCache[url] = Reloader(compoName);
		} else {
			reloader.compos.push(compoName);
		}

		include.reload = reloader;
	}

	function Reloader(compoName, url) {

		var compos = [compoName],
			reloader = function(source) {
				var length = compos.length;

				eval(source);
				for (var i = 0; i < length; i++) {
					reload(compos[i]);
				}
			};

		reloader.compos = compos;

		return reloader;
	}

}(mask));<commit_msg>add (auto reload) reset the reloaded instance in any parents compos collection<commit_after>(function(mask) {
	if (typeof DEBUG === 'undefined' || DEBUG === false) {
		return;
	}

	var _cache = {},
		_mask_Component = mask.Dom.Component,
		_mask_getHandler = mask.getHandler,
		_mask_render = mask.render,
		_signal_emitIn = (Compo || mask.Compo)
			.signal.emitIn;

	mask.Module.reload = function (path) {
		var filename = mask.Module.resolvePath({ path: path });
		var endpoint = new mask.Module.Endpoint(filename);
		var module = mask.Module.getCache(endpoint);
		if (module == null) {
			return false;
		}
		var compos = Object.keys(module.exports.__handlers__);
		module.state = 0;
		module.defer();
		module.loadModule().then(function(){
			compos.forEach(function (name, index) {
				reload(name, compos.slice(0, index));
			})
		});
		return true;
	};

	function reload(compoName, reloadedCompoNames) {
		var cache = _cache[compoName];

		_cache[compoName] = [];

		if (!cache) {
			console.log('No compos', compoName, _cache);
			window.location.reload();
			return;
		}

		var imax = cache.length,
			i = -1;
		while (++i < imax) {

			var x = cache[i],
				_instance = x.instance;
				_parent = _instance.parent,
				_stateTree = null;

			if (_instance == null || !_instance.$) {
				console.error('Mask.Reload - no instance', x);
				continue;
			}

			if (wasReloadedViaParent(_instance, reloadedCompoNames)) {
				_cache[compoName].push(x);
				continue;
			}
			_stateTree = serializeStateTree(_instance);

			var $placeholder = dom_createPlaceholder(_instance);
			compo_remove(_instance);

			var frag = _mask_render(x.node, x.model, x.ctx, $placeholder && $placeholder.container, _parent);
			compo_insert(frag, $placeholder, _parent, _stateTree, _instance);
		}
	}

	function serializeStateTree (compo) {
		return mask.TreeWalker.map(compo, function (x) {
			return {
				compoName: x.compoName,
				state: x.serializeState && (x.serializeState() || {}),
				components: null
			};
		});
	}
	function deserializeStateTree (compo, stateTree) {
		var ctx = {};
		mask.TreeWalker.superpose(compo, stateTree, function (x, stateNode) {
			if (stateNode.state != null && x.deserializeState) {
				x.deserializeState(stateNode.state, ctx, compo);
			}
		});
	}

	function wasReloadedViaParent (compo, names) {
		var parent = compo.parent;
		while(parent != null) {
			if (names.indexOf(parent.compoName) !== -1) {
				return true;
			}
			parent = parent.parent;
		}
		return false;
	}

	/** Reload Helpers > */

	function compo_remove(instance) {
		cache_remove(instance);
		if (instance.remove) {
			instance.remove();
			return;
		}
		instance.$ && instance.$.remove();
	}

	function dom_createPlaceholder(instance) {
		var element = instance.$[0];
		if (element == null) {
			return null;
		}
		var parentNode = element.parentNode;
		if (parentNode == null) {
			return null;
		}
		if (parentNode.lastElementChild === element) {
			return { container: parentNode, anchor: null };
		}

		var anchor = document.createComment('');
		parentNode.insertBefore(anchor, element);
		return { container: null, anchor: anchor };
	}

	function compo_insert(fragment, placeholder, parentController, stateTree, prevInstance) {
		if (placeholder && placeholder.anchor) {
			placeholder.parentNode.insertBefore(fragment, placeholder);
		}

		var last = parentController.components[parentController.components.length - 1];
		if (last) {
			_signal_emitIn(last, 'domInsert');
			if (stateTree) {
				deserializeStateTree(last, stateTree);
			}
		}
		for(var x = parentController; x != null; x = x.parent) {
			var compos = x.compos;
			if (compos == null) {
				continue;
			}
			for (var key in compos) {
				if (compos[key] === prevInstance) {
					compos[key] = last;
				}
			}
		}
	}

	function cache_remove (compo) {
		var arr = _cache[compo.compoName];
		var i = arr.indexOf(compo);
		arr.splice(i, 1);
	}

	/* < Reload Helpers */

	mask.on('compoCreated', function(custom, model, ctx, container, node) {
		(_cache[custom.compoName] || (_cache[custom.compoName] = []))
			.push({
				node: node,
				nodes: custom.nodes,
				attr: custom.attr,
				model: model,
				instance: custom,
				ctx: ctx
			});

		var dispose = custom.dispose;
		custom.dispose = function () {
			cache_remove(custom);
			if (dispose) {
				dispose.apply(custom, arguments);
			}
		};
	});

	mask.delegateReload = function() {
		var compos = arguments,
			length = arguments.length;

		return function(source) {
			eval(source);
			for (var i = 0; i < length; i++) {
				reload(compos[i]);
			}
		};
	};

	var _mask_registerHandler = mask.registerHandler,
		_reloadersCache = {};

	mask.registerHandler = function(compoName, handler) {
		_mask_registerHandler(compoName, handler);

		var url = include.url,
			reloader = _reloadersCache[url];

		if (reloader && include.reload && include.reload != reloader) {
			// resource already has reloader, and this is custom
			console.log(' - custom reloader registered. Mask compo reload dropped');
			return;
		}

		if (!reloader) {
			reloader = _reloadersCache[url] = Reloader(compoName);
		} else {
			reloader.compos.push(compoName);
		}

		include.reload = reloader;
	}

	function Reloader(compoName, url) {

		var compos = [compoName],
			reloader = function(source) {
				var length = compos.length;

				eval(source);
				for (var i = 0; i < length; i++) {
					reload(compos[i]);
				}
			};

		reloader.compos = compos;

		return reloader;
	}

}(mask));<|endoftext|>


<commit_before>var Point = Base.extend({
	beans: true,

	initialize: function() {
		if (arguments.length == 2) {
			this.x = arguments[0];
			this.y = arguments[1];
		} else if (arguments.length == 1) {
			var arg = arguments[0];
			if (arg == null) {
				this.x = this.y = 0;
			} else if (arg.x !== undefined) {
				this.x = arg.x;
				this.y = arg.y;
			} else if (arg.width !== undefined) {
				this.x = arg.width;
				this.y = arg.height;
			} else if (Array.isArray(arg)) {
				this.x = arg[0];
				this.y = arg.length > 1 ? arg[1] : arg[0];
			} else if (typeof arg === 'number') {
				this.x = this.y = arg;
			} else {
				this.x = this.y = 0;
			}
		} else {
			this.x = this.y = 0;
		}
	},

	clone: function() {
		return Point.create(this.x, this.y);
	},

	add: function() {
		var point = Point.read(arguments);
		return Point.create(this.x + point.x, this.y + point.y);
	},

	subtract: function() {
		var point = Point.read(arguments);
		return Point.create(this.x - point.x, this.y - point.y);
	},

	multiply: function() {
		var point = Point.read(arguments);
		return Point.create(this.x * point.x, this.y * point.y);
	},

	divide: function() {
		var point = Point.read(arguments);
		return Point.create(this.x / point.x, this.y / point.y);
	},

	modulo: function() {
		var point = Point.read(arguments);
		return Point.create(this.x % point.x, this.y % point.y);
	},

	negate: function() {
		return Point.create(-this.x, -this.y);
	},

	equals: function() {
		var point = Point.read(arguments);
		return this.x == point.x && this.y == point.y;
	},

	getDistance: function() {
		var point = Point.read(arguments);
		var px = point.x - this.x;
		var py = point.y - this.y;
		return Math.sqrt(px * px + py * py);
	},

	getDistanceSquared: function() {
		var point = Point.read(arguments);
		var px = point.x - this.x;
		var py = point.y - this.y;
		return px * px + py * py;
	},

	getLength: function() {
		var point = Point.read(arguments);
		return Math.sqrt(this.x * this.x + this.y * this.y);
	},

	setLength: function(length) {
		if (this.isZero()) {
			if (this._angle != null) {
				var a = this._angle;
				this.x = Math.cos(a) * length;
				this.y = Math.sin(a) * length;
			} else {
				// Assume angle = 0
				this.x = length;
				// y is already 0
			}
		} else {
			var scale = length / this.length;
			if (scale == 0.0) {
				// Calculate angle now, so it will be preserved even when
				// x and y are 0
				this.getAngle();
			}
			this.x *= scale;
			this.y *= scale;
		}
	},

	normalize: function(length) {
		if (length === null)
			length = 1;
		var len = this.length;
		var scale = len != 0 ? length / len : 0;
		var res = Point.create(this.x * scale, this.y * scale);
		// Preserve angle.
		res._angle = this._angle;
		return res;
	},

	getAngleInRadians: function() {
		// TODO: Not sur we want this one, but if so, just rely on
		// this.getAngle(), which caches values internally?
		return Math.atan2(this.y, this.x);
	},

	getAngleInDegrees: function() {
		// TODO: Not sur we want this one, but if so, just rely on
		// this.getAngle(), which caches values internally?
		return Math.atan2(this.y, this.x) * 180 / Math.PI;
	},

	getQuadrant: function() {
		if (this.x >= 0) {
			if (this.y >= 0) {
				return 1;
			} else {
				return 4;
			}
		} else {
			if (this.y >= 0) {
				return 2;
			} else {
				return 3;
			}
		}
	},

	setAngle: function(angle) {
		angle = this._angle = angle * Math.PI / 180;
		if (!this.isZero()) {
			var length = this.length;
			this.x = Math.cos(angle) * length;
			this.y = Math.sin(angle) * length;
		}
	},

	getAngle: function() {
		var angle;
		if (arguments.length) {
			var point = Point.read(arguments);
			var div = this.length * point.length;
			if (div == 0) {
				return NaN;
			} else {
				angle = Math.acos(this.dot(point) / div);
			}
		} else {
			if (this._angle == null)
				this._angle = Math.atan2(this.y, this.x);
			angle = this._angle;
		}
		return angle * 180 / Math.PI;
	},

	getDirectedAngle: function() {
		var point = Point.read(arguments);
		var angle = this.angle - point.angle;
		var bounds = 180;
		if (angle < - bounds) {
			return angle + bounds * 2;
		} else if (angle > bounds) {
			return angle - bounds * 2;
		} else {
			return angle;
		}
	},

	// TODO: Add center parameter support back to Scriptographer
	rotate: function(angle, center) {
		var point = center ? this.subtract(center) : this;
		angle = angle * Math.PI / 180;
		var s = Math.sin(angle);
		var c = Math.cos(angle);
		point = Point.create(
			point.x * c - point.y * s,
			point.y * c + point.x * s
		);
		return center ? point.add(center) : point;
	},

	interpolate: function(point, t) {
		return Point.create(
			this.x * (1 - t) + point.x * t,
			this.y * (1 - t) + point.y * t
		);
	},

	isInside: function(rect) {
		return rect.contains(this);
	},

	isClose: function(point, tolerance) {
		return this.getDistance(point) < tolerance;
	},

	isParallel: function(point) {
		return Math.abs(this.x / point.x - this.y / point.y) < 0.00001;
	},

	isZero: function() {
		return this.x == 0 && this.y == 0;
	},

	isNaN: function() {
		return isNaN(this.x) || isNaN(this.y);
	},

	round: function() {
		return Point.create(Math.round(this.x), Math.round(this.y));
	},

	ceil: function() {
		return Point.create(Math.ceil(this.x), Math.ceil(this.y));
	},

	floor: function() {
		return Point.create(Math.floor(this.x), Math.floor(this.y));
	},

	abs: function() {
		return Point.create(Math.abs(this.x), Math.abs(this.y));
	},

	dot: function() {
		var point = Point.read(arguments);
		return this.x * point.x + this.y * point.y;
	},

	cross: function() {
		var point = Point.read(arguments);
		return this.x * point.y - this.y - point.x;
	},

	project: function() {
		var point = Point.read(arguments);
		if (point.isZero()) {
			return Point.create(0, 0);
		} else {
			var scale = this.dot(point) / point.dot(point);
			return Point.create(
				point.x * scale,
				point.y * scale
			);
		}
	},

	toString: function() {
		return '{ x: ' + this.x + ', y: ' + this.y + ' }';
	},

	statics: {
		/**
		 * Provide a faster creator for Points out of two coordinates that
		 * does not rely on Point#initialize at all. This speeds up all math
		 * operations a lot.
		 */
		create: function(x, y) {
			var point = new Point(Point.dont);
			point.x = x;
			point.y = y;
			return point;
		},

		read: function(args, index) {
			var index = index || 0, length = args.length - index;
			if (length == 1 && args[index] instanceof Point) {
				return args[index];
			} else if (length != 0) {
				var point = new Point(Point.dont);
				point.initialize.apply(point, index > 0
						? Array.prototype.slice.call(args, index) : args);
				return point;
			}
			return null;
		},

		min: function(point1, point2) {
			return Point.create(
				Math.min(point1.x, point2.x),
				Math.min(point1.y, point2.y));
		},

		max: function(point1, point2) {
			return Point.create(
				Math.max(point1.x, point2.x),
				Math.max(point1.y, point2.y));
		},

		random: function() {
			return Point.create(Math.random(), Math.random());
		}
	}
});
<commit_msg>Implement Point#transform(matrix).<commit_after>var Point = Base.extend({
	beans: true,

	initialize: function() {
		if (arguments.length == 2) {
			this.x = arguments[0];
			this.y = arguments[1];
		} else if (arguments.length == 1) {
			var arg = arguments[0];
			if (arg == null) {
				this.x = this.y = 0;
			} else if (arg.x !== undefined) {
				this.x = arg.x;
				this.y = arg.y;
			} else if (arg.width !== undefined) {
				this.x = arg.width;
				this.y = arg.height;
			} else if (Array.isArray(arg)) {
				this.x = arg[0];
				this.y = arg.length > 1 ? arg[1] : arg[0];
			} else if (typeof arg === 'number') {
				this.x = this.y = arg;
			} else {
				this.x = this.y = 0;
			}
		} else {
			this.x = this.y = 0;
		}
	},

	clone: function() {
		return Point.create(this.x, this.y);
	},

	add: function() {
		var point = Point.read(arguments);
		return Point.create(this.x + point.x, this.y + point.y);
	},

	subtract: function() {
		var point = Point.read(arguments);
		return Point.create(this.x - point.x, this.y - point.y);
	},

	multiply: function() {
		var point = Point.read(arguments);
		return Point.create(this.x * point.x, this.y * point.y);
	},

	divide: function() {
		var point = Point.read(arguments);
		return Point.create(this.x / point.x, this.y / point.y);
	},

	modulo: function() {
		var point = Point.read(arguments);
		return Point.create(this.x % point.x, this.y % point.y);
	},

	negate: function() {
		return Point.create(-this.x, -this.y);
	},

	equals: function() {
		var point = Point.read(arguments);
		return this.x == point.x && this.y == point.y;
	},

	transform: function(matrix) {
		return matrix.transform(this);
	},

	getDistance: function() {
		var point = Point.read(arguments);
		var px = point.x - this.x;
		var py = point.y - this.y;
		return Math.sqrt(px * px + py * py);
	},

	getDistanceSquared: function() {
		var point = Point.read(arguments);
		var px = point.x - this.x;
		var py = point.y - this.y;
		return px * px + py * py;
	},

	getLength: function() {
		var point = Point.read(arguments);
		return Math.sqrt(this.x * this.x + this.y * this.y);
	},

	setLength: function(length) {
		if (this.isZero()) {
			if (this._angle != null) {
				var a = this._angle;
				this.x = Math.cos(a) * length;
				this.y = Math.sin(a) * length;
			} else {
				// Assume angle = 0
				this.x = length;
				// y is already 0
			}
		} else {
			var scale = length / this.length;
			if (scale == 0.0) {
				// Calculate angle now, so it will be preserved even when
				// x and y are 0
				this.getAngle();
			}
			this.x *= scale;
			this.y *= scale;
		}
	},

	normalize: function(length) {
		if (length === null)
			length = 1;
		var len = this.length;
		var scale = len != 0 ? length / len : 0;
		var res = Point.create(this.x * scale, this.y * scale);
		// Preserve angle.
		res._angle = this._angle;
		return res;
	},

	getAngleInRadians: function() {
		// TODO: Not sur we want this one, but if so, just rely on
		// this.getAngle(), which caches values internally?
		return Math.atan2(this.y, this.x);
	},

	getAngleInDegrees: function() {
		// TODO: Not sur we want this one, but if so, just rely on
		// this.getAngle(), which caches values internally?
		return Math.atan2(this.y, this.x) * 180 / Math.PI;
	},

	getQuadrant: function() {
		if (this.x >= 0) {
			if (this.y >= 0) {
				return 1;
			} else {
				return 4;
			}
		} else {
			if (this.y >= 0) {
				return 2;
			} else {
				return 3;
			}
		}
	},

	setAngle: function(angle) {
		angle = this._angle = angle * Math.PI / 180;
		if (!this.isZero()) {
			var length = this.length;
			this.x = Math.cos(angle) * length;
			this.y = Math.sin(angle) * length;
		}
	},

	getAngle: function() {
		var angle;
		if (arguments.length) {
			var point = Point.read(arguments);
			var div = this.length * point.length;
			if (div == 0) {
				return NaN;
			} else {
				angle = Math.acos(this.dot(point) / div);
			}
		} else {
			if (this._angle == null)
				this._angle = Math.atan2(this.y, this.x);
			angle = this._angle;
		}
		return angle * 180 / Math.PI;
	},

	getDirectedAngle: function() {
		var point = Point.read(arguments);
		var angle = this.angle - point.angle;
		var bounds = 180;
		if (angle < - bounds) {
			return angle + bounds * 2;
		} else if (angle > bounds) {
			return angle - bounds * 2;
		} else {
			return angle;
		}
	},

	// TODO: Add center parameter support back to Scriptographer
	rotate: function(angle, center) {
		var point = center ? this.subtract(center) : this;
		angle = angle * Math.PI / 180;
		var s = Math.sin(angle);
		var c = Math.cos(angle);
		point = Point.create(
			point.x * c - point.y * s,
			point.y * c + point.x * s
		);
		return center ? point.add(center) : point;
	},

	interpolate: function(point, t) {
		return Point.create(
			this.x * (1 - t) + point.x * t,
			this.y * (1 - t) + point.y * t
		);
	},

	isInside: function(rect) {
		return rect.contains(this);
	},

	isClose: function(point, tolerance) {
		return this.getDistance(point) < tolerance;
	},

	isParallel: function(point) {
		return Math.abs(this.x / point.x - this.y / point.y) < 0.00001;
	},

	isZero: function() {
		return this.x == 0 && this.y == 0;
	},

	isNaN: function() {
		return isNaN(this.x) || isNaN(this.y);
	},

	round: function() {
		return Point.create(Math.round(this.x), Math.round(this.y));
	},

	ceil: function() {
		return Point.create(Math.ceil(this.x), Math.ceil(this.y));
	},

	floor: function() {
		return Point.create(Math.floor(this.x), Math.floor(this.y));
	},

	abs: function() {
		return Point.create(Math.abs(this.x), Math.abs(this.y));
	},

	dot: function() {
		var point = Point.read(arguments);
		return this.x * point.x + this.y * point.y;
	},

	cross: function() {
		var point = Point.read(arguments);
		return this.x * point.y - this.y - point.x;
	},

	project: function() {
		var point = Point.read(arguments);
		if (point.isZero()) {
			return Point.create(0, 0);
		} else {
			var scale = this.dot(point) / point.dot(point);
			return Point.create(
				point.x * scale,
				point.y * scale
			);
		}
	},

	toString: function() {
		return '{ x: ' + this.x + ', y: ' + this.y + ' }';
	},

	statics: {
		/**
		 * Provide a faster creator for Points out of two coordinates that
		 * does not rely on Point#initialize at all. This speeds up all math
		 * operations a lot.
		 */
		create: function(x, y) {
			var point = new Point(Point.dont);
			point.x = x;
			point.y = y;
			return point;
		},

		read: function(args, index) {
			var index = index || 0, length = args.length - index;
			if (length == 1 && args[index] instanceof Point) {
				return args[index];
			} else if (length != 0) {
				var point = new Point(Point.dont);
				point.initialize.apply(point, index > 0
						? Array.prototype.slice.call(args, index) : args);
				return point;
			}
			return null;
		},

		min: function(point1, point2) {
			return Point.create(
				Math.min(point1.x, point2.x),
				Math.min(point1.y, point2.y));
		},

		max: function(point1, point2) {
			return Point.create(
				Math.max(point1.x, point2.x),
				Math.max(point1.y, point2.y));
		},

		random: function() {
			return Point.create(Math.random(), Math.random());
		}
	}
});
<|endoftext|>