<commit_before>module.exports = {
    languages: {
        en: "English",
        cn: "简体中文",
        fr: "Français",
        ko: "한국어",
        de: "Deutsch"
    },
    header: {
        title: "比特股 2.0",
        dashboard: "概览",
        explorer: "浏览",
        exchange: "交易",
        payments: "支付",
        logout: "注销",
        settings: "设置",
        current: "当前账户",
        create_account: "创建账户",
        create_asset: "创建资产",
        lock: "锁定钱包",
        unlock: "解锁钱包"
    },
    account: {
        assets: "资产",
        value: "价值",
        hour_24: "24小时",
        recent: "近期活动",
        name: "账户名",
        member: {
            stats: "会员统计",
            join: "加入于",
            reg: "注册人",
            ref: "推荐人",
            referrals: "被推荐人",
            rewards: "返现奖励",
            cashback: "返现",
            vested: "既得"
        },
        connections: {
            known: "Known by",
            "black": "被屏蔽"
        }
    },
    transfer: {
        from: "来自",
        amount: "金额",
        to: "发往",
        memo: "备注消息",
        fee: "手续费",
        send: "发送",
        final: "转账后余额",
        balances: "余额",
        errors: {
            req: "必填信息",
            pos: "数量必须大于0",
            valid: "请输入一个合法的大于0的半角数字"
        },
        back: "返回",
        confirm: "确认发送",
        broadcast: "你的转账已经向网络广播",
        again: "发起新的转账",
        see: "查看我的转账记录"
    },
    transaction: {
        sent: "已发送",
        to: "发往",
        received: "已接收",
        from: "来自",
        amount_sell: "出售数量",
        expiration: "过期时间",
        fill_or: "成交或取消",
        min_receive: "接收的最小数量",
        seller: "卖家",
        collateral: "抵押",
        coll_ratio: "初始抵押率",
        coll_maint: "Collateral maintenance ratio",
        "create_key": "创建一个公钥",
        reg_account: "注册账户",
        was_reg_account: "注册人",
        create_asset: "Created the asset",
        limit_order: "限价出售单",
        limit_order_buy: "限价买入单",
        limit_order_cancel: "已取消的限价单",
        short_order: "空单",
        short_order_cancel: "已取消的空单Cancelled short with id",
        at: "at",
        coll_of: "抵押为",
        call_order_update: "Updated call order",
        upgrade_account: "升级到终身会员账户",
        update_account: "Updated account",
        whitelist_account: "Whitelisted the account",
        whitelisted_by: "Was whitelisted by the account",
        transfer_account: "Transferred the account",
        update_asset: "Updated the asset",
        update_feed_producers: "Updated the feed producers of asset",
        feed_producer: "Became a feed producer for the asset",
        asset_issue: "Issued",
        was_issued: "Was issued",
        by: "by",
        burn_asset: "Burnt",
        fund_pool: "Funded asset fee pool with",
        asset_settle: "Requested settlement of",
        asset_global_settle: "Requested global settlement of",
        publish_feed: "Published new feed for asset",
        delegate_create: "Created the delegate",
        witness_create: "Created the witness",
        witness_pay: "Withdrew witness pay to account",
        witness_receive: "Received witness from witness",
        proposal_create: "Created a proposal",
        proposal_update: "Updated a proposal",
        proposal_delete: "Deleted a proposal",
        withdraw_permission_create: "Gave withdrawal permission for account",
        withdraw_permission_update: "Updated withdrawal permission for account",
        withdraw_permission_claim: "Claimed withdrawal permission for account",
        withdraw_permission_delete: "Deleted withdrawal permissions for account",
        paid: "Paid",
        obtain: "to obtain",
        global_parameters_update: "Updated global parameters",
        file_write: "Wrote a file",
        vesting_balance_create: "created vesting balance of",
        for: "for",
        vesting_balance_withdraw: "Withdrew vesting balance of",
        bond_create_offer: "Created bond offer",
        bond_cancel_offer: "Cancelled bond offer",
        bond_accept_offer: "Accepted bond offer of",
        bond_claim_collateral: "Claimed collateral of",
        bond_pay_collateral: "Paid collateral of",
        create_worker: "Created a worker with a pay of",
        custom: "Created a custom operation",
        order_id: "Order ID",
        trxTypes: {
            transfer: "转账",
            limit_order_create: "限价单",
            limit_order_cancel: "取消限价单",
            call_order_update: "Update call order",
            account_create: "创建账户",
            account_update: "更新账户",
            account_whitelist: "Account whitelist",
            account_upgrade: "升级账户",
            account_transfer: "账户转移",
            asset_create: "创建资产",
            asset_update: "更新资产",
            asset_update_bitasset: "更新智能币",
            asset_update_feed_producers: "更新资产喂价者",
            asset_issue: "发行资产",
            asset_reserve: "销毁资产",
            asset_fund_fee_pool: "积存资产费用池",
            asset_settle: "资产结算",
            asset_global_settle: "Global asset settlement",
            asset_publish_feed: "发布资产喂价",
            delegate_create: "创建受托人",
            witness_create: "创建见证人",
            witness_withdraw_pay: "见证人取回报酬",
            proposal_create: "创建提案",
            proposal_update: "更新提案",
            proposal_delete: "删除提案",
            withdraw_permission_create: "创建取回权限",
            withdraw_permission_update: "更新取回权限",
            withdraw_permission_claim: "Claim withdrawal permission",
            withdraw_permission_delete: "删除取回权限",
            fill_order: "撮合订单",
            delegate_update_global_parameters: "全局参数更新",
            vesting_balance_create: "创建冻结账目余额",
            vesting_balance_withdraw: "取回解冻账户余额",
            worker_create: "创建雇员",
            custom: "自定义",
            assert: "Assert operation",
            balance_claim: "Claim balance",
            override_transfer: "Override transfer"
        }
    },
    explorer: {
        accounts: {
            title: "账户"
        },
        blocks: {
            title: "区块链",
            globals: "全局参数",
            recent: "最近区块"
        },
        block: {
            title: "区块",
            id: "区块 ID",
            witness: "见证人",
            count: "交易数",
            date: "日期",
            previous: "上一个",
            previous_secret: "上一个密文",
            next_secret: "下一个密文哈希值",
            op: "操作",
            trx: "交易",
            op_type: "操作类型",
            fee_payer: "手续费支付账户",
            key: "公钥",
            transactions: "交易数量",
            account_upgrade: "可升级账户",
            lifetime: "升级到终身会员账户",
            authorizing_account: "授权账户",
            listed_account: "Listed account",
            new_listing: "New listing",
            asset_update: "可更新资产",
            common_options: "Common options",
            new_options: "New options",
            new_producers: "New feed producers",
            asset_issue: "发行数量",
            max_margin_period_sec: "Max margin period (s)",
            call_limit: "Call limit",
            short_limit: "Short limit",
            settlement_price: "结算价格"
        },
        assets: {
            title: "资产",
            market: "智能币",
            user: "用户发行资产",
            symbol: "代码",
            id: "ID",
            issuer: "发行人",
            precision: "精度"
        },
        asset: {
            title: "资产"
        },
        witnesses: {
            title: "见证人"
        },
        delegates: {
            title: "受托人"
        },
        delegate: {
            title: "受托人"
        },
        workers: {
            title: "雇员"
        },
        proposals: {
            title: "提案"
        },
        account: {
            title: "账户"
        }
    },
    settings: {
        inverseMarket: "市场交易对视角",
        unit: "显示记账单位",
        confirmMarketOrder: "Ask for confirmation of market orders",
        locale: "语言选择",
        confirm_yes: "Always",
        confirm_no: "Never",
        always_confirm: "Always ask for confirmation"
    }
};
<commit_msg>partial Chinese locale part II<commit_after>module.exports = {
    languages: {
        en: "English",
        cn: "简体中文",
        fr: "Français",
        ko: "한국어",
        de: "Deutsch"
    },
    header: {
        title: "比特股 2.0",
        dashboard: "概览",
        explorer: "浏览",
        exchange: "交易",
        payments: "支付",
        logout: "注销",
        settings: "设置",
        current: "当前账户",
        create_account: "创建账户",
        create_asset: "创建资产",
        lock: "锁定钱包",
        unlock: "解锁钱包"
    },
    account: {
        assets: "资产",
        market_value: "市值",
        hour_24: "24小时",
        recent: "近期活动",
        name: "账户名",
        member: {
            stats: "会员统计",
            join: "加入于",
            reg: "注册人",
            ref: "推荐人",
            referrals: "被推荐人",
            rewards: "返现奖励",
            cashback: "返现",
            vested: "既得",
            ref_percentage: "Referrer fee percentage",
            network_percentage: "Network fee percentage",
            fees_paid: "Lifetime fees paid",
            fees_pending: "Pending fees",
            fees_vested: "Pending vested fees",
            in_orders: "Total %(core_asset)s in orders"
        },
        connections: {
            known: "Known by",
            black: "被屏蔽"
        },
        asset: "资产",
        more: "查看更多",
        user_issued_assets: {
            symbol: "符号",
            name: "资产名称",
            description: "描述",
            max_supply: "最大供给量",
            precision: "精度",
            to: "发行到账户",
            details: "详细"
        },
        perm: {
            active: "活跃权限",
            owner: "所有人权限",
            publish: "保存修改",
            reset: "重置修改",
            add: "增加权限",
            type: "类型",
            key: "键/名字",
            weight: "权重",
            threshold: "阈值",
            confirm_add: "增加",
            cancel: "取消"
        },
        votes: {
            proxy: "代理投票账户",
            no_proxy: "无代理",
            name: "账户名",
            info: "信息",
            votes: "votes",
            url: "主页",
            support: "支持",
            workers: "预算项目",
            publish: "保存修改",
            add_witness: "添加",
            remove_witness: "移除",
            remove_committee: "移除",
            add_committee: "添加",
            add_committee_label: "受托人",
            add_witness_label: "见证人"
        },
        options: {
            num_witnesses: "Desired Witnesses",
            num_committee: "Desired Committee Members",
            memo_key: "Memo Key"
        },
        upgrade: "升级账户",
        unlink: "取消关联",
        link: "关联",
        pay: "向他付款",
        overview: "概述",
        history: "交易历史",
        payees: "付款人",
        permissions: "权限",
        voting: "投票",
        orders: "订单",
        select_placeholder: "选择账户...",
        errors: {
            not_found: "账户 %(name)s 不存在, 你确定输入正确么?"
        }
    },
    transfer: {
        from: "来自",
        amount: "金额",
        to: "发往",
        memo: "备注消息",
        fee: "手续费",
        send: "发送",
        "final": "转账后余额",
        balances: "余额",
        errors: {
            req: "必填信息",
            pos: "数量必须大于0",
            valid: "请输入一个合法的大于0的半角数字",
            balance: "最终余额必须大于0"
        },
        back: "返回",
        confirm: "确认发送",
        broadcast: "你的转账已经向网络广播",
        again: "发起新的转账",
        see: "查看我的转账记录",
        available: "可用余额: ",
        broadcasting: "交易广播中..."
    },
    transaction: {
        sent: "已发送",
        to: "发往",
        received: "已接收",
        from: "来自",
        amount_sell: "出售数量",
        expiration: "过期时间",
        fill_or: "成交或取消",
        min_receive: "接收的最小数量",
        seller: "卖家",
        collateral: "抵押",
        coll_ratio: "初始抵押率",
        coll_maint: "Collateral maintenance ratio",
        create_key: "创建一个公钥",
        reg_account: "注册账户",
        was_reg_account: "注册人",
        create_asset: "Created the asset",
        limit_order: "限价出售单",
        limit_order_buy: "限价买入单",
        limit_order_cancel: "已取消的限价单",
        short_order: "空单",
        short_order_cancel: "已取消的空单",
        at: "at",
        coll_of: "抵押为",
        call_order_update: "Updated call order",
        upgrade_account: "升级到终身会员账户",
        update_account: "Updated account",
        whitelist_account: "Whitelisted the account",
        whitelisted_by: "Was whitelisted by the account",
        transfer_account: "Transferred the account",
        update_asset: "Updated the asset",
        update_feed_producers: "Updated the feed producers of asset",
        feed_producer: "Became a feed producer for the asset",
        asset_issue: "Issued",
        was_issued: "Was issued",
        by: "by",
        burn_asset: "Burnt",
        fund_pool: "Funded asset fee pool with",
        asset_settle: "Requested settlement of",
        asset_global_settle: "Requested global settlement of",
        publish_feed: "Published new feed for asset",
        delegate_create: "Created the delegate",
        witness_create: "Created the witness",
        witness_pay: "Withdrew witness pay to account",
        witness_receive: "Received witness from witness",
        proposal_create: "Created a proposal",
        proposal_update: "Updated a proposal",
        proposal_delete: "Deleted a proposal",
        withdraw_permission_create: "Gave withdrawal permission for account",
        withdraw_permission_update: "Updated withdrawal permission for account",
        withdraw_permission_claim: "Claimed withdrawal permission for account",
        withdraw_permission_delete: "Deleted withdrawal permissions for account",
        paid: "Paid",
        obtain: "to obtain",
        global_parameters_update: "Updated global parameters",
        file_write: "Wrote a file",
        vesting_balance_create: "created vesting balance of",
        "for": "for",
        vesting_balance_withdraw: "Withdrew vesting balance of",
        bond_create_offer: "Created bond offer",
        bond_cancel_offer: "Cancelled bond offer",
        bond_accept_offer: "Accepted bond offer of",
        bond_claim_collateral: "Claimed collateral of",
        bond_pay_collateral: "Paid collateral of",
        create_worker: "Created a worker with a pay of",
        custom: "Created a custom operation",
        order_id: "订单ID",
        trxTypes: {
            transfer: "转账",
            limit_order_create: "限价单",
            limit_order_cancel: "取消限价单",
            call_order_update: "Update call order",
            account_create: "创建账户",
            account_update: "更新账户",
            account_whitelist: "Account whitelist",
            account_upgrade: "升级账户",
            account_transfer: "账户转移",
            asset_create: "创建资产",
            asset_update: "更新资产",
            asset_update_bitasset: "更新智能币",
            asset_update_feed_producers: "更新资产喂价者",
            asset_issue: "发行资产",
            asset_reserve: "销毁资产",
            asset_fund_fee_pool: "积存资产费用池",
            asset_settle: "资产结算",
            asset_global_settle: "Global asset settlement",
            asset_publish_feed: "发布资产喂价",
            delegate_create: "创建受托人",
            witness_create: "创建见证人",
            witness_withdraw_pay: "见证人取回报酬",
            proposal_create: "创建提案",
            proposal_update: "更新提案",
            proposal_delete: "删除提案",
            withdraw_permission_create: "创建取回权限",
            withdraw_permission_update: "更新取回权限",
            withdraw_permission_claim: "Claim withdrawal permission",
            withdraw_permission_delete: "删除取回权限",
            fill_order: "撮合订单",
            delegate_update_global_parameters: "全局参数更新",
            vesting_balance_create: "创建冻结账目余额",
            vesting_balance_withdraw: "取回解冻账户余额",
            worker_create: "创建雇员",
            custom: "自定义",
            assert: "Assert operation",
            balance_claim: "Claim balance",
            override_transfer: "Override transfer"
        },
        confirm: "Please confirm the transaction",
        broadcast_success: "Transaction has been broadcast",
        broadcast_fail: "Failed to broadcast the transaction: %(message)s",
        limit_order_sell: "Placed order #%(num)s to sell %(sell_amount)s at %(sell_price)s",
        balance_claim: "Claimed a balance of %(balance_amount)s from balance ID #%(balance_id)s",
        balance_owner: "Balance owner key",
        balance_id: "Balance ID",
        deposit_to: "Deposited to account",
        claimed: "Total claimed"
    },
    explorer: {
        accounts: {
            title: "账户"
        },
        blocks: {
            title: "区块链",
            globals: "全局参数",
            recent: "最近区块"
        },
        block: {
            title: "区块",
            id: "区块 ID",
            witness: "见证人",
            count: "交易数",
            date: "日期",
            previous: "上一个",
            previous_secret: "上一个密文",
            next_secret: "下一个密文哈希值",
            op: "操作",
            trx: "交易",
            op_type: "操作类型",
            fee_payer: "手续费支付账户",
            key: "公钥",
            transactions: "交易数量",
            account_upgrade: "可升级账户",
            lifetime: "升级到终身会员账户",
            authorizing_account: "授权账户",
            listed_account: "Listed account",
            new_listing: "New listing",
            asset_update: "可更新资产",
            common_options: "Common options",
            new_options: "New options",
            new_producers: "New feed producers",
            asset_issue: "发行数量",
            max_margin_period_sec: "Max margin period (s)",
            call_limit: "Call limit",
            short_limit: "Short limit",
            settlement_price: "结算价格"
        },
        assets: {
            title: "资产",
            market: "智能币",
            user: "用户发行资产",
            symbol: "代码",
            id: "ID",
            issuer: "发行人",
            precision: "精度"
        },
        asset: {
            title: "资产",
            not_found: "资产 %(name)s 不存在"
        },
        witnesses: {
            title: "见证人"
        },
        delegates: {
            title: "受托人"
        },
        delegate: {
            title: "受托人"
        },
        workers: {
            title: "雇员"
        },
        proposals: {
            title: "提案"
        },
        account: {
            title: "账户"
        }
    },
    settings: {
        inverseMarket: "市场交易对视角",
        unit: "显示记账单位",
        confirmMarketOrder: "市场订单要求确认",
        locale: "语言选择",
        confirm_yes: "总是",
        confirm_no: "从不",
        always_confirm: "总是要求确认"
    },
    pagination: {
        newer: "更近",
        older: "更早"
    },
    footer: {
        title: "Graphene 石墨烯",
        block: "最新区块",
        loading: "载入中..."
    },
    exchange: {
        price_history: "Price History",
        order_depth: "订单深度",
        market_history: "市场历史",
        balance: "我的余额",
        lowest_ask: "最低卖单",
        highest_bid: "最高买单",
        total: "Total",
        value: "Value",
        price: "Price",
        latest: "Latest Price",
        call: "Call Price",
        volume: "成交量",
        spread: "Spread",
        quantity: "Amount",
        buy: "Buy",
        sell: "Sell",
        confirm_buy: "Confirm order: Buy %(buy_amount)s %(buy_symbol)s at a price of %(price_amount)s %(price_symbol)s",
        confirm_sell: "Confirm order: Sell %(sell_amount)s %(sell_symbol)s at a price of %(price_amount)s %(price_symbol)s"
    },
    markets: {
        choose_base: "选择基准资产",
        filter: "筛选",
        core_rate: "Core rate",
        supply: "供应量",
        search: "搜索"
    }
};<|endoftext|>


<commit_before>
/*

  Compile.js

*/

var Bundler     = require("./bundler"),
    express     = require("express"),
    Metadata    = require("./metadata"),
    Motors      = global.engines,
    Promise     = require("bluebird"),
    Utils       = require("./utils");
    makeQuery   = Promise.promisify(global.db.queries);

function createDataQuery(queries) {
  return function(context) {
    return makeQuery(queries, context).then(function(data) {
      return Promise.resolve(Object.assign({}, global.vars, context, data));
    });
  }
}

function sequence(tasks, initial) {
  return Promise.reduce(tasks || [], function(val, task) {
    return task(val);
  }, initial);
}

function addFile(router, route, file, type, basePath) {

    var tasks = [],
        metadata = {};

    // Add to list of extensions if not present
    if (!Motors.hasEngine(file.ext)) Motors.addEngine(file.ext);

    // Extract metadata
    if ("html" === type) {
      metadata = Metadata.extract(Utils.readFileHead(file.path, 500));
      tasks.push(createDataQuery(metadata.data));
    }

    // File compilation function
    if (file.bundle)
      tasks.push(Bundler.fromFile(file, type).get);
    else
      tasks.push(Promise.promisify(Motors.compileFile.bind(Motors, file.path)));

    // Route handling function
    function handler(req, res) {

      // Set cookies
      for (var key in metadata.cookies || {})
        res.cookie(key, metadata.cookies[key]);

      // Set session
      for (var key in metadata.session || {})
        req.session[key] = metadata.session[key];

      sequence(tasks, req.params)
      .then(res.type(type).send.bind(res))
      .catch(function(err) { console.log(err); res.sendStatus(500); });

    }

    // Add routes to router
    Utils.makeRoutes(route, file, { type : type, query : metadata.query }).forEach(function(r) {
      router.get(r, handler);
    });

}

module.exports = function(options) {

  var router = express(),
      files  = Utils.mapFiles(options.path, options),
      exts   = {};

  files.forEach(function(file) {
    addFile(router, options.url, file, options.ext);
    if (!exts[file.ext]) exts[file.ext] = Utils.watch(options.path, file.ext, options.ext);
  });

  return router;

};
<commit_msg>Compiler: ignores files handled by Bundler<commit_after>
/*

  Compile.js

*/

var Bundler     = require("./bundler"),
    express     = require("express"),
    Metadata    = require("./metadata"),
    Motors      = global.engines,
    Promise     = require("bluebird"),
    Utils       = require("./utils");
    makeQuery   = Promise.promisify(global.db.queries);

function createDataQuery(queries) {
  return function(context) {
    return makeQuery(queries, context).then(function(data) {
      return Promise.resolve(Object.assign({}, global.vars, context, data));
    });
  }
}

function sequence(tasks, initial) {
  return Promise.reduce(tasks || [], function(val, task) {
    return task(val);
  }, initial);
}

/**

  @returns <String> Directory to ignore (if exists)

**/

function addFile(router, route, file, type, basePath) {

    var tasks = [],
        metadata = {};

    // Add to list of extensions if not present
    if (!Motors.hasEngine(file.ext)) Motors.addEngine(file.ext);

    // Extract metadata
    if ("html" === type) {
      metadata = Metadata.extract(Utils.readFileHead(file.path, 500));
      tasks.push(createDataQuery(metadata.data));
    }

    // File compilation function
    if (file.bundle)
      tasks.push(Bundler.fromFile(file, type).get);
    else
      tasks.push(Promise.promisify(Motors.compileFile.bind(Motors, file.path)));

    // Route handling function
    function handler(req, res) {

      // Set cookies
      for (var key in metadata.cookies || {})
        res.cookie(key, metadata.cookies[key]);

      // Set session
      for (var key in metadata.session || {})
        req.session[key] = metadata.session[key];

      sequence(tasks, req.params)
      .then(res.type(type).send.bind(res))
      .catch(function(err) { console.log(err); res.sendStatus(500); });

    }

    // Add routes to router
    Utils.makeRoutes(route, file, { type : type, query : metadata.query }).forEach(function(r) {
      router.get(r, handler);
    });

    // If we have a bundle, return the path (we won't "watch" as this happens
    // already in Bundler.
    if (file.bundle) return file.dir;
    return;

}

module.exports = function(options) {

  var router  = express(),
      ignore,
      ignored = [],
      files   = Utils.mapFiles(options.path, options),
      exts    = {};

  files.forEach(function(file) {

    ignore = addFile(router, options.url, file, options.ext);
    if (ignore) ignored.push(ignore);

    exts[file.ext] = 1;

  });

  for (var key in exts)
    Utils.watch(options.path, key, options.ext, { ignored : ignored });

  return router;

};
<|endoftext|>


<commit_before>/*jshint node: true */
'use strict';

/*
* Name :  MapChartController.js
* Module : FrontEnd::Controller::GraphsController
* Location : /frontend/app/Controller/GraphsController
*
* History :
* Version       Date        Programmer                  Description
* =================================================================================================
* 0.1.0         2015-05-25  Maria Giovanna Chinellato   Add all attributes and all methods
*
* 0.0.1         2015-05-25  Maria Giovanna Chinellato   Initial code
* =================================================================================================
*
*/

angular.module('app')
.controller('MapChartController', ['$scope', 'location', 'MapChartFactory', 'MapChartFlowFactory', 'SocketServices' function($scope, $location, MapChartFactory, MapChartFlowFactory, SocketServices){

	//var mapChart = $scope.mapChart;
	var socket;
	var url = $scope.mapChart.getUrl();

	this.socketConnection = function(){
		socket = io.connect(url);
		$scope.socket = socket;
		// listenOnEvents();
	};

	this.listenOnEvents = function(){
		socket.on('configGraph', function(info){
			$scope.mapChart.updateParameters(info.properties);
			$scope.mapChart.initializeData(info.data);
		});
		socket.on('updateGraphProp', function(info){
			$scope.mapChart.updateParameters(info);
		});
		socket.on('insertFlow', function(info){
			var flow = MapChartFlowFactory.build(info.properties);
			flow.initializeData(info.data);
			$scope.mapChart.addFlow(info.properties.ID, flow);
		});
		socket.on('deleteFlow', function(info){
			$scope.mapChart.deleteFlow(info.ID);
		});
		socket.on('updateFlowProp', function(info){
			var flowList = $scope.mapChart.getFlowList();
			for (var i=0; i<flowList.length; i++){
				if (flowList[i].id === info.ID){
					flowList[i].flow.updateParameters(info);
				}
			}
		});
		socket.on('updateFlowData', function(data){
			switch (data.action){
				case 'insertRecords':
					$scope.mapChart.streamUpdate(data);
					break;
				case 'deleteRecord':
					$scope.mapChart.deleteData(data);
					break;
				case 'updateRecord':
					$scope.mapChart.inPlaceUpdate(data);
					break;
				case 'replaceData':
					$scope.mapChart.replaceData(data);
					break;
			}
		});

	};

	$scope.socketConnection = this.socketConnection;
	$scope.listenOnEvents = this.listenOnEvents;

});<commit_msg>some fixes<commit_after>/*jshint node: true */
'use strict';

/*
* Name :  MapChartController.js
* Module : FrontEnd::Controller::GraphsController
* Location : /frontend/app/Controller/GraphsController
*
* History :
* Version       Date        Programmer                  Description
* =================================================================================================
* 0.1.0         2015-05-25  Maria Giovanna Chinellato   Add all attributes and all methods
*
* 0.0.1         2015-05-25  Maria Giovanna Chinellato   Initial code
* =================================================================================================
*
*/

angular.module('app')
.controller('MapChartController', ['$scope', 'location', 'MapChartFactory', 'MapChartFlowFactory', 'SocketServices', function($scope, $location, MapChartFactory, MapChartFlowFactory, SocketServices){

	//var mapChart = $scope.mapChart;
	var socket;
	var url = $scope.mapChart.getUrl();

	this.socketConnection = function(){
		socket = io.connect(url);
		$scope.socket = socket;
		// listenOnEvents();
	};

	this.listenOnEvents = function(){
		socket.on('configGraph', function(info){
			$scope.mapChart.updateParameters(info.properties);
			$scope.mapChart.initializeData(info.data);
		});
		socket.on('updateGraphProp', function(info){
			$scope.mapChart.updateParameters(info);
		});
		socket.on('insertFlow', function(info){
			var flow = MapChartFlowFactory.build(info.properties);
			flow.initializeData(info.data);
			$scope.mapChart.addFlow(info.properties.ID, flow);
		});
		socket.on('deleteFlow', function(info){
			$scope.mapChart.deleteFlow(info.ID);
		});
		socket.on('updateFlowProp', function(info){
			var flowList = $scope.mapChart.getFlowList();
			for (var i=0; i<flowList.length; i++){
				if (flowList[i].id === info.ID){
					flowList[i].flow.updateParameters(info);
				}
			}
		});
		socket.on('updateFlowData', function(data){
			switch (data.action){
				case 'insertRecords':
					$scope.mapChart.streamUpdate(data);
					break;
				case 'deleteRecord':
					$scope.mapChart.deleteData(data);
					break;
				case 'updateRecord':
					$scope.mapChart.inPlaceUpdate(data);
					break;
				case 'replaceData':
					$scope.mapChart.replaceData(data);
					break;
			}
		});

	};

	$scope.socketConnection = this.socketConnection;
	$scope.listenOnEvents = this.listenOnEvents;

}]);<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Kagilum SAS.
 *
 * This file is part of iceScrum.
 *
 * iceScrum is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License.
 *
 * iceScrum is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with iceScrum.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *
 * Vincent Barrier (vbarrier@kagilum.com)
 * Nicolas Noullet (nnoullet@kagilum.com)
 *
 */

services.service("AppService", ['Session', 'FormService', function(Session, FormService) {
    var self = this;
    this.updateEnabledForProject = function(appDefinition, project, enabledForProject) {
        return FormService.httpPost('app/updateEnabledForProject', {appDefinitionId: appDefinition.id, enabledForProject: enabledForProject}).then(function() {
            var updatedAppDefinition = _.find(project.simpleProjectApps, {appDefinitionId: appDefinition.id});
            if (!updatedAppDefinition) {
                updatedAppDefinition = {appDefinitionId: appDefinition.id};
                project.simpleProjectApps.push(updatedAppDefinition);
            }
            updatedAppDefinition.enabled = enabledForProject;
        });
    };
    this.getAppDefinitions = function() {
        return FormService.httpGet('app/definitions', null, true);
    };
    this.getAppDefinitionsWithProjectSettings = function(project) {
        return self.getAppDefinitions().then(function(appDefinitions) {
            return _.filter(appDefinitions, function(appDefinition) {
                return self.authorizedApp('updateProjectSettings', appDefinition, project)
            });
        });
    };
    this.authorizedApp = function(action, appDefinitionOrId, project) {
        switch (action) {
            case 'show':
                return Session.authenticated() && Session.workspaceType == 'project';
            case 'enableForProject':
                var appDefinition = appDefinitionOrId;
                return Session.poOrSm() && appDefinition && appDefinition.availableForServer && appDefinition.enabledForServer && appDefinition.isProject;
            case 'askToEnableForProject':
                var appDefinition = appDefinitionOrId;
                return Session.tm() && !Session.admin() && appDefinition && appDefinition.availableForServer && appDefinition.enabledForServer && appDefinition.isProject;
            case 'updateProjectSettings':
                var appDefinition = appDefinitionOrId;
                return self.authorizedApp('enableForProject', appDefinition) && self.authorizedApp('use', appDefinition.id, project) && appDefinition.projectSettings;
            case 'use':
                var appDefinitionId = appDefinitionOrId;
                return !!(project && _.find(project.simpleProjectApps, {appDefinitionId: appDefinitionId, availableForServer: true, enabledForServer: true, enabled: true}));
            default:
                return false;
        }
    };
}]);<commit_msg>T1410-0 Apps status needs refreshing the page after first activation<commit_after>/*
 * Copyright (c) 2017 Kagilum SAS.
 *
 * This file is part of iceScrum.
 *
 * iceScrum is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License.
 *
 * iceScrum is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with iceScrum.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *
 * Vincent Barrier (vbarrier@kagilum.com)
 * Nicolas Noullet (nnoullet@kagilum.com)
 *
 */

services.service("AppService", ['Session', 'FormService', function(Session, FormService) {
    var self = this;
    this.updateEnabledForProject = function(appDefinition, project, enabledForProject) {
        return FormService.httpPost('app/updateEnabledForProject', {appDefinitionId: appDefinition.id, enabledForProject: enabledForProject}).then(function() {
            var updatedAppDefinition = _.find(project.simpleProjectApps, {appDefinitionId: appDefinition.id});
            if (!updatedAppDefinition) {
                updatedAppDefinition = {appDefinitionId: appDefinition.id, availableForServer: true, enabledForServer: true};
                project.simpleProjectApps.push(updatedAppDefinition);
            }
            updatedAppDefinition.enabled = enabledForProject;
        });
    };
    this.getAppDefinitions = function() {
        return FormService.httpGet('app/definitions', null, true);
    };
    this.getAppDefinitionsWithProjectSettings = function(project) {
        return self.getAppDefinitions().then(function(appDefinitions) {
            return _.filter(appDefinitions, function(appDefinition) {
                return self.authorizedApp('updateProjectSettings', appDefinition, project)
            });
        });
    };
    this.authorizedApp = function(action, appDefinitionOrId, project) {
        switch (action) {
            case 'show':
                return Session.authenticated() && Session.workspaceType == 'project';
            case 'enableForProject':
                var appDefinition = appDefinitionOrId;
                return Session.poOrSm() && appDefinition && appDefinition.availableForServer && appDefinition.enabledForServer && appDefinition.isProject;
            case 'askToEnableForProject':
                var appDefinition = appDefinitionOrId;
                return Session.tm() && !Session.admin() && appDefinition && appDefinition.availableForServer && appDefinition.enabledForServer && appDefinition.isProject;
            case 'updateProjectSettings':
                var appDefinition = appDefinitionOrId;
                return self.authorizedApp('enableForProject', appDefinition) && self.authorizedApp('use', appDefinition.id, project) && appDefinition.projectSettings;
            case 'use':
                var appDefinitionId = appDefinitionOrId;
                return !!(project && _.find(project.simpleProjectApps, {appDefinitionId: appDefinitionId, availableForServer: true, enabledForServer: true, enabled: true}));
            default:
                return false;
        }
    };
}]);<|endoftext|>


<commit_before>var expect = require('chai').expect;
var request = require('request');
var fs = require('fs');
var helpers = require('../helpers');
var Handlebars = require('handlebars');
var childProcess = require('child_process');
var path = require('path');
describe('Server', function () {
	describe('HTTPS', function () {
		var port = 8443;
		var server;
		var key = path.normalize(process.cwd() + "/key.key");
		var cert = path.normalize(process.cwd() + "/cert.crt");
		describe('Startup', function () {
			it('should allow OpenSSL to generate an SSL certificate', function (done) {
				childProcess.exec('openssl req -x509 -sha256 -nodes -subj "/C=US/ST=Ohio/L=h/O=h/CN=localhost" -days 365 -newkey rsa:2048 -keyout key.key -out cert.crt',
					function (err) {
						expect(err).to.not.exist;
						server = require('../index').init({
								port: port,
								ssl: {
									key: key,
									cert: cert
								}
							}
						);
						done();
					});
			});
			it('should connect to MongoDB', function (done) {
				expect(server.connectMongoose(function (err) {
					expect(err).to.not.exist;
					done();
				}))
			});
			it('should store sessions in MongoDB', function () {
				expect(server.connectMongoStore()).to.not.throw;
			});
			it('should startup the server', function () {
				expect(server.startServer()).to.not.throw;
			});
		});
		describe('Content', function () {
			it('should respond to connections', function (done) {
				request({
					url: 'https://localhost:'+port,
					agentOptions: {ca: fs.readFileSync(cert)}
				}, function (err, res) {
					expect(err).to.not.exist;
					expect(res.statusCode).to.be.at.most(399);
					done();
				});
			});
			describe('Pages', function () {
				var menu = {
					'/': ['Home', []],
					'/data': ['View Draws', []],
					'/contact': ['Contact', []],
					'/about': ['About', []],
					'/login': ['Login', ['right']],
					'/signup': ['Sign Up', ['right']]
				};
				var template = Handlebars.compile(fs.readFileSync('content/page.handlebars').toString('utf-8'));
				it('should show the home page correctly', function (done) {
					request({
						url: 'https://localhost:'+port,
						agentOptions: {ca: fs.readFileSync(cert)}
					}, function (err, res, resBody) {
						expect(err).to.not.exist;
						expect(res.statusCode).to.be.at.most(399);
						fs.readFile('../content/index.handlebars', function (index) {
							var templateParameters = {
								title: "Curling CSC",
								menu: menu,
								content: Handlebars.compile(index.toString('utf-8')),
								serviceWorker: false
							};
							var originalYear = 2015;
							if(new Date().getFullYear() !== originalYear){
								templateParameters.showSecondYear = true;
								templateParameters.year = new Date().getFullYear();
							}
							expect(resBody).to.equal(template(templateParameters));
						});
						done();
					});
				});
			});
		});
		describe('Shutdown', function () {
			it('should shutdown properly', function (done) {
				server.stop();
				request('http://localhost:' + port, function (err) {
					expect(err).to.exist;
					done();
				});
			});
		});
	})
});<commit_msg>Extend timeout for certificates<commit_after>var expect = require('chai').expect;
var request = require('request');
var fs = require('fs');
var helpers = require('../helpers');
var Handlebars = require('handlebars');
var childProcess = require('child_process');
var path = require('path');
describe('Server', function () {
	describe('HTTPS', function () {
		var port = 8443;
		var server;
		var key = path.normalize(process.cwd() + "/key.key");
		var cert = path.normalize(process.cwd() + "/cert.crt");
		describe('Startup', function () {
			this.timeout(5000);
			it('should allow OpenSSL to generate an SSL certificate', function (done) {
				childProcess.exec('openssl req -x509 -sha256 -nodes -subj "/C=US/ST=Ohio/L=h/O=h/CN=localhost" -days 365 -newkey rsa:2048 -keyout key.key -out cert.crt',
					function (err) {
						expect(err).to.not.exist;
						server = require('../index').init({
								port: port,
								ssl: {
									key: key,
									cert: cert
								}
							}
						);
						done();
					});
			});
			it('should connect to MongoDB', function (done) {
				expect(server.connectMongoose(function (err) {
					expect(err).to.not.exist;
					done();
				}))
			});
			it('should store sessions in MongoDB', function () {
				expect(server.connectMongoStore()).to.not.throw;
			});
			it('should startup the server', function () {
				expect(server.startServer()).to.not.throw;
			});
		});
		describe('Content', function () {
			it('should respond to connections', function (done) {
				request({
					url: 'https://localhost:'+port,
					agentOptions: {ca: fs.readFileSync(cert)}
				}, function (err, res) {
					expect(err).to.not.exist;
					expect(res.statusCode).to.be.at.most(399);
					done();
				});
			});
			describe('Pages', function () {
				var menu = {
					'/': ['Home', []],
					'/data': ['View Draws', []],
					'/contact': ['Contact', []],
					'/about': ['About', []],
					'/login': ['Login', ['right']],
					'/signup': ['Sign Up', ['right']]
				};
				var template = Handlebars.compile(fs.readFileSync('content/page.handlebars').toString('utf-8'));
				it('should show the home page correctly', function (done) {
					request({
						url: 'https://localhost:'+port,
						agentOptions: {ca: fs.readFileSync(cert)}
					}, function (err, res, resBody) {
						expect(err).to.not.exist;
						expect(res.statusCode).to.be.at.most(399);
						fs.readFile('../content/index.handlebars', function (index) {
							var templateParameters = {
								title: "Curling CSC",
								menu: menu,
								content: Handlebars.compile(index.toString('utf-8')),
								serviceWorker: false
							};
							var originalYear = 2015;
							if(new Date().getFullYear() !== originalYear){
								templateParameters.showSecondYear = true;
								templateParameters.year = new Date().getFullYear();
							}
							expect(resBody).to.equal(template(templateParameters));
						});
						done();
					});
				});
			});
		});
		describe('Shutdown', function () {
			it('should shutdown properly', function (done) {
				server.stop();
				request('http://localhost:' + port, function (err) {
					expect(err).to.exist;
					done();
				});
			});
		});
	})
});
<|endoftext|>


<commit_before>const express = require('express')
const router = express.Router()
const User = require('../db/models/user')
const Message = require('../db/models/message')
const Oauth = require('../db/models/oauth')
// const passport = require('passport')
const axios = require('axios')
const google = require('googleapis')
const Gmail = require('node-gmail-api')
const Promise = require('bluebird')
const simpleParser = require('mailparser').simpleParser

// const loadContacts = require('../util/loadContacts')
// const loadMessages = require('../util/loadMessages')

// iMESSAGE DB / get all contacts

router.post('/', (req, res, next) => {
	const contacts = req.body
	const ourUser = req.user

	return Promise.all(contacts.map(elem => {

		if (elem.ZFULLNUMBER) {
			return User.findOrCreate(
				{
					defaults: { ZFIRSTNAME: elem.ZFIRSTNAME, ZLASTNAME: elem.ZLASTNAME, ZFULLNUMBER: elem.ZFULLNUMBER },
					where: { ZFULLNUMBER: elem.ZFULLNUMBER.replace(/[^0-9]/g, '').slice(-10) }
				}
			)
		}

	})) //closes the Promise.all
		.then((allCreatedContacts) => {
			console.log('=====Finished Syncing Contacts====')
	})
})

router.get('/', function (req, res, next){

let newContacts

	User.findAll({
		where: {
			user_id: req.user && req.user.id
		}
	})
	.then(contacts => {
		newContacts = contacts.map( contact => {

			return Message.findAll({
        where: { uploader_id: req.user.guid, ZFULLNUMBER: contact.ZFULLNUMBER },
        order: 'date DESC'
				//TODO: the order: date DESC might cause problems because of the weird date thing being a string
      })
			.then(messageArray => {
				if(messageArray){
					contact.dataValues.latestMessage = messageArray[0]
				}
					return contact
			})
		})
		Promise.all(newContacts)
		.then((modifiedContacts) => {
			res.json(modifiedContacts)
		})

	})
	.catch(console.error)
})

router.get('/sync', (req, res, next) => {

	const child = exec('node util/sync.js', {maxBuffer: 1024 * 100000000000000000}, (error, stdout, stderr) => {

		if (error) console.error(error)

	})

	child.stdout.on('data', (chunk) => {
		console.log(chunk.toString())
	})

	child.stderr.on('data', (chunk) => {
		console.error(chunk.toString())
	})

// This child.on function will first run the child function which uploads iMessage contacts and messages to our database
// Afterwards, it will update the database with associations.
	child.on('close', () => {

		User.findAll(
			{
				where: {user_id: null}
			}
		)
		.then((yourContacts) => {

			yourContacts.forEach((elem) => {
				elem.update({user_id: req.user.id})
			})
		})
		.catch(console.error)

		Message.findAll(
			{
				where: {sender_id: null}
			}
		)
		.then((yourMessages) => {
			console.log('you are in the Message.findAll part')
			yourMessages.forEach((elem) => {
				User.findOne({
					where: {ZFULLNUMBER: elem.ZFULLNUMBER}
				})
				.then((foundUser) => {
					if(foundUser){
						if(elem.is_sender){
							elem.update({
								sender_id: req.user.id,
								recipient_id: foundUser.id
							})
						}
						else{
							elem.update({
								sender_id: foundUser.id,
								recipient_id: req.user.id
							})
						}
					}
				})
				.catch(console.error)
			})
			console.log('suuupersyyyyync complete')
		})
		.then(() => {
			res.redirect('/')
		})
		.catch(console.error)
	})

});

router.get('/messages/all', function (req, res, next) {

	User.findById(req.session.passport.user)
	.then(user => {
		return user.getMessages()
	})
	.then(userMessages => {
		console.log("USER MESSAGES", userMessages)
		res.json(userMessages)
	})

})

router.get('/messages/latest/:contactId', function (req, res, next) {

	User.findById(req.params.contactId)
	.then(contact => {
		return contact.getMessages()
	})
	.then(contactMessageswithUser => {
		console.log("CONTACT MESSAGES", contactMessageswithUser[0])
		res.json(contactMessageswithUser[0].content)
	})
})

router.get('/gmail', function(req, res, next){

	// Find User
	Oauth.findOne({
		where: {
			user_id: req.user.id
		}
	})
	.then(authUser => {

		// Get list of new message IDs
		axios.get('https://www.googleapis.com/gmail/v1/users/me/messages', {
			headers: {
				Authorization: 'Bearer ' + authUser.accessToken
			}
		})
		.then(allMails => {
			console.log('ALL MAILS OBJECT :', allMails)

			const emailPromises = allMails.data.messages.map( message => {
				return axios.get(`https://www.googleapis.com/gmail/v1/users/me/messages/${message.id}/?format=metadata`, {
					headers: {
						Authorization: 'Bearer ' + authUser.accessToken
					}
				})
			})
			return Promise.all(emailPromises)
			// need to pass down the next page token
		})
		.then(emailsArray => {

			function findSender (array) {
				return array.name === "From"
			}

			function findSubject (array) {
				return array.name === "Subject"
			}

			function findDate(array) {
				return array.name === "Date"
			}

			const emailMap = emailsArray.map( email => {
				const snippet  = email.data.snippet.replace(/'/g, '').replace(/&/g, '&').trim()
				const headers = email.data.payload.headers

				const senderEmail = headers.find(findSender).value.trim()
				let emailAddress = senderEmail.slice(senderEmail.indexOf('<') +1, senderEmail.length -1)

				const senderName = headers.find(findSender).value.trim()
				let name = senderName.slice(0, senderEmail.indexOf('<')-1).replace(/"/g, '').trim()

				const subject = headers.find(findSubject).value
				const date = headers.find(findDate).value
				return {
					name,
					emailAddress,
					subject,
					snippet,
					date
				}
			})
			res.json(emailMap)
		})
		.catch(error => {
			console.log(error)
			next(error)
		})
	})
})

router.get('/googleprofile/:id', (req, res, next) => {

	Oauth.findOne({
	    where: {user_id: req.user.id}
	})
	.then(authUser => {

	    return axios.get(`https://www.googleapis.com/plus/v1/people/me`, {
			headers: {
				Authorization: 'Bearer ' + authUser.accessToken
			}
	    })
	})
	.then(profile => {
		res.json(profile)
	})
	.catch(next)
})

router.get('/gmail/:id', function(req, res, next){

	Oauth.findOne({
		where: {user_id: req.user.id}
	})
	.then(authUser => {

		axios.get(`https://www.googleapis.com/gmail/v1/users/me/messages/${req.params.id}`, {
			headers: {
				Authorization: 'Bearer ' + authUser.accessToken
			}
		})
		.then(response => {

			if (response.payload.body.size === 0) {

				let bodyArray = []

				response.payload.parts.forEach( i => {

					let base64 = i.body.data
					let buff = Buffer.from(base64, 'base64')
					bodyArray.push(simpleParser(buff))
				})

				Promise.all(bodyArray)
				.then(bodyarray => {
					res.json(bodyarray)
				})
				.catch(error => {
					console.log(error)
					next(error)
				})

			} else {

				let base64 = response.payload.body.data
				let buff = Buffer.from(base64, 'base64')
				simpleParser(buff)
				.then( results => {
					console.log(results)
					res.json(results)
				})
				.catch(error => {
					console.log(error)
					next(error)
				})
			}
		})
		.catch(error => {
			console.log(error)
			next(error)
		})
	})
})

router.get('/:id', (req, res) => {
	let contact = null

	return User.findById(req.params.id)
		.then(foundContact => {
			contact = foundContact
			return contact.getMessages()
		})
		.then(contactMessages => {
			contact.dataValues.latestMessage = contactMessages[0]
			res.json(contact)
		})
	.catch(console.error)
})

module.exports = router
<commit_msg>fix(contacts route): Associates contacts to user on create)<commit_after>const express = require('express')
const router = express.Router()
const User = require('../db/models/user')
const Message = require('../db/models/message')
const Oauth = require('../db/models/oauth')
// const passport = require('passport')
const axios = require('axios')
const google = require('googleapis')
const Gmail = require('node-gmail-api')
const Promise = require('bluebird')
const simpleParser = require('mailparser').simpleParser

// const loadContacts = require('../util/loadContacts')
// const loadMessages = require('../util/loadMessages')

// iMESSAGE DB / get all contacts

router.post('/', (req, res, next) => {
	const contacts = req.body
	const ourUser = req.user

	return Promise.all(contacts.map(elem => {

		if (elem.ZFULLNUMBER) {
			return User.findOrCreate(
				{
					defaults: { ZFIRSTNAME: elem.ZFIRSTNAME, ZLASTNAME: elem.ZLASTNAME, ZFULLNUMBER: elem.ZFULLNUMBER },
					where: { ZFULLNUMBER: elem.ZFULLNUMBER.replace(/[^0-9]/g, '').slice(-10) }
				}
			)
			.then((createdContact) => {
				ourUser.addFriend(createdContact[0])
				console.log('=====Finished Syncing Contacts====')
			})
		}
	})) //closes the Promise.all
	.catch(next)
})

router.get('/', function (req, res, next){

let newContacts

	User.findAll({
		where: {
			user_id: req.user && req.user.id
		}
	})
	.then(contacts => {
		newContacts = contacts.map( contact => {

			return Message.findAll({
        where: { uploader_id: req.user.guid, ZFULLNUMBER: contact.ZFULLNUMBER },
        order: 'date DESC'
				//TODO: the order: date DESC might cause problems because of the weird date thing being a string
      })
			.then(messageArray => {
				if(messageArray){
					contact.dataValues.latestMessage = messageArray[0]
				}
					return contact
			})
		})
		Promise.all(newContacts)
		.then((modifiedContacts) => {
			res.json(modifiedContacts)
		})

	})
	.catch(console.error)
})

router.get('/sync', (req, res, next) => {

	const child = exec('node util/sync.js', {maxBuffer: 1024 * 100000000000000000}, (error, stdout, stderr) => {

		if (error) console.error(error)

	})

	child.stdout.on('data', (chunk) => {
		console.log(chunk.toString())
	})

	child.stderr.on('data', (chunk) => {
		console.error(chunk.toString())
	})

// This child.on function will first run the child function which uploads iMessage contacts and messages to our database
// Afterwards, it will update the database with associations.
	child.on('close', () => {

		User.findAll(
			{
				where: {user_id: null}
			}
		)
		.then((yourContacts) => {

			yourContacts.forEach((elem) => {
				elem.update({user_id: req.user.id})
			})
		})
		.catch(console.error)

		Message.findAll(
			{
				where: {sender_id: null}
			}
		)
		.then((yourMessages) => {
			console.log('you are in the Message.findAll part')
			yourMessages.forEach((elem) => {
				User.findOne({
					where: {ZFULLNUMBER: elem.ZFULLNUMBER}
				})
				.then((foundUser) => {
					if(foundUser){
						if(elem.is_sender){
							elem.update({
								sender_id: req.user.id,
								recipient_id: foundUser.id
							})
						}
						else{
							elem.update({
								sender_id: foundUser.id,
								recipient_id: req.user.id
							})
						}
					}
				})
				.catch(console.error)
			})
			console.log('suuupersyyyyync complete')
		})
		.then(() => {
			res.redirect('/')
		})
		.catch(console.error)
	})

});

router.get('/messages/all', function (req, res, next) {

	User.findById(req.session.passport.user)
	.then(user => {
		return user.getMessages()
	})
	.then(userMessages => {
		console.log("USER MESSAGES", userMessages)
		res.json(userMessages)
	})

})

router.get('/messages/latest/:contactId', function (req, res, next) {

	User.findById(req.params.contactId)
	.then(contact => {
		return contact.getMessages()
	})
	.then(contactMessageswithUser => {
		console.log("CONTACT MESSAGES", contactMessageswithUser[0])
		res.json(contactMessageswithUser[0].content)
	})
})

router.get('/gmail', function(req, res, next){

	// Find User
	Oauth.findOne({
		where: {
			user_id: req.user.id
		}
	})
	.then(authUser => {

		// Get list of new message IDs
		axios.get('https://www.googleapis.com/gmail/v1/users/me/messages', {
			headers: {
				Authorization: 'Bearer ' + authUser.accessToken
			}
		})
		.then(allMails => {
			console.log('ALL MAILS OBJECT :', allMails)

			const emailPromises = allMails.data.messages.map( message => {
				return axios.get(`https://www.googleapis.com/gmail/v1/users/me/messages/${message.id}/?format=metadata`, {
					headers: {
						Authorization: 'Bearer ' + authUser.accessToken
					}
				})
			})
			return Promise.all(emailPromises)
			// need to pass down the next page token
		})
		.then(emailsArray => {

			function findSender (array) {
				return array.name === "From"
			}

			function findSubject (array) {
				return array.name === "Subject"
			}

			function findDate(array) {
				return array.name === "Date"
			}

			const emailMap = emailsArray.map( email => {
				const snippet  = email.data.snippet.replace(/'/g, '').replace(/&/g, '&').trim()
				const headers = email.data.payload.headers

				const senderEmail = headers.find(findSender).value.trim()
				let emailAddress = senderEmail.slice(senderEmail.indexOf('<') +1, senderEmail.length -1)

				const senderName = headers.find(findSender).value.trim()
				let name = senderName.slice(0, senderEmail.indexOf('<')-1).replace(/"/g, '').trim()

				const subject = headers.find(findSubject).value
				const date = headers.find(findDate).value
				return {
					name,
					emailAddress,
					subject,
					snippet,
					date
				}
			})
			res.json(emailMap)
		})
		.catch(error => {
			console.log(error)
			next(error)
		})
	})
})

router.get('/googleprofile/:id', (req, res, next) => {

	Oauth.findOne({
	    where: {user_id: req.user.id}
	})
	.then(authUser => {

	    return axios.get(`https://www.googleapis.com/plus/v1/people/me`, {
			headers: {
				Authorization: 'Bearer ' + authUser.accessToken
			}
	    })
	})
	.then(profile => {
		res.json(profile)
	})
	.catch(next)
})

router.get('/gmail/:id', function(req, res, next){

	Oauth.findOne({
		where: {user_id: req.user.id}
	})
	.then(authUser => {

		axios.get(`https://www.googleapis.com/gmail/v1/users/me/messages/${req.params.id}`, {
			headers: {
				Authorization: 'Bearer ' + authUser.accessToken
			}
		})
		.then(response => {

			if (response.payload.body.size === 0) {

				let bodyArray = []

				response.payload.parts.forEach( i => {

					let base64 = i.body.data
					let buff = Buffer.from(base64, 'base64')
					bodyArray.push(simpleParser(buff))
				})

				Promise.all(bodyArray)
				.then(bodyarray => {
					res.json(bodyarray)
				})
				.catch(error => {
					console.log(error)
					next(error)
				})

			} else {

				let base64 = response.payload.body.data
				let buff = Buffer.from(base64, 'base64')
				simpleParser(buff)
				.then( results => {
					console.log(results)
					res.json(results)
				})
				.catch(error => {
					console.log(error)
					next(error)
				})
			}
		})
		.catch(error => {
			console.log(error)
			next(error)
		})
	})
})

router.get('/:id', (req, res) => {
	let contact = null

	return User.findById(req.params.id)
		.then(foundContact => {
			contact = foundContact
			return contact.getMessages()
		})
		.then(contactMessages => {
			contact.dataValues.latestMessage = contactMessages[0]
			res.json(contact)
		})
	.catch(console.error)
})

module.exports = router
<|endoftext|>


<commit_before>"use strict";

/*global module, require*/

var d3 = require("d3"),
    search = require("./search.js"),
    helpers = require("./helpers.js"),
    guid = helpers.guid,
    callbacks = helpers.callbackHandler;

/*
 Provides UI buttons to manage documents.
 */
module.exports = function(container, searchFunction) {
    var title = null,
	temp = false,
	lastSearch = null,
	onNew = callbacks(),
	onOpen = callbacks(),
	onSaveAs = callbacks(),
	onInsert = callbacks(),
	onDelete = callbacks();

    var setTitle = function(newTitle, newTemp) {
	if (temp) {
	    onDelete(title);
	}
	title = newTitle;
	temp = newTemp;
	jsonExport.attr("download", title + ".json");
    };

    var withSearch = function(alwaysIncludeSearchText, callback) {
	return function() {
	    if (lastSearch) {
		lastSearch.hide();
	    }
	    lastSearch = search(container, searchFunction, alwaysIncludeSearchText, title, callback);
	};
    };

    var newDoc = function() {
	setTitle(guid(), true);
	onNew(title);
    };

    var open = function(name) {
	setTitle(name, false);
    };

    var buttons = d3.map({
	New: newDoc,

	Open: withSearch(false, open),

	"Save as": withSearch(true, function(result) {
	    setTitle(result, false);
	    onSaveAs(result);
	}),

	Insert: withSearch(false, function(result) {
	    onInsert(result);
	}),

	Delete: withSearch(false, function(result) {
	    if (result === title) {
		setTitle(guid(), true);
		onNew(title);
	    }
		onDelete(result);
	})
    });

    container.selectAll("div.document-control-button")
	.data(buttons.keys())
	.enter()
	.append("div")
	.classed("document-control-button", true)
	.text(function(d, i) {
	    return d;
	})
	.on("click", function(d, i) {
	    buttons.get(d)();
	});

    var jsonExport = container.append("a")
	    .classed("document-control-button", true)
	    .text("Export")
	    .attr("href", "javascript:void(0)");

    return {
	newDoc: newDoc,
	onNew: onNew.add,
	open: open,
	onOpen: onOpen.add,
	onSaveAs: onSaveAs.add,
	onInsert: onInsert.add,
	onDelete: onDelete.add,
	updateExportLink: function(val) {
	    jsonExport.attr("href", val);
	}
    };
};
<commit_msg>Fixed onOpen behaviour again.<commit_after>"use strict";

/*global module, require*/

var d3 = require("d3"),
    search = require("./search.js"),
    helpers = require("./helpers.js"),
    guid = helpers.guid,
    callbacks = helpers.callbackHandler;

/*
 Provides UI buttons to manage documents.
 */
module.exports = function(container, searchFunction) {
    var title = null,
	temp = false,
	lastSearch = null,
	onNew = callbacks(),
	onOpen = callbacks(),
	onSaveAs = callbacks(),
	onInsert = callbacks(),
	onDelete = callbacks();

    var setTitle = function(newTitle, newTemp) {
	if (temp) {
	    onDelete(title);
	}
	title = newTitle;
	temp = newTemp;
	jsonExport.attr("download", title + ".json");
    };

    var withSearch = function(alwaysIncludeSearchText, callback) {
	return function() {
	    if (lastSearch) {
		lastSearch.hide();
	    }
	    lastSearch = search(container, searchFunction, alwaysIncludeSearchText, title, callback);
	};
    };

    var newDoc = function() {
	setTitle(guid(), true);
	onNew(title);
    };

    var open = function(name) {
	setTitle(name, false);
	onOpen(name);
    };

    var buttons = d3.map({
	New: newDoc,

	Open: withSearch(false, open),

	"Save as": withSearch(true, function(result) {
	    setTitle(result, false);
	    onSaveAs(result);
	}),

	Insert: withSearch(false, function(result) {
	    onInsert(result);
	}),

	Delete: withSearch(false, function(result) {
	    if (result === title) {
		setTitle(guid(), true);
		onNew(title);
	    }
		onDelete(result);
	})
    });

    container.selectAll("div.document-control-button")
	.data(buttons.keys())
	.enter()
	.append("div")
	.classed("document-control-button", true)
	.text(function(d, i) {
	    return d;
	})
	.on("click", function(d, i) {
	    buttons.get(d)();
	});

    var jsonExport = container.append("a")
	    .classed("document-control-button", true)
	    .text("Export")
	    .attr("href", "javascript:void(0)");

    return {
	newDoc: newDoc,
	onNew: onNew.add,
	open: open,
	onOpen: onOpen.add,
	onSaveAs: onSaveAs.add,
	onInsert: onInsert.add,
	onDelete: onDelete.add,
	updateExportLink: function(val) {
	    jsonExport.attr("href", val);
	}
    };
};
<|endoftext|>


<commit_before>(function($, Symphony) {
	'use strict';

	Symphony.Language.add({
		'Edit': false,
		'Associated {$section-name}': false,
		'You just closed “{$title}” with unsaved changes.': false,
		'Reopen to save?': false,
		'Or dismiss?': false,
		'You just edited “{$title}”.': false,
		'Reopen?': false
	});

	Symphony.Extensions.AssociationUIEditor = function() {
		var fields,
			templateTrigger, templateEditor, templateCreate,
			editors = {},
			progress, progressFrame;

		var init = function() {
			fields = Symphony.Elements.contents.find('.field[data-editor^="aui-editor"]');
			templateTrigger = createTriggerTemplate();
			templateEditor = createEditorTemplate();
			templateCreate = createNewTemplate();

			attachEditor();
			createNew();
		};

		var createTriggerTemplate = function() {
			return $('' + Symphony.Language.get('Edit') + '');
		};

		var createEditorTemplate = function() {
			return $('

');
		};

		var createNewTemplate = function() {
			return $('
<button class="aui-editor-button">' + Symphony.Language.get('Create New') + '</button>
');
		};

		var createNew = function() {
			fields.each(attachCreateButton);
		};

		var attachCreateButton = function() {
			var field = $(this),
				button, handle, link;

			if(field.is('[data-editor="aui-editor-new"]')) {
				button = templateCreate.clone();
				handle = getSectionHandle(field.data('parent-section-id'));
				link = Symphony.Context.get('symphony') + '/publish/' + handle + '/new/';

				button.on('click.aui-editor', function(event) {
					event.stopPropagation();
					event.preventDefault();

					loadEditor(link);
				}).appendTo(field);
			}
		};

		var attachEditor = function() {
			fields.each(attachTrigger);
		};

		var attachTrigger = function() {
			var item = $(this).find('.item'),
				trigger = templateTrigger.clone();

			trigger.on('mousedown.aui-editor', triggerPage);
			item.not('.aui-editor-trigger').prepend(trigger);
		};

		var triggerPage = function(event) {
			var link = $(this).parent().data('link');

			event.preventDefault();
			event.stopPropagation();

			if(editors[link]) {
				showEditor(link);
			}
			else {
				loadEditor(link);
			}
		};

		var loadEditor = function(link) {
			var editor = templateEditor.clone(),
				iframe = editor.find('iframe');

			// Setup progress bar
			progress = editor.find('.aui-editor-progress');
			progressFrame = iframe[0];
			window.requestAnimationFrame(indicateState);

			// Load content
			iframe.on('load.aui-editor', loadPage);
			iframe.attr('src', link);

			// Prepare closing
			editor.on('click.aui-editor', closeEditor);

			// Attach editor
			editor.data('link', link);
			editors[link] = editor;
			showEditor(link);
		};

		var indicateState = function() {
			var	state = progressFrame.contentDocument.readyState;

			if(state == 'complete' || state == 'interactive') {
				if(state == 'complete') {
					progress.addClass('changes-fast');
					progress.css('width', '100%');
					progress.addClass('is-hidden');
				}
				else {
					progress.addClass('changes-fast');
					window.requestAnimationFrame(indicateState);
				}
			}
			else {
				progress.css('width', '50%');
				window.requestAnimationFrame(indicateState);
			}
		};

		var closeEditor = function() {
			var editor = $(this),
				link;

			if(!editor.is('.aui-editor')) {
				editor = Symphony.Elements.contents.find('.aui-editor:visible');
			}

			link = editor.data('link');
			editor.addClass('is-canceled');
			resetScrollHeight();

			// Hide wrapper
			setTimeout(function() {
				editor.addClass('is-hidden');
			}, 500);

			// Prepare undo
			prepareUndo(link);

			// Trigger update
			$('.field .item[data-link="' + link + '"]').trigger('update');
		};

		var loadPage = function() {
			var iframe = $(this),
				editor = iframe.parents('.aui-editor'),
				contents = iframe.contents(),
				wrapper = contents.find('#wrapper'),
				header = contents.find('#header'),
				notifier = header.find('.notifier'),
				context = contents.find('#context'),
				breadcrumbs = contents.find('#breadcrumbs'),
				content = contents.find('#contents'),
				form = contents.find('#contents form'),
				title = contents.find('#symphony-subheading').text(),
				link = editor.data('link'),
				close, height;

			// Store title
			editor.data('title', title);

			// Modify header links
			close = $('', {
				class: 'aui-editor-close',
				html: Symphony.Language.get('Close') + ' ×',
				on: {
					click: closeEditor
				}
			});
			breadcrumbs.after(close);
			breadcrumbs.find('a').each(modifyHeader);

			// Relocate notifications
			notifier.find('p').not('.success').not('.error').remove();
			notifier.find('a').remove();
			if(!notifier.find('p').length) {
				notifier.hide();
			}
			context.after(notifier);

			// Remove elements
			contents.find('body').addClass('aui-editor-section');
			header.remove();
			context.find('.actions').remove();
			content.find('.actions .delete').remove();

			// Show content
			iframe.removeClass('is-hidden');

			// Store state
			editor.data('form', form.serialize());

			// Set height
			height = wrapper.height();
			editor.data('height', height);
			setScrollHeight(link);

			// Prepare saving
			content.find('.actions input[type="submit"]').on('click', function() {
				$('html, body').animate({
					scrollTop: 0
				});
			});
		};

		var modifyHeader = function(index) {
			var link = $(this);

			// Remove internal links
			link.removeAttr('href');

			// Set title
			if(index === 0) {
				link.text(Symphony.Language.get('Associated {$section-name}', {
					'section-name': link.text()
				}));
			}
		};

		var showEditor = function(link) {
			var editor = editors[link],
				iframe, contents, notifier;

			if(editor.is('.is-hidden')) {
				iframe = editor.find('iframe');
				contents = iframe.contents();
				notifier = contents.find('.notifier').hide();
				notifier.find('p').remove();

				editor.removeClass('is-hidden');
				editor.removeClass('is-canceled');
				setScrollHeight(link);
			}
			else {
				Symphony.Elements.contents.append(editor);
			}

			// Set close action
			Symphony.Elements.context.one('click.aui-editor', closeEditor);

			// Remove existing undo options
			Symphony.Elements.header.find('.notifier .undo').trigger('detach.notify');
		};

		var prepareUndo = function(link) {
			var id = new Date().getTime(),
				editor = editors[link],
				title = editor.data('title'),
				notifier = Symphony.Elements.header.find('div.notifier'),
				iframe = editor.find('iframe'),
				contents = iframe.contents(),
				form = contents.find('#contents form');

			// Unsaved changes
			if(form.serialize() != editor.data('form')) {
				notifier.trigger('attach.notify', [
					Symphony.Language.get('You just closed “{$title}” with unsaved changes.', {title: title}) + '' + Symphony.Language.get('Reopen to save?') + '' + '' + Symphony.Language.get('Or dismiss?') + '',
					'protected error undo'
				]);

				// Prepare field recovery
				$('#' + id).on('click.aui-editor', function() {
					$(this).parent().trigger('detach.notify');
					showEditor(link);
				});

				// Dismiss
				$('#' + id + '-dismiss').on('click.aui-editor', function() {
					$(this).parent().trigger('detach.notify');
					editor.remove();
					delete editors[link];
				});
			}
		};

		var setScrollHeight = function(link) {
			var editor = editors[link],
				height = editor.data('height');

			Symphony.Elements.contents.css({
				minHeight: height,
				maxHeight: height,
				overflow: 'hidden'
			});
		};

		var resetScrollHeight = function() {
			Symphony.Elements.contents.removeAttr('style');
		};

		var getSectionHandle = function(id) {
			var associations = Symphony.Context.get('env').associations.parent,
				handle = '';

			$.each(associations, function() {
				if(this.id == id) {
					handle = this.handle;
				}
			});

			return handle;
		};

		// API
		return {
			init: init
		};
	}();

	$(window).on('load.aui-editor', function() {
		Symphony.Extensions.AssociationUIEditor.init();
	});

})(window.jQuery, window.Symphony);
<commit_msg>Update and add items<commit_after>(function($, Symphony) {
	'use strict';

	Symphony.Language.add({
		'Edit': false,
		'Associated {$section-name}': false,
		'You just closed “{$title}” with unsaved changes.': false,
		'Reopen to save?': false,
		'Or dismiss?': false,
		'You just edited “{$title}”.': false,
		'Reopen?': false
	});

	Symphony.Extensions.AssociationUIEditor = function() {
		var fields,
			templateTrigger, templateEditor, templateCreate,
			editors = {},
			progress, progressFrame;

		var init = function() {
			fields = Symphony.Elements.contents.find('.field[data-editor^="aui-editor"]');
			templateTrigger = createTriggerTemplate();
			templateEditor = createEditorTemplate();
			templateCreate = createNewTemplate();

			attachEditor();
			createNew();
		};

		var createTriggerTemplate = function() {
			return $('' + Symphony.Language.get('Edit') + '');
		};

		var createEditorTemplate = function() {
			return $('

');
		};

		var createNewTemplate = function() {
			return $('
<button class="aui-editor-button">' + Symphony.Language.get('Create New') + '</button>
');
		};

		var createNew = function() {
			fields.each(attachCreateButton);
		};

		var attachCreateButton = function() {
			var field = $(this),
				button, handle, link;

			if(field.is('[data-editor="aui-editor-new"]')) {
				button = templateCreate.clone();
				handle = getSectionHandle(field.data('parent-section-id'));
				link = Symphony.Context.get('symphony') + '/publish/' + handle + '/new/';

				button.on('click.aui-editor', function(event) {
					event.stopPropagation();
					event.preventDefault();

					loadEditor(link, field);
				}).appendTo(field);
			}
		};

		var attachEditor = function() {
			fields.each(attachTrigger);
		};

		var attachTrigger = function() {
			var item = $(this).find('.item'),
				trigger = templateTrigger.clone();

			trigger.on('mousedown.aui-editor', triggerPage);
			item.not('.aui-editor-trigger').prepend(trigger);
		};

		var triggerPage = function(event) {
			var link = $(this).parent().data('link'),
				field;

			event.preventDefault();
			event.stopPropagation();

			if(editors[link]) {
				showEditor(link);
			}
			else {
				loadEditor(link);
			}
		};

		var loadEditor = function(link, field) {
			var editor = templateEditor.clone(),
				iframe = editor.find('iframe');

			// Setup progress bar
			progress = editor.find('.aui-editor-progress');
			progressFrame = iframe[0];
			window.requestAnimationFrame(indicateState);

			// Load content
			iframe.on('load.aui-editor', loadPage);
			iframe.attr('src', link);

			// Prepare closing
			editor.on('click.aui-editor', closeEditor);

			// Store field reference
			if(field) {
				editor.data(field);
			}

			// Attach editor
			editor.data('link', link);
			editors[link] = editor;
			showEditor(link);
		};

		var indicateState = function() {
			var	state = progressFrame.contentDocument.readyState;

			if(state == 'complete' || state == 'interactive') {
				if(state == 'complete') {
					progress.addClass('changes-fast');
					progress.css('width', '100%');
					progress.addClass('is-hidden');
				}
				else {
					progress.addClass('changes-fast');
					window.requestAnimationFrame(indicateState);
				}
			}
			else {
				progress.css('width', '50%');
				window.requestAnimationFrame(indicateState);
			}
		};

		var closeEditor = function() {
			var editor = $(this),
				link, id, field, contents;

			if(!editor.is('.aui-editor')) {
				editor = Symphony.Elements.contents.find('.aui-editor:visible');
			}

			link = editor.data('link');
			editor.addClass('is-canceled');
			resetScrollHeight();

			// Hide wrapper
			setTimeout(function() {
				editor.addClass('is-hidden');
			}, 500);

			// Prepare undo
			prepareUndo(link);

			// Trigger update
			field = editor.data(field);
			if(field) {
				contents = editor.find('iframe').contents();
				id = contents.find('body').attr('class').match(/ id-(\d+)\/?/)[1];
				Symphony.Extensions.AssociationUISelector.add(field, id);
			}
			else {
				id = link.match(/\/edit\/(\d+)\/?/)[1];
				Symphony.Extensions.AssociationUISelector.update(id);
			}
			Symphony.Extensions.AssociationUISelector.update(id);
		};

		var loadPage = function() {
			var iframe = $(this),
				editor = iframe.parents('.aui-editor'),
				contents = iframe.contents(),
				wrapper = contents.find('#wrapper'),
				header = contents.find('#header'),
				notifier = header.find('.notifier'),
				context = contents.find('#context'),
				breadcrumbs = contents.find('#breadcrumbs'),
				content = contents.find('#contents'),
				form = contents.find('#contents form'),
				title = contents.find('#symphony-subheading').text(),
				link = editor.data('link'),
				close, height;

			// Store title
			editor.data('title', title);

			// Modify header links
			close = $('', {
				class: 'aui-editor-close',
				html: Symphony.Language.get('Close') + ' ×',
				on: {
					click: closeEditor
				}
			});
			breadcrumbs.after(close);
			breadcrumbs.find('a').each(modifyHeader);

			// Relocate notifications
			notifier.find('p').not('.success').not('.error').remove();
			notifier.find('a').remove();
			if(!notifier.find('p').length) {
				notifier.hide();
			}
			context.after(notifier);

			// Remove elements
			contents.find('body').addClass('aui-editor-section');
			header.remove();
			context.find('.actions').remove();
			content.find('.actions .delete').remove();

			// Show content
			iframe.removeClass('is-hidden');

			// Store state
			editor.data('form', form.serialize());

			// Set height
			height = wrapper.height();
			editor.data('height', height);
			setScrollHeight(link);

			// Prepare saving
			content.find('.actions input[type="submit"]').on('click', function() {
				$('html, body').animate({
					scrollTop: 0
				});
			});
		};

		var modifyHeader = function(index) {
			var link = $(this);

			// Remove internal links
			link.removeAttr('href');

			// Set title
			if(index === 0) {
				link.text(Symphony.Language.get('Associated {$section-name}', {
					'section-name': link.text()
				}));
			}
		};

		var showEditor = function(link) {
			var editor = editors[link],
				iframe, contents, notifier;

			if(editor.is('.is-hidden')) {
				iframe = editor.find('iframe');
				contents = iframe.contents();
				notifier = contents.find('.notifier').hide();
				notifier.find('p').remove();

				editor.removeClass('is-hidden');
				editor.removeClass('is-canceled');
				setScrollHeight(link);
			}
			else {
				Symphony.Elements.contents.append(editor);
			}

			// Set close action
			Symphony.Elements.context.one('click.aui-editor', closeEditor);

			// Remove existing undo options
			Symphony.Elements.header.find('.notifier .undo').trigger('detach.notify');
		};

		var prepareUndo = function(link) {
			var id = new Date().getTime(),
				editor = editors[link],
				title = editor.data('title'),
				notifier = Symphony.Elements.header.find('div.notifier'),
				iframe = editor.find('iframe'),
				contents = iframe.contents(),
				form = contents.find('#contents form');

			// Unsaved changes
			if(form.serialize() != editor.data('form')) {
				notifier.trigger('attach.notify', [
					Symphony.Language.get('You just closed “{$title}” with unsaved changes.', {title: title}) + '' + Symphony.Language.get('Reopen to save?') + '' + '' + Symphony.Language.get('Or dismiss?') + '',
					'protected error undo'
				]);

				// Prepare field recovery
				$('#' + id).on('click.aui-editor', function() {
					$(this).parent().trigger('detach.notify');
					showEditor(link);
				});

				// Dismiss
				$('#' + id + '-dismiss').on('click.aui-editor', function() {
					$(this).parent().trigger('detach.notify');
					editor.remove();
					delete editors[link];
				});
			}
		};

		var setScrollHeight = function(link) {
			var editor = editors[link],
				height = editor.data('height');

			Symphony.Elements.contents.css({
				minHeight: height,
				maxHeight: height,
				overflow: 'hidden'
			});
		};

		var resetScrollHeight = function() {
			Symphony.Elements.contents.removeAttr('style');
		};

		var getSectionHandle = function(id) {
			var associations = Symphony.Context.get('env').associations.parent,
				handle = '';

			$.each(associations, function() {
				if(this.id == id) {
					handle = this.handle;
				}
			});

			return handle;
		};

		// API
		return {
			init: init
		};
	}();

	$(window).on('load.aui-editor', function() {
		Symphony.Extensions.AssociationUIEditor.init();
	});

})(window.jQuery, window.Symphony);
<|endoftext|>


<commit_before>// ==UserScript==
// @name         CleanTwitter
// @namespace    https://github.com/Alpha-Strike/UserScripts
// @version      0.1
// @description  Get rid of annoying twitter widgets
// @author       AlphaStrike
// @license      MIT
// @downloadURL  https://raw.githubusercontent.com/Alpha-Strike/UserScripts/master/CleanTwitter.user.js
// @updateURL    https://raw.githubusercontent.com/Alpha-Strike/UserScripts/master/CleanTwitter.user.js
// @include      *://*.twitter.com/*
// @include      *://twitter.com/*
// @grant        none
// ==/UserScript==

document.querySelector(".trends").style.display = "none";
document.querySelector(".wtf-module").style.display = "none";
document.querySelector(".Footer").style.display = "none";
<commit_msg>Update CleanTwitter.user.js<commit_after>// ==UserScript==
// @name         CleanTwitter
// @namespace    https://github.com/Alpha-Strike/UserScripts
// @version      0.2
// @description  Get rid of annoying twitter widgets
// @author       AlphaStrike
// @license      MIT
// @downloadURL  https://raw.githubusercontent.com/Alpha-Strike/UserScripts/master/CleanTwitter.user.js
// @updateURL    https://raw.githubusercontent.com/Alpha-Strike/UserScripts/master/CleanTwitter.user.js
// @include      *://*.twitter.com/*
// @include      *://twitter.com/*
// @grant        none
// ==/UserScript==

var modules = [".trends", ".wtf-module", ".has-recap", ".Footer"];

for (var i = 0; i < modules.length; i++) {
    var module = document.querySelector(modules[i]);
    if (module != null) {
        module.style.display = "none";
    }
}
<|endoftext|>