<commit_before>var request = require('request');
var EventEmitter = require("events").EventEmitter;
var util = require("util");

/**
 * 物件TGBOT
 *
 * @class TGBOT
 * @constructor
 * @param {Object} options 選項
 */
function TGBOT(options) {
    EventEmitter.call(this);

    this.token = options.token;
    this.pollingTimeout = options.pollingTimeout || 40;
    this.help = options.help;
    this.fullRegex = options.fullRegex;

    this.cmdList = {};
    this.onCBQList = [];
    this.onReplyList = [];

    this.lastOffset = null;
    this.username = null;
    this.cmdRegex = null;
}
util.inherits(TGBOT, EventEmitter);
/**
 * 啟動bot
 * @method start
 */
TGBOT.prototype.start = function() {
    var self = this;
    this.getUpdates(self.pollingTimeout, null);
    this.getMe(function(error, result) {
        if (error) console.log(error);
        self.username = result.username;
        if (this.fullRegex) {
            self.cmdRegex = new RegExp("^\/(\\w+)(?:@" + self.username + ")(?: ((.|\\n)*))?$", "i");
        } else {
            self.cmdRegex = new RegExp("^\/(\\w+)(?:@" + self.username + ")?(?: ((.|\\n)*))?$", "i");
        }
    });
    if (self.help) {
        self.addCmd('help', function(message, args) {
            if (args[1]&&self.cmdList[args[1]]) {
                message.replyMsg(self.cmdList[args[1]].helpMsg || (self.cmdList[args[1]].desc || "Command " + args[1] + " not found or nothing to display :("));
            }
            else {
                message.replyMsg(self.genHelp());
            }
        }, "Show help", "/help command\nShow how to use the command\nIf no argument,show the commnad list");
    }
};

TGBOT.prototype.getUpdates = function(timeout, offset) {
    var self = this;

    var params = {
        timeout: timeout
    };
    if (offset != null) {
        params.offset = offset;
    }

    self._invoke('getUpdates', params, function(error, result) {
        if (error != null) {
            self.lastOffset = null;
            console.log(error.toString());
        }
        else {
            result.forEach(function(update) {
                if (update.update_id >= self.lastOffset) {
                    self.lastOffset = update.update_id;
                }
                if (update.message) {
                    var message = self.addMethodToMessage(update.message);
                    self.emit('message', message);
                    if (message.text) self.execCmd(message);
                    if (message.reply_to_message) {
                        var onReply = self.onReplyList.find(function(element) {
                            return element.id == message.reply_to_message.message_id;
                        });
                        if (onReply) onReply.fn(message);
                    }
                    //console.log(update.message);
                }
                else if (update.inline_query) {
                    self.emit('inline_query', update.inline_query);
                }
                else if (update.chosen_inline_result) {
                    self.emit('chosen_inline_result', update.chosen_inline_result);
                }
                else if (update.edited_message) {
                    self.emit('edited_message', update.edited_message);
                }
                else if (update.callback_query) {
                    self.emit('callback_query', update.callback_query);
                    if (update.callback_query.message) {
                        var onCBQ = self.onCBQList.find(function(element) {
                            return element.id == update.callback_query.message.message_id;
                        });
                        if (onCBQ) onCBQ.fn(update.callback_query);
                    }
                }

            });
        }
        self.getUpdates(timeout, self.lastOffset + 1);
    }, timeout * 1000 + 15000);

};

TGBOT.prototype.addMethodToMessage = function(message, oldDatas) {
    if (!message) return;
    var self = this;
    message.sendToChat = function(text, datas, cb) {
        return self.sendMessage(message.chat.id, text, datas, cb);
    };
    message.replyMsg = function(text, datas, cb) {
        datas = typeof datas === "object" ? datas : {};
        datas.reply_to_message_id = message.message_id;
        return self.sendMessage(message.chat.id, text, datas, cb);
    };

    if (!message.from || message.from.username == self.username) {
        message.editText = function(text, datas, cb) {
            datas = typeof datas === "object" ? datas : {};
            datas.chat_id = message.chat.id;
            datas.message_id = message.message_id;
            if (oldDatas && !datas.reply_markup) datas.reply_markup = oldDatas.reply_markup;
            return self.editMessageText(text, datas, cb);
        };
        message.editCaption = function(caption, datas, cb) {
            datas = typeof datas === "object" ? datas : {};
            datas.chat_id = message.chat.id;
            datas.message_id = message.message_id;
            if (oldDatas && !datas.reply_markup) datas.reply_markup = oldDatas.reply_markup;
            return self.editMessageCaption(caption, datas, cb);
        };
        message.editReplyMarkup = function(replyMarkup, datas, cb) {
            datas = typeof datas === "object" ? datas : {};
            datas.chat_id = message.chat.id;
            datas.message_id = message.message_id;
            return self.editMessageReplyMarkup(replyMarkup, datas, cb);
        };
    }
    else {
        message.sendToUser = function(text, datas, cb) {
            return self.sendMessage(message.from.id, text, datas, cb);
        };
    }
    return message;
};

TGBOT.prototype.answerCallbackQuery = function(callback_query_id, text, show_alert, cb) {
    var datas = {};
    datas.callback_query_id = callback_query_id;
    datas.text = text || "";
    datas.show_alert = show_alert || false;
    return this._invoke('answerCallbackQuery', datas, cb);
};

TGBOT.prototype.answerInlineQuery = function(inline_query_id, results, datas, cb) {
    datas = datas || {};
    results = results || [];
    datas.inline_query_id = inline_query_id;
    datas.results = JSON.stringify(results);
    return this._invoke('answerInlineQuery', datas, cb);
};

TGBOT.prototype._invoke = function(apiName, params, cb, timeout, multiPart) {
    cb = cb || function() {};
    timeout = timeout || 15000;
    console.log("[INVOKE]", apiName, params);
    var targetURL = 'https://api.telegram.org/bot' + this.token + '/' + apiName;

    var requestData = {
        url: targetURL,
        timeout: timeout // 15 sec
    };

    if (!multiPart || !params) {
        params = params || {};
        requestData.form = params;
    }
    else {
        params = params || {};
        requestData.formData = params;
    }
    //console.log(requestData);
    request.post(requestData, function(err, response, body) {
        // console.log(response);
        if (err || response.statusCode !== 200) {
            return cb(err || new Error(body));
        }
        try {
            body = JSON.parse(body);
        }
        catch (e) {
            return cb(e);
        }
        if (body.ok !== true) {
            return cb(new Error('response is not ok'));
        }
        cb(null, body.result);
    });
};
/**
 * 獲取bot資訊
 * @method getMe
 * @param {Function} cb callback
 */
TGBOT.prototype.getMe = function getMe(cb) {
    return this._invoke('getMe', null, cb);
};
/**
 * 發送訊息
 * @method sendMessage
 * @param chat_id 要送到哪
 * @param {String} text 要發送的文字
 * @param {Object} [datas] 其他資料
 * @cb {Function} [cb] callback
 */
TGBOT.prototype.sendMessage = function sendMessage(chat_id, text, datas, cb) {
    var self = this;
    datas = typeof datas === "object" ? datas : {};
    datas.chat_id = chat_id;
    datas.text = text;
    var onCBQ, message, onReply;
    this._invoke('sendMessage', datas, function(err, result) {
        if (err) console.log(err);
        message = self.addMethodToMessage(result, datas);
        if (message) {
            if (onCBQ) {
                self.onCBQList.push({
                    id: message.message_id,
                    fn: onCBQ
                });
            }
            if (onReply) {
                self.onReplyList.push({
                    id: message.message_id,
                    fn: onReply
                });
            }
        }
        if (cb) cb(err, message);
    });

    var returnValue = {
        onCallbackQuery: function(fn) {
            onCBQ = function(cbq) {
                if (message) cbq.message = message;
                if (cbq) {
                    cbq.answer = function(text, show_alert, cb) {
                        self.answerCallbackQuery(cbq.id, text, show_alert, cb);
                    };
                }
                fn(cbq);
            };
            return returnValue;
        },
        onReply: function(fn) {
            onReply = function(newMsg) {
                fn(newMsg, message);
            };
            return returnValue;
        }
    };
    return returnValue;
};
/**
 * 回復訊息
 * @method replyMessage
 * @param chat_id 要送到哪
 * @param reply_to_message_id 回復的訊息id
 * @param {String} text 要發送的文字
 * @param {Object} [datas] 其他資料
 * @cb {Function} [cb] callback
 */
TGBOT.prototype.replyMessage = function replyMessage(chat_id, reply_to_message_id, text, datas, cb) {
    datas = typeof datas === "object" ? datas : {};
    datas.reply_to_message_id = reply_to_message_id;
    this.sendMessage(chat_id, text, datas, cb)
};
/**
 * 轉傳訊息
 * @method forwardMessage
 * @param chat_id 要送到哪
 * @param from_chat_id 來源id
 * @param message_id 要轉傳的訊息id
 * @param {String} text 要發送的文字
 * @param {Object} [datas] 其他資料
 * @cb {Function} [cb] callback
 */
TGBOT.prototype.forwardMessage = function forwardMessage(chat_id, from_chat_id, message_id, datas, cb) {
    datas = typeof datas === "object" ? datas : {};
    datas.chat_id = chat_id;
    datas.from_chat_id = from_chat_id;
    datas.message_id = message_id;
    return this._invoke('forwardMessage', datas, cb);
};
/**
 * 添加指令
 * @method addCmd
 * @param {String} cmd 指令名稱
 * @param {Function} script 指令的內容
 * @param {String} desc 簡短描述
 * @param {String} helpMsg 說明文字
 */
TGBOT.prototype.addCmd = function(cmd, script, desc, helpMsg) {
    this.cmdList[cmd] = {
        cmd: cmd,
        script: script,
        desc: desc,
        helpMsg: helpMsg
    };
    console.log("Added Command : " + cmd);
};

TGBOT.prototype.execCmd = function(message) {
    var self = this;
    var result = message.text.match(this.cmdRegex);
    var cmd;
    var args = [];
    if (result) {
        cmd = result[1];
        args[0] = result[2];
        args = args.concat(result[2] ? result[2].split(' ') : []);
        if (this.cmdList[cmd]) {
            this.cmdList[cmd].script(message, args);
            console.log("[COMMAND]", cmd, args);
        }
    }
};

TGBOT.prototype.editMessageText = function(text, datas, cb) {
    datas = typeof datas === "object" ? datas : {};
    if (!(datas.inline_message_id || (datas.chat_id && datas.message_id))) {
        return false;
    }
    datas.text = text;
    return this._invoke('editMessageText', datas, cb);
};

TGBOT.prototype.editMessageCaption = function(caption, datas, cb) {
    datas = typeof datas === "object" ? datas : {};
    if (!(datas.inline_message_id || (datas.chat_id && datas.message_id))) {
        return false;
    }
    datas.caption = caption;
    return this._invoke('editMessageCaption', datas, cb);
};

TGBOT.prototype.editMessageReplyMarkup = function(replyMarkup, datas, cb) {
    datas = typeof datas === "object" ? datas : {};
    if (!(datas.inline_message_id || (datas.chat_id && datas.message_id))) {
        return false;
    }
    datas.reply_markup = replyMarkup;
    return this._invoke('editMessageReplyMarkup', datas, cb);
};
/**
 * 產生Help
 * @method genHelp
 * @param {Function} Help的格式
 * @return {String} help help
 */
TGBOT.prototype.genHelp = function(format) {
    var self = this;
    var help = "";
    format = format || (command => "/" + command.cmd + " : " + command.desc + "\n");
    for (var command in self.cmdList) {
        help += format(self.cmdList[command]);
    }
    return help;
};

module.exports = TGBOT;
<commit_msg>telegram.js<commit_after>var request = require('request');
var EventEmitter = require("events").EventEmitter;
var util = require("util");

/**
 * 物件TGBOT
 *
 * @class TGBOT
 * @constructor
 * @param {Object} options 選項
 */
function TGBOT(options) {
    EventEmitter.call(this);

    this.token = options.token;
    this.pollingTimeout = options.pollingTimeout || 40;
    this.help = options.help;
    this.fullRegex = options.fullRegex;

    this.cmdList = {};
    this.onCBQList = [];
    this.onReplyList = [];

    this.lastOffset = null;
    this.username = null;
    this.cmdRegex = null;
}
util.inherits(TGBOT, EventEmitter);
/**
 * 啟動bot
 * @method start
 */
TGBOT.prototype.start = function() {
    var self = this;
    this.getUpdates(self.pollingTimeout, null);
    this.getMe(function(error, result) {
        if (error) console.log(error);
        self.username = result.username;
        if (this.fullRegex) {
            self.cmdRegex = new RegExp("^\/(\\w+)(?:@" + self.username + ")(?: ((.|\\n)*))?$", "i");
        } else {
            self.cmdRegex = new RegExp("^\/(\\w+)(?:@" + self.username + ")?(?: ((.|\\n)*))?$", "i");
        }
    });
    if (self.help) {
        self.addCmd('help', function(message, args) {
            if (args[1]&&self.cmdList[args[1]]) {
                message.replyMsg(self.cmdList[args[1]].helpMsg || (self.cmdList[args[1]].desc || "Command " + args[1] + " not found or nothing to display :("));
            }
            else {
                message.replyMsg(self.genHelp());
            }
        }, "Show help", "/help command\nShow how to use the command\nIf no argument,show the commnad list");
    }
};

TGBOT.prototype.getUpdates = function(timeout, offset) {
    var self = this;

    var params = {
        timeout: timeout
    };
    if (offset != null) {
        params.offset = offset;
    }

    self._invoke('getUpdates', params, function(error, result) {
        if (error != null) {
            self.lastOffset = null;
            console.log(error.toString());
        }
        else {
            result.forEach(function(update) {
                if (update.update_id >= self.lastOffset) {
                    self.lastOffset = update.update_id;
                }
                if (update.message) {
                    var message = self.addMethodToMessage(update.message);
                    self.emit('message', message);
                    if (message.text) self.execCmd(message);
                    if (message.reply_to_message) {
                        var onReply = self.onReplyList.find(function(element) {
                            return element.id == message.reply_to_message.message_id;
                        });
                        if (onReply) onReply.fn(message);
                    }
                    //console.log(update.message);
                }
                else if (update.inline_query) {
                    self.emit('inline_query', update.inline_query);
                }
                else if (update.chosen_inline_result) {
                    self.emit('chosen_inline_result', update.chosen_inline_result);
                }
                else if (update.edited_message) {
                    self.emit('edited_message', update.edited_message);
                }
                else if (update.callback_query) {
                    self.emit('callback_query', update.callback_query);
                    if (update.callback_query.message) {
                        var onCBQ = self.onCBQList.find(function(element) {
                            return element.id == update.callback_query.message.message_id;
                        });
                        if (onCBQ) onCBQ.fn(update.callback_query);
                    }
                }

            });
        }
        self.getUpdates(timeout, self.lastOffset + 1);
    }, timeout * 1000 + 15000);

};

TGBOT.prototype.addMethodToMessage = function(message, oldDatas) {
    if (!message) return;
    var self = this;
    message.sendToChat = function(text, datas, cb) {
        return self.sendMessage(message.chat.id, text, datas, cb);
    };
    message.replyMsg = function(text, datas, cb) {
        datas = typeof datas === "object" ? datas : {};
        datas.reply_to_message_id = message.message_id;
        return self.sendMessage(message.chat.id, text, datas, cb);
    };

    if (!message.from || message.from.username == self.username) {
        message.editText = function(text, datas, cb) {
            datas = typeof datas === "object" ? datas : {};
            datas.chat_id = message.chat.id;
            datas.message_id = message.message_id;
            if (oldDatas && !datas.reply_markup) datas.reply_markup = oldDatas.reply_markup;
            return self.editMessageText(text, datas, cb);
        };
        message.editCaption = function(caption, datas, cb) {
            datas = typeof datas === "object" ? datas : {};
            datas.chat_id = message.chat.id;
            datas.message_id = message.message_id;
            if (oldDatas && !datas.reply_markup) datas.reply_markup = oldDatas.reply_markup;
            return self.editMessageCaption(caption, datas, cb);
        };
        message.editReplyMarkup = function(replyMarkup, datas, cb) {
            datas = typeof datas === "object" ? datas : {};
            datas.chat_id = message.chat.id;
            datas.message_id = message.message_id;
            return self.editMessageReplyMarkup(replyMarkup, datas, cb);
        };
    }
    else {
        message.sendToUser = function(text, datas, cb) {
            return self.sendMessage(message.from.id, text, datas, cb);
        };
    }
    return message;
};

TGBOT.prototype.answerCallbackQuery = function(callback_query_id, text, show_alert, cb) {
    var datas = {};
    datas.callback_query_id = callback_query_id;
    datas.text = text || "";
    datas.show_alert = show_alert || false;
    return this._invoke('answerCallbackQuery', datas, cb);
};

TGBOT.prototype.answerInlineQuery = function(inline_query_id, results, datas, cb) {
    datas = datas || {};
    results = results || [];
    datas.inline_query_id = inline_query_id;
    datas.results = JSON.stringify(results);
    return this._invoke('answerInlineQuery', datas, cb);
};

TGBOT.prototype._invoke = function(apiName, params, cb, timeout, multiPart) {
    cb = cb || function() {};
    timeout = timeout || 15000;
    console.log("[INVOKE]", apiName, params);
    var targetURL = 'https://api.telegram.org/bot' + this.token + '/' + apiName;

    var requestData = {
        url: targetURL,
        timeout: timeout // 15 sec
    };

    if (!multiPart || !params) {
        params = params || {};
        requestData.form = params;
    }
    else {
        params = params || {};
        requestData.formData = params;
    }
    //console.log(requestData);
    request.post(requestData, function(err, response, body) {
        // console.log(response);
        if (err || response.statusCode !== 200) {
            return cb(err || new Error(body));
        }
        try {
            body = JSON.parse(body);
        }
        catch (e) {
            return cb(e);
        }
        if (body.ok !== true) {
            return cb(new Error('response is not ok'));
        }
        cb(null, body.result);
    });
};
/**
 * 獲取bot資訊
 * @method getMe
 * @param {Function} cb callback
 */
TGBOT.prototype.getMe = function getMe(cb) {
    return this._invoke('getMe', null, cb);
};
/**
 * 發送訊息
 * @method sendMessage
 * @param chat_id 要送到哪
 * @param {String} text 要發送的文字
 * @param {Object} [datas] 其他資料
 * @cb {Function} [cb] callback
 */
TGBOT.prototype.sendMessage = function sendMessage(chat_id, text, datas, cb) {
    var self = this;
    datas = typeof datas === "object" ? datas : {};
    datas.chat_id = chat_id;
    datas.text = text;
    var onCBQ, message, onReply;
    this._invoke('sendMessage', datas, function(err, result) {
        if (err) console.log(err);
        message = self.addMethodToMessage(result, datas);
        if (message) {
            if (onCBQ) {
                self.onCBQList.push({
                    id: message.message_id,
                    fn: onCBQ
                });
            }
            if (onReply) {
                self.onReplyList.push({
                    id: message.message_id,
                    fn: onReply
                });
            }
        }
        if (cb) cb(err, message);
    });

    var returnValue = {
        onCallbackQuery: function(fn) {
            onCBQ = function(cbq) {
                if (message) cbq.message = message;
                if (cbq) {
                    cbq.answer = function(text, show_alert, cb) {
                        self.answerCallbackQuery(cbq.id, text, show_alert, cb);
                    };
                }
                fn(cbq);
            };
            return returnValue;
        },
        onReply: function(fn) {
            onReply = function(newMsg) {
                fn(newMsg, message);
            };
            return returnValue;
        }
    };
    return returnValue;
};
/**
 * 回復訊息
 * @method replyMessage
 * @param chat_id 要送到哪
 * @param reply_to_message_id 回復的訊息id
 * @param {String} text 要發送的文字
 * @param {Object} [datas] 其他資料
 * @cb {Function} [cb] callback
 */
TGBOT.prototype.replyMessage = function replyMessage(chat_id, reply_to_message_id, text, datas, cb) {
    datas = typeof datas === "object" ? datas : {};
    datas.reply_to_message_id = reply_to_message_id;
    this.sendMessage(chat_id, text, datas, cb)
};
/**
 * 轉傳訊息
 * @method forwardMessage
 * @param chat_id 要送到哪
 * @param from_chat_id 來源id
 * @param message_id 要轉傳的訊息id
 * @param {String} text 要發送的文字
 * @param {Object} [datas] 其他資料
 * @cb {Function} [cb] callback
 */
TGBOT.prototype.forwardMessage = function forwardMessage(chat_id, from_chat_id, message_id, datas, cb) {
    datas = typeof datas === "object" ? datas : {};
    datas.chat_id = chat_id;
    datas.from_chat_id = from_chat_id;
    datas.message_id = message_id;
    return this._invoke('forwardMessage', datas, cb);
};
/**
 * 添加指令
 * @method addCmd
 * @param {String} cmd 指令名稱
 * @param {Function} script 指令的內容
 * @param {String} desc 簡短描述
 * @param {String} helpMsg 說明文字
 */
TGBOT.prototype.addCmd = function(cmd, script, desc, helpMsg) {
    this.cmdList[cmd] = {
        cmd: cmd,
        script: script,
        desc: desc,
        helpMsg: helpMsg
    };
    console.log("Added Command : " + cmd);
};

TGBOT.prototype.execCmd = function(message) {
    var self = this;
    var result = message.text.match(this.cmdRegex);
    var cmd;
    var args = [];
    if (result) {
        cmd = result[1];
        args[0] = result[2];
        args = args.concat(result[2] ? result[2].split(' ') : []);
        if (this.cmdList[cmd]) {
            this.cmdList[cmd].script(message, args);
            console.log("[COMMAND]", cmd, args);
        }
    }
};

TGBOT.prototype.editMessageText = function(text, datas, cb) {
    datas = typeof datas === "object" ? datas : {};
    if (!(datas.inline_message_id || (datas.chat_id && datas.message_id))) {
        return false;
    }
    datas.text = text;
    return this._invoke('editMessageText', datas, cb);
};

TGBOT.prototype.editMessageCaption = function(caption, datas, cb) {
    datas = typeof datas === "object" ? datas : {};
    if (!(datas.inline_message_id || (datas.chat_id && datas.message_id))) {
        return false;
    }
    datas.caption = caption;
    return this._invoke('editMessageCaption', datas, cb);
};

TGBOT.prototype.editMessageReplyMarkup = function(replyMarkup, datas, cb) {
    datas = typeof datas === "object" ? datas : {};
    if (!(datas.inline_message_id || (datas.chat_id && datas.message_id))) {
        return false;
    }
    datas.reply_markup = replyMarkup;
    return this._invoke('editMessageReplyMarkup', datas, cb);
};
/**
 * 產生Help
 * @method genHelp
 * @param {Function} Help的格式
 * @return {String} help help
 */
TGBOT.prototype.genHelp = function(format) {
    var self = this;
    var help = "";
    format = format || (command => "/" + command.cmd + " : " + command.desc + "\n");
    for (var command in self.cmdList) {
        help += format(self.cmdList[command]);
    }
    return help;
};

TGBOT.prototype.getChatAdministrators = function(chat_id, cb){
    return this._invoke('getChatAdministrators', {chat_id:chat_id}, cb);
};

module.exports = TGBOT;
<|endoftext|>


<commit_before>var testnet = require("./testnet");
var eth = testnet.eth;
var utils = testnet.utils;

function sendTx(rawTx, account) {
	try {
		var Tx = require('ethereumjs-tx');
		var tx = new Tx(rawTx);

		var key = new Buffer(account.privateKey.slice(2), 'hex');
		tx.sign(key);
		var txData = '0x' + tx.serialize().toString('hex');
		console.log("Sending raw:", txData);

		eth.sendSignedTransaction(txData).
		on('transactionHash', function(hash){
	    	console.log("Transaction hash:", hash);
		})
		.on('receipt', function(receipt){
		    console.log("Receipt:", receipt);
		})
		.on('confirmation', function(confirmationNumber, receipt){
			console.log("Confirmation ", confirmationNumber, "for receipt", receipt);
		})
		.on('error', console.log)
		.then(function(result) {
			console.log("Success\n", result);
		})
		.catch(function(error) {
			console.log(error);
		});
	} catch(error) {
		console.log(error);
	}
}

module.exports = {
	send: sendTx
}<commit_msg>Minor<commit_after>var testnet = require("./testnet");
var eth = testnet.eth;
var utils = testnet.utils;

function sendTx(rawTx, account) {
	try {
		var Tx = require('ethereumjs-tx');
		var tx = new Tx(rawTx);

		var key = new Buffer(account.privateKey.slice(2), 'hex');
		tx.sign(key);
		var txData = '0x' + tx.serialize().toString('hex');
		console.log("Sending raw:", txData);

		eth.sendSignedTransaction(txData)
		.on('transactionHash', function(hash){
	    	console.log("Transaction hash:", hash);
		})
		.on('receipt', function(receipt){
		    console.log("Receipt:", receipt);
		})
		.on('confirmation', function(confirmationNumber, receipt){
			console.log("Confirmation ", confirmationNumber, "for receipt", receipt);
		})
		.on('error', console.log)
		.then(function(result) {
			console.log("Success\n", result);
		})
		.catch(function(error) {
			console.log(error);
		});
	} catch(error) {
		console.log(error);
	}
}

module.exports = {
	send: sendTx
}<|endoftext|>


<commit_before>var fs            = require('fs')
  , path          = require('path')
  , os            = require('os')
  , exercise      = require('workshopper-exercise')()
  , filecheck     = require('workshopper-exercise/filecheck')
  , execute       = require('workshopper-exercise/execute')
  , comparestdout = require('workshopper-exercise/comparestdout')
  , wrappedexec   = require('workshopper-wrappedexec')
  , after         = require('after')
  , rimraf        = require('rimraf')
  , verify        = require('./verify')
  , files         = require('../filtered_ls/file-list')

  , testDir       = path.join(os.tmpDir(), '_learnyounode_' + process.pid)

// checks that the submission file actually exists
exercise = filecheck(exercise)

// execute the solution and submission in parallel with spawn()
exercise = execute(exercise)

// compare stdout of solution and submission
exercise = comparestdout(exercise)

// wrap up the child process in a phantom wrapper that can
// mess with the global environment and inspect execution
exercise = wrappedexec(exercise)

// modules we want run just prior to the submission in the
// child process
exercise.wrapModule(require.resolve('../my_first_io/wrap'))
exercise.wrapModule(require.resolve('./wrap-requires'))

// set up the data file to be passed to the submission
exercise.addSetup(function (mode, callback) {
  // mode == 'run' || 'verify'

  // store for later use by verify()
  this._testDir = testDir

  // supply the dir and extensions as args to the 'execute' processor for both
  // solution and submission spawn()
  // using unshift here because wrappedexec needs to use additional
  // args to do its magic
  this.submissionArgs.unshift('md')
  this.submissionArgs.unshift(testDir)
  this.solutionArgs.unshift('md')
  this.solutionArgs.unshift(testDir)

  fs.mkdir(testDir, function (err) {
    if (err)
      return callback(err)

    var done = after(files.length, callback)

    files.forEach(function (f) {
      fs.writeFile(
          path.join(testDir, f)
        , 'nothing to see here'
        , 'utf8'
        , done
      )
    })
  })
})

// add a processor only for 'verify' calls
exercise.addVerifyProcessor(verify)

// cleanup for both run and verify
exercise.addCleanup(function (mode, passed, callback) {
  // mode == 'run' || 'verify'

  rimraf(testDir, callback)
})

module.exports = exercise
<commit_msg>Fixes https://github.com/workshopper/learnyounode/issues/378<commit_after>var fs            = require('fs')
  , path          = require('path')
  , os            = require('os')
  , exercise      = require('workshopper-exercise')()
  , filecheck     = require('workshopper-exercise/filecheck')
  , execute       = require('workshopper-exercise/execute')
  , comparestdout = require('workshopper-exercise/comparestdout')
  , wrappedexec   = require('workshopper-wrappedexec')
  , after         = require('after')
  , rimraf        = require('rimraf')
  , verify        = require('./verify')
  , files         = require('../filtered_ls/file-list')

  , testDir       = path.join(os.tmpDir(), '_learnyounode_' + process.pid)

// checks that the submission file actually exists
exercise = filecheck(exercise)

// execute the solution and submission in parallel with spawn()
exercise = execute(exercise)

// compare stdout of solution and submission
exercise = comparestdout(exercise)

// wrap up the child process in a phantom wrapper that can
// mess with the global environment and inspect execution
exercise = wrappedexec(exercise)

// modules we want run just prior to the submission in the
// child process
exercise.wrapModule(require.resolve('../my_first_io/wrap'))
exercise.wrapModule(require.resolve('./wrap-requires'))

// set up the data file to be passed to the submission
exercise.addSetup(function (mode, callback) {
  // mode == 'run' || 'verify'

  // store for later use by verify()
  this._testDir = testDir

  // supply the dir and extensions as args to the 'execute' processor for both
  // solution and submission spawn()
  // using unshift here because wrappedexec needs to use additional
  // args to do its magic
  this.submissionArgs.unshift('md')
  this.submissionArgs.unshift(testDir)
  this.solutionArgs.unshift('md')
  this.solutionArgs.unshift(testDir)

  fs.mkdir(testDir, function (err) {
    if (err)
      return callback(err)

    var done = after(files.length, callback)

    files.forEach(function (f) {
      fs.writeFile(
          path.join(testDir, f)
        , 'nothing to see here'
        , 'utf8'
        , done
      )
    })
  })
})

// add a processor only for 'verify' calls
exercise.addVerifyProcessor(verify)

// cleanup for both run and verify
exercise.addCleanup(function (mode, passed, callback) {
  // mode == 'run' || 'verify'

  rimraf(testDir, function () {
    // Ignoring error.
    callback()
  })
})

module.exports = exercise
<|endoftext|>


<commit_before><commit_msg>delete v1.js<commit_after><|endoftext|>


<commit_before>/* See license.txt for terms of usage */

FBL.ns(function() { with (FBL) {

// ************************************************************************************************
// Constants

const Cc = Components.classes;
const Ci = Components.interfaces;

const httpObserver = Cc["@joehewitt.com/firebug-http-observer;1"].getService(Ci.nsIObserverService);

// List of text content types.
const contentTypes =
{
    "text/plain": 1,
    "text/html": 1,
    "text/html": 1,
    "text/html": 1,
    "text/xml": 1,
    "text/css": 1,
    "application/x-javascript": 1,
    "application/x-javascript": 1,
    "image/jpeg": 0,
    "image/jpeg": 0,
    "image/gif": 0,
    "image/png": 0,
    "image/bmp": 0,
    "application/x-shockwave-flash": 0
};

// Helper array for prematurely created contexts.
var contexts = new Array();

// ************************************************************************************************
// Model implementation

/**
 * Implementation of cache model. The only purpose of this object is to register an HTTP
 * observer so, HTTP communication can be interecepted and all incoming data stored within
 * a cache.
 */
Firebug.TabCacheModel = extend(Firebug.Module,
{
    initializeUI: function(owner)
    {
        if (FBTrace.DBG_CACHE)
            FBTrace.sysout("tabCache. Cache model initialized.");

        // Register for HTTP events.
        if (Ci.nsITraceableChannel)
            httpObserver.addObserver(this, "firebug-http-event", false);
    },

    shutdown: function()
    {
        if (Ci.nsITraceableChannel)
            httpObserver.removeObserver(this, "firebug-http-event");
    },

    initContext: function(context)
    {
        if (FBTrace.DBG_CACHE)
            FBTrace.dumpProperties("tabCache.initContext for: " + context.window.location.href);

        // See if a temp context is available.
        var tabId = Firebug.getTabIdForWindow(context.window);

        var tempContext = contexts[tabId];
        if (tempContext)
        {
            context.sourceCache.cache = tempContext.sourceCache.cache;
            delete contexts[tabId];

            if (FBTrace.DBG_CACHE)
                FBTrace.dumpProperties("tabCache.Temporary context used for: " +
                    context.window.location.href, context.sourceCache.cache);
        }
    },

    /* nsIObserver */
    observe: function(subject, topic, data)
    {
        try
        {
            if (!(subject instanceof Ci.nsIHttpChannel))
                return;

            var win = getWindowForRequest(subject);
            var tabId = Firebug.getTabIdForWindow(win);
            if (!(tabId && win))
                return;

            if (topic == "http-on-modify-request")
                this.onModifyRequest(subject, win, tabId);
            else if (topic == "http-on-examine-response")
                this.onExamineResponse(subject, win, tabId);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("tabCache.observe EXCEPTION", err);
        }
    },

    onModifyRequest: function(request, win, tabId)
    {
        // Ignore redirects
        if (request.URI.spec != request.originalURI.spec)
            return;

        if (request.loadFlags & Ci.nsIHttpChannel.LOAD_DOCUMENT_URI)
        {
            if (win == win.parent)
            {
                // Create temporary context so no request is missed. The real one is created
                // later by tabWatcher. Merge is done in Firebug.TabCacheModel.initContext.
                var context = {sourceCache: new Firebug.TabCache(win)};
                contexts[tabId] = context;

                if (FBTrace.DBG_CACHE)
                    FBTrace.sysout("tabCache.Temporary context created for: " + win.location.href);
            }
        }
    },

    onExamineResponse: function(request, win, tabId)
    {
        var context = contexts[tabId];
        context = context ? context : TabWatcher.getContextByWindow(win);

        try
        {
            // Register traceable channel listener in order to intercept all incoming data for
            // this context/tab. nsITraceableChannel interface is introduced in Firefox 3.0.4
            request.QueryInterface(Ci.nsITraceableChannel);
            var newListener = new TracingListener(context);
            newListener.listener = request.setNewListener(newListener);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.dumpProperties("tabCache: Register Traceable Listener EXCEPTION", err);
        }

        if (FBTrace.DBG_CACHE)
            FBTrace.dumpProperties("tabCache:onExamineResponse: Traceable Listener Registered for: " +
                safeGetName(request), request);
    },
});

// ************************************************************************************************

/**
 * This cache object is intended to cache all responses made by a specific tab.
 * The implementation is based on nsITraceableChannel interface introduced in
 * Firefox 3.0.4. This interface allows to intercept all incoming HTTP data.
 *
 * This object replaces the SourceCache, which still exist only for backward
 * compatibility.
 *
 * The object is derived from SourceCache so, the same interface and most of the
 * implementation is used.
 */
Firebug.TabCache = function(win)
{
    if (FBTrace.DBG_CACHE)
        FBTrace.dumpProperties("tabCache.TabCache Created for: " + win.location.href);

    Firebug.SourceCache.call(this, win, null);
};

Firebug.TabCache.prototype = extend(Firebug.SourceCache.prototype,
{
    listeners: [],

    loadFromCache: function(url, method, file)
    {
        // The ancestor implementation (SourceCache) uses ioService.newChannel, which
        // can result in additional request to the server (in case the response can't
        // be loaded from the Firefox cache) - known as double-load problem.
        // This new implementation (TabCache) uses nsITraceableListener so, all responses
        // should be already cached.

        if (FBTrace.DBG_CACHE)
            FBTrace.dumpProperties("tabCache.loadFromCache: FAILED" +
                this.window.location.href, this.cache);
    },

    // Listeners
    addListener: function(listener)
    {
        this.listeners.push(listener);
    },

    removeListener: function(listener)
    {
        remove(this.listeners, listener);
    },

    fireOnStoreResponse: function(context, request, responseText)
    {
        for (var i=0; i<this.listeners.length; i++)
        {
            var listener = this.listeners[i];
            if (listener.onStoreResponse)
                listener.onStoreResponse(context, request, responseText);
        }
    }
});

// ************************************************************************************************
// TracingListener implementation

/**
 * This object implements nsIStreamListener interface and is intended to monitor all network
 * channels (nsIHttpChannel). For every channel a new instance of this object is created and
 * registered. See Firebug.TabCacheModel.onExamineResponse method.
 */
function TracingListener(context)
{
    this.context = context;
    this.listener = null;
    this.receivedData = [];
}

TracingListener.prototype =
{
    onCollectData: function(inputStream, offset, count)
    {
        try
        {
            var binaryInputStream = CCIN("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream");
            var storageStream = CCIN("@mozilla.org/storagestream;1", "nsIStorageStream");
            var binaryOutputStream = CCIN("@mozilla.org/binaryoutputstream;1", "nsIBinaryOutputStream");

            binaryInputStream.setInputStream(inputStream);
            storageStream.init(8192, count, null);
            binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));

            // Copy received data as they come.
            var data = binaryInputStream.readBytes(count);
            this.receivedData.push(data);

            binaryOutputStream.writeBytes(data, count);
            return storageStream.newInputStream(0);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.dumpProperties("tabCache.TracingListener.onCollectData EXCEPTION\n", err);
        }

        return null;
    },

    /* nsIStreamListener */
    onDataAvailable: function(request, requestContext, inputStream, offset, count)
    {
        // xxxHonza: all content types should be cached?
        var newStream = this.onCollectData(inputStream, offset, count);
        if (newStream)
            inputStream = newStream;

        try
        {
            if (this.listener)
                this.listener.onDataAvailable(request, requestContext, inputStream, offset, count);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.dumpProperties("tabCache.TracingListener.onDataAvailable" +
                    "(" + request + ", " + requestContext + ", " +
                    inputStream + ", " + offset + ", " + count + ") EXCEPTION: " +
                    safeGetName(request), err);
        }
    },

    onStartRequest: function(request, requestContext)
    {
        try
        {
            if (this.listener)
                this.listener.onStartRequest(request, requestContext);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.dumpProperties("tabCache.TracingListener.onStartRequest EXCEPTION\n", err);
        }
    },

    onStopRequest: function(request, requestContext, statusCode)
    {
        try
        {
            if (statusCode != Ci.nsIRequest.NS_BINDING_ABORTED)
            {
                var responseText = this.receivedData.join();

                // Convert text types.
                if (contentTypes[request.contentType])
                    responseText = FBL.convertToUnicode(responseText);

                this.context.sourceCache.store(safeGetName(request), responseText);

                // Notify listeners.
                this.context.sourceCache.fireOnStoreResponse(this.context, request, responseText);
            }

            if (this.listener)
                this.listener.onStopRequest(request, requestContext, statusCode);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.dumpProperties("tabCache.TracingListener.onStopRequest EXCEPTION\n", err);
        }
    },

    /* nsISupports */
    QueryInterface: function(iid)
    {
        if (iid.equals(Ci.nsIStreamListener) ||
            iid.equals(Ci.nsISupportsWeakReference) ||
            iid.equals(Ci.nsISupports))
        {
            return this;
        }

        throw Components.results.NS_NOINTERFACE;
    }
}

// ************************************************************************************************
// Helpers

function safeGetName(request)
{
    try {
        return request.name;
    }
    catch (exc) {
    }

    return null;
}

// ************************************************************************************************
// Registration

Firebug.registerModule(Firebug.TabCacheModel);

// ************************************************************************************************

}});
<commit_msg>more certain tracing from onExamineResponse<commit_after>/* See license.txt for terms of usage */

FBL.ns(function() { with (FBL) {

// ************************************************************************************************
// Constants

const Cc = Components.classes;
const Ci = Components.interfaces;

const httpObserver = Cc["@joehewitt.com/firebug-http-observer;1"].getService(Ci.nsIObserverService);

// List of text content types.
const contentTypes =
{
    "text/plain": 1,
    "text/html": 1,
    "text/html": 1,
    "text/html": 1,
    "text/xml": 1,
    "text/css": 1,
    "application/x-javascript": 1,
    "application/x-javascript": 1,
    "image/jpeg": 0,
    "image/jpeg": 0,
    "image/gif": 0,
    "image/png": 0,
    "image/bmp": 0,
    "application/x-shockwave-flash": 0
};

// Helper array for prematurely created contexts.
var contexts = new Array();

// ************************************************************************************************
// Model implementation

/**
 * Implementation of cache model. The only purpose of this object is to register an HTTP
 * observer so, HTTP communication can be interecepted and all incoming data stored within
 * a cache.
 */
Firebug.TabCacheModel = extend(Firebug.Module,
{
    initializeUI: function(owner)
    {
        if (FBTrace.DBG_CACHE)
            FBTrace.sysout("tabCache. Cache model initialized.");

        // Register for HTTP events.
        if (Ci.nsITraceableChannel)
            httpObserver.addObserver(this, "firebug-http-event", false);
    },

    shutdown: function()
    {
        if (Ci.nsITraceableChannel)
            httpObserver.removeObserver(this, "firebug-http-event");
    },

    initContext: function(context)
    {
        if (FBTrace.DBG_CACHE)
            FBTrace.dumpProperties("tabCache.initContext for: " + context.window.location.href);

        // See if a temp context is available.
        var tabId = Firebug.getTabIdForWindow(context.window);

        var tempContext = contexts[tabId];
        if (tempContext)
        {
            context.sourceCache.cache = tempContext.sourceCache.cache;
            delete contexts[tabId];

            if (FBTrace.DBG_CACHE)
                FBTrace.dumpProperties("tabCache.Temporary context used for: " +
                    context.window.location.href, context.sourceCache.cache);
        }
    },

    /* nsIObserver */
    observe: function(subject, topic, data)
    {
        try
        {
            if (!(subject instanceof Ci.nsIHttpChannel))
                return;

            var win = getWindowForRequest(subject);
            var tabId = Firebug.getTabIdForWindow(win);
            if (!(tabId && win))
                return;

            if (topic == "http-on-modify-request")
                this.onModifyRequest(subject, win, tabId);
            else if (topic == "http-on-examine-response")
                this.onExamineResponse(subject, win, tabId);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("tabCache.observe EXCEPTION", err);
        }
    },

    onModifyRequest: function(request, win, tabId)
    {
        // Ignore redirects
        if (request.URI.spec != request.originalURI.spec)
            return;

        if (request.loadFlags & Ci.nsIHttpChannel.LOAD_DOCUMENT_URI)
        {
            if (win == win.parent)
            {
                // Create temporary context so no request is missed. The real one is created
                // later by tabWatcher. Merge is done in Firebug.TabCacheModel.initContext.
                var context = {sourceCache: new Firebug.TabCache(win)};
                contexts[tabId] = context;

                if (FBTrace.DBG_CACHE)
                    FBTrace.sysout("tabCache.Temporary context created for: " + win.location.href);
            }
        }
    },

    onExamineResponse: function(request, win, tabId)
    {
        try
        {
            var context = contexts[tabId];

            if (FBTrace.DBG_CACHE)
                FBTrace.sysout("tabCache:onExamineResponse: checking contexts found: " + (context && context.window?context.window.location:"none"), tabId);

            context = context ? context : TabWatcher.getContextByWindow(win);

            // Register traceable channel listener in order to intercept all incoming data for
            // this context/tab. nsITraceableChannel interface is introduced in Firefox 3.0.4
            request.QueryInterface(Ci.nsITraceableChannel);
            var newListener = new TracingListener(context);
            newListener.listener = request.setNewListener(newListener);
            if (FBTrace.DBG_CACHE)
            {
            	var loc = (context && context.window) ? context.window.location : "no context or no context.window";
                FBTrace.dumpProperties("tabCache:onExamineResponse: Traceable Listener in context "+loc+" Registered for: " +
                    safeGetName(request), request);
            }
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.dumpProperties("tabCache: Register Traceable Listener EXCEPTION", err);
        }
    },
});

// ************************************************************************************************

/**
 * This cache object is intended to cache all responses made by a specific tab.
 * The implementation is based on nsITraceableChannel interface introduced in
 * Firefox 3.0.4. This interface allows to intercept all incoming HTTP data.
 *
 * This object replaces the SourceCache, which still exist only for backward
 * compatibility.
 *
 * The object is derived from SourceCache so, the same interface and most of the
 * implementation is used.
 */
Firebug.TabCache = function(win)
{
    if (FBTrace.DBG_CACHE)
        FBTrace.dumpProperties("tabCache.TabCache Created for: " + win.location.href);

    Firebug.SourceCache.call(this, win, null);
};

Firebug.TabCache.prototype = extend(Firebug.SourceCache.prototype,
{
    listeners: [],

    loadFromCache: function(url, method, file)
    {
        // The ancestor implementation (SourceCache) uses ioService.newChannel, which
        // can result in additional request to the server (in case the response can't
        // be loaded from the Firefox cache) - known as double-load problem.
        // This new implementation (TabCache) uses nsITraceableListener so, all responses
        // should be already cached.

        if (FBTrace.DBG_CACHE)
            FBTrace.dumpProperties("tabCache.loadFromCache: FAILED" +
                this.window.location.href, this.cache);
    },

    // Listeners
    addListener: function(listener)
    {
        this.listeners.push(listener);
    },

    removeListener: function(listener)
    {
        remove(this.listeners, listener);
    },

    fireOnStoreResponse: function(context, request, responseText)
    {
        for (var i=0; i<this.listeners.length; i++)
        {
            var listener = this.listeners[i];
            if (listener.onStoreResponse)
                listener.onStoreResponse(context, request, responseText);
        }
    }
});

// ************************************************************************************************
// TracingListener implementation

/**
 * This object implements nsIStreamListener interface and is intended to monitor all network
 * channels (nsIHttpChannel). For every channel a new instance of this object is created and
 * registered. See Firebug.TabCacheModel.onExamineResponse method.
 */
function TracingListener(context)
{
    this.context = context;
    this.listener = null;
    this.receivedData = [];
}

TracingListener.prototype =
{
    onCollectData: function(inputStream, offset, count)
    {
        try
        {
            var binaryInputStream = CCIN("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream");
            var storageStream = CCIN("@mozilla.org/storagestream;1", "nsIStorageStream");
            var binaryOutputStream = CCIN("@mozilla.org/binaryoutputstream;1", "nsIBinaryOutputStream");

            binaryInputStream.setInputStream(inputStream);
            storageStream.init(8192, count, null);
            binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));

            // Copy received data as they come.
            var data = binaryInputStream.readBytes(count);
            this.receivedData.push(data);

            binaryOutputStream.writeBytes(data, count);
            return storageStream.newInputStream(0);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.dumpProperties("tabCache.TracingListener.onCollectData EXCEPTION\n", err);
        }

        return null;
    },

    /* nsIStreamListener */
    onDataAvailable: function(request, requestContext, inputStream, offset, count)
    {
        // xxxHonza: all content types should be cached?
        var newStream = this.onCollectData(inputStream, offset, count);
        if (newStream)
            inputStream = newStream;

        try
        {
            if (this.listener)
                this.listener.onDataAvailable(request, requestContext, inputStream, offset, count);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.dumpProperties("tabCache.TracingListener.onDataAvailable" +
                    "(" + request + ", " + requestContext + ", " +
                    inputStream + ", " + offset + ", " + count + ") EXCEPTION: " +
                    safeGetName(request), err);
        }
    },

    onStartRequest: function(request, requestContext)
    {
        try
        {
            if (this.listener)
                this.listener.onStartRequest(request, requestContext);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.dumpProperties("tabCache.TracingListener.onStartRequest EXCEPTION\n", err);
        }
    },

    onStopRequest: function(request, requestContext, statusCode)
    {
        try
        {
            if (statusCode != Ci.nsIRequest.NS_BINDING_ABORTED)
            {
                var responseText = this.receivedData.join();

                // Convert text types.
                if (contentTypes[request.contentType])
                    responseText = FBL.convertToUnicode(responseText);

                this.context.sourceCache.store(safeGetName(request), responseText);

                // Notify listeners.
                this.context.sourceCache.fireOnStoreResponse(this.context, request, responseText);
            }

            if (this.listener)
                this.listener.onStopRequest(request, requestContext, statusCode);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.dumpProperties("tabCache.TracingListener.onStopRequest EXCEPTION\n", err);
        }
    },

    /* nsISupports */
    QueryInterface: function(iid)
    {
        if (iid.equals(Ci.nsIStreamListener) ||
            iid.equals(Ci.nsISupportsWeakReference) ||
            iid.equals(Ci.nsISupports))
        {
            return this;
        }

        throw Components.results.NS_NOINTERFACE;
    }
}

// ************************************************************************************************
// Helpers

function safeGetName(request)
{
    try {
        return request.name;
    }
    catch (exc) {
    }

    return null;
}

// ************************************************************************************************
// Registration

Firebug.registerModule(Firebug.TabCacheModel);

// ************************************************************************************************

}});
<|endoftext|>


<commit_before>/*global define*/
define([
        '../Core/BoundingSphere',
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/defineProperties',
        '../Core/destroyObject',
        '../Core/DeveloperError',
        '../Core/EventHelper',
        './BillboardVisualizer',
        './BoundingSphereState',
        './BoxGeometryUpdater',
        './CorridorGeometryUpdater',
        './CustomDataSource',
        './CylinderGeometryUpdater',
        './EllipseGeometryUpdater',
        './EllipsoidGeometryUpdater',
        './GeometryVisualizer',
        './LabelVisualizer',
        './ModelVisualizer',
        './PathVisualizer',
        './PointVisualizer',
        './PolygonGeometryUpdater',
        './PolylineGeometryUpdater',
        './PolylineVolumeGeometryUpdater',
        './RectangleGeometryUpdater',
        './WallGeometryUpdater'
    ], function(
        BoundingSphere,
        defaultValue,
        defined,
        defineProperties,
        destroyObject,
        DeveloperError,
        EventHelper,
        BillboardVisualizer,
        BoundingSphereState,
        BoxGeometryUpdater,
        CorridorGeometryUpdater,
        CustomDataSource,
        CylinderGeometryUpdater,
        EllipseGeometryUpdater,
        EllipsoidGeometryUpdater,
        GeometryVisualizer,
        LabelVisualizer,
        ModelVisualizer,
        PathVisualizer,
        PointVisualizer,
        PolygonGeometryUpdater,
        PolylineGeometryUpdater,
        PolylineVolumeGeometryUpdater,
        RectangleGeometryUpdater,
        WallGeometryUpdater) {
    "use strict";

    /**
     * Visualizes a collection of {@link DataSource} instances.
     * @alias DataSourceDisplay
     * @constructor
     *
     * @param {Object} options Object with the following properties:
     * @param {Scene} options.scene The scene in which to display the data.
     * @param {DataSourceCollection} options.dataSourceCollection The data sources to display.
     * @param {DataSourceDisplay~VisualizersCallback} [options.visualizersCallback=DataSourceDisplay.defaultVisualizersCallback]
     *        A function which creates an array of visualizers used for visualization.
     *        If undefined, all standard visualizers are used.
     */
    function DataSourceDisplay(options) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(options)) {
            throw new DeveloperError('options is required.');
        }
        if (!defined(options.scene)) {
            throw new DeveloperError('scene is required.');
        }
        if (!defined(options.dataSourceCollection)) {
            throw new DeveloperError('dataSourceCollection is required.');
        }
        //>>includeEnd('debug');

        var scene = options.scene;
        var dataSourceCollection = options.dataSourceCollection;

        this._eventHelper = new EventHelper();
        this._eventHelper.add(dataSourceCollection.dataSourceAdded, this._onDataSourceAdded, this);
        this._eventHelper.add(dataSourceCollection.dataSourceRemoved, this._onDataSourceRemoved, this);

        this._dataSourceCollection = dataSourceCollection;
        this._scene = scene;
        this._visualizersCallback = defaultValue(options.visualizersCallback, DataSourceDisplay.defaultVisualizersCallback);

        for (var i = 0, len = dataSourceCollection.length; i < len; i++) {
            this._onDataSourceAdded(dataSourceCollection, dataSourceCollection.get(i));
        }

        var defaultDataSource = new CustomDataSource();
        this._onDataSourceAdded(undefined, defaultDataSource);
        this._defaultDataSource = defaultDataSource;
    }

    /**
     * Gets or sets the default function which creates an array of visualizers used for visualization.
     * By default, this function uses all standard visualizers.
     *
     * @member
     * @type {DataSourceDisplay~VisualizersCallback}
     */
    DataSourceDisplay.defaultVisualizersCallback = function(scene, dataSource) {
        var entities = dataSource.entities;
        return [new BillboardVisualizer(scene, entities),
                new GeometryVisualizer(BoxGeometryUpdater, scene, entities),
                new GeometryVisualizer(CylinderGeometryUpdater, scene, entities),
                new GeometryVisualizer(CorridorGeometryUpdater, scene, entities),
                new GeometryVisualizer(EllipseGeometryUpdater, scene, entities),
                new GeometryVisualizer(EllipsoidGeometryUpdater, scene, entities),
                new GeometryVisualizer(PolygonGeometryUpdater, scene, entities),
                new GeometryVisualizer(PolylineGeometryUpdater, scene, entities),
                new GeometryVisualizer(PolylineVolumeGeometryUpdater, scene, entities),
                new GeometryVisualizer(RectangleGeometryUpdater, scene, entities),
                new GeometryVisualizer(WallGeometryUpdater, scene, entities),
                new LabelVisualizer(scene, entities),
                new ModelVisualizer(scene, entities),
                new PointVisualizer(scene, entities),
                new PathVisualizer(scene, entities)];
    };

    defineProperties(DataSourceDisplay.prototype, {
        /**
         * Gets the scene associated with this display.
         * @memberof DataSourceDisplay.prototype
         * @type {Scene}
         */
        scene : {
            get : function() {
                return this._scene;
            }
        },
        /**
         * Gets the collection of data sources to display.
         * @memberof DataSourceDisplay.prototype
         * @type {DataSourceCollection}
         */
        dataSources : {
            get : function() {
                return this._dataSourceCollection;
            }
        },
        /**
         * Gets the default data source instance which can be used to
         * manually create and visualize entities not tied to
         * a specific data source. This instance is always available
         * and does not appear in the list dataSources collection.
         * @memberof DataSourceDisplay.prototype
         * @type {CustomDataSource}
         */
        defaultDataSource : {
            get : function() {
                return this._defaultDataSource;
            }
        }
    });

    /**
     * Returns true if this object was destroyed; otherwise, false.
     *

     * If this object was destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.
     *
     * @returns {Boolean} True if this object was destroyed; otherwise, false.
     *
     * @see DataSourceDisplay#destroy
     */
    DataSourceDisplay.prototype.isDestroyed = function() {
        return false;
    };

    /**
     * Destroys the WebGL resources held by this object.  Destroying an object allows for deterministic
     * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
     *

     * Once an object is destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.  Therefore,
     * assign the return value (undefined) to the object as done in the example.
     *
     * @returns {undefined}
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     *
     * @example
     * dataSourceDisplay = dataSourceDisplay.destroy();
     * @see DataSourceDisplay#isDestroyed
     */
    DataSourceDisplay.prototype.destroy = function() {
        this._eventHelper.removeAll();

        var dataSourceCollection = this._dataSourceCollection;
        for (var i = 0, length = dataSourceCollection.length; i < length; ++i) {
            this._onDataSourceRemoved(this._dataSourceCollection, dataSourceCollection.get(i));
        }
        this._onDataSourceRemoved(undefined, this._defaultDataSource);

        return destroyObject(this);
    };

    /**
     * Updates the display to the provided time.
     *
     * @param {JulianDate} time The simulation time.
     * @returns {Boolean} True if all data sources are ready to be displayed, false otherwise.
     */
    DataSourceDisplay.prototype.update = function(time) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(time)) {
            throw new DeveloperError('time is required.');
        }
        //>>includeEnd('debug');

        var result = true;

        var i;
        var x;
        var visualizers;
        var vLength;
        var dataSources = this._dataSourceCollection;
        var length = dataSources.length;
        for (i = 0; i < length; i++) {
            var dataSource = dataSources.get(i);
            if (defined(dataSource.update)) {
                result = dataSource.update(time) && result;
            }

            visualizers = dataSource._visualizers;
            vLength = visualizers.length;
            for (x = 0; x < vLength; x++) {
                result = visualizers[x].update(time) && result;
            }
        }

        visualizers = this._defaultDataSource._visualizers;
        vLength = visualizers.length;
        for (x = 0; x < vLength; x++) {
            result = visualizers[x].update(time) && result;
        }

        return result;
    };

    var getBoundingSphereArrayScratch = [];
    var getBoundingSphereBoundingSphereScratch = new BoundingSphere();

    /**
     * Computes a bounding sphere which encloses the visualization produced for the specified entity.
     * The bounding sphere is in the fixed frame of the scene's globe.
     *
     * @param {Entity} entity The entity whose bounding sphere to compute.
     * @param {Boolean} allowPartial If true, pending bounding spheres are ignored and an answer will be returned from the currently available data.
     *                               If false, the the function will halt and return pending if any of the bounding spheres are pending.
     * @param {BoundingSphere} result The bounding sphere onto which to store the result.
     * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere,
     *                       BoundingSphereState.PENDING if the result is still being computed, or
     *                       BoundingSphereState.FAILED if the entity has no visualization in the current scene.
     * @private
     */
    DataSourceDisplay.prototype.getBoundingSphere = function(entity, allowPartial, result) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(entity)) {
            throw new DeveloperError('entity is required.');
        }
        if (!defined(allowPartial)) {
            throw new DeveloperError('allowPartial is required.');
        }
        if (!defined(result)) {
            throw new DeveloperError('result is required.');
        }
        //>>includeEnd('debug');

        var i;
        var length;
        var dataSource = this._defaultDataSource;
        if (!dataSource.entities.contains(entity)) {
            dataSource = undefined;

            var dataSources = this._dataSourceCollection;
            length = dataSources.length;
            for (i = 0; i < length; i++) {
                var d = dataSources.get(i);
                if (d.entities.contains(entity)) {
                    dataSource = d;
                    break;
                }
            }
        }

        if (!defined(dataSource)) {
            return BoundingSphereState.FAILED;
        }

        var boundingSpheres = getBoundingSphereArrayScratch;
        var tmp = getBoundingSphereBoundingSphereScratch;

        var count = 0;
        var state = BoundingSphereState.DONE;
        var visualizers = dataSource._visualizers;
        var visualizersLength = visualizers.length;

        for (i = 0; i < visualizersLength; i++) {
            var visualizer = visualizers[i];
            if (defined(visualizer.getBoundingSphere)) {
                state = visualizers[i].getBoundingSphere(entity, tmp);
                if (!allowPartial && state === BoundingSphereState.PENDING) {
                    return BoundingSphereState.PENDING;
                } else if (state === BoundingSphereState.DONE) {
                    boundingSpheres[count] = BoundingSphere.clone(tmp, boundingSpheres[count]);
                    count++;
                }
            }
        }

        if (count === 0) {
            return BoundingSphereState.FAILED;
        }

        boundingSpheres.length = count;
        BoundingSphere.fromBoundingSpheres(boundingSpheres, result);
        return BoundingSphereState.DONE;
    };

    DataSourceDisplay.prototype._onDataSourceAdded = function(dataSourceCollection, dataSource) {
        var visualizers = this._visualizersCallback(this._scene, dataSource);
        dataSource._visualizers = visualizers;
    };

    DataSourceDisplay.prototype._onDataSourceRemoved = function(dataSourceCollection, dataSource) {
        var visualizers = dataSource._visualizers;
        var length = visualizers.length;
        for (var i = 0; i < length; i++) {
            visualizers[i].destroy();
            dataSource._visualizers = undefined;
        }
    };

    /**
     * A function which creates an array of visualizers used for visualization.
     * @callback DataSourceDisplay~VisualizersCallback
     *
     * @param {Scene} scene The scene to create visualizers for.
     * @param {DataSource} dataSource The data source to create visualizers for.
     * @returns {Visualizer[]} An array of visualizers used for visualization.
     *
     * @example
     * function createVisualizers(scene, dataSource) {
     *     return [new Cesium.BillboardVisualizer(scene, dataSource.entities)];
     * }
     */

    return DataSourceDisplay;
});
<commit_msg>Update DataSourceDisplay.js<commit_after>/*global define*/
define([
        '../Core/BoundingSphere',
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/defineProperties',
        '../Core/destroyObject',
        '../Core/DeveloperError',
        '../Core/EventHelper',
        './BillboardVisualizer',
        './BoundingSphereState',
        './BoxGeometryUpdater',
        './CorridorGeometryUpdater',
        './CustomDataSource',
        './CylinderGeometryUpdater',
        './EllipseGeometryUpdater',
        './EllipsoidGeometryUpdater',
        './GeometryVisualizer',
        './LabelVisualizer',
        './ModelVisualizer',
        './PathVisualizer',
        './PointVisualizer',
        './PolygonGeometryUpdater',
        './PolylineGeometryUpdater',
        './PolylineVolumeGeometryUpdater',
        './RectangleGeometryUpdater',
        './WallGeometryUpdater'
    ], function(
        BoundingSphere,
        defaultValue,
        defined,
        defineProperties,
        destroyObject,
        DeveloperError,
        EventHelper,
        BillboardVisualizer,
        BoundingSphereState,
        BoxGeometryUpdater,
        CorridorGeometryUpdater,
        CustomDataSource,
        CylinderGeometryUpdater,
        EllipseGeometryUpdater,
        EllipsoidGeometryUpdater,
        GeometryVisualizer,
        LabelVisualizer,
        ModelVisualizer,
        PathVisualizer,
        PointVisualizer,
        PolygonGeometryUpdater,
        PolylineGeometryUpdater,
        PolylineVolumeGeometryUpdater,
        RectangleGeometryUpdater,
        WallGeometryUpdater) {
    "use strict";

    /**
     * Visualizes a collection of {@link DataSource} instances.
     * @alias DataSourceDisplay
     * @constructor
     *
     * @param {Object} options Object with the following properties:
     * @param {Scene} options.scene The scene in which to display the data.
     * @param {DataSourceCollection} options.dataSourceCollection The data sources to display.
     * @param {DataSourceDisplay~VisualizersCallback} [options.visualizersCallback=DataSourceDisplay.defaultVisualizersCallback]
     *        A function which creates an array of visualizers used for visualization.
     *        If undefined, all standard visualizers are used.
     */
    function DataSourceDisplay(options) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(options)) {
            throw new DeveloperError('options is required.');
        }
        if (!defined(options.scene)) {
            throw new DeveloperError('scene is required.');
        }
        if (!defined(options.dataSourceCollection)) {
            throw new DeveloperError('dataSourceCollection is required.');
        }
        //>>includeEnd('debug');

        var scene = options.scene;
        var dataSourceCollection = options.dataSourceCollection;

        this._eventHelper = new EventHelper();
        this._eventHelper.add(dataSourceCollection.dataSourceAdded, this._onDataSourceAdded, this);
        this._eventHelper.add(dataSourceCollection.dataSourceRemoved, this._onDataSourceRemoved, this);

        this._dataSourceCollection = dataSourceCollection;
        this._scene = scene;
        this._visualizersCallback = defaultValue(options.visualizersCallback, DataSourceDisplay.defaultVisualizersCallback);

        for (var i = 0, len = dataSourceCollection.length; i < len; i++) {
            this._onDataSourceAdded(dataSourceCollection, dataSourceCollection.get(i));
        }

        var defaultDataSource = new CustomDataSource();
        this._onDataSourceAdded(undefined, defaultDataSource);
        this._defaultDataSource = defaultDataSource;
    }

    /**
     * Gets or sets the default function which creates an array of visualizers used for visualization.
     * By default, this function uses all standard visualizers.
     *
     * @member
     * @type {DataSourceDisplay~VisualizersCallback}
     */
    DataSourceDisplay.defaultVisualizersCallback = function(scene, dataSource) {
        var entities = dataSource.entities;
        return [new BillboardVisualizer(scene, entities),
                new GeometryVisualizer(BoxGeometryUpdater, scene, entities),
                new GeometryVisualizer(CylinderGeometryUpdater, scene, entities),
                new GeometryVisualizer(CorridorGeometryUpdater, scene, entities),
                new GeometryVisualizer(EllipseGeometryUpdater, scene, entities),
                new GeometryVisualizer(EllipsoidGeometryUpdater, scene, entities),
                new GeometryVisualizer(PolygonGeometryUpdater, scene, entities),
                new GeometryVisualizer(PolylineGeometryUpdater, scene, entities),
                new GeometryVisualizer(PolylineVolumeGeometryUpdater, scene, entities),
                new GeometryVisualizer(RectangleGeometryUpdater, scene, entities),
                new GeometryVisualizer(WallGeometryUpdater, scene, entities),
                new LabelVisualizer(scene, entities),
                new ModelVisualizer(scene, entities),
                new PointVisualizer(scene, entities),
                new PathVisualizer(scene, entities)];
    };

    defineProperties(DataSourceDisplay.prototype, {
        /**
         * Gets the scene associated with this display.
         * @memberof DataSourceDisplay.prototype
         * @type {Scene}
         */
        scene : {
            get : function() {
                return this._scene;
            }
        },
        /**
         * Gets the collection of data sources to display.
         * @memberof DataSourceDisplay.prototype
         * @type {DataSourceCollection}
         */
        dataSources : {
            get : function() {
                return this._dataSourceCollection;
            }
        },
        /**
         * Gets the default data source instance which can be used to
         * manually create and visualize entities not tied to
         * a specific data source. This instance is always available
         * and does not appear in the list dataSources collection.
         * @memberof DataSourceDisplay.prototype
         * @type {CustomDataSource}
         */
        defaultDataSource : {
            get : function() {
                return this._defaultDataSource;
            }
        }
    });

    /**
     * Returns true if this object was destroyed; otherwise, false.
     *

     * If this object was destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.
     *
     * @returns {Boolean} True if this object was destroyed; otherwise, false.
     *
     * @see DataSourceDisplay#destroy
     */
    DataSourceDisplay.prototype.isDestroyed = function() {
        return false;
    };

    /**
     * Destroys the WebGL resources held by this object.  Destroying an object allows for deterministic
     * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
     *

     * Once an object is destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.  Therefore,
     * assign the return value (undefined) to the object as done in the example.
     *
     * @returns {undefined}
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     *
     * @example
     * dataSourceDisplay = dataSourceDisplay.destroy();
     *
     * @see DataSourceDisplay#isDestroyed
     */
    DataSourceDisplay.prototype.destroy = function() {
        this._eventHelper.removeAll();

        var dataSourceCollection = this._dataSourceCollection;
        for (var i = 0, length = dataSourceCollection.length; i < length; ++i) {
            this._onDataSourceRemoved(this._dataSourceCollection, dataSourceCollection.get(i));
        }
        this._onDataSourceRemoved(undefined, this._defaultDataSource);

        return destroyObject(this);
    };

    /**
     * Updates the display to the provided time.
     *
     * @param {JulianDate} time The simulation time.
     * @returns {Boolean} True if all data sources are ready to be displayed, false otherwise.
     */
    DataSourceDisplay.prototype.update = function(time) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(time)) {
            throw new DeveloperError('time is required.');
        }
        //>>includeEnd('debug');

        var result = true;

        var i;
        var x;
        var visualizers;
        var vLength;
        var dataSources = this._dataSourceCollection;
        var length = dataSources.length;
        for (i = 0; i < length; i++) {
            var dataSource = dataSources.get(i);
            if (defined(dataSource.update)) {
                result = dataSource.update(time) && result;
            }

            visualizers = dataSource._visualizers;
            vLength = visualizers.length;
            for (x = 0; x < vLength; x++) {
                result = visualizers[x].update(time) && result;
            }
        }

        visualizers = this._defaultDataSource._visualizers;
        vLength = visualizers.length;
        for (x = 0; x < vLength; x++) {
            result = visualizers[x].update(time) && result;
        }

        return result;
    };

    var getBoundingSphereArrayScratch = [];
    var getBoundingSphereBoundingSphereScratch = new BoundingSphere();

    /**
     * Computes a bounding sphere which encloses the visualization produced for the specified entity.
     * The bounding sphere is in the fixed frame of the scene's globe.
     *
     * @param {Entity} entity The entity whose bounding sphere to compute.
     * @param {Boolean} allowPartial If true, pending bounding spheres are ignored and an answer will be returned from the currently available data.
     *                               If false, the the function will halt and return pending if any of the bounding spheres are pending.
     * @param {BoundingSphere} result The bounding sphere onto which to store the result.
     * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere,
     *                       BoundingSphereState.PENDING if the result is still being computed, or
     *                       BoundingSphereState.FAILED if the entity has no visualization in the current scene.
     * @private
     */
    DataSourceDisplay.prototype.getBoundingSphere = function(entity, allowPartial, result) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(entity)) {
            throw new DeveloperError('entity is required.');
        }
        if (!defined(allowPartial)) {
            throw new DeveloperError('allowPartial is required.');
        }
        if (!defined(result)) {
            throw new DeveloperError('result is required.');
        }
        //>>includeEnd('debug');

        var i;
        var length;
        var dataSource = this._defaultDataSource;
        if (!dataSource.entities.contains(entity)) {
            dataSource = undefined;

            var dataSources = this._dataSourceCollection;
            length = dataSources.length;
            for (i = 0; i < length; i++) {
                var d = dataSources.get(i);
                if (d.entities.contains(entity)) {
                    dataSource = d;
                    break;
                }
            }
        }

        if (!defined(dataSource)) {
            return BoundingSphereState.FAILED;
        }

        var boundingSpheres = getBoundingSphereArrayScratch;
        var tmp = getBoundingSphereBoundingSphereScratch;

        var count = 0;
        var state = BoundingSphereState.DONE;
        var visualizers = dataSource._visualizers;
        var visualizersLength = visualizers.length;

        for (i = 0; i < visualizersLength; i++) {
            var visualizer = visualizers[i];
            if (defined(visualizer.getBoundingSphere)) {
                state = visualizers[i].getBoundingSphere(entity, tmp);
                if (!allowPartial && state === BoundingSphereState.PENDING) {
                    return BoundingSphereState.PENDING;
                } else if (state === BoundingSphereState.DONE) {
                    boundingSpheres[count] = BoundingSphere.clone(tmp, boundingSpheres[count]);
                    count++;
                }
            }
        }

        if (count === 0) {
            return BoundingSphereState.FAILED;
        }

        boundingSpheres.length = count;
        BoundingSphere.fromBoundingSpheres(boundingSpheres, result);
        return BoundingSphereState.DONE;
    };

    DataSourceDisplay.prototype._onDataSourceAdded = function(dataSourceCollection, dataSource) {
        var visualizers = this._visualizersCallback(this._scene, dataSource);
        dataSource._visualizers = visualizers;
    };

    DataSourceDisplay.prototype._onDataSourceRemoved = function(dataSourceCollection, dataSource) {
        var visualizers = dataSource._visualizers;
        var length = visualizers.length;
        for (var i = 0; i < length; i++) {
            visualizers[i].destroy();
            dataSource._visualizers = undefined;
        }
    };

    /**
     * A function which creates an array of visualizers used for visualization.
     * @callback DataSourceDisplay~VisualizersCallback
     *
     * @param {Scene} scene The scene to create visualizers for.
     * @param {DataSource} dataSource The data source to create visualizers for.
     * @returns {Visualizer[]} An array of visualizers used for visualization.
     *
     * @example
     * function createVisualizers(scene, dataSource) {
     *     return [new Cesium.BillboardVisualizer(scene, dataSource.entities)];
     * }
     */

    return DataSourceDisplay;
});
<|endoftext|>


<commit_before>var keystone = require('keystone'),
	Types = keystone.Field.Types;

var Everything = new keystone.List('Everything', {
	label: 'Everything',
	singular: 'Thing',
	plural: 'Things',
	path: 'things',
	autokey: { from: 'name', path: 'autokey' }
});

Everything.add(
   'Simple Fields', {
	name: { type: String },
	requiredString: { type: String, required: true, initial: true, note: 'This field is required.' },
	defaultString: { type: String, default: 'Default Value' },
	shortString: { type: String, width: 'short' },
	mediumString: { type: String, width: 'medium' },
	longString: { type: String, width: 'long' },
	textarea: { type: Types.Textarea, initial: true },
	key: { type: Types.Key },
	email: { type: Types.Email },
	url: { type: Types.Url },
	number: { type: Types.Number },
	money: { type: Types.Money },
	checkbox: { type: Boolean, initial: true },
	date: { type: Types.Date },
	dateTime: { type: Date },
	html: { type: Types.Html }
}, 'Complex Fields', {
	select: { type: Types.Select, options: 'first, second, third', initial: true },
	indentedCheckbox: { type: Boolean, initial: true, indent: true, note: 'This checkbox is indented' },
	customSelect: { type: Types.Select, options: [
		{ label: 'Option 1', value: 'one' },
		{ label: 'Option 2', value: 'two' },
		{ label: 'Option 3', value: 'three' }
	] },
	numericSelect: { type: Types.Select, numeric: true, options: [
		{ label: 'Number 1', value: 1 },
		{ label: 'Number 2', value: 2 },
		{ label: 'Number 3', value: 3 }
	] },
	splitName: { type: Types.Name, initial: true },
	password: { type: Types.Password, initial: true },
	cloudinaryImage: { type: Types.CloudinaryImage },
	cloudinaryImages: { type: Types.CloudinaryImages },
	location: { type: Types.Location },
	wysiwygHtml: { type: Types.Html, wysiwyg: true },
	shortWysiwygField: { type: Types.Html, wysiwyg: true, height: 100 },
	embedSrc: { type: String },
	embedData: { type: Types.Embedly, from: 'embedSrc' }
}, 'Relationships', {
	user: { type: Types.Relationship, ref: 'User', initial: true },
	users: { type: Types.Relationship, ref: 'User', many: true }
}, 'Uneditable Fields', {
	uneditableString: { type: String, noedit: true, default: "Not editable" },
	uneditableCheckbox: { type: Boolean, noedit: true, default: true, note: 'Uneditable boolean notes are displayed next to the checkbox' },
	uneditableDate: { type: Types.Date, noedit: true, default: Date.now },
	uneditableSelect: { type: Types.Select, noedit: true, options: 'Sydney, New York, London, Paris, Hong Kong', default: 'Sydney' },
	uneditableLocation: { type: Types.Location, noedit: true, defaults: { street1: '283-285 Kent St', suburb: 'Sydney', state: 'NSW', postcode: '2000', country: 'Australia' } },
	uneditableImage: { type: Types.CloudinaryImage, noedit: true }
});

Everything.addPattern('standard meta');
Everything.register();
<commit_msg>Adding example of select fields with custom values<commit_after>var keystone = require('keystone'),
	Types = keystone.Field.Types;

var Everything = new keystone.List('Everything', {
	label: 'Everything',
	singular: 'Thing',
	plural: 'Things',
	path: 'things',
	autokey: { from: 'name', path: 'autokey' }
});

Everything.add(
   'Simple Fields', {
	name: { type: String },
	requiredString: { type: String, required: true, initial: true, note: 'This field is required.' },
	defaultString: { type: String, default: 'Default Value' },
	shortString: { type: String, width: 'short' },
	mediumString: { type: String, width: 'medium' },
	longString: { type: String, width: 'long' },
	textarea: { type: Types.Textarea, initial: true },
	key: { type: Types.Key },
	email: { type: Types.Email },
	url: { type: Types.Url },
	number: { type: Types.Number },
	money: { type: Types.Money },
	checkbox: { type: Boolean, initial: true },
	date: { type: Types.Date },
	dateTime: { type: Date },
	html: { type: Types.Html }
}, 'Complex Fields', {
	select: { type: Types.Select, options: 'first, second, third', initial: true },
	indentedCheckbox: { type: Boolean, initial: true, indent: true, note: 'This checkbox is indented' },
	customSelect: { type: Types.Select, options: [
		{ label: 'Option 1', value: 'one' },
		{ label: 'Option 2', value: 'two' },
		{ label: 'Option 3', value: 'three' }
	] },
	numericSelect: { type: Types.Select, numeric: true, options: [
		{ label: 'Number 1', value: 1 },
		{ label: 'Number 2', value: 2 },
		{ label: 'Number 3', value: 3 }
	] },
	splitName: { type: Types.Name, initial: true },
	password: { type: Types.Password, initial: true },
	cloudinaryImage: { type: Types.CloudinaryImage },
	cloudinaryImages: { type: Types.CloudinaryImages },
	location: { type: Types.Location },
	wysiwygHtml: { type: Types.Html, wysiwyg: true },
	shortWysiwygField: { type: Types.Html, wysiwyg: true, height: 100 },
	embedSrc: { type: String },
	embedData: { type: Types.Embedly, from: 'embedSrc' }
}, 'Dependent Fields', {
	otherSelect: { type: Types.Select, options: [
		{ label: 'Pre-defined Value', value: 'predefined' },
		{ label: 'Other Value', value: 'other' }
	]},
	otherValue: { type: String, dependsOn: { otherSelect: 'other' } }
}, 'Relationships', {
	user: { type: Types.Relationship, ref: 'User', initial: true },
	users: { type: Types.Relationship, ref: 'User', many: true }
}, 'Uneditable Fields', {
	uneditableString: { type: String, noedit: true, default: "Not editable" },
	uneditableCheckbox: { type: Boolean, noedit: true, default: true, note: 'Uneditable boolean notes are displayed next to the checkbox' },
	uneditableDate: { type: Types.Date, noedit: true, default: Date.now },
	uneditableSelect: { type: Types.Select, noedit: true, options: 'Sydney, New York, London, Paris, Hong Kong', default: 'Sydney' },
	uneditableLocation: { type: Types.Location, noedit: true, defaults: { street1: '283-285 Kent St', suburb: 'Sydney', state: 'NSW', postcode: '2000', country: 'Australia' } },
	uneditableImage: { type: Types.CloudinaryImage, noedit: true }
});

Everything.schema.virtual('otherSelectValue').get(function() {
	return (this.otherSelect == 'other') ? this.otherValue : this.otherSelect;
});

Everything.addPattern('standard meta');
Everything.register();
<|endoftext|>


<commit_before><commit_msg>remove acceptance-test proxy from app<commit_after><|endoftext|>


<commit_before><commit_msg>only grab num key combinations... not sure why we had a-i<commit_after><|endoftext|>


<commit_before>app.controller("transCtrl", function($scope, $rootScope) {
	$scope.currentPage = 1;
	var pageSize = 15;

	$scope.pagesCount = 0;

	$scope.countPages = function() {
		return $scope.pagesCount
				|| ($scope.pagesCount = centsa.transactions
						.countPages(pageSize));
	};

	$scope.goToPage = function(n) {
		if ($scope.currentPage != ($scope.currentPage = n)) {
			$scope.transactions = centsa.transactions.getAll(
					$scope.currentPage, pageSize, "ID DESC");
		}
	};

	$scope.transactions = centsa.transactions.getAll($scope.currentPage,
			pageSize, "ID DESC");
	$scope.accounts = centsa.accounts.getAll(0, 0);
	$scope.types = centsa.types.getAll(0, 0);
	$scope.expenses = centsa.expenses.getAll(0, 0);
	$scope.uniqueComments = centsa.transactions.getUniqueComments();

	$scope.showDataList = false;

	$scope.setComment = function(c) {
		$scope.showDataList = false;
		$scope.newTrans.comment = c;
	};

	$scope.closeDataList = function() {
		setTimeout(function() {
			if (!$rootScope.isActive('.datalist *')) {
				$scope.showDataList = false;
				$scope.$apply();
			}
		}, 200);
	};

	$scope.newTrans = {
		amount : 0.0,
		comment : "",
		account_id : "1",
		type_id : "1",
		expense_id : "1",
		date : new Date().formatDate("yyyy/MM/dd")
	};

	var newTrans = Object.assign({}, $scope.newTrans);

	$scope.saveTrans = function() {
		$scope.pagesCount = 0;
		$scope.newTrans.date = new Date($scope.newTrans.date).getTime();
		$scope.newTrans.amount = $scope.newTrans.amount * 100;
		$scope.newTrans.id = centsa.transactions.insert($scope.newTrans);
		if ($scope.currentPage == 1) {
			$scope.transactions.unshift($scope.newTrans);
			if ($scope.transactions.length > pageSize) {
				$scope.transactions.pop();
			}
		}
		$scope.newTrans = Object.assign({}, newTrans);
		$('.datepicker').datepicker("update",
				new Date().formatDate("yyyy/MM/dd"));
	};

	$scope.getFromArray = function(arr, id) {
		return arr.filter(function(item) {
			return item.id == id;
		})[0];
	};

	$('.datepicker').datepicker({
		format : "yyyy/mm/dd",
		endDate : new Date(),
		todayBtn : "linked",
		autoclose : true,
		todayHighlight : true
	});

});
<commit_msg>Changed sorting to date<commit_after>app.controller("transCtrl", function($scope, $rootScope) {
	$scope.currentPage = 1;
	var pageSize = 15;

	$scope.pagesCount = 0;

	$scope.countPages = function() {
		return $scope.pagesCount
				|| ($scope.pagesCount = centsa.transactions
						.countPages(pageSize));
	};

	$scope.goToPage = function(n) {
		if ($scope.currentPage != ($scope.currentPage = n)) {
			$scope.transactions = centsa.transactions.getAll(
					$scope.currentPage, pageSize, "DATE DESC");
		}
	};

	$scope.transactions = centsa.transactions.getAll($scope.currentPage,
			pageSize, "DATE DESC");
	$scope.accounts = centsa.accounts.getAll(0, 0);
	$scope.types = centsa.types.getAll(0, 0);
	$scope.expenses = centsa.expenses.getAll(0, 0);
	$scope.uniqueComments = centsa.transactions.getUniqueComments();

	$scope.showDataList = false;

	$scope.setComment = function(c) {
		$scope.showDataList = false;
		$scope.newTrans.comment = c;
	};

	$scope.closeDataList = function() {
		setTimeout(function() {
			if (!$rootScope.isActive('.datalist *')) {
				$scope.showDataList = false;
				$scope.$apply();
			}
		}, 200);
	};

	$scope.newTrans = {
		amount : 0.0,
		comment : "",
		account_id : "1",
		type_id : "1",
		expense_id : "1",
		date : new Date().formatDate("yyyy/MM/dd")
	};

	var newTrans = Object.assign({}, $scope.newTrans);

	$scope.saveTrans = function() {
		$scope.pagesCount = 0;
		$scope.newTrans.date = new Date($scope.newTrans.date).getTime();
		$scope.newTrans.amount = $scope.newTrans.amount * 100;
		$scope.newTrans.id = centsa.transactions.insert($scope.newTrans);
		if ($scope.currentPage == 1) {
			$scope.transactions.unshift($scope.newTrans);
			if ($scope.transactions.length > pageSize) {
				$scope.transactions.pop();
			}
		}
		$scope.newTrans = Object.assign({}, newTrans);
		$('.datepicker').datepicker("update",
				new Date().formatDate("yyyy/MM/dd"));
	};

	$scope.getFromArray = function(arr, id) {
		return arr.filter(function(item) {
			return item.id == id;
		})[0];
	};

	$('.datepicker').datepicker({
		format : "yyyy/mm/dd",
		endDate : new Date(),
		todayBtn : "linked",
		autoclose : true,
		todayHighlight : true
	});

});
<|endoftext|>