diff --git a/ported_plugins/plugins/rex_firebase_pack/README.md b/ported_plugins/plugins/rex_firebase_pack/README.md new file mode 100644 index 0000000..0165b12 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/README.md @@ -0,0 +1,5 @@ +Rex_firebase bundle for c3runtime. + +official plugin repo +https://github.com/rexrainbow/C3RexDoc/blob/master/repo/index.md + diff --git a/ported_plugins/plugins/rex_firebase_pack/firebase_cors_error.txt b/ported_plugins/plugins/rex_firebase_pack/firebase_cors_error.txt new file mode 100644 index 0000000..27de44f --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/firebase_cors_error.txt @@ -0,0 +1 @@ +https://stackoverflow.com/questions/37760695/firebase-storage-and-access-control-allow-origin/37765371#37765371 \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/dist/rex_firebase.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/dist/rex_firebase.c3addon new file mode 100644 index 0000000..0430934 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/dist/rex_firebase.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/aces.json new file mode 100755 index 0000000..587fa27 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/aces.json @@ -0,0 +1,663 @@ +{ + "domain": { + "conditions": [ + ], + "actions": [ + { + "c2id": 0, + "id": "setdomainref0", + "scriptName": "SetDomainRef", + "highlight": false, + "params": [ + {"id":"domain0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + { + "c2id": 0, + "id": "domain0", + "expressionName": "Domain", + "scriptName": "Domain", + "highlight": false, + "returnType": "string" + } + ] + }, + "send_-_set": { + "conditions": [ + ], + "actions": [ + { + "c2id": 1, + "id": "setvalue1", + "scriptName": "SetValue", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"value1", "type":"any", "initialValue":"0"}, + {"id":"on_complete2", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 2, + "id": "setjson2", + "scriptName": "SetJSON", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"json_value1", "type":"string", "initialValue":"\"{}\""}, + {"id":"on_complete2", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 10, + "id": "setbooleanvalue10", + "scriptName": "SetBooleanValue", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"boolean3", "type":"combo", "items":["false","true"]}, + {"id":"on_complete4", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 12, + "id": "setservertimestamp12", + "scriptName": "SetServerTimestamp", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"on_complete1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "send_-_update_json": { + "conditions": [ + ], + "actions": [ + { + "c2id": 3, + "id": "updatejson3", + "scriptName": "UpdateJSON", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"json_value1", "type":"string", "initialValue":"\"{}\""}, + {"id":"on_complete2", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "send_-_push": { + "conditions": [ + ], + "actions": [ + { + "c2id": 4, + "id": "pushvalue4", + "scriptName": "PushValue", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"value1", "type":"any", "initialValue":"0"}, + {"id":"on_complete2", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 5, + "id": "pushjson5", + "scriptName": "PushJSON", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"json_value1", "type":"string", "initialValue":"\"{}\""}, + {"id":"on_complete2", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 11, + "id": "pushbooleanvalue11", + "scriptName": "PushBooleanValue", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"boolean3", "type":"combo", "items":["false","true"]}, + {"id":"on_complete4", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 13, + "id": "pushservertimestamp13", + "scriptName": "PushServerTimestamp", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"on_complete1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "send_-_transaction": { + "conditions": [ + ], + "actions": [ + { + "c2id": 6, + "id": "transaction6", + "scriptName": "Transaction", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"on_transaction1", "type":"string", "initialValue":"\"_\""}, + {"id":"on_complete2", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 7, + "id": "returntransactionvalue7", + "scriptName": "ReturnTransactionValue", + "highlight": false, + "params": [ + {"id":"value0", "type":"any", "initialValue":"0"} + ] + }, + { + "c2id": 8, + "id": "returntransactionjson8", + "scriptName": "ReturnTransactionJSON", + "highlight": false, + "params": [ + {"id":"json_value0", "type":"string", "initialValue":"\"{}\""} + ] + } + ], + "expressions": [ + { + "c2id": 1, + "id": "transactionın1", + "expressionName": "TransactionIn", + "scriptName": "TransactionIn", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + }, + { + "c2id": 5, + "id": "transactionresult5", + "expressionName": "TransactionResult", + "scriptName": "TransactionResult", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + } + ] + }, + "send_-_remove": { + "conditions": [ + ], + "actions": [ + { + "c2id": 9, + "id": "remove9", + "scriptName": "Remove", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"on_complete1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "receive_-_add": { + "conditions": [ + ], + "actions": [ + { + "c2id": 21, + "id": "addreadingcallback21", + "scriptName": "AddReadingCallback", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"type6", "type":"combo", "items":["value changed","child added","child changed","child removed","child moved"]}, + {"id":"callback_function7", "type":"string", "initialValue":"\"_\""} + ] + } + ], + "expressions": [ + ] + }, + "receive_-_remove": { + "conditions": [ + ], + "actions": [ + { + "c2id": 22, + "id": "removereadingcallback22", + "scriptName": "RemoveReadingCallback", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"type6", "type":"combo", "items":["value changed","child added","child changed","child removed","child moved"]}, + {"id":"callback_function7", "type":"string", "initialValue":"\"_\""} + ] + }, + { + "c2id": 23, + "id": "removereadingcallback23", + "scriptName": "RemoveReadingCallback", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"type6", "type":"combo", "items":["value changed","child added","child changed","child removed","child moved"]} + ] + }, + { + "c2id": 24, + "id": "removereadingcallback24", + "scriptName": "RemoveReadingCallback", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 34, + "id": "removereadingcallback34", + "scriptName": "RemoveReadingCallback", + "highlight": false + } + ], + "expressions": [ + ] + }, + "receive_-_add_once": { + "conditions": [ + ], + "actions": [ + { + "c2id": 25, + "id": "addreadingcallbackonce25", + "scriptName": "AddReadingCallbackOnce", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"type6", "type":"combo", "items":["value changed","child added","child changed","child removed","child moved"]}, + {"id":"callback_function7", "type":"string", "initialValue":"\"_\""} + ] + } + ], + "expressions": [ + ] + }, + "on_disconnect": { + "conditions": [ + ], + "actions": [ + { + "c2id": 31, + "id": "removerefondisconnect31", + "scriptName": "RemoveRefOnDisconnect", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 32, + "id": "setvalueondisconnect32", + "scriptName": "SetValueOnDisconnect", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""}, + {"id":"value1", "type":"any", "initialValue":"0"} + ] + }, + { + "c2id": 33, + "id": "updatejsonondisconnect33", + "scriptName": "UpdateJSONOnDisconnect", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"/myref\""}, + {"id":"json_value1", "type":"string", "initialValue":"\"{}\""} + ] + }, + { + "c2id": 35, + "id": "cancelondisconnect35", + "scriptName": "CancelOnDisconnect", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "query": { + "conditions": [ + ], + "actions": [ + { + "c2id": 51, + "id": "addquerycallback51", + "scriptName": "AddQueryCallback", + "highlight": false, + "params": [ + {"id":"query0", "type":"object"}, + {"id":"type6", "type":"combo", "items":["value changed","child added","child changed","child removed","child moved"]}, + {"id":"callback_function7", "type":"string", "initialValue":"\"_\""} + ] + }, + { + "c2id": 52, + "id": "addquerycallbackonce52", + "scriptName": "AddQueryCallbackOnce", + "highlight": false, + "params": [ + {"id":"query0", "type":"object"}, + {"id":"type6", "type":"combo", "items":["value changed","child added","child changed","child removed","child moved"]}, + {"id":"callback_function7", "type":"string", "initialValue":"\"_\""} + ] + } + ], + "expressions": [ + ] + }, + "online": { + "conditions": [ + ], + "actions": [ + { + "c2id": 61, + "id": "gooffline61", + "scriptName": "GoOffline", + "highlight": false + }, + { + "c2id": 62, + "id": "goonline62", + "scriptName": "GoOnline", + "highlight": false + } + ], + "expressions": [ + ] + }, + "transaction": { + "conditions": [ + { + "c2id": 1, + "id": "ontransaction1", + "scriptName": "OnTransaction", + "isTrigger": "true", + "highlight": false, + "params": [ + {"id":"callback_function0", "type":"string", "initialValue":"\"_\""} + ] + }, + { + "c2id": 6, + "id": "transactionınısnull6", + "scriptName": "TransactionInIsNull", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "receive": { + "conditions": [ + { + "c2id": 2, + "id": "onreading2", + "scriptName": "OnReading", + "isTrigger": "true", + "highlight": false, + "params": [ + {"id":"callback_function0", "type":"string", "initialValue":"\"_\""} + ] + }, + { + "c2id": 5, + "id": "lastdataısnull5", + "scriptName": "LastDataIsNull", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 2, + "id": "lastdata2", + "expressionName": "LastData", + "scriptName": "LastData", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + }, + { + "c2id": 3, + "id": "lastkey3", + "expressionName": "LastKey", + "scriptName": "LastKey", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + }, + { + "c2id": 4, + "id": "prevchildname4", + "expressionName": "PrevChildName", + "scriptName": "PrevChildName", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + } + ] + }, + "send": { + "conditions": [ + { + "c2id": 3, + "id": "oncomplete3", + "scriptName": "OnComplete", + "isTrigger": "true", + "highlight": false, + "params": [ + {"id":"callback_function0", "type":"string", "initialValue":"\"_\""} + ] + }, + { + "c2id": 4, + "id": "onerror4", + "scriptName": "OnError", + "isTrigger": "true", + "highlight": false, + "params": [ + {"id":"callback_function0", "type":"string", "initialValue":"\"_\""} + ] + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "transaction_-_completed": { + "conditions": [ + { + "c2id": 7, + "id": "ıstransactionaborted7", + "scriptName": "IsTransactionAborted", + "isDeprecated": "true", + "highlight": false + }, + { + "c2id": 8, + "id": "ontransactioncomplete8", + "scriptName": "OnTransactionComplete", + "isTrigger": "true", + "highlight": false, + "params": [ + {"id":"callback_function0", "type":"string", "initialValue":"\"_\""} + ] + }, + { + "c2id": 9, + "id": "ontransactionerror9", + "scriptName": "OnTransactionError", + "isTrigger": "true", + "highlight": false, + "params": [ + {"id":"callback_function0", "type":"string", "initialValue":"\"_\""} + ] + }, + { + "c2id": 10, + "id": "ontransactionabort10", + "scriptName": "OnTransactionAbort", + "isTrigger": "true", + "highlight": false, + "params": [ + {"id":"callback_function0", "type":"string", "initialValue":"\"_\""} + ] + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "connection": { + "conditions": [ + { + "c2id": 11, + "id": "onconnected11", + "scriptName": "OnConnected", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 12, + "id": "ondisconnected12", + "scriptName": "OnDisconnected", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 13, + "id": "ısconnected13", + "scriptName": "IsConnected", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "push": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 11, + "id": "lastpushref11", + "expressionName": "LastPushRef", + "scriptName": "LastPushRef", + "highlight": false, + "returnType": "string" + } + ] + }, + "ıtemıd": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 21, + "id": "generatekey21", + "expressionName": "GenerateKey", + "scriptName": "GenerateKey", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 22, + "id": "lastgeneratedkey22", + "expressionName": "LastGeneratedKey", + "scriptName": "LastGeneratedKey", + "highlight": false, + "returnType": "string" + } + ] + }, + "server_time_offset": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 31, + "id": "servertimeoffset31", + "expressionName": "ServerTimeOffset", + "scriptName": "ServerTimeOffset", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 32, + "id": "estimatedtime32", + "expressionName": "EstimatedTime", + "scriptName": "EstimatedTime", + "highlight": false, + "returnType": "number" + } + ] + }, + "error": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 101, + "id": "lasterrorcode101", + "expressionName": "LastErrorCode", + "scriptName": "LastErrorCode", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 102, + "id": "lasterrormessage102", + "expressionName": "LastErrorMessage", + "scriptName": "LastErrorMessage", + "highlight": false, + "returnType": "string" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/addon.json new file mode 100755 index 0000000..f16278d --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/addon.json @@ -0,0 +1,26 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Firebase", + "id": "Rex_Firebase", + "version": "1.3.1.0", + "author": "Rex.Rainbow", + "website": "http://c2rexplugins.weebly.com/rex_firebase.html", + "documentation": "http://c2rexplugins.weebly.com/rex_firebase.html", + "description": "Real time database-as-a-service. https://www.firebase.com/", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c2runtime/runtime.js new file mode 100755 index 0000000..8ccebf6 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c2runtime/runtime.js @@ -0,0 +1,622 @@ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + var EVENTTYPEMAP = ["value", "child_added", "child_changed", "child_removed","child_moved"]; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/"; + + // push + this.lastPushRef = ""; + // transaction + this.onTransaction = {}; + this.onTransaction.cb = null; + this.onTransaction.input = null; + this.onTransaction.output = null; + // transaction completed + this.onTransaction.completedCB = null; + this.onTransaction.committedValue = null; + // on complete + this.onCompleteCb = null; + this.error = null; + // reading + if (!this.recycled) + this.callbackMap = new window.FirebaseCallbackMapKlass(); + else + this.callbackMap.Reset(); + + this.onReadCb = null; + this.snapshot = null; + this.prevChildName = null; + this.exp_LastGeneratedKey = ""; + this.exp_ServerTimeOffset = 0; + this.isConnected = false; + + + var self=this; + var setupFn = function () + { + if (self.properties[1] === 1) + self.connectionDetectingStart(); + + if (self.properties[2] === 1) + self.serverTimeOffsetDetectingStart(); + } + window.FirebaseAddAfterInitializeHandler(setupFn); + }; + + instanceProto.onDestroy = function () + { + this.callbackMap.Remove(); + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.getRef = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var getKey = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var getRefPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var getRoot = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var getTimestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + instanceProto.addCallback = function (query, type_, cbName) + { + var eventType = EVENTTYPEMAP[type_]; + var self = this; + var reading_handler = function (snapshot, prevChildName) + { + self.onReadCb = cbName; + self.snapshot = snapshot; + self.prevChildName = prevChildName; + self.runtime.trigger(cr.plugins_.Rex_Firebase.prototype.cnds.OnReading, self); + self.onReadCb = null; + }; + + this.callbackMap.Add(query, eventType, cbName, reading_handler); + }; + + instanceProto.addCallbackOnce = function (refObj, type_, cb) + { + var eventType = EVENTTYPEMAP[type_]; + + var self = this; + var reading_handler = function (snapshot, prevChildName) + { + self.onReadCb = cb; + self.snapshot = snapshot; + self.prevChildName = prevChildName; + self.runtime.trigger(cr.plugins_.Rex_Firebase.prototype.cnds.OnReading, self); + self.onReadCb = null; + }; + refObj["once"](eventType, reading_handler); + }; + + instanceProto.connectionDetectingStart = function () + { + var self = this; + var onValueChanged = function (snap) + { + var trig; + var isConnected = !!snap["val"](); + if ( isConnected ) + trig = cr.plugins_.Rex_Firebase.prototype.cnds.OnConnected; + else if (self.isConnected && !isConnected) // disconnected after connected + trig = cr.plugins_.Rex_Firebase.prototype.cnds.OnDisconnected; + + self.isConnected = isConnected; + + self.runtime.trigger(trig, self); + }; + + var p = getRoot(this.getRef()) + "/.info/connected"; + var ref = this.getRef(p); + ref.on("value", onValueChanged); + }; + + instanceProto.serverTimeOffsetDetectingStart = function () + { + var self = this; + var onValueChanged = function (snap) + { + self.exp_ServerTimeOffset = snap["val"]() || 0; + }; + + var p = getRoot(this.getRef()) + "/.info/serverTimeOffset"; + var ref = this.getRef(p); + ref.on("value", onValueChanged); + }; + /**BEGIN-PREVIEWONLY**/ + instanceProto.getDebuggerValues = function (propsections) + { + var prop = []; + this.callbackMap.getDebuggerValues(prop); + + propsections.push({ + "title": this.type.name, + "properties": prop + }); + }; + + instanceProto.onDebugValueEdited = function (header, name, value) + { + }; + /**END-PREVIEWONLY**/ + + ////////////////////////////////////// + // Conditions + function Cnds() {}; + pluginProto.cnds = new Cnds(); + + Cnds.prototype.OnTransaction = function (cb) + { + return cr.equals_nocase(cb, this.onTransaction.cb); + }; + + Cnds.prototype.OnReading = function (cb) + { + return cr.equals_nocase(cb, this.onReadCb); + }; + + Cnds.prototype.OnComplete = function (cb) + { + return cr.equals_nocase(cb, this.onCompleteCb); + }; + + Cnds.prototype.OnError = function (cb) + { + return cr.equals_nocase(cb, this.onCompleteCb); + }; + + Cnds.prototype.LastDataIsNull = function () + { + var data =(this.snapshot === null)? null: this.snapshot["val"](); + return (data === null); + }; + + Cnds.prototype.TransactionInIsNull = function () + { + var data =(this.onTransaction.input === null)? null: this.onTransaction.input; + return (data === null); + }; + + // cf_deprecated + Cnds.prototype.IsTransactionAborted = function () { return false; }; + // cf_deprecated + + Cnds.prototype.OnTransactionComplete = function (cb) + { + return cr.equals_nocase(cb, this.onTransaction.completedCB); + }; + + Cnds.prototype.OnTransactionError = function (cb) + { + return cr.equals_nocase(cb, this.onTransaction.completedCB); + }; + + Cnds.prototype.OnTransactionAbort = function (cb) + { + return cr.equals_nocase(cb, this.onTransaction.completedCB); + }; + + Cnds.prototype.OnConnected = function () + { + return true; + }; + + Cnds.prototype.OnDisconnected = function () + { + return true; + }; + + Cnds.prototype.IsConnected = function () + { + return this.isConnected; + }; + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetDomainRef = function (ref) + { + this.rootpath = ref + "/"; + }; + + var getOnCompleteHandler = function (self, onCompleteCb) + { + if ((onCompleteCb === null) || (onCompleteCb === "")) + return; + + var handler = function(error) + { + self.onCompleteCb = onCompleteCb; + self.error = error; + var trig = (error)? cr.plugins_.Rex_Firebase.prototype.cnds.OnError: + cr.plugins_.Rex_Firebase.prototype.cnds.OnComplete; + self.runtime.trigger(trig, self); + self.onCompleteCb = null; + }; + return handler; + }; + + Acts.prototype.SetValue = function (k, v, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["set"](v, handler); + }; + + Acts.prototype.SetJSON = function (k, v, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["set"](JSON.parse(v), handler); + }; + + Acts.prototype.UpdateJSON = function (k, v, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["update"](JSON.parse(v), handler); + }; + + Acts.prototype.PushValue = function (k, v, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + var ref = this.getRef(k)["push"](v, handler); + this.lastPushRef = k + "/" + getKey(ref); + }; + + Acts.prototype.PushJSON = function (k, v, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + var ref = this.getRef(k)["push"](JSON.parse(v), handler); + this.lastPushRef = k + "/" + getKey(ref); + }; + + Acts.prototype.Transaction = function (k, onTransactionCb, onCompleteCb) + { + var self = this; + + var _onComplete = function(error, committed, snapshot) + { + self.onTransaction.completedCB = onCompleteCb; + self.error = error; + self.onTransaction.committedValue = snapshot["val"](); + + var cnds = cr.plugins_.Rex_Firebase.prototype.cnds; + var trig = (error)? cnds.OnTransactionError: + (!committed)? cnds.OnTransactionAbort: + cnds.OnTransactionComplete; + + self.runtime.trigger(trig, self); + self.onTransaction.completedCB = null; + }; + + var _onTransaction = function(current_value) + { + self.onTransaction.cb = onTransactionCb; + self.onTransaction.input = current_value; + self.onTransaction.output = null; + self.runtime.trigger(cr.plugins_.Rex_Firebase.prototype.cnds.OnTransaction, self); + self.onTransaction.cb = null; + + if (self.onTransaction.output === null) + return; + else + return self.onTransaction.output; + }; + this.getRef(k)["transaction"](_onTransaction, _onComplete); + }; + + Acts.prototype.ReturnTransactionValue = function (v) + { + this.onTransaction.output = v; + }; + + Acts.prototype.ReturnTransactionJSON = function (v) + { + this.onTransaction.output = JSON.parse(v); + }; + + Acts.prototype.Remove = function (k, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["remove"](handler); + }; + + Acts.prototype.SetBooleanValue = function (k, b, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["set"]((b===1), handler); + }; + + Acts.prototype.PushBooleanValue = function (k, b, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + var ref = this.getRef(k)["push"]((b===1), handler); + this.lastPushRef = k + "/" + getKey(ref); + }; + + Acts.prototype.SetServerTimestamp = function (k, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["set"](serverTimeStamp(), handler); + }; + + Acts.prototype.PushServerTimestamp = function (k, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + var ref = this.getRef(k)["push"](serverTimeStamp(), handler); + this.lastPushRef = k + "/" + getKey(ref); + }; + Acts.prototype.AddReadingCallback = function (k, type_, cbName) + { + this.addCallback(this.getRef(k), type_, cbName); + }; + + Acts.prototype.RemoveReadingCallback = function (k, type_, cbName) + { + var absRef = (k != null)? this.getRef(k)["toString"](): null; + var eventType = (type_ != null)? EVENTTYPEMAP[type_]: null; + this.callbackMap.Remove(absRef, eventType, cbName); + }; + + Acts.prototype.AddReadingCallbackOnce = function (k, type_, cbName) + { + this.addCallbackOnce(this.getRef(k), type_, cbName); + }; + + Acts.prototype.RemoveRefOnDisconnect = function (k) + { + this.getRef(k)["onDisconnect"]()["remove"](); + }; + + Acts.prototype.SetValueOnDisconnect = function (k, v) + { + this.getRef(k)["onDisconnect"]()["set"](v); + }; + + Acts.prototype.UpdateJSONOnDisconnect = function (k, v) + { + this.getRef(k)["onDisconnect"]()["update"](JSON.parse(v)); + }; + + Acts.prototype.CancelOnDisconnect = function (k) + { + this.getRef(k)["onDisconnect"]()["cancel"](); + }; + + + // query + var get_query = function (queryObjs) + { + if (queryObjs == null) + return null; + var query = queryObjs.getFirstPicked(); + if (query == null) + return null; + + return query.GetQuery(); + }; + Acts.prototype.AddQueryCallback = function (queryObjs, type_, cbName) + { + var refObj = get_query(queryObjs); + if (refObj == null) + return; + + this.addCallback(refObj, type_, cbName); + }; + + Acts.prototype.AddQueryCallbackOnce = function (queryObjs, type_, cbName) + { + var refObj = get_query(queryObjs); + if (refObj == null) + return; + + this.addCallbackOnce(refObj, type_, cbName); + }; + + Acts.prototype.GoOffline = function () + { + // 2.x + if (!isFirebase3x()) + { + window["Firebase"]["goOffline"](); + } + + // 3.x + else + { + window["Firebase"]["database"]()["goOffline"](); + } + }; + + Acts.prototype.GoOnline = function () + { + // 2.x + if (!isFirebase3x()) + { + window["Firebase"]["goOnline"](); + + } + + // 3.x + else + { + window["Firebase"]["database"]()["goOnline"](); + } + }; + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.Domain = function (ret) + { + ret.set_string(this.rootpath); + }; + + Exps.prototype.TransactionIn = function (ret, default_value) + { + ret.set_any(window.FirebaseGetValueByKeyPath(this.onTransaction.input, null, default_value)); + }; + + Exps.prototype.LastData = function (ret, default_value) + { + var data =(this.snapshot === null)? null: this.snapshot["val"](); + ret.set_any(window.FirebaseGetValueByKeyPath(data, null, default_value)); + }; + + Exps.prototype.LastKey = function (ret, default_value) + { + var key =(this.snapshot === null)? null: getKey(this.snapshot); + ret.set_any(window.FirebaseGetValueByKeyPath(key, null, default_value)); + }; + + Exps.prototype.PrevChildName = function (ret, default_value) + { + ret.set_any(window.FirebaseGetValueByKeyPath(this.prevChildName, null, default_value)); + }; + + Exps.prototype.TransactionResult = function (ret, default_value) + { + ret.set_any(window.FirebaseGetValueByKeyPath(this.onTransaction.committedValue, null, default_value)); + }; + + Exps.prototype.LastPushRef = function (ret) + { + ret.set_string(this.lastPushRef); + }; + + Exps.prototype.GenerateKey = function (ret) + { + var ref = this.getRef()["push"](); + this.exp_LastGeneratedKey = getKey(ref); + ret.set_string(this.exp_LastGeneratedKey); + }; + + Exps.prototype.LastGeneratedKey = function (ret) + { + ret.set_string(this.exp_LastGeneratedKey); + }; + + Exps.prototype.ServerTimeOffset = function (ret) + { + ret.set_int(this.exp_ServerTimeOffset); + }; + + Exps.prototype.EstimatedTime = function (ret) + { + ret.set_int(new Date().getTime() + this.exp_ServerTimeOffset); + }; + + Exps.prototype.LastErrorCode = function (ret) + { + var code; + if (this.error) + code = this.error["code"]; + ret.set_string(code || ""); + }; + + Exps.prototype.LastErrorMessage = function (ret) + { + var s; + if (this.error) + s = this.error["serverResponse"]; + ret.set_string(s || ""); + }; + +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/actions.js new file mode 100755 index 0000000..21d2d9a --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/actions.js @@ -0,0 +1,209 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase.Acts = + { + + SetDomainRef(ref) + { + this.rootpath = ref + "/"; + }, + + + SetValue(k, v, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["set"](v, handler); + }, + + SetJSON(k, v, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["set"](JSON.parse(v), handler); + }, + + UpdateJSON(k, v, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["update"](JSON.parse(v), handler); + }, + + PushValue(k, v, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + var ref = this.getRef(k)["push"](v, handler); + this.lastPushRef = k + "/" + getKey(ref); + }, + + PushJSON(k, v, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + var ref = this.getRef(k)["push"](JSON.parse(v), handler); + this.lastPushRef = k + "/" + getKey(ref); + }, + + Transaction(k, onTransactionCb, onCompleteCb) + { + var self = this; + + var _onComplete = function(error, committed, snapshot) + { + self.onTransaction.completedCB = onCompleteCb; + self.error = error; + self.onTransaction.committedValue = snapshot["val"](); + + var cnds = C3.Plugins.Rex_Firebase.Cnds; + var trig = (error)? cnds.OnTransactionError: + (!committed)? cnds.OnTransactionAbort: + cnds.OnTransactionComplete; + + self.Trigger(trig, self); + self.onTransaction.completedCB = null; + }; + + var _onTransaction = function(current_value) + { + self.onTransaction.cb = onTransactionCb; + self.onTransaction.input = current_value; + self.onTransaction.output = null; + self.Trigger(C3.Plugins.Rex_Firebase.Cnds.OnTransaction, self); + self.onTransaction.cb = null; + + if (self.onTransaction.output === null) + return; + else + return self.onTransaction.output; + }; + this.getRef(k)["transaction"](_onTransaction, _onComplete); + }, + + ReturnTransactionValue(v) + { + this.onTransaction.output = v; + }, + + ReturnTransactionJSON(v) + { + this.onTransaction.output = JSON.parse(v); + }, + + Remove(k, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["remove"](handler); + }, + + SetBooleanValue(k, b, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["set"]((b===1), handler); + }, + + PushBooleanValue(k, b, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + var ref = this.getRef(k)["push"]((b===1), handler); + this.lastPushRef = k + "/" + getKey(ref); + }, + + SetServerTimestamp(k, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + this.getRef(k)["set"](serverTimeStamp(), handler); + }, + + PushServerTimestamp(k, onCompleteCb) + { + var handler = getOnCompleteHandler(this, onCompleteCb); + var ref = this.getRef(k)["push"](serverTimeStamp(), handler); + this.lastPushRef = k + "/" + getKey(ref); + }, + AddReadingCallback(k, type_, cbName) + { + this.addCallback(this.getRef(k), type_, cbName); + }, + + RemoveReadingCallback(k, type_, cbName) + { + var absRef = (k != null)? this.getRef(k)["toString"](): null; + var eventType = (type_ != null)? EVENTTYPEMAP[type_]: null; + this.callbackMap.Remove(absRef, eventType, cbName); + }, + + AddReadingCallbackOnce(k, type_, cbName) + { + this.addCallbackOnce(this.getRef(k), type_, cbName); + }, + + RemoveRefOnDisconnect(k) + { + this.getRef(k)["onDisconnect"]()["remove"](); + }, + + SetValueOnDisconnect(k, v) + { + this.getRef(k)["onDisconnect"]()["set"](v); + }, + + UpdateJSONOnDisconnect(k, v) + { + this.getRef(k)["onDisconnect"]()["update"](JSON.parse(v)); + }, + + CancelOnDisconnect(k) + { + this.getRef(k)["onDisconnect"]()["cancel"](); + }, + + + + AddQueryCallback(queryObjs, type_, cbName) + { + var refObj = get_query(queryObjs); + if (refObj == null) + return; + + this.addCallback(refObj, type_, cbName); + }, + + AddQueryCallbackOnce(queryObjs, type_, cbName) + { + var refObj = get_query(queryObjs); + if (refObj == null) + return; + + this.addCallbackOnce(refObj, type_, cbName); + }, + + GoOffline() + { + // 2.x + if (!isFirebase3x()) + { + window["Firebase"]["goOffline"](); + } + + // 3.x + else + { + window["Firebase"]["database"]()["goOffline"](); + } + }, + + GoOnline() + { + // 2.x + if (!isFirebase3x()) + { + window["Firebase"]["goOnline"](); + + } + + // 3.x + else + { + window["Firebase"]["database"]()["goOnline"](); + } + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/conditions.js new file mode 100755 index 0000000..65fd956 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/conditions.js @@ -0,0 +1,73 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase.Cnds = + { + + OnTransaction (cb) + { + return C3.equalsNoCase(cb, this.onTransaction.cb); + }, + + OnReading (cb) + { + return C3.equalsNoCase(cb, this.onReadCb); + }, + + OnComplete (cb) + { + return C3.equalsNoCase(cb, this.onCompleteCb); + }, + + OnError (cb) + { + return C3.equalsNoCase(cb, this.onCompleteCb); + }, + + LastDataIsNull () + { + var data =(this.snapshot === null)? null: this.snapshot["val"](); + return (data === null); + }, + + TransactionInIsNull () + { + var data =(this.onTransaction.input === null)? null: this.onTransaction.input; + return (data === null); + }, + + // cf_deprecated + IsTransactionAborted () { return false; }, + // cf_deprecated + + OnTransactionComplete (cb) + { + return C3.equalsNoCase(cb, this.onTransaction.completedCB); + }, + + OnTransactionError (cb) + { + return C3.equalsNoCase(cb, this.onTransaction.completedCB); + }, + + OnTransactionAbort (cb) + { + return C3.equalsNoCase(cb, this.onTransaction.completedCB); + }, + + OnConnected () + { + return true; + }, + + OnDisconnected () + { + return true; + }, + + IsConnected () + { + return this.isConnected; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/expressions.js new file mode 100755 index 0000000..066d2db --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/expressions.js @@ -0,0 +1,81 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase.Exps = + { + Domain() + { + return (this.rootpath); + }, + + TransactionIn(default_value) + { + return (window.FirebaseGetValueByKeyPath(this.onTransaction.input, null, default_value)); + }, + + LastData(default_value) + { + var data =(this.snapshot === null)? null: this.snapshot["val"](); + return (window.FirebaseGetValueByKeyPath(data, null, default_value)); + }, + + LastKey(default_value) + { + var key =(this.snapshot === null)? null: getKey(this.snapshot); + return (window.FirebaseGetValueByKeyPath(key, null, default_value)); + }, + + PrevChildName(default_value) + { + return (window.FirebaseGetValueByKeyPath(this.prevChildName, null, default_value)); + }, + + TransactionResult(default_value) + { + return (window.FirebaseGetValueByKeyPath(this.onTransaction.committedValue, null, default_value)); + }, + + LastPushRef() + { + return (this.lastPushRef); + }, + + GenerateKey() + { + var ref = this.getRef()["push"](); + this.exp_LastGeneratedKey = getKey(ref); + return (this.exp_LastGeneratedKey); + }, + + LastGeneratedKey() + { + return (this.exp_LastGeneratedKey); + }, + + ServerTimeOffset() + { + return (this.exp_ServerTimeOffset); + }, + + EstimatedTime() + { + return (new Date().getTime() + this.exp_ServerTimeOffset); + }, + + LastErrorCode() + { + var code; + if (this.error) + code = this.error["code"]; + return (code || ""); + }, + + LastErrorMessage() + { + var s; + if (this.error) + s = this.error["serverResponse"]; + return (s || ""); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/instance.js new file mode 100755 index 0000000..59d41ca --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/instance.js @@ -0,0 +1,166 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase.Instance = class Rex_FirebaseInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + + + // push + this.lastPushRef = ""; + // transaction + this.onTransaction = {}; + this.onTransaction.cb = null; + this.onTransaction.input = null; + this.onTransaction.output = null; + // transaction completed + this.onTransaction.completedCB = null; + this.onTransaction.committedValue = null; + // on complete + this.onCompleteCb = null; + this.error = null; + // reading + /* + if (!this.recycled) + this.callbackMap = new window.FirebaseCallbackMapKlass(); + else + this.callbackMap.Reset(); + */ + this.callbackMap = new window.FirebaseCallbackMapKlass(); + this.onReadCb = null; + this.snapshot = null; + this.prevChildName = null; + this.exp_LastGeneratedKey = ""; + this.exp_ServerTimeOffset = 0; + this.isConnected = false; + + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/"; + var self=this; + var setupFn = function () + { + if (properties[1] === 1) + self.connectionDetectingStart(); + + if (properties[2] === 1) + self.serverTimeOffsetDetectingStart(); + } + } + + + window.FirebaseAddAfterInitializeHandler(setupFn); + + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + getRef(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + } + addCallback(query, type_, cbName) + { + var eventType = EVENTTYPEMAP[type_]; + var self = this; + var reading_handler = function (snapshot, prevChildName) + { + self.onReadCb = cbName; + self.snapshot = snapshot; + self.prevChildName = prevChildName; + self.Trigger(C3.Plugins.Rex_Firebase.Cnds.OnReading, self); + self.onReadCb = null; + }; + + this.callbackMap.Add(query, eventType, cbName, reading_handler); + } + + addCallbackOnce(refObj, type_, cb) + { + var eventType = EVENTTYPEMAP[type_]; + + var self = this; + var reading_handler = function (snapshot, prevChildName) + { + self.onReadCb = cb; + self.snapshot = snapshot; + self.prevChildName = prevChildName; + self.Trigger(C3.Plugins.Rex_Firebase.Cnds.OnReading, self); + self.onReadCb = null; + }; + refObj["once"](eventType, reading_handler); + } + + connectionDetectingStart() + { + var self = this; + var onValueChanged = function (snap) + { + var trig; + var isConnected = !!snap["val"](); + if ( isConnected ) + trig = C3.Plugins.Rex_Firebase.Cnds.OnConnected; + else if (self.isConnected && !isConnected) // disconnected after connected + trig = C3.Plugins.Rex_Firebase.Cnds.OnDisconnected; + + self.isConnected = isConnected; + + self.Trigger(trig, self); + }; + + var p = getRoot(this.getRef()) + "/.info/connected"; + var ref = this.getRef(p); + ref.on("value", onValueChanged); + } + + serverTimeOffsetDetectingStart() + { + var self = this; + var onValueChanged = function (snap) + { + self.exp_ServerTimeOffset = snap["val"]() || 0; + }; + + var p = getRoot(this.getRef()) + "/.info/serverTimeOffset"; + var ref = this.getRef(p); + ref.on("value", onValueChanged); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/plugin.js new file mode 100755 index 0000000..ce66825 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/plugin.js @@ -0,0 +1,81 @@ +"use strict"; + var EVENTTYPEMAP = ["value", "child_added", "child_changed", "child_removed","child_moved"]; + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var getKey = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var getRefPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var getRoot = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var getTimestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + var getOnCompleteHandler = function (self, onCompleteCb) + { + if ((onCompleteCb === null) || (onCompleteCb === "")) + return; + + var handler = function(error) + { + self.onCompleteCb = onCompleteCb; + self.error = error; + var trig = (error)? C3.Plugins.Rex_Firebase.Cnds.OnError: + C3.Plugins.Rex_Firebase.Cnds.OnComplete; + self.Trigger(trig, self); + self.onCompleteCb = null; + }; + return handler; + }; + // query + var get_query = function (queryObjs) + { + if (queryObjs == null) + return null; + var query = queryObjs.GetFirstPicked(); + if (query == null) + return null; + + return query.GetSdkInstance().GetQuery();; + }; +{ + C3.Plugins.Rex_Firebase = class Rex_FirebasePlugin extends C3.SDKPluginBase + { + constructor(opts) + { + super(opts); + } + + Release() + { + super.Release(); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/type.js new file mode 100755 index 0000000..3c7ec5d --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/c3runtime/type.js @@ -0,0 +1,20 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase.Type = class Rex_FirebaseType extends C3.SDKTypeBase + { + constructor(objectClass) + { + super(objectClass); + } + + Release() + { + super.Release(); + } + + OnCreate() + { + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/icon.png new file mode 100755 index 0000000..1f6724e Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/instance.js new file mode 100755 index 0000000..0df6ef4 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase; + + PLUGIN_CLASS.Instance = class Rex_FirebaseInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/lang/en-US.json new file mode 100755 index 0000000..6af36cb --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/lang/en-US.json @@ -0,0 +1,449 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Firebase.", + "text": { + "plugins": { + "rex_firebase": { + "name": "Firebase", + "description": "Real time database-as-a-service. https://www.firebase.com/", + "help-url": "http://c2rexplugins.weebly.com/rex_firebase.html", + "properties": { + "domain": { + "name": "Domain", + "desc": "The root location of the Firebase data." + }, + "connection-detection": { + "name": "Connection detection", + "desc": "Enable connection detection.", + "items": { + "no":"No", + "yes":"Yes" + } + }, + "server-time-offset-detection": { + "name": "Server time offset detection", + "desc": "Enable server time offset detection.", + "items": { + "no":"No", + "yes":"Yes" + } + } + }, + "aceCategories": { + "domain": "Domain", + "send_-_set": "Send - Set", + "send_-_update_json": "Send - Update JSON", + "send_-_push": "Send - Push", + "send_-_transaction": "Send - Transaction", + "send_-_remove": "Send - Remove", + "receive_-_add": "Receive - Add", + "receive_-_remove": "Receive - Remove", + "receive_-_add_once": "Receive - Add once", + "on_disconnect": "On disconnect", + "query": "Query", + "online": "Online", + "transaction": "Transaction", + "receive": "Receive", + "send": "Send", + "transaction_-_completed": "Transaction - completed", + "connection": "Connection", + "push": "Push", + "ıtemıd": "ItemID", + "server_time_offset": "Server time offset", + "error": "Error" + }, + "conditions": { + "ontransaction1": { + "list-name": "On transaction", + "display-text": "On transaction [b]{0}[/b]", + "description": "Triggered by calling \"action: Transaction\", to get return value.", + "params": { + "callback_function0": { "name":"Callback function", "desc":"Callback function."} + } + }, + "onreading2": { + "list-name": "On received", + "display-text": "On received [b]{0}[/b]", + "description": "Triggered when registered received event received.", + "params": { + "callback_function0": { "name":"Callback function", "desc":"Callback function."} + } + }, + "oncomplete3": { + "list-name": "On complete", + "display-text": "On complete [b]{0}[/b]", + "description": "Triggered after any sending action success.", + "params": { + "callback_function0": { "name":"Callback function", "desc":"Callback function."} + } + }, + "onerror4": { + "list-name": "On error", + "display-text": "On error [b]{0}[/b]", + "description": "Triggered after any sending action error.", + "params": { + "callback_function0": { "name":"Callback function", "desc":"Callback function."} + } + }, + "lastdataısnull5": { + "list-name": "LastData is null", + "display-text": "LastData is null", + "description": "Return true if LastData is null." + }, + "transactionınısnull6": { + "list-name": "TransactionIn is null", + "display-text": "TransactionIn is null", + "description": "Return true if TransactionIn is null." + }, + "ıstransactionaborted7": { + "list-name": "TransactionIn aborted", + "display-text": "Transaction is aborted", + "description": "Return true if the last transaction is aborted." + }, + "ontransactioncomplete8": { + "list-name": "On complete", + "display-text": "On transaction complete [b]{0}[/b]", + "description": "Triggered when transaction success.", + "params": { + "callback_function0": { "name":"Callback function", "desc":"Callback function."} + } + }, + "ontransactionerror9": { + "list-name": "On error", + "display-text": "On transaction error [b]{0}[/b]", + "description": "Triggered when transaction error.", + "params": { + "callback_function0": { "name":"Callback function", "desc":"Callback function."} + } + }, + "ontransactionabort10": { + "list-name": "On aborted", + "display-text": "On transaction aborted [b]{0}[/b]", + "description": "Triggered when transaction aborted.", + "params": { + "callback_function0": { "name":"Callback function", "desc":"Callback function."} + } + }, + "onconnected11": { + "list-name": "On connected", + "display-text": "On connected", + "description": "Triggered while connecting start." + }, + "ondisconnected12": { + "list-name": "On disconnected", + "display-text": "On disconnected", + "description": "Triggered while disconnected." + }, + "ısconnected13": { + "list-name": "Is connected", + "display-text": "Is connected", + "description": "Return true if connected to firebase server." + } + }, + "actions": { + "setdomainref0": { + "list-name": "Set domain", + "display-text": "Set domain ref to [i]{0}[/i]", + "description": "Set domain ref.", + "params": { + "domain0": { "name":"Domain", "desc":"The Firebase data ref URL"} + } + }, + "setvalue1": { + "list-name": "Set value", + "display-text": "Set [i]{1}[/i] at [i]{0}[/i], on complete callback to [i]{2}[/i]", + "description": "Sets value at data ref.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "value1": { "name":"Value", "desc":"The value to set"}, + "on_complete2": { "name":"On complete", "desc":"On complete callback, ignored if enter an empty string \"\"."} + } + }, + "setjson2": { + "list-name": "Set JSON", + "display-text": "Set JSON [i]{1}[/i] at [i]{0}[/i], on complete callback to [i]{2}[/i]", + "description": "Sets JSON value at data ref.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "json_value1": { "name":"JSON value", "desc":"JSON value to set"}, + "on_complete2": { "name":"On complete", "desc":"On complete callback, ignored if enter an empty string \"\"."} + } + }, + "updatejson3": { + "list-name": "Update JSON", + "display-text": "Update JSON [i]{1}[/i] at [i]{0}[/i], on complete callback to [i]{2}[/i]", + "description": "Updates JSON values at the data ref.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "json_value1": { "name":"JSON value", "desc":"JSON value to set"}, + "on_complete2": { "name":"On complete", "desc":"On complete callback, ignored if enter an empty string \"\"."} + } + }, + "pushvalue4": { + "list-name": "Push value", + "display-text": "Push [i]{1}[/i] at [i]{0}[/i], on complete callback to [i]{2}[/i]", + "description": "Push value at data ref.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "value1": { "name":"Value", "desc":"The value to set"}, + "on_complete2": { "name":"On complete", "desc":"On complete callback, ignored if enter an empty string \"\"."} + } + }, + "pushjson5": { + "list-name": "Push JSON", + "display-text": "Push JSON [i]{1}[/i] at [i]{0}[/i], on complete callback to [i]{2}[/i]", + "description": "Push JSON value at data ref.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "json_value1": { "name":"JSON value", "desc":"JSON value to set"}, + "on_complete2": { "name":"On complete", "desc":"On complete callback, ignored if enter an empty string \"\"."} + } + }, + "transaction6": { + "list-name": "Transaction", + "display-text": "Transaction with callback: [i]{1}[/i] at [i]{0}[/i], on complete callback to [i]{2}[/i]", + "description": "Transaction value with callback.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "on_transaction1": { "name":"On transaction", "desc":"On transaction function."}, + "on_complete2": { "name":"On complete", "desc":"On complete callback, ignored if enter an empty string \"\"."} + } + }, + "returntransactionvalue7": { + "list-name": "Set value", + "display-text": "Set transaction value to [i]{0}[/i]", + "description": "Returns transaction value.", + "params": { + "value0": { "name":"Value", "desc":"The value to set"} + } + }, + "returntransactionjson8": { + "list-name": "Set JSON", + "display-text": "Set transaction JSON to [i]{0}[/i]", + "description": "Returns transaction JSON.", + "params": { + "json_value0": { "name":"JSON value", "desc":"JSON value to set"} + } + }, + "remove9": { + "list-name": "Remove", + "display-text": "Remove all values at [i]{0}[/i], on complete callback to [i]{1}[/i]", + "description": "Remove all values at data ref.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "on_complete1": { "name":"On complete", "desc":"On complete callback, ignored if enter an empty string \"\"."} + } + }, + "setbooleanvalue10": { + "list-name": "Set boolean value", + "display-text": "Set [i]{1}[/i] at [i]{0}[/i], on complete callback to [i]{2}[/i]", + "description": "Sets boolean value at data ref.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "boolean3": { "name":"Boolean", "desc":"Boolean value.", "items":{"false":"False","true":"True"}}, + "on_complete4": { "name":"On complete", "desc":"On complete callback, ignored if enter an empty string \"\"."} + } + }, + "pushbooleanvalue11": { + "list-name": "Push boolean value", + "display-text": "Push [i]{1}[/i] at [i]{0}[/i], on complete callback to [i]{2}[/i]", + "description": "Push boolean value at data ref.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "boolean3": { "name":"Boolean", "desc":"Boolean value.", "items":{"false":"False","true":"True"}}, + "on_complete4": { "name":"On complete", "desc":"On complete callback, ignored if enter an empty string \"\"."} + } + }, + "setservertimestamp12": { + "list-name": "Set server timestamp", + "display-text": "Set server timestamp at [i]{0}[/i], on complete callback to [i]{1}[/i]", + "description": "Sets server timestamp at data ref.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "on_complete1": { "name":"On complete", "desc":"On complete callback, ignored if enter an empty string \"\"."} + } + }, + "pushservertimestamp13": { + "list-name": "Push server timestamp", + "display-text": "Push server timestamp at [i]{0}[/i], on complete callback to [i]{1}[/i]", + "description": "Push server timestamp at data ref.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "on_complete1": { "name":"On complete", "desc":"On complete callback, ignored if enter an empty string \"\"."} + } + }, + "addreadingcallback21": { + "list-name": "Add callback", + "display-text": "Add received callback: [i]{2}[/i] for ref [i]{0}[/i] ([i]{1}[/i])", + "description": "Add received callback.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "type6": { "name":"Type", "desc":"Event type", "items":{"value changed":"Value changed","child added":"Child added","child changed":"Child changed","child removed":"Child removed","child moved":"Child moved"}}, + "callback_function7": { "name":"Callback function", "desc":"Callback function."} + } + }, + "removereadingcallback22": { + "list-name": "Remove callback", + "display-text": "Remove received callback: [i]{2}[/i] for ref [i]{0}[/i] ([i]{1}[/i])", + "description": "Remove received callback.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "type6": { "name":"Type", "desc":"Event type", "items":{"value changed":"Value changed","child added":"Child added","child changed":"Child changed","child removed":"Child removed","child moved":"Child moved"}}, + "callback_function7": { "name":"Callback function", "desc":"Callback function."} + } + }, + "removereadingcallback23": { + "list-name": "Remove callback by type", + "display-text": "Remove all received callbacks for ref [i]{0}[/i] ([i]{1}[/i])", + "description": "Remove all received callbacks by type.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "type6": { "name":"Type", "desc":"Event type", "items":{"value changed":"Value changed","child added":"Child added","child changed":"Child changed","child removed":"Child removed","child moved":"Child moved"}} + } + }, + "removereadingcallback24": { + "list-name": "Remove all callbacks at ref", + "display-text": "Remove all received callbacks for ref [i]{0}[/i]", + "description": "Remove all received callbacks at ref.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"} + } + }, + "addreadingcallbackonce25": { + "list-name": "Add once", + "display-text": "Add received callback: [i]{2}[/i] once for ref [i]{0}[/i] ([i]{1}[/i])", + "description": "Add received callback once.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "type6": { "name":"Type", "desc":"Event type", "items":{"value changed":"Value changed","child added":"Child added","child changed":"Child changed","child removed":"Child removed","child moved":"Child moved"}}, + "callback_function7": { "name":"Callback function", "desc":"Callback function."} + } + }, + "removerefondisconnect31": { + "list-name": "Remove", + "display-text": "Remove all values at [i]{0}[/i] when disconnected", + "description": "Remove all values at data ref when disconnected. Uses under \"condition: On received\".", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"} + } + }, + "setvalueondisconnect32": { + "list-name": "Set value", + "display-text": "Set [i]{1}[/i] at [i]{0}[/i] when disconnected", + "description": "Sets value at data ref when disconnected. Uses under \"condition: On received\".", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "value1": { "name":"Value", "desc":"The value to set"} + } + }, + "updatejsonondisconnect33": { + "list-name": "Update JSON", + "display-text": "Update JSON [i]{1}[/i] at [i]{0}[/i] when disconnected", + "description": "Updates JSON values at the data ref when disconnected. Uses under \"condition: On received\".", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"}, + "json_value1": { "name":"JSON value", "desc":"JSON value to set"} + } + }, + "removereadingcallback34": { + "list-name": "Remove all callbacks", + "display-text": "Remove all registered received callbacks", + "description": "Remove all registered received callbacks." + }, + "cancelondisconnect35": { + "list-name": "Cancel", + "display-text": "Cancel disconnected writing at [i]{0}[/i]", + "description": "Cancel disconnected writing.", + "params": { + "dataref0": { "name":"DataRef", "desc":"The Firebase data ref URL"} + } + }, + "addquerycallback51": { + "list-name": "Add callback", + "display-text": "Add received callback: [i]{2}[/i] for query [i]{0}[/i] ([i]{1}[/i])", + "description": "Add received callback.", + "params": { + "query0": { "name":"Query", "desc":"Query object."}, + "type6": { "name":"Type", "desc":"Event type", "items":{"value changed":"Value changed","child added":"Child added","child changed":"Child changed","child removed":"Child removed","child moved":"Child moved"}}, + "callback_function7": { "name":"Callback function", "desc":"Callback function."} + } + }, + "addquerycallbackonce52": { + "list-name": "Add callback once", + "display-text": "Add received callback: [i]{2}[/i] once for query [i]{0}[/i] ([i]{1}[/i])", + "description": "Add received callback once.", + "params": { + "query0": { "name":"Query", "desc":"Query object."}, + "type6": { "name":"Type", "desc":"Event type", "items":{"value changed":"Value changed","child added":"Child added","child changed":"Child changed","child removed":"Child removed","child moved":"Child moved"}}, + "callback_function7": { "name":"Callback function", "desc":"Callback function."} + } + }, + "gooffline61": { + "list-name": "Go offline", + "display-text": "Go offline", + "description": "Manually disconnect the Firebase client from the server and disable automatic reconnection. ." + }, + "goonline62": { + "list-name": "Go online", + "display-text": "Go online", + "description": "Manually reestablish a connection to the Firebase server and enable automatic reconnection. . ." + } + }, + "expressions": { + "domain0": { + "description": "Get root location reference.", + "translated-name": "Domain" + }, + "transactionın1": { + "description": "Transaction input parameter, using under \"condition:On transaction\", JSON will be stringified. Add default value at 1st parameter if read data is null.", + "translated-name": "TransactionIn" + }, + "lastdata2": { + "description": "Received data, using under \"condition:On received\". JSON will be stringified. Add default value at 1st parameter if read data is null.", + "translated-name": "LastData" + }, + "lastkey3": { + "description": "Key of received data, using under \"condition:On received\"", + "translated-name": "LastKey" + }, + "prevchildname4": { + "description": "Previous child name, using under \"condition:On received\" with one of \"Child added\", \"Child changed\", \"Child moved\" type. Add default value at 1st parameter if read data is null.", + "translated-name": "PrevChildName" + }, + "transactionresult5": { + "description": "Transaction wrote result, using under \"condition:On completed\", JSON will be stringified. Add default value at 1st parameter if read data is null.", + "translated-name": "TransactionResult" + }, + "lastpushref11": { + "description": "Data reference at last push.", + "translated-name": "LastPushRef" + }, + "generatekey21": { + "description": "Generate new key from push action.", + "translated-name": "GenerateKey" + }, + "lastgeneratedkey22": { + "description": "Get last generate a key from push action.", + "translated-name": "LastGeneratedKey" + }, + "servertimeoffset31": { + "description": "Get current server time offset.", + "translated-name": "ServerTimeOffset" + }, + "estimatedtime32": { + "description": "Get estimated time from curent time + current server time offset.", + "translated-name": "EstimatedTime" + }, + "lasterrorcode101": { + "description": "Error code.", + "translated-name": "LastErrorCode" + }, + "lasterrormessage102": { + "description": "Error message (error.serverResponse) .", + "translated-name": "LastErrorMessage" + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/plugin.js new file mode 100755 index 0000000..179d380 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/plugin.js @@ -0,0 +1,43 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase"; + const PLUGIN_VERSION = "1.3.1.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase = class Rex_Firebase extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "domain", ""), + new SDK.PluginProperty("combo", "connection-detection", {initialValue:"yes", items:["no","yes"]}), + new SDK.PluginProperty("combo", "server-time-offset-detection", {initialValue:"yes", items:["no","yes"]}) + ]); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/type.js new file mode 100755 index 0000000..c548c76 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase; + + PLUGIN_CLASS.Type = class Rex_FirebaseType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/dist/rex_firebase_api.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/dist/rex_firebase_api.c3addon new file mode 100644 index 0000000..2c3eed3 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/dist/rex_firebase_api.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/source/aces.json new file mode 100755 index 0000000..5ccf10f --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/source/aces.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/source/addon.json new file mode 100755 index 0000000..9851851 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/source/addon.json @@ -0,0 +1,27 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Firebase API", + "id": "Rex_FirebaseAPI", + "version": "2.4.2.0", + "author": "Rex.Rainbow", + "website": "http://c2rexplugins.weebly.com/rex_firebaseapi.html", + "documentation": "http://c2rexplugins.weebly.com/rex_firebaseapi.html", + "description": "API of real time database-as-a-service. https://www.firebase.com/", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "firebase.js", + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/source/c2runtime/runtime.js new file mode 100755 index 0000000..17447d8 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_api/source/c2runtime/runtime.js @@ -0,0 +1,680 @@ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_FirebaseAPI = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_FirebaseAPI.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + window["Firebase"]["enableLogging"](this.properties[0] == 1); + runAfterInitializeHandlers(); + }; + + instanceProto.onDestroy = function () + { + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + var get_ref = function(path) + { + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + return get_ref(path); + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + ////////////////////////////////////// + // Conditions + function Cnds() {}; + pluginProto.cnds = new Cnds(); + + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + // -------------------------------------------------------------------------- + // -------------------------------------------------------------------------- + // -------------------------------------------------------------------------- + var __afterInitialHandler = []; + var addAfterInitialHandler = function(callback) + { + if (__afterInitialHandler === null) + callback() + else + __afterInitialHandler.push(callback); + }; + var runAfterInitializeHandlers = function() + { + var i, cnt=__afterInitialHandler.length; + for(i=0; i this.items.length - 1)) + end = this.items.length - 1; + + var current_frame = runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var i; + for(i=start; i<=end; i++) + { + if (solModifierAfterCnds) + { + runtime.pushCopySol(current_event.solModifiers); + } + + if (this.onGetIterItem) + this.onGetIterItem(this.items[i], i); + current_event.retrigger(); + + if (solModifierAfterCnds) + { + runtime.popSol(current_event.solModifiers); + } + } + + return false; + }; + // export + // -------------------------------------------------------------------------- + + // -------------------------------------------------------------------------- + // internal + ItemListKlassProto.add_item = function(snapshot, prevName, force_push) + { + var item; + if (this.snapshot2Item) + item = this.snapshot2Item(snapshot); + else + { + var k = get_key(snapshot); + item = snapshot["val"](); + item[this.keyItemID] = k; + } + + if (force_push === true) + { + this.items.push(item); + return; + } + + if (prevName == null) + { + this.items.unshift(item); + } + else + { + var i = this.itemID2Index[prevName]; + if (i == this.items.length-1) + this.items.push(item); + else + this.items.splice(i+1, 0, item); + } + + return item; + }; + + ItemListKlassProto.remove_item = function(snapshot) + { + var k = get_key(snapshot); + var i = this.itemID2Index[k]; + var item = this.items[i]; + cr.arrayRemove(this.items, i); + return item; + }; + + ItemListKlassProto.update_itemID2Index = function() + { + clean_table(this.itemID2Index); + var i,cnt = this.items.length; + for (i=0; i this.items.length - 1)) + end = this.items.length - 1; + + var current_frame = runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = runtime.GetEventSheetManager().GetEventStack(); + var p = runtime.GetEventStack(); + var h = c.Push(current_event); + + var i; + for(i=start; i<=end; i++) + { + if (solModifierAfterCnds) + { + runtime.GetEventSheetManager().PushCopySol(solmod); + } + + if (this.onGetIterItem) + this.onGetIterItem(this.items[i], i); + current_event.Retrigger(current_frame,h); + + if (solModifierAfterCnds) + { + runtime.GetEventSheetManager().PopSol(solmod); + + } + } + p.Pop(); + + return false; + }; + // export + // -------------------------------------------------------------------------- + + // -------------------------------------------------------------------------- + // internal + ItemListKlassProto.add_item = function(snapshot, prevName, force_push) + { + var item; + if (this.snapshot2Item) + item = this.snapshot2Item(snapshot); + else + { + var k = get_key(snapshot); + item = snapshot["val"](); + item[this.keyItemID] = k; + } + + if (force_push === true) + { + this.items.push(item); + return; + } + + if (prevName == null) + { + this.items.unshift(item); + } + else + { + var i = this.itemID2Index[prevName]; + if (i == this.items.length-1) + this.items.push(item); + else + this.items.splice(i+1, 0, item); + } + + return item; + }; + + ItemListKlassProto.remove_item = function(snapshot) + { + var k = get_key(snapshot); + var i = this.itemID2Index[k]; + var item = this.items[i]; + C3.arrayRemove(this.items, i); + return item; + }; + + ItemListKlassProto.update_itemID2Index = function() + { + clean_table(this.itemID2Index); + var i,cnt = this.items.length; + for (i=0; ib?e+="000":256>b?e+="00":4096>b&&(e+="0");return Da[a]=e+b.toString(16)}),'"')};function Fa(){return Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^ja()).toString(36)};var w;a:{var Ga=n.navigator;if(Ga){var Ha=Ga.userAgent;if(Ha){w=Ha;break a}}w=""};function Ia(){this.Ya=-1};function Ja(){this.Ya=-1;this.Ya=64;this.P=[];this.pe=[];this.eg=[];this.Od=[];this.Od[0]=128;for(var a=1;ae;e++)d[e]=b.charCodeAt(c)<<24|b.charCodeAt(c+1)<<16|b.charCodeAt(c+2)<<8|b.charCodeAt(c+3),c+=4;else for(e=0;16>e;e++)d[e]=b[c]<<24|b[c+1]<<16|b[c+2]<<8|b[c+3],c+=4;for(e=16;80>e;e++){var f=d[e-3]^d[e-8]^d[e-14]^d[e-16];d[e]=(f<<1|f>>>31)&4294967295}b=a.P[0];c=a.P[1];for(var g=a.P[2],k=a.P[3],m=a.P[4],l,e=0;80>e;e++)40>e?20>e?(f=k^c&(g^k),l=1518500249):(f=c^g^k,l=1859775393):60>e?(f=c&g|k&(c|g),l=2400959708):(f=c^g^k,l=3395469782),f=(b<< +5|b>>>27)+f+m+l+d[e]&4294967295,m=k,k=g,g=(c<<30|c>>>2)&4294967295,c=b,b=f;a.P[0]=a.P[0]+b&4294967295;a.P[1]=a.P[1]+c&4294967295;a.P[2]=a.P[2]+g&4294967295;a.P[3]=a.P[3]+k&4294967295;a.P[4]=a.P[4]+m&4294967295} +Ja.prototype.update=function(a,b){if(null!=a){p(b)||(b=a.length);for(var c=b-this.Ya,d=0,e=this.pe,f=this.ec;dc?Math.max(0,a.length+c):c;if(q(a))return q(b)&&1==b.length?a.indexOf(b,c):-1;for(;cc?null:q(a)?a.charAt(c):a[c]}function Sa(a,b,c){for(var d=a.length,e=q(a)?a.split(""):a,f=0;f=arguments.length?x.slice.call(a,b):x.slice.call(a,b,c)} +function Va(a,b){a.sort(b||Wa)}function Wa(a,b){return a>b?1:aparseFloat(a))?String(b):a})();var kb=null,lb=null,mb=null;function nb(a,b){if(!ea(a))throw Error("encodeByteArray takes an array as a parameter");ob();for(var c=b?lb:kb,d=[],e=0;e>2,f=(f&3)<<4|k>>4,k=(k&15)<<2|l>>6,l=l&63;m||(l=64,g||(k=64));d.push(c[t],c[f],c[k],c[l])}return d.join("")} +function ob(){if(!kb){kb={};lb={};mb={};for(var a=0;65>a;a++)kb[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a),lb[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.".charAt(a),mb[lb[a]]=a,62<=a&&(mb["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a)]=a)}};function pb(a,b){this.N=qb;this.Rf=void 0;this.Ba=this.Ha=null;this.yd=this.ye=!1;if(a==rb)sb(this,tb,b);else try{var c=this;a.call(b,function(a){sb(c,tb,a)},function(a){if(!(a instanceof ub))try{if(a instanceof Error)throw a;throw Error("Promise rejected.");}catch(b){}sb(c,vb,a)})}catch(d){sb(this,vb,d)}}var qb=0,tb=2,vb=3;function rb(){}pb.prototype.then=function(a,b,c){return wb(this,r(a)?a:null,r(b)?b:null,c)};pb.prototype.then=pb.prototype.then;pb.prototype.$goog_Thenable=!0;h=pb.prototype; +h.gh=function(a,b){return wb(this,null,a,b)};h.cancel=function(a){this.N==qb&&$a(function(){var b=new ub(a);xb(this,b)},this)};function xb(a,b){if(a.N==qb)if(a.Ha){var c=a.Ha;if(c.Ba){for(var d=0,e=-1,f=0,g;g=c.Ba[f];f++)if(g=g.o)if(d++,g==a&&(e=f),0<=e&&1=e&&(e-=55296,d++,Kb(de?b[c++]=e:(2048>e?b[c++]=e>>6|192:(65536>e?b[c++]=e>>12|224:(b[c++]=e>>18|240,b[c++]=e>>12&63|128),b[c++]=e>>6&63|128),b[c++]=e&63|128)}return b}function Pb(a){for(var b=0,c=0;cd?b++:2048>d?b+=2:55296<=d&&56319>=d?(b+=4,c++):b+=3}return b};function D(a,b,c,d){var e;dc&&(e=0===c?"none":"no more than "+c);if(e)throw Error(a+" failed: Was called with "+d+(1===d?" argument.":" arguments.")+" Expects "+e+".");}function E(a,b,c){var d="";switch(b){case 1:d=c?"first":"First";break;case 2:d=c?"second":"Second";break;case 3:d=c?"third":"Third";break;case 4:d=c?"fourth":"Fourth";break;default:throw Error("errorPrefix called with argumentNumber > 4. Need to update it?");}return a=a+" failed: "+(d+" argument ")} +function F(a,b,c,d){if((!d||p(c))&&!r(c))throw Error(E(a,b,d)+"must be a valid function.");}function Qb(a,b,c){if(p(c)&&(!ga(c)||null===c))throw Error(E(a,b,!0)+"must be a valid context object.");};function Rb(a){return"undefined"!==typeof JSON&&p(JSON.parse)?JSON.parse(a):za(a)}function G(a){if("undefined"!==typeof JSON&&p(JSON.stringify))a=JSON.stringify(a);else{var b=[];Ba(new Aa,a,b);a=b.join("")}return a};function Sb(){this.Zd=H}Sb.prototype.j=function(a){return this.Zd.S(a)};Sb.prototype.toString=function(){return this.Zd.toString()};function Tb(){}Tb.prototype.uf=function(){return null};Tb.prototype.Ce=function(){return null};var Ub=new Tb;function Vb(a,b,c){this.bg=a;this.Oa=b;this.Nd=c}Vb.prototype.uf=function(a){var b=this.Oa.Q;if(Wb(b,a))return b.j().T(a);b=null!=this.Nd?new Xb(this.Nd,!0,!1):this.Oa.w();return this.bg.Bc(a,b)};Vb.prototype.Ce=function(a,b,c){var d=null!=this.Nd?this.Nd:Yb(this.Oa);a=this.bg.qe(d,b,1,c,a);return 0===a.length?null:a[0]};function Zb(){this.xb=[]}function $b(a,b){for(var c=null,d=0;db?c=c.left:0c?d=d.left:0e)a=this.Je?a.left:a.right;else if(0===e){this.Ta.push(a);break}else this.Ta.push(a),a=this.Je?a.right:a.left} +function Ic(a){if(0===a.Ta.length)return null;var b=a.Ta.pop(),c;c=a.Xd?a.Xd(b.key,b.value):{key:b.key,value:b.value};if(a.Je)for(b=b.left;!b.e();)a.Ta.push(b),b=b.right;else for(b=b.right;!b.e();)a.Ta.push(b),b=b.left;return c}function Jc(a){if(0===a.Ta.length)return null;var b;b=a.Ta;b=b[b.length-1];return a.Xd?a.Xd(b.key,b.value):{key:b.key,value:b.value}}function Kc(a,b,c,d,e){this.key=a;this.value=b;this.color=null!=c?c:!0;this.left=null!=d?d:Fc;this.right=null!=e?e:Fc}h=Kc.prototype; +h.$=function(a,b,c,d,e){return new Kc(null!=a?a:this.key,null!=b?b:this.value,null!=c?c:this.color,null!=d?d:this.left,null!=e?e:this.right)};h.count=function(){return this.left.count()+1+this.right.count()};h.e=function(){return!1};h.ka=function(a){return this.left.ka(a)||a(this.key,this.value)||this.right.ka(a)};function Lc(a){return a.left.e()?a:Lc(a.left)}h.Vc=function(){return Lc(this).key};h.jc=function(){return this.right.e()?this.key:this.right.jc()}; +h.Sa=function(a,b,c){var d,e;e=this;d=c(a,e.key);e=0>d?e.$(null,null,null,e.left.Sa(a,b,c),null):0===d?e.$(null,b,null,null,null):e.$(null,null,null,null,e.right.Sa(a,b,c));return Mc(e)};function Nc(a){if(a.left.e())return Fc;a.left.ha()||a.left.left.ha()||(a=Oc(a));a=a.$(null,null,null,Nc(a.left),null);return Mc(a)} +h.remove=function(a,b){var c,d;c=this;if(0>b(a,c.key))c.left.e()||c.left.ha()||c.left.left.ha()||(c=Oc(c)),c=c.$(null,null,null,c.left.remove(a,b),null);else{c.left.ha()&&(c=Pc(c));c.right.e()||c.right.ha()||c.right.left.ha()||(c=Qc(c),c.left.left.ha()&&(c=Pc(c),c=Qc(c)));if(0===b(a,c.key)){if(c.right.e())return Fc;d=Lc(c.right);c=c.$(d.key,d.value,null,null,Nc(c.right))}c=c.$(null,null,null,null,c.right.remove(a,b))}return Mc(c)};h.ha=function(){return this.color}; +function Mc(a){a.right.ha()&&!a.left.ha()&&(a=Rc(a));a.left.ha()&&a.left.left.ha()&&(a=Pc(a));a.left.ha()&&a.right.ha()&&(a=Qc(a));return a}function Oc(a){a=Qc(a);a.right.left.ha()&&(a=a.$(null,null,null,null,Pc(a.right)),a=Rc(a),a=Qc(a));return a}function Rc(a){return a.right.$(null,null,a.color,a.$(null,null,!0,null,a.right.left),null)}function Pc(a){return a.left.$(null,null,a.color,null,a.$(null,null,!0,a.left.right,null))} +function Qc(a){return a.$(null,null,!a.color,a.left.$(null,null,!a.left.color,null,null),a.right.$(null,null,!a.right.color,null,null))}function Sc(){}h=Sc.prototype;h.$=function(){return this};h.Sa=function(a,b){return new Kc(a,b,null)};h.remove=function(){return this};h.count=function(){return 0};h.e=function(){return!0};h.ka=function(){return!1};h.Vc=function(){return null};h.jc=function(){return null};h.ha=function(){return!1};var Fc=new Sc;function Tc(a,b){return a&&"object"===typeof a?(O(".sv"in a,"Unexpected leaf node or priority contents"),b[a[".sv"]]):a}function Uc(a,b){var c=new Vc;Wc(a,new P(""),function(a,e){c.rc(a,Xc(e,b))});return c}function Xc(a,b){var c=a.C().J(),c=Tc(c,b),d;if(a.L()){var e=Tc(a.Ea(),b);return e!==a.Ea()||c!==a.C().J()?new Yc(e,Q(c)):a}d=a;c!==a.C().J()&&(d=d.ia(new Yc(c)));a.R(R,function(a,c){var e=Xc(c,b);e!==c&&(d=d.W(a,e))});return d};function Zc(){this.Ac={}}Zc.prototype.set=function(a,b){null==b?delete this.Ac[a]:this.Ac[a]=b};Zc.prototype.get=function(a){return y(this.Ac,a)?this.Ac[a]:null};Zc.prototype.remove=function(a){delete this.Ac[a]};Zc.prototype.Af=!0;function $c(a){this.Ic=a;this.Sd="firebase:"}h=$c.prototype;h.set=function(a,b){null==b?this.Ic.removeItem(this.Sd+a):this.Ic.setItem(this.Sd+a,G(b))};h.get=function(a){a=this.Ic.getItem(this.Sd+a);return null==a?null:Rb(a)};h.remove=function(a){this.Ic.removeItem(this.Sd+a)};h.Af=!1;h.toString=function(){return this.Ic.toString()};function ad(a){try{if("undefined"!==typeof window&&"undefined"!==typeof window[a]){var b=window[a];b.setItem("firebase:sentinel","cache");b.removeItem("firebase:sentinel");return new $c(b)}}catch(c){}return new Zc}var bd=ad("localStorage"),cd=ad("sessionStorage");function dd(a,b,c,d,e){this.host=a.toLowerCase();this.domain=this.host.substr(this.host.indexOf(".")+1);this.ob=b;this.lc=c;this.jh=d;this.Rd=e||"";this.ab=bd.get("host:"+a)||this.host}function ed(a,b){b!==a.ab&&(a.ab=b,"s-"===a.ab.substr(0,2)&&bd.set("host:"+a.host,a.ab))} +function fd(a,b,c){O("string"===typeof b,"typeof type must == string");O("object"===typeof c,"typeof params must == object");if(b===gd)b=(a.ob?"wss://":"ws://")+a.ab+"/.ws?";else if(b===hd)b=(a.ob?"https://":"http://")+a.ab+"/.lp?";else throw Error("Unknown connection type: "+b);a.host!==a.ab&&(c.ns=a.lc);var d=[];v(c,function(a,b){d.push(b+"="+a)});return b+d.join("&")}dd.prototype.toString=function(){var a=(this.ob?"https://":"http://")+this.host;this.Rd&&(a+="<"+this.Rd+">");return a};var id=function(){var a=1;return function(){return a++}}(),O=Kb,jd=Lb; +function kd(a){try{var b;if("undefined"!==typeof atob)b=atob(a);else{ob();for(var c=mb,d=[],e=0;e>4);64!=k&&(d.push(g<<4&240|k>>2),64!=m&&d.push(k<<6&192|m))}if(8192>d.length)b=String.fromCharCode.apply(null,d);else{a="";for(c=0;ca.ec?a.update(a.Od,56-a.ec):a.update(a.Od,a.Ya-(a.ec-56));for(var d=a.Ya-1;56<=d;d--)a.pe[d]=c&255,c/=256;Ka(a,a.pe);for(d=c=0;5>d;d++)for(var e=24;0<=e;e-=8)b[c]=a.P[d]>>e&255,++c;return nb(b)} +function md(a){for(var b="",c=0;ca?c.push(a.substring(d,a.length)):c.push(a.substring(d,d+b));return c}function zd(a,b){if(da(a))for(var c=0;ca,a=Math.abs(a),a>=Math.pow(2,-1022)?(d=Math.min(Math.floor(Math.log(a)/Math.LN2),1023),c=d+1023,d=Math.round(a*Math.pow(2,52-d)-Math.pow(2,52))):(c=0,d=Math.round(a/Math.pow(2,-1074))));e=[];for(a=52;a;--a)e.push(d%2?1:0),d=Math.floor(d/2);for(a=11;a;--a)e.push(c%2?1:0),c=Math.floor(c/2);e.push(b?1:0);e.reverse();b=e.join("");c="";for(a=0;64>a;a+=8)d=parseInt(b.substr(a,8),2).toString(16),1===d.length&& +(d="0"+d),c+=d;return c.toLowerCase()}var Bd=/^-?\d{1,10}$/;function vd(a){return Bd.test(a)&&(a=Number(a),-2147483648<=a&&2147483647>=a)?a:null}function gc(a){try{a()}catch(b){setTimeout(function(){S("Exception was thrown by user callback.",b.stack||"");throw b;},Math.floor(0))}}function T(a,b){if(r(a)){var c=Array.prototype.slice.call(arguments,1).slice();gc(function(){a.apply(null,c)})}};function Cd(a){var b={},c={},d={},e="";try{var f=a.split("."),b=Rb(kd(f[0])||""),c=Rb(kd(f[1])||""),e=f[2],d=c.d||{};delete c.d}catch(g){}return{mh:b,Ec:c,data:d,bh:e}}function Dd(a){a=Cd(a).Ec;return"object"===typeof a&&a.hasOwnProperty("iat")?z(a,"iat"):null}function Ed(a){a=Cd(a);var b=a.Ec;return!!a.bh&&!!b&&"object"===typeof b&&b.hasOwnProperty("iat")};function Fd(a){this.Y=a;this.g=a.n.g}function Gd(a,b,c,d){var e=[],f=[];Ma(b,function(b){"child_changed"===b.type&&a.g.Dd(b.Oe,b.Na)&&f.push(new J("child_moved",b.Na,b.Za))});Hd(a,e,"child_removed",b,d,c);Hd(a,e,"child_added",b,d,c);Hd(a,e,"child_moved",f,d,c);Hd(a,e,"child_changed",b,d,c);Hd(a,e,ic,b,d,c);return e}function Hd(a,b,c,d,e,f){d=Na(d,function(a){return a.type===c});Va(d,u(a.qg,a));Ma(d,function(c){var d=Id(a,c,f);Ma(e,function(e){e.Qf(c.type)&&b.push(e.createEvent(d,a.Y))})})} +function Id(a,b,c){"value"!==b.type&&"child_removed"!==b.type&&(b.Td=c.wf(b.Za,b.Na,a.g));return b}Fd.prototype.qg=function(a,b){if(null==a.Za||null==b.Za)throw jd("Should only compare child_ events.");return this.g.compare(new L(a.Za,a.Na),new L(b.Za,b.Na))};function Jd(){this.ib={}} +function Kd(a,b){var c=b.type,d=b.Za;O("child_added"==c||"child_changed"==c||"child_removed"==c,"Only child changes supported for tracking");O(".priority"!==d,"Only non-priority child changes can be tracked.");var e=z(a.ib,d);if(e){var f=e.type;if("child_added"==c&&"child_removed"==f)a.ib[d]=new J("child_changed",b.Na,d,e.Na);else if("child_removed"==c&&"child_added"==f)delete a.ib[d];else if("child_removed"==c&&"child_changed"==f)a.ib[d]=new J("child_removed",e.Oe,d);else if("child_changed"==c&& +"child_added"==f)a.ib[d]=new J("child_added",b.Na,d);else if("child_changed"==c&&"child_changed"==f)a.ib[d]=new J("child_changed",b.Na,d,e.Oe);else throw jd("Illegal combination of changes: "+b+" occurred after "+e);}else a.ib[d]=b};function Ld(a){this.g=a}h=Ld.prototype;h.H=function(a,b,c,d,e,f){O(a.Mc(this.g),"A node must be indexed if only a child is updated");e=a.T(b);if(e.S(d).ea(c.S(d))&&e.e()==c.e())return a;null!=f&&(c.e()?a.Fa(b)?Kd(f,new J("child_removed",e,b)):O(a.L(),"A child remove without an old child only makes sense on a leaf node"):e.e()?Kd(f,new J("child_added",c,b)):Kd(f,new J("child_changed",c,b,e)));return a.L()&&c.e()?a:a.W(b,c).pb(this.g)}; +h.ya=function(a,b,c){null!=c&&(a.L()||a.R(R,function(a,e){b.Fa(a)||Kd(c,new J("child_removed",e,a))}),b.L()||b.R(R,function(b,e){if(a.Fa(b)){var f=a.T(b);f.ea(e)||Kd(c,new J("child_changed",e,b,f))}else Kd(c,new J("child_added",e,b))}));return b.pb(this.g)};h.ia=function(a,b){return a.e()?H:a.ia(b)};h.Ra=function(){return!1};h.$b=function(){return this};function Md(a){this.Fe=new Ld(a.g);this.g=a.g;var b;a.oa?(b=Nd(a),b=a.g.Sc(Od(a),b)):b=a.g.Wc();this.gd=b;a.ra?(b=Pd(a),a=a.g.Sc(Rd(a),b)):a=a.g.Tc();this.Jc=a}h=Md.prototype;h.matches=function(a){return 0>=this.g.compare(this.gd,a)&&0>=this.g.compare(a,this.Jc)};h.H=function(a,b,c,d,e,f){this.matches(new L(b,c))||(c=H);return this.Fe.H(a,b,c,d,e,f)}; +h.ya=function(a,b,c){b.L()&&(b=H);var d=b.pb(this.g),d=d.ia(H),e=this;b.R(R,function(a,b){e.matches(new L(a,b))||(d=d.W(a,H))});return this.Fe.ya(a,d,c)};h.ia=function(a){return a};h.Ra=function(){return!0};h.$b=function(){return this.Fe};function Sd(a){this.ua=new Md(a);this.g=a.g;O(a.la,"Only valid if limit has been set");this.ma=a.ma;this.Nb=!Td(a)}h=Sd.prototype;h.H=function(a,b,c,d,e,f){this.ua.matches(new L(b,c))||(c=H);return a.T(b).ea(c)?a:a.Hb()=this.g.compare(this.ua.gd,f):0>=this.g.compare(f,this.ua.Jc))d=d.W(f.name,f.U),e++;else break}}else{d=b.pb(this.g);d=d.ia(H);var k,m,l;if(this.Nb){b=d.xf(this.g);k=this.ua.Jc;m=this.ua.gd;var t=Vd(this.g);l=function(a,b){return t(b,a)}}else b=d.ac(this.g),k=this.ua.gd, +m=this.ua.Jc,l=Vd(this.g);for(var e=0,A=!1;0=l(k,f)&&(A=!0),(g=A&&e=l(f,m))?e++:d=d.W(f.name,H)}return this.ua.$b().ya(a,d,c)};h.ia=function(a){return a};h.Ra=function(){return!0};h.$b=function(){return this.ua.$b()}; +function Ud(a,b,c,d,e,f){var g;if(a.Nb){var k=Vd(a.g);g=function(a,b){return k(b,a)}}else g=Vd(a.g);O(b.Hb()==a.ma,"");var m=new L(c,d),l=a.Nb?Wd(b,a.g):Xd(b,a.g),t=a.ua.matches(m);if(b.Fa(c)){for(var A=b.T(c),l=e.Ce(a.g,l,a.Nb);null!=l&&(l.name==c||b.Fa(l.name));)l=e.Ce(a.g,l,a.Nb);e=null==l?1:g(l,m);if(t&&!d.e()&&0<=e)return null!=f&&Kd(f,new J("child_changed",d,c,A)),b.W(c,d);null!=f&&Kd(f,new J("child_removed",A,c));b=b.W(c,H);return null!=l&&a.ua.matches(l)?(null!=f&&Kd(f,new J("child_added", +l.U,l.name)),b.W(l.name,l.U)):b}return d.e()?b:t&&0<=g(l,m)?(null!=f&&(Kd(f,new J("child_removed",l.U,l.name)),Kd(f,new J("child_added",d,c))),b.W(c,d).W(l.name,H)):b};function Yd(a,b){this.me=a;this.og=b}function Zd(a){this.X=a} +Zd.prototype.gb=function(a,b,c,d){var e=new Jd,f;if(b.type===Bc)b.source.Ae?c=$d(this,a,b.path,b.Ja,c,d,e):(O(b.source.tf,"Unknown source."),f=b.source.ef||mc(a.w())&&!b.path.e(),c=ae(this,a,b.path,b.Ja,c,d,f,e));else if(b.type===be)b.source.Ae?c=ce(this,a,b.path,b.children,c,d,e):(O(b.source.tf,"Unknown source."),f=b.source.ef||mc(a.w()),c=de(this,a,b.path,b.children,c,d,f,e));else if(b.type===ee)if(b.Yd)if(b=b.path,null!=c.xc(b))c=a;else{f=new Vb(c,a,d);d=a.Q.j();if(b.e()||".priority"===K(b))lc(a.w())? +b=c.Aa(Yb(a)):(b=a.w().j(),O(b instanceof fe,"serverChildren would be complete if leaf node"),b=c.Cc(b)),b=this.X.ya(d,b,e);else{var g=K(b),k=c.Bc(g,a.w());null==k&&Wb(a.w(),g)&&(k=d.T(g));b=null!=k?this.X.H(d,g,k,N(b),f,e):a.Q.j().Fa(g)?this.X.H(d,g,H,N(b),f,e):d;b.e()&&lc(a.w())&&(d=c.Aa(Yb(a)),d.L()&&(b=this.X.ya(b,d,e)))}d=lc(a.w())||null!=c.xc(M);c=ge(a,b,d,this.X.Ra())}else c=he(this,a,b.path,b.Ub,c,d,e);else if(b.type===Dc)d=b.path,b=a.w(),f=b.j(),g=b.ga||d.e(),c=ie(this,new je(a.Q,new Xb(f, +g,b.Yb)),d,c,Ub,e);else throw jd("Unknown operation type: "+b.type);e=qa(e.ib);d=c;b=d.Q;b.ga&&(f=b.j().L()||b.j().e(),g=ke(a),(0b.compare(d,a);)Ic(c),d=Jc(c);return c};h.xf=function(a){return this.dc(a.Tc(),a)};h.dc=function(a,b){var c=Te(this,b);if(c)return c.dc(a,function(a){return a});for(var c=this.m.dc(a.name,wc),d=Jc(c);null!=d&&0f.status){try{b=Rb(f.responseText)}catch(c){S("Failed to parse JSON response for "+e+": "+f.responseText)}d(null,b)}else 401!==f.status&&404!== +f.status&&S("Got unsuccessful REST response for "+e+" Status: "+f.status),d(f.status);d=null}};f.open("GET",e,!0);f.send()};function ff(a){O(da(a)&&0f;f++)b[f]=Math.floor(64*Math.random());for(f=0;12>f;f++)c+="-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(b[f]);O(20===c.length,"nextPushId: Length should be 20."); +return c}}();function jf(){ff.call(this,["online"]);this.oc=!0;if("undefined"!==typeof window&&"undefined"!==typeof window.addEventListener){var a=this;window.addEventListener("online",function(){a.oc||(a.oc=!0,a.ie("online",!0))},!1);window.addEventListener("offline",function(){a.oc&&(a.oc=!1,a.ie("online",!1))},!1)}}ka(jf,ff);jf.prototype.Ee=function(a){O("online"===a,"Unknown event type: "+a);return[this.oc]};ba(jf);function kf(){ff.call(this,["visible"]);var a,b;"undefined"!==typeof document&&"undefined"!==typeof document.addEventListener&&("undefined"!==typeof document.hidden?(b="visibilitychange",a="hidden"):"undefined"!==typeof document.mozHidden?(b="mozvisibilitychange",a="mozHidden"):"undefined"!==typeof document.msHidden?(b="msvisibilitychange",a="msHidden"):"undefined"!==typeof document.webkitHidden&&(b="webkitvisibilitychange",a="webkitHidden"));this.Sb=!0;if(b){var c=this;document.addEventListener(b, +function(){var b=!document[a];b!==c.Sb&&(c.Sb=b,c.ie("visible",b))},!1)}}ka(kf,ff);kf.prototype.Ee=function(a){O("visible"===a,"Unknown event type: "+a);return[this.Sb]};ba(kf);function P(a,b){if(1==arguments.length){this.u=a.split("/");for(var c=0,d=0;d=a.u.length?null:a.u[a.aa]}function le(a){return a.u.length-a.aa}function N(a){var b=a.aa;b=this.u.length)return null;for(var a=[],b=this.aa;b=this.u.length};h.ea=function(a){if(le(this)!==le(a))return!1;for(var b=this.aa,c=a.aa;b<=this.u.length;b++,c++)if(this.u[b]!==a.u[c])return!1;return!0}; +h.contains=function(a){var b=this.aa,c=a.aa;if(le(this)>le(a))return!1;for(;b=b&&Rf(g,c.path)?d=!1:c.path.contains(g.path)&&(e=!0));f--}if(d){if(e)this.V=Sf(this.pa,Tf,M),this.Pc=010485760/3&&10485760=a}else if(-1=a;return!1};function Gg(){var a=window.opener.frames,b;for(b=a.length-1;0<=b;b--)try{if(a[b].location.protocol===window.location.protocol&&a[b].location.host===window.location.host&&"__winchan_relay_frame"===a[b].name)return a[b]}catch(c){}return null}function Hg(a,b,c){a.attachEvent?a.attachEvent("on"+b,c):a.addEventListener&&a.addEventListener(b,c,!1)}function Ig(a,b,c){a.detachEvent?a.detachEvent("on"+b,c):a.removeEventListener&&a.removeEventListener(b,c,!1)} +function Jg(a){/^https?:\/\//.test(a)||(a=window.location.href);var b=/^(https?:\/\/[\-_a-zA-Z\.0-9:]+)/.exec(a);return b?b[1]:a}function Kg(a){var b="";try{a=a.replace(/.*\?/,"");var c=Jb(a);c&&y(c,"__firebase_request_key")&&(b=z(c,"__firebase_request_key"))}catch(d){}return b}function Lg(){try{var a=document.location.hash.replace(/&__firebase_request_key=([a-zA-z0-9]*)/,""),a=a.replace(/\?$/,""),a=a.replace(/^#+$/,"");document.location.hash=a}catch(b){}} +function Mg(){var a=sd(xg);return a.scheme+"://"+a.host+"/v2"}function Ng(a){return Mg()+"/"+a+"/auth/channel"};function Og(a){var b=this;this.hb=a;this.fe="*";Fg(8)?this.Uc=this.Cd=Gg():(this.Uc=window.opener,this.Cd=window);if(!b.Uc)throw"Unable to find relay frame";Hg(this.Cd,"message",u(this.nc,this));Hg(this.Cd,"message",u(this.Ff,this));try{Pg(this,{a:"ready"})}catch(c){Hg(this.Uc,"load",function(){Pg(b,{a:"ready"})})}Hg(window,"unload",u(this.Ng,this))}function Pg(a,b){b=G(b);Fg(8)?a.Uc.doPost(b,a.fe):a.Uc.postMessage(b,a.fe)} +Og.prototype.nc=function(a){var b=this,c;try{c=Rb(a.data)}catch(d){}c&&"request"===c.a&&(Ig(window,"message",this.nc),this.fe=a.origin,this.hb&&setTimeout(function(){b.hb(b.fe,c.d,function(a,c){b.mg=!c;b.hb=void 0;Pg(b,{a:"response",d:a,forceKeepWindowOpen:c})})},0))};Og.prototype.Ng=function(){try{Ig(this.Cd,"message",this.Ff)}catch(a){}this.hb&&(Pg(this,{a:"error",d:"unknown closed window"}),this.hb=void 0);try{window.close()}catch(b){}};Og.prototype.Ff=function(a){if(this.mg&&"die"===a.data)try{window.close()}catch(b){}};function Qg(a){this.tc=Fa()+Fa()+Fa();this.Kf=a}Qg.prototype.open=function(a,b){cd.set("redirect_request_id",this.tc);cd.set("redirect_request_id",this.tc);b.requestId=this.tc;b.redirectTo=b.redirectTo||window.location.href;a+=(/\?/.test(a)?"":"?")+Ib(b);window.location=a};Qg.isAvailable=function(){return!Eg()&&!Dg()};Qg.prototype.Fc=function(){return"redirect"};var Rg={NETWORK_ERROR:"Unable to contact the Firebase server.",SERVER_ERROR:"An unknown server error occurred.",TRANSPORT_UNAVAILABLE:"There are no login transports available for the requested method.",REQUEST_INTERRUPTED:"The browser redirected the page before the login request could complete.",USER_CANCELLED:"The user cancelled authentication."};function Sg(a){var b=Error(z(Rg,a),a);b.code=a;return b};function Tg(a){var b;(b=!a.window_features)||(b=Cg(),b=-1!==b.indexOf("Fennec/")||-1!==b.indexOf("Firefox/")&&-1!==b.indexOf("Android"));b&&(a.window_features=void 0);a.window_name||(a.window_name="_blank");this.options=a} +Tg.prototype.open=function(a,b,c){function d(a){g&&(document.body.removeChild(g),g=void 0);t&&(t=clearInterval(t));Ig(window,"message",e);Ig(window,"unload",d);if(l&&!a)try{l.close()}catch(b){k.postMessage("die",m)}l=k=void 0}function e(a){if(a.origin===m)try{var b=Rb(a.data);"ready"===b.a?k.postMessage(A,m):"error"===b.a?(d(!1),c&&(c(b.d),c=null)):"response"===b.a&&(d(b.forceKeepWindowOpen),c&&(c(null,b.d),c=null))}catch(e){}}var f=Fg(8),g,k;if(!this.options.relay_url)return c(Error("invalid arguments: origin of url and relay_url must match")); +var m=Jg(a);if(m!==Jg(this.options.relay_url))c&&setTimeout(function(){c(Error("invalid arguments: origin of url and relay_url must match"))},0);else{f&&(g=document.createElement("iframe"),g.setAttribute("src",this.options.relay_url),g.style.display="none",g.setAttribute("name","__winchan_relay_frame"),document.body.appendChild(g),k=g.contentWindow);a+=(/\?/.test(a)?"":"?")+Ib(b);var l=window.open(a,this.options.window_name,this.options.window_features);k||(k=l);var t=setInterval(function(){l&&l.closed&& +(d(!1),c&&(c(Sg("USER_CANCELLED")),c=null))},500),A=G({a:"request",d:b});Hg(window,"unload",d);Hg(window,"message",e)}}; +Tg.isAvailable=function(){var a;if(a="postMessage"in window&&!Eg())(a=Dg()||"undefined"!==typeof navigator&&(!!Cg().match(/Windows Phone/)||!!window.Windows&&/^ms-appx:/.test(location.href)))||(a=Cg(),a="undefined"!==typeof navigator&&"undefined"!==typeof window&&!!(a.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i)||a.match(/CriOS/)||a.match(/Twitter for iPhone/)||a.match(/FBAN\/FBIOS/)||window.navigator.standalone)),a=!a;return a&&!Cg().match(/PhantomJS/)};Tg.prototype.Fc=function(){return"popup"};function Ug(a){a.method||(a.method="GET");a.headers||(a.headers={});a.headers.content_type||(a.headers.content_type="application/json");a.headers.content_type=a.headers.content_type.toLowerCase();this.options=a} +Ug.prototype.open=function(a,b,c){function d(){c&&(c(Sg("REQUEST_INTERRUPTED")),c=null)}var e=new XMLHttpRequest,f=this.options.method.toUpperCase(),g;Hg(window,"beforeunload",d);e.onreadystatechange=function(){if(c&&4===e.readyState){var a;if(200<=e.status&&300>e.status){try{a=Rb(e.responseText)}catch(b){}c(null,a)}else 500<=e.status&&600>e.status?c(Sg("SERVER_ERROR")):c(Sg("NETWORK_ERROR"));c=null;Ig(window,"beforeunload",d)}};if("GET"===f)a+=(/\?/.test(a)?"":"?")+Ib(b),g=null;else{var k=this.options.headers.content_type; +"application/json"===k&&(g=G(b));"application/x-www-form-urlencoded"===k&&(g=Ib(b))}e.open(f,a,!0);a={"X-Requested-With":"XMLHttpRequest",Accept:"application/json;text/plain"};ya(a,this.options.headers);for(var m in a)e.setRequestHeader(m,a[m]);e.send(g)};Ug.isAvailable=function(){var a;if(a=!!window.XMLHttpRequest)a=Cg(),a=!(a.match(/MSIE/)||a.match(/Trident/))||Fg(10);return a};Ug.prototype.Fc=function(){return"json"};function Vg(a){this.tc=Fa()+Fa()+Fa();this.Kf=a} +Vg.prototype.open=function(a,b,c){function d(){c&&(c(Sg("USER_CANCELLED")),c=null)}var e=this,f=sd(xg),g;b.requestId=this.tc;b.redirectTo=f.scheme+"://"+f.host+"/blank/page.html";a+=/\?/.test(a)?"":"?";a+=Ib(b);(g=window.open(a,"_blank","location=no"))&&r(g.addEventListener)?(g.addEventListener("loadstart",function(a){var b;if(b=a&&a.url)a:{try{var l=document.createElement("a");l.href=a.url;b=l.host===f.host&&"/blank/page.html"===l.pathname;break a}catch(t){}b=!1}b&&(a=Kg(a.url),g.removeEventListener("exit", +d),g.close(),a=new yg(null,null,{requestId:e.tc,requestKey:a}),e.Kf.requestWithCredential("/auth/session",a,c),c=null)}),g.addEventListener("exit",d)):c(Sg("TRANSPORT_UNAVAILABLE"))};Vg.isAvailable=function(){return Dg()};Vg.prototype.Fc=function(){return"redirect"};function Wg(a){a.callback_parameter||(a.callback_parameter="callback");this.options=a;window.__firebase_auth_jsonp=window.__firebase_auth_jsonp||{}} +Wg.prototype.open=function(a,b,c){function d(){c&&(c(Sg("REQUEST_INTERRUPTED")),c=null)}function e(){setTimeout(function(){window.__firebase_auth_jsonp[f]=void 0;va(window.__firebase_auth_jsonp)&&(window.__firebase_auth_jsonp=void 0);try{var a=document.getElementById(f);a&&a.parentNode.removeChild(a)}catch(b){}},1);Ig(window,"beforeunload",d)}var f="fn"+(new Date).getTime()+Math.floor(99999*Math.random());b[this.options.callback_parameter]="__firebase_auth_jsonp."+f;a+=(/\?/.test(a)?"":"?")+Ib(b); +Hg(window,"beforeunload",d);window.__firebase_auth_jsonp[f]=function(a){c&&(c(null,a),c=null);e()};Xg(f,a,c)}; +function Xg(a,b,c){setTimeout(function(){try{var d=document.createElement("script");d.type="text/javascript";d.id=a;d.async=!0;d.src=b;d.onerror=function(){var b=document.getElementById(a);null!==b&&b.parentNode.removeChild(b);c&&c(Sg("NETWORK_ERROR"))};var e=document.getElementsByTagName("head");(e&&0!=e.length?e[0]:document.documentElement).appendChild(d)}catch(f){c&&c(Sg("NETWORK_ERROR"))}},0)}Wg.isAvailable=function(){return"undefined"!==typeof document&&null!=document.createElement}; +Wg.prototype.Fc=function(){return"json"};function Yg(a,b,c,d){ff.call(this,["auth_status"]);this.G=a;this.hf=b;this.ih=c;this.Pe=d;this.wc=new Bg(a,[bd,cd]);this.qb=null;this.We=!1;Zg(this)}ka(Yg,ff);h=Yg.prototype;h.Be=function(){return this.qb||null};function Zg(a){cd.get("redirect_request_id")&&$g(a);var b=a.wc.get();b&&b.token?(ah(a,b),a.hf(b.token,function(c,d){bh(a,c,d,!1,b.token,b)},function(b,d){ch(a,"resumeSession()",b,d)})):ah(a,null)} +function dh(a,b,c,d,e,f){"firebaseio-demo.com"===a.G.domain&&S("Firebase authentication is not supported on demo Firebases (*.firebaseio-demo.com). To secure your Firebase, create a production Firebase at https://www.firebase.com.");a.hf(b,function(f,k){bh(a,f,k,!0,b,c,d||{},e)},function(b,c){ch(a,"auth()",b,c,f)})}function eh(a,b){a.wc.clear();ah(a,null);a.ih(function(a,d){if("ok"===a)T(b,null);else{var e=(a||"error").toUpperCase(),f=e;d&&(f+=": "+d);f=Error(f);f.code=e;T(b,f)}})} +function bh(a,b,c,d,e,f,g,k){"ok"===b?(d&&(b=c.auth,f.auth=b,f.expires=c.expires,f.token=Ed(e)?e:"",c=null,b&&y(b,"uid")?c=z(b,"uid"):y(f,"uid")&&(c=z(f,"uid")),f.uid=c,c="custom",b&&y(b,"provider")?c=z(b,"provider"):y(f,"provider")&&(c=z(f,"provider")),f.provider=c,a.wc.clear(),Ed(e)&&(g=g||{},c=bd,"sessionOnly"===g.remember&&(c=cd),"none"!==g.remember&&a.wc.set(f,c)),ah(a,f)),T(k,null,f)):(a.wc.clear(),ah(a,null),f=a=(b||"error").toUpperCase(),c&&(f+=": "+c),f=Error(f),f.code=a,T(k,f))} +function ch(a,b,c,d,e){S(b+" was canceled: "+d);a.wc.clear();ah(a,null);a=Error(d);a.code=c.toUpperCase();T(e,a)}function fh(a,b,c,d,e){gh(a);c=new yg(d||{},{},c||{});hh(a,[Ug,Wg],"/auth/"+b,c,e)} +function ih(a,b,c,d){gh(a);var e=[Tg,Vg];c=Ag(c);var f=625;"anonymous"===b||"password"===b?setTimeout(function(){T(d,Sg("TRANSPORT_UNAVAILABLE"))},0):("github"===b&&(f=1025),c.he.window_features="menubar=yes,modal=yes,alwaysRaised=yeslocation=yes,resizable=yes,scrollbars=yes,status=yes,height=625,width="+f+",top="+("object"===typeof screen?.5*(screen.height-625):0)+",left="+("object"===typeof screen?.5*(screen.width-f):0),c.he.relay_url=Ng(a.G.lc),c.he.requestWithCredential=u(a.uc,a),hh(a,e,"/auth/"+ +b,c,d))}function $g(a){var b=cd.get("redirect_request_id");if(b){var c=cd.get("redirect_client_options");cd.remove("redirect_request_id");cd.remove("redirect_client_options");var d=[Ug,Wg],b={requestId:b,requestKey:Kg(document.location.hash)},c=new yg(c,{},b);a.We=!0;Lg();hh(a,d,"/auth/session",c,function(){this.We=!1}.bind(a))}}h.ve=function(a,b){gh(this);var c=Ag(a);c.fb._method="POST";this.uc("/users",c,function(a,c){a?T(b,a):T(b,a,c)})}; +h.Xe=function(a,b){var c=this;gh(this);var d="/users/"+encodeURIComponent(a.email),e=Ag(a);e.fb._method="DELETE";this.uc(d,e,function(a,d){!a&&d&&d.uid&&c.qb&&c.qb.uid&&c.qb.uid===d.uid&&eh(c);T(b,a)})};h.se=function(a,b){gh(this);var c="/users/"+encodeURIComponent(a.email)+"/password",d=Ag(a);d.fb._method="PUT";d.fb.password=a.newPassword;this.uc(c,d,function(a){T(b,a)})}; +h.re=function(a,b){gh(this);var c="/users/"+encodeURIComponent(a.oldEmail)+"/email",d=Ag(a);d.fb._method="PUT";d.fb.email=a.newEmail;d.fb.password=a.password;this.uc(c,d,function(a){T(b,a)})};h.Ze=function(a,b){gh(this);var c="/users/"+encodeURIComponent(a.email)+"/password",d=Ag(a);d.fb._method="POST";this.uc(c,d,function(a){T(b,a)})};h.uc=function(a,b,c){jh(this,[Ug,Wg],a,b,c)}; +function hh(a,b,c,d,e){jh(a,b,c,d,function(b,c){!b&&c&&c.token&&c.uid?dh(a,c.token,c,d.qd,function(a,b){a?T(e,a):T(e,null,b)}):T(e,b||Sg("UNKNOWN_ERROR"))})} +function jh(a,b,c,d,e){b=Na(b,function(a){return"function"===typeof a.isAvailable&&a.isAvailable()});0===b.length?setTimeout(function(){T(e,Sg("TRANSPORT_UNAVAILABLE"))},0):(b=new (b.shift())(d.he),d=Gb(d.fb),d.v="js-"+Eb,d.transport=b.Fc(),d.suppress_status_codes=!0,a=Mg()+"/"+a.G.lc+c,b.open(a,d,function(a,b){if(a)T(e,a);else if(b&&b.error){var c=Error(b.error.message);c.code=b.error.code;c.details=b.error.details;T(e,c)}else T(e,null,b)}))} +function ah(a,b){var c=null!==a.qb||null!==b;a.qb=b;c&&a.ie("auth_status",b);a.Pe(null!==b)}h.Ee=function(a){O("auth_status"===a,'initial event must be of type "auth_status"');return this.We?null:[this.qb]};function gh(a){var b=a.G;if("firebaseio.com"!==b.domain&&"firebaseio-demo.com"!==b.domain&&"auth.firebase.com"===xg)throw Error("This custom Firebase server ('"+a.G.domain+"') does not support delegated login.");};var gd="websocket",hd="long_polling";function kh(a){this.nc=a;this.Qd=[];this.Wb=0;this.te=-1;this.Jb=null}function lh(a,b,c){a.te=b;a.Jb=c;a.tedocument.domain="'+document.domain+'";\x3c/script>');a=""+a+"";try{this.Ga.jb.open(),this.Ga.jb.write(a),this.Ga.jb.close()}catch(f){fc("frame writing exception"),f.stack&&fc(f.stack),fc(f)}} +qh.prototype.close=function(){this.oe=!1;if(this.Ga){this.Ga.jb.body.innerHTML="";var a=this;setTimeout(function(){null!==a.Ga&&(document.body.removeChild(a.Ga),a.Ga=null)},Math.floor(0))}var b=this.lb;b&&(this.lb=null,b())}; +function th(a){if(a.oe&&a.$d&&a.Te.count()<(0=a.cd[0].of.length+30+c.length){var e=a.cd.shift(),c=c+"&seg"+d+"="+e.Yg+"&ts"+d+"="+e.hh+"&d"+d+"="+e.of;d++}else break;uh(a,b+c,a.we);return!0}return!1}function uh(a,b,c){function d(){a.Te.remove(c);th(a)}a.Te.add(c,1);var e=setTimeout(d,Math.floor(25E3));sh(a,b,function(){clearTimeout(e);d()})} +function sh(a,b,c){setTimeout(function(){try{if(a.$d){var d=a.Ga.jb.createElement("script");d.type="text/javascript";d.async=!0;d.src=b;d.onload=d.onreadystatechange=function(){var a=d.readyState;a&&"loaded"!==a&&"complete"!==a||(d.onload=d.onreadystatechange=null,d.parentNode&&d.parentNode.removeChild(d),c())};d.onerror=function(){fc("Long-poll script failed to load: "+b);a.$d=!1;a.close()};a.Ga.jb.body.appendChild(d)}}catch(e){}},Math.floor(1))};var vh=null;"undefined"!==typeof MozWebSocket?vh=MozWebSocket:"undefined"!==typeof WebSocket&&(vh=WebSocket);function wh(a,b,c,d){this.ue=a;this.f=pd(this.ue);this.frames=this.Nc=null;this.rb=this.sb=this.ff=0;this.Xa=uc(b);a={v:"5"};"undefined"!==typeof location&&location.href&&-1!==location.href.indexOf("firebaseio.com")&&(a.r="f");c&&(a.s=c);d&&(a.ls=d);this.jf=fd(b,gd,a)}var xh; +wh.prototype.open=function(a,b){this.lb=b;this.Lg=a;this.f("Websocket connecting to "+this.jf);this.Kc=!1;bd.set("previous_websocket_failure",!0);try{this.La=new vh(this.jf)}catch(c){this.f("Error instantiating WebSocket.");var d=c.message||c.data;d&&this.f(d);this.bb();return}var e=this;this.La.onopen=function(){e.f("Websocket connected.");e.Kc=!0};this.La.onclose=function(){e.f("Websocket connection was disconnected.");e.La=null;e.bb()};this.La.onmessage=function(a){if(null!==e.La)if(a=a.data,e.rb+= +a.length,rc(e.Xa,"bytes_received",a.length),yh(e),null!==e.frames)zh(e,a);else{a:{O(null===e.frames,"We already have a frame buffer");if(6>=a.length){var b=Number(a);if(!isNaN(b)){e.ff=b;e.frames=[];a=null;break a}}e.ff=1;e.frames=[]}null!==a&&zh(e,a)}};this.La.onerror=function(a){e.f("WebSocket error. Closing connection.");(a=a.message||a.data)&&e.f(a);e.bb()}};wh.prototype.start=function(){}; +wh.isAvailable=function(){var a=!1;if("undefined"!==typeof navigator&&navigator.userAgent){var b=navigator.userAgent.match(/Android ([0-9]{0,}\.[0-9]{0,})/);b&&1parseFloat(b[1])&&(a=!0)}return!a&&null!==vh&&!xh};wh.responsesRequiredToBeHealthy=2;wh.healthyTimeout=3E4;h=wh.prototype;h.Hd=function(){bd.remove("previous_websocket_failure")};function zh(a,b){a.frames.push(b);if(a.frames.length==a.ff){var c=a.frames.join("");a.frames=null;c=Rb(c);a.Lg(c)}} +h.send=function(a){yh(this);a=G(a);this.sb+=a.length;rc(this.Xa,"bytes_sent",a.length);a=yd(a,16384);1=a.Tf?(a.f("Secondary connection is healthy."),a.Eb=!0,a.F.Hd(),a.F.start(),a.f("sending client ack on secondary"),a.F.send({t:"c",d:{t:"a",d:{}}}),a.f("Ending transmission on primary"),a.K.send({t:"c",d:{t:"n",d:{}}}),a.kd=a.F,Lh(a)):(a.f("sending ping on secondary."),a.F.send({t:"c",d:{t:"p",d:{}}}))}Fh.prototype.Ld=function(a){Nh(this);this.nc(a)};function Nh(a){a.Eb||(a.Ve--,0>=a.Ve&&(a.f("Primary connection is healthy."),a.Eb=!0,a.K.Hd()))} +function Kh(a,b){a.F=new b("c:"+a.id+":"+a.kf++,a.G,a.Uf);a.Tf=b.responsesRequiredToBeHealthy||0;a.F.open(Hh(a,a.F),Ih(a,a.F));setTimeout(function(){a.F&&(a.f("Timed out trying to upgrade."),a.F.close())},Math.floor(6E4))}function Jh(a,b,c){a.f("Realtime connection established.");a.K=b;a.N=1;a.Zc&&(a.Zc(c,a.Uf),a.Zc=null);0===a.Ve?(a.f("Primary connection is healthy."),a.Eb=!0):setTimeout(function(){Oh(a)},Math.floor(5E3))} +function Oh(a){a.Eb||1!==a.N||(a.f("sending ping on primary."),Qh(a,{t:"c",d:{t:"p",d:{}}}))}function Qh(a,b){if(1!==a.N)throw"Connection is not connected";a.kd.send(b)}Fh.prototype.close=function(){2!==this.N&&(this.f("Closing realtime connection."),this.N=2,Mh(this),this.na&&(this.na(),this.na=null))};function Mh(a){a.f("Shutting down all connections");a.K&&(a.K.close(),a.K=null);a.F&&(a.F.close(),a.F=null);a.Bd&&(clearTimeout(a.Bd),a.Bd=null)};function Rh(a,b,c,d){this.id=Sh++;this.f=pd("p:"+this.id+":");this.Bf=this.Ie=!1;this.ba={};this.sa=[];this.ad=0;this.Yc=[];this.qa=!1;this.eb=1E3;this.Id=3E5;this.Kb=b;this.Xc=c;this.Se=d;this.G=a;this.wb=this.Ca=this.Ma=this.Fb=this.$e=null;this.Sb=!1;this.Wd={};this.Xg=0;this.rf=!0;this.Oc=this.Ke=null;Th(this,0);kf.yb().Ib("visible",this.Og,this);-1===a.host.indexOf("fblocal")&&jf.yb().Ib("online",this.Mg,this)}var Sh=0,Uh=0;h=Rh.prototype; +h.Ia=function(a,b,c){var d=++this.Xg;a={r:d,a:a,b:b};this.f(G(a));O(this.qa,"sendRequest call when we're not connected not allowed.");this.Ma.Ia(a);c&&(this.Wd[d]=c)};h.Cf=function(a,b,c,d){var e=a.wa(),f=a.path.toString();this.f("Listen called for "+f+" "+e);this.ba[f]=this.ba[f]||{};O(Ie(a.n)||!He(a.n),"listen() called for non-default but complete query");O(!this.ba[f][e],"listen() called twice for same path/queryId.");a={I:d,Ad:b,Ug:a,tag:c};this.ba[f][e]=a;this.qa&&Vh(this,a)}; +function Vh(a,b){var c=b.Ug,d=c.path.toString(),e=c.wa();a.f("Listen on "+d+" for "+e);var f={p:d};b.tag&&(f.q=Ge(c.n),f.t=b.tag);f.h=b.Ad();a.Ia("q",f,function(f){var k=f.d,m=f.s;if(k&&"object"===typeof k&&y(k,"w")){var l=z(k,"w");da(l)&&0<=La(l,"no_index")&&S("Using an unspecified index. Consider adding "+('".indexOn": "'+c.n.g.toString()+'"')+" at "+c.path.toString()+" to your security rules for better performance")}(a.ba[d]&&a.ba[d][e])===b&&(a.f("listen response",f),"ok"!==m&&Wh(a,d,e),b.I&& +b.I(m,k))})}h.O=function(a,b,c){this.Ca={rg:a,sf:!1,Dc:b,od:c};this.f("Authenticating using credential: "+a);Xh(this);(b=40==a.length)||(a=Cd(a).Ec,b="object"===typeof a&&!0===z(a,"admin"));b&&(this.f("Admin auth credential detected. Reducing max reconnect time."),this.Id=3E4)};h.je=function(a){this.Ca=null;this.qa&&this.Ia("unauth",{},function(b){a(b.s,b.d)})}; +function Xh(a){var b=a.Ca;a.qa&&b&&a.Ia("auth",{cred:b.rg},function(c){var d=c.s;c=c.d||"error";"ok"!==d&&a.Ca===b&&(a.Ca=null);b.sf?"ok"!==d&&b.od&&b.od(d,c):(b.sf=!0,b.Dc&&b.Dc(d,c))})}h.$f=function(a,b){var c=a.path.toString(),d=a.wa();this.f("Unlisten called for "+c+" "+d);O(Ie(a.n)||!He(a.n),"unlisten() called for non-default but complete query");if(Wh(this,c,d)&&this.qa){var e=Ge(a.n);this.f("Unlisten on "+c+" for "+d);c={p:c};b&&(c.q=e,c.t=b);this.Ia("n",c)}}; +h.Qe=function(a,b,c){this.qa?Yh(this,"o",a,b,c):this.Yc.push({bd:a,action:"o",data:b,I:c})};h.Gf=function(a,b,c){this.qa?Yh(this,"om",a,b,c):this.Yc.push({bd:a,action:"om",data:b,I:c})};h.Md=function(a,b){this.qa?Yh(this,"oc",a,null,b):this.Yc.push({bd:a,action:"oc",data:null,I:b})};function Yh(a,b,c,d,e){c={p:c,d:d};a.f("onDisconnect "+b,c);a.Ia(b,c,function(a){e&&setTimeout(function(){e(a.s,a.d)},Math.floor(0))})}h.put=function(a,b,c,d){Zh(this,"p",a,b,c,d)}; +h.Df=function(a,b,c,d){Zh(this,"m",a,b,c,d)};function Zh(a,b,c,d,e,f){d={p:c,d:d};p(f)&&(d.h=f);a.sa.push({action:b,Pf:d,I:e});a.ad++;b=a.sa.length-1;a.qa?$h(a,b):a.f("Buffering put: "+c)}function $h(a,b){var c=a.sa[b].action,d=a.sa[b].Pf,e=a.sa[b].I;a.sa[b].Vg=a.qa;a.Ia(c,d,function(d){a.f(c+" response",d);delete a.sa[b];a.ad--;0===a.ad&&(a.sa=[]);e&&e(d.s,d.d)})} +h.Ye=function(a){this.qa&&(a={c:a},this.f("reportStats",a),this.Ia("s",a,function(a){"ok"!==a.s&&this.f("reportStats","Error sending stats: "+a.d)}))}; +h.Ld=function(a){if("r"in a){this.f("from server: "+G(a));var b=a.r,c=this.Wd[b];c&&(delete this.Wd[b],c(a.b))}else{if("error"in a)throw"A server-side error has occurred: "+a.error;"a"in a&&(b=a.a,c=a.b,this.f("handleServerMessage",b,c),"d"===b?this.Kb(c.p,c.d,!1,c.t):"m"===b?this.Kb(c.p,c.d,!0,c.t):"c"===b?ai(this,c.p,c.q):"ac"===b?(a=c.s,b=c.d,c=this.Ca,this.Ca=null,c&&c.od&&c.od(a,b)):"sd"===b?this.$e?this.$e(c):"msg"in c&&"undefined"!==typeof console&&console.log("FIREBASE: "+c.msg.replace("\n", +"\nFIREBASE: ")):qd("Unrecognized action received from server: "+G(b)+"\nAre you using the latest client?"))}};h.Zc=function(a,b){this.f("connection ready");this.qa=!0;this.Oc=(new Date).getTime();this.Se({serverTimeOffset:a-(new Date).getTime()});this.Fb=b;if(this.rf){var c={};c["sdk.js."+Eb.replace(/\./g,"-")]=1;Dg()?c["framework.cordova"]=1:"object"===typeof navigator&&"ReactNative"===navigator.product&&(c["framework.reactnative"]=1);this.Ye(c)}bi(this);this.rf=!1;this.Xc(!0)}; +function Th(a,b){O(!a.Ma,"Scheduling a connect when we're already connected/ing?");a.wb&&clearTimeout(a.wb);a.wb=setTimeout(function(){a.wb=null;ci(a)},Math.floor(b))}h.Og=function(a){a&&!this.Sb&&this.eb===this.Id&&(this.f("Window became visible. Reducing delay."),this.eb=1E3,this.Ma||Th(this,0));this.Sb=a};h.Mg=function(a){a?(this.f("Browser went online."),this.eb=1E3,this.Ma||Th(this,0)):(this.f("Browser went offline. Killing connection."),this.Ma&&this.Ma.close())}; +h.If=function(){this.f("data client disconnected");this.qa=!1;this.Ma=null;for(var a=0;af.Pc,"Stacking an older write on top of newer ones");p(g)||(g=!0);f.pa.push({path:b,Ja:c,md:d,visible:g});g&&(f.V=Jf(f.V,b,c));f.Pc=d;return e?qi(a,new Ac(Ef,b,c)):[]}function ri(a,b,c,d){var e=a.mb;O(d>e.Pc,"Stacking an older merge on top of newer ones");e.pa.push({path:b,children:c,md:d,visible:!0});e.V=Kf(e.V,b,c);e.Pc=d;c=sf(c);return qi(a,new bf(Ef,b,c))} +function si(a,b,c){c=c||!1;var d=Qf(a.mb,b);if(a.mb.Ud(b)){var e=qe;null!=d.Ja?e=e.set(M,!0):Fb(d.children,function(a,b){e=e.set(new P(a),b)});return qi(a,new Df(d.path,e,c))}return[]}function ti(a,b,c){c=sf(c);return qi(a,new bf(Gf,b,c))}function ui(a,b,c,d){d=vi(a,d);if(null!=d){var e=wi(d);d=e.path;e=e.Lb;b=lf(d,b);c=new Ac(new Ff(!1,!0,e,!0),b,c);return xi(a,d,c)}return[]} +function yi(a,b,c,d){if(d=vi(a,d)){var e=wi(d);d=e.path;e=e.Lb;b=lf(d,b);c=sf(c);c=new bf(new Ff(!1,!0,e,!0),b,c);return xi(a,d,c)}return[]} +oi.prototype.Tb=function(a,b){var c=a.path,d=null,e=!1;zf(this.va,c,function(a,b){var f=lf(a,c);d=d||b.kb(f);e=e||null!=li(b)});var f=this.va.get(c);f?(e=e||null!=li(f),d=d||f.kb(M)):(f=new ki,this.va=this.va.set(c,f));var g;null!=d?g=!0:(g=!1,d=H,Cf(this.va.subtree(c),function(a,b){var c=b.kb(M);c&&(d=d.W(a,c))}));var k=null!=ni(f,a);if(!k&&!He(a.n)){var m=zi(a);O(!(m in this.qc),"View does not exist, but we have a tag");var l=Ai++;this.qc[m]=l;this.df["_"+l]=m}g=f.Tb(a,b,new Uf(c,this.mb),d,g); +k||e||(f=ni(f,a),g=g.concat(Bi(this,a,f)));return g}; +oi.prototype.nb=function(a,b,c){var d=a.path,e=this.va.get(d),f=[];if(e&&("default"===a.wa()||null!=ni(e,a))){f=e.nb(a,b,c);e.e()&&(this.va=this.va.remove(d));e=f.Wg;f=f.vg;b=-1!==Sa(e,function(a){return He(a.n)});var g=xf(this.va,d,function(a,b){return null!=li(b)});if(b&&!g&&(d=this.va.subtree(d),!d.e()))for(var d=Ci(d),k=0;k=a)throw Error("Query.limit: First argument must be a positive integer.");if(this.n.la)throw Error("Query.limit: Limit was already set (by another call to limit, limitToFirst, orlimitToLast.");var b=this.n.Le(a);cj(b);return new Y(this.k,this.path,b,this.pc)}; +h.Me=function(a){D("Query.limitToFirst",1,1,arguments.length);if(!fa(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limitToFirst: First argument must be a positive integer.");if(this.n.la)throw Error("Query.limitToFirst: Limit was already set (by another call to limit, limitToFirst, or limitToLast).");return new Y(this.k,this.path,this.n.Me(a),this.pc)}; +h.Ne=function(a){D("Query.limitToLast",1,1,arguments.length);if(!fa(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limitToLast: First argument must be a positive integer.");if(this.n.la)throw Error("Query.limitToLast: Limit was already set (by another call to limit, limitToFirst, or limitToLast).");return new Y(this.k,this.path,this.n.Ne(a),this.pc)}; +h.Qg=function(a){D("Query.orderByChild",1,1,arguments.length);if("$key"===a)throw Error('Query.orderByChild: "$key" is invalid. Use Query.orderByKey() instead.');if("$priority"===a)throw Error('Query.orderByChild: "$priority" is invalid. Use Query.orderByPriority() instead.');if("$value"===a)throw Error('Query.orderByChild: "$value" is invalid. Use Query.orderByValue() instead.');ng("Query.orderByChild",a);dj(this,"Query.orderByChild");var b=new P(a);if(b.e())throw Error("Query.orderByChild: cannot pass in empty path. Use Query.orderByValue() instead."); +b=new ve(b);b=Fe(this.n,b);bj(b);return new Y(this.k,this.path,b,!0)};h.Rg=function(){D("Query.orderByKey",0,0,arguments.length);dj(this,"Query.orderByKey");var a=Fe(this.n,re);bj(a);return new Y(this.k,this.path,a,!0)};h.Sg=function(){D("Query.orderByPriority",0,0,arguments.length);dj(this,"Query.orderByPriority");var a=Fe(this.n,R);bj(a);return new Y(this.k,this.path,a,!0)}; +h.Tg=function(){D("Query.orderByValue",0,0,arguments.length);dj(this,"Query.orderByValue");var a=Fe(this.n,Be);bj(a);return new Y(this.k,this.path,a,!0)};h.ce=function(a,b){D("Query.startAt",0,2,arguments.length);gg("Query.startAt",a,this.path,!0);mg("Query.startAt",b);var c=this.n.ce(a,b);cj(c);bj(c);if(this.n.oa)throw Error("Query.startAt: Starting point was already set (by another call to startAt or equalTo).");p(a)||(b=a=null);return new Y(this.k,this.path,c,this.pc)}; +h.vd=function(a,b){D("Query.endAt",0,2,arguments.length);gg("Query.endAt",a,this.path,!0);mg("Query.endAt",b);var c=this.n.vd(a,b);cj(c);bj(c);if(this.n.ra)throw Error("Query.endAt: Ending point was already set (by another call to endAt or equalTo).");return new Y(this.k,this.path,c,this.pc)}; +h.tg=function(a,b){D("Query.equalTo",1,2,arguments.length);gg("Query.equalTo",a,this.path,!1);mg("Query.equalTo",b);if(this.n.oa)throw Error("Query.equalTo: Starting point was already set (by another call to endAt or equalTo).");if(this.n.ra)throw Error("Query.equalTo: Ending point was already set (by another call to endAt or equalTo).");return this.ce(a,b).vd(a,b)}; +h.toString=function(){D("Query.toString",0,0,arguments.length);for(var a=this.path,b="",c=a.aa;c.firebaseio.com instead");c&&"undefined"!=c||rd("Cannot parse Firebase url. Please use https://.firebaseio.com");d.ob||"undefined"!==typeof window&&window.location&&window.location.protocol&&-1!==window.location.protocol.indexOf("https:")&&S("Insecure Firebase access from a secure page. Please use https in calls to new Firebase()."); +c=new dd(d.host,d.ob,c,"ws"===d.scheme||"wss"===d.scheme);d=new P(d.bd);e=d.toString();var f;!(f=!q(c.host)||0===c.host.length||!eg(c.lc))&&(f=0!==e.length)&&(e&&(e=e.replace(/^\/*\.info(\/|$)/,"/")),f=!(q(e)&&0!==e.length&&!cg.test(e)));if(f)throw Error(E("new Firebase",1,!1)+'must be a valid firebase URL and the path can\'t contain ".", "#", "$", "[", or "]".');if(b)if(b instanceof aj)e=b;else if(q(b))e=aj.yb(),c.Rd=b;else throw Error("Expected a valid Firebase.Context for second argument to new Firebase()"); +else e=aj.yb();f=c.toString();var g=z(e.sc,f);g||(g=new Ji(c,e.ag),e.sc[f]=g);c=g}Y.call(this,c,d,De,!1);this.then=void 0;this["catch"]=void 0}ka(X,Y);var fj=X,gj=["Firebase"],hj=n;gj[0]in hj||!hj.execScript||hj.execScript("var "+gj[0]);for(var ij;gj.length&&(ij=gj.shift());)!gj.length&&p(fj)?hj[ij]=fj:hj=hj[ij]?hj[ij]:hj[ij]={};X.goOffline=function(){D("Firebase.goOffline",0,0,arguments.length);aj.yb().Cb()};X.goOnline=function(){D("Firebase.goOnline",0,0,arguments.length);aj.yb().vc()}; +X.enableLogging=od;X.ServerValue={TIMESTAMP:{".sv":"timestamp"}};X.SDK_VERSION=Eb;X.INTERNAL=U;X.Context=aj;X.TEST_ACCESS=Z;X.prototype.name=function(){S("Firebase.name() being deprecated. Please use Firebase.key() instead.");D("Firebase.name",0,0,arguments.length);return this.key()};X.prototype.name=X.prototype.name;X.prototype.key=function(){D("Firebase.key",0,0,arguments.length);return this.path.e()?null:me(this.path)};X.prototype.key=X.prototype.key; +X.prototype.o=function(a){D("Firebase.child",1,1,arguments.length);if(fa(a))a=String(a);else if(!(a instanceof P))if(null===K(this.path)){var b=a;b&&(b=b.replace(/^\/*\.info(\/|$)/,"/"));ng("Firebase.child",b)}else ng("Firebase.child",a);return new X(this.k,this.path.o(a))};X.prototype.child=X.prototype.o;X.prototype.parent=function(){D("Firebase.parent",0,0,arguments.length);var a=this.path.parent();return null===a?null:new X(this.k,a)};X.prototype.parent=X.prototype.parent; +X.prototype.root=function(){D("Firebase.ref",0,0,arguments.length);for(var a=this;null!==a.parent();)a=a.parent();return a};X.prototype.root=X.prototype.root;X.prototype.set=function(a,b){D("Firebase.set",1,2,arguments.length);og("Firebase.set",this.path);gg("Firebase.set",a,this.path,!1);F("Firebase.set",2,b,!0);var c=new B;this.k.Ob(this.path,a,null,C(c,b));return c.D};X.prototype.set=X.prototype.set; +X.prototype.update=function(a,b){D("Firebase.update",1,2,arguments.length);og("Firebase.update",this.path);if(da(a)){for(var c={},d=0;d this.items.length - 1)) + end = this.items.length - 1; + + var current_frame = runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var i; + for(i=start; i<=end; i++) + { + if (solModifierAfterCnds) + { + runtime.pushCopySol(current_event.solModifiers); + } + + if (this.onGetIterItem) + this.onGetIterItem(this.items[i], i); + current_event.retrigger(); + + if (solModifierAfterCnds) + { + runtime.popSol(current_event.solModifiers); + } + } + + return false; + }; + // export + // -------------------------------------------------------------------------- + + // -------------------------------------------------------------------------- + // internal + ItemListKlassProto.addItem = function(snapshot, prevName, force_push) + { + var item; + if (this.snapshot2Item) + item = this.snapshot2Item(snapshot); + else + { + var k = getKey(snapshot); + item = snapshot["val"](); + item[this.keyItemID] = k; + } + + if (force_push === true) + { + this.items.push(item); + return; + } + + if (prevName == null) + { + this.items.unshift(item); + } + else + { + var i = this.itemID2Index[prevName]; + if (i == this.items.length-1) + this.items.push(item); + else + this.items.splice(i+1, 0, item); + } + + return item; + }; + + ItemListKlassProto.removeItem = function(snapshot) + { + var k = getKey(snapshot); + var i = this.itemID2Index[k]; + var item = this.items[i]; + cr.arrayRemove(this.items, i); + return item; + }; + + ItemListKlassProto.updateItemID2Index = function() + { + cleanTable(this.itemID2Index); + var i,cnt = this.items.length; + for (i=0; i this.items.length - 1)) + end = this.items.length - 1; + var current_frame = runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = runtime.GetEventSheetManager().GetEventStack(); + var p = runtime.GetEventStack(); + var h = c.Push(current_event); + + var i; + for(i=start; i<=end; i++) + { + if (solModifierAfterCnds) + { + runtime.GetEventSheetManager().PushCopySol(solmod); + } + + if (this.onGetIterItem) + this.onGetIterItem(this.items[i], i); + current_event.Retrigger(current_frame,h); + + if (solModifierAfterCnds) + { + runtime.GetEventSheetManager().PopSol(solmod); + } + } + p.Pop(); + + return false; + }; + // export + // -------------------------------------------------------------------------- + + // -------------------------------------------------------------------------- + // internal + ItemListKlassProto.addItem = function(snapshot, prevName, force_push) + { + var item; + if (this.snapshot2Item) + item = this.snapshot2Item(snapshot); + else + { + var k = getKey(snapshot); + item = snapshot["val"](); + item[this.keyItemID] = k; + } + + if (force_push === true) + { + this.items.push(item); + return; + } + + if (prevName == null) + { + this.items.unshift(item); + } + else + { + var i = this.itemID2Index[prevName]; + if (i == this.items.length-1) + this.items.push(item); + else + this.items.splice(i+1, 0, item); + } + + return item; + }; + + ItemListKlassProto.removeItem = function(snapshot) + { + var k = getKey(snapshot); + var i = this.itemID2Index[k]; + var item = this.items[i]; + C3.arrayRemove(this.items, i); + return item; + }; + + ItemListKlassProto.updateItemID2Index = function() + { + cleanTable(this.itemID2Index); + var i,cnt = this.items.length; + for (i=0; i1)for(var r=1;r255;)t[r++]=255&o,o>>=8;t[r++]=o}return t},o=function(e){if(e.length<8192)return String.fromCharCode.apply(null,e);for(var t="",r=0;r>2,l=(3&i)<<4|c>>4,h=(15&c)<<2|u>>6,p=63&u;s||(p=64,a||(h=64)),n.push(r[f],r[l],r[h],r[p])}return n.join("")},encodeString:function(e,t){return this.HAS_NATIVE_SUPPORT&&!t?btoa(e):this.encodeByteArray(n(e),t)},decodeString:function(e,t){return this.HAS_NATIVE_SUPPORT&&!t?atob(e):o(this.decodeStringToByteArray(e,t))},decodeStringToByteArray:function(e,t){this.O();for(var r=t?this.g:this.b,n=[],o=0;o>4;if(n.push(h),64!=u){var p=c<<4&240|u>>2;if(n.push(p),64!=l){var d=u<<6&192|l;n.push(d)}}}return n},O:function(){if(!this.y){this.y={},this.b={},this._={},this.g={};for(var e=0;e=this.ENCODED_VALS_BASE.length&&(this.b[this.ENCODED_VALS_WEBSAFE.charAt(e)]=e,this.g[this.ENCODED_VALS.charAt(e)]=e)}}},t.base64Encode=function(e){var r=n(e);return t.base64.encodeByteArray(r,!0)},t.base64Decode=function(e){try{return t.base64.decodeString(e,!0)}catch(e){console.error("base64Decode failed: ",e)}return null}},function(e,t,r){"use strict";function n(e){return JSON.parse(e)}function o(e){return JSON.stringify(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.jsonEval=n,t.stringify=o},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.contains=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.safeGet=function(e,t){if(Object.prototype.hasOwnProperty.call(e,t))return e[t]},t.forEach=function(e,t){for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t(r,e[r])},t.extend=function(e,r){return t.forEach(r,function(t,r){e[t]=r}),e},t.clone=function(e){return t.extend({},e)},t.isNonNullObject=function(e){return"object"==typeof e&&null!==e},t.isEmpty=function(e){for(var t in e)return!1;return!0},t.getCount=function(e){var t=0;for(var r in e)t++;return t},t.map=function(e,t,r){var n={};for(var o in e)n[o]=t.call(r,e[o],o,e);return n},t.findKey=function(e,t,r){for(var n in e)if(t.call(r,e[n],n,e))return n},t.findValue=function(e,r,n){var o=t.findKey(e,r,n);return o&&e[o]},t.getAnyKey=function(e){for(var t in e)return t},t.getValues=function(e){var t=[],r=0;for(var n in e)t[r++]=e[n];return t},t.every=function(e,t){for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)&&!t(r,e[r]))return!1;return!0}},,,,,,,,,,,,,,,,,,,,,,,,,,function(e,t,r){r(58),e.exports=r(6).default},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(59),o=(r.n(n),r(63)),i=(r.n(o),r(64));r.n(i)},function(t,r,n){(function(t){var r=function(){if(void 0!==t)return t;if(void 0!==e)return e;if("undefined"!=typeof self)return self;throw Error("unable to locate global object")}();"undefined"==typeof Promise&&(r.Promise=Promise=n(60))}).call(r,n(19))},function(e,t,r){(function(t){!function(r){function n(){}function o(e,t){return function(){e.apply(t,arguments)}}function i(e){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this.T=[],l(e,this)}function a(e,t){for(;3===e._state;)e=e._value;if(0===e._state)return void e.T.push(t);e._handled=!0,i.A(function(){var r=1===e._state?t.onFulfilled:t.onRejected;if(null===r)return void(1===e._state?c:s)(t.promise,e._value);var n;try{n=r(e._value)}catch(e){return void s(t.promise,e)}c(t.promise,n)})}function c(e,t){try{if(t===e)throw new TypeError("A promise cannot be resolved with itself.");if(t&&("object"==typeof t||"function"==typeof t)){var r=t.then;if(t instanceof i)return e._state=3,e._value=t,void u(e);if("function"==typeof r)return void l(o(r,t),e)}e._state=1,e._value=t,u(e)}catch(t){s(e,t)}}function s(e,t){e._state=2,e._value=t,u(e)}function u(e){2===e._state&&0===e.T.length&&i.A(function(){e._handled||i.j(e._value)});for(var t=0,r=e.T.length;t=0&&(e.N=setTimeout(function(){e.M&&e.M()},t))},n(62),r.setImmediate=setImmediate,r.clearImmediate=clearImmediate},function(e,t,r){(function(e,t){!function(e,r){"use strict";function n(e){"function"!=typeof e&&(e=Function(""+e));for(var t=Array(arguments.length-1),r=0;r>>0;if("function"!=typeof e)throw new TypeError("predicate must be a function");for(var n=arguments[1],o=0;o>>0;if("function"!=typeof e)throw new TypeError("predicate must be a function");for(var n=arguments[1],o=0;o"}),r=this.serviceName+": "+r+" ("+o+").";var i=new a(o,r);for(var c in t)t.hasOwnProperty(c)&&"_"!==c.slice(-1)&&(i[c]=t[c]);return i},e}();t.ErrorFactory=c},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(29),o=r(30);t.decode=function(e){var t={},r={},i={},a="";try{var c=e.split(".");t=o.jsonEval(n.base64Decode(c[0])||""),r=o.jsonEval(n.base64Decode(c[1])||""),a=c[2],i=r.d||{},delete r.d}catch(e){}return{header:t,claims:r,data:i,signature:a}},t.isValidTimestamp=function(e){var r,n,o=t.decode(e).claims,i=Math.floor((new Date).getTime()/1e3);return"object"==typeof o&&(o.hasOwnProperty("nbf")?r=o.nbf:o.hasOwnProperty("iat")&&(r=o.iat),n=o.hasOwnProperty("exp")?o.exp:r+86400),i&&r&&n&&i>=r&&i<=n},t.issuedAtTime=function(e){var r=t.decode(e).claims;return"object"==typeof r&&r.hasOwnProperty("iat")?r.iat:null},t.isValidFormat=function(e){var r=t.decode(e),n=r.claims;return!!r.signature&&!!n&&"object"==typeof n&&n.hasOwnProperty("iat")},t.isAdmin=function(e){var r=t.decode(e).claims;return"object"==typeof r&&!0===r.admin}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(31);t.querystring=function(e){var t=[];return n.forEach(e,function(e,r){Array.isArray(r)?r.forEach(function(r){t.push(encodeURIComponent(e)+"="+encodeURIComponent(r))}):t.push(encodeURIComponent(e)+"="+encodeURIComponent(r))}),t.length?"&"+t.join("&"):""},t.querystringDecode=function(e){var t={};return e.replace(/^\?/,"").split("&").forEach(function(e){if(e){var r=e.split("=");t[r[0]]=r[1]}}),t}},function(e,t,r){"use strict";var n=this&&this.__extends||function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])};return function(t,r){function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}();Object.defineProperty(t,"__esModule",{value:!0});var o=r(72),i=function(e){function t(){var t=e.call(this)||this;t.D=[],t.I=[],t.x=[],t.F=[],t.L=0,t.R=0,t.blockSize=64,t.F[0]=128;for(var r=1;r>>31)}for(var i,a,c=this.D[0],s=this.D[1],u=this.D[2],f=this.D[3],l=this.D[4],n=0;n<80;n++){n<40?n<20?(i=f^s&(u^f),a=1518500249):(i=s^u^f,a=1859775393):n<60?(i=s&u|f&(s|u),a=2400959708):(i=s^u^f,a=3395469782);var o=(c<<5|c>>>27)+i+l+a+r[n]&4294967295;l=f,f=u,u=4294967295&(s<<30|s>>>2),s=c,c=o}this.D[0]=this.D[0]+c&4294967295,this.D[1]=this.D[1]+s&4294967295,this.D[2]=this.D[2]+u&4294967295,this.D[3]=this.D[3]+f&4294967295,this.D[4]=this.D[4]+l&4294967295},t.prototype.update=function(e,t){if(null!=e){void 0===t&&(t=e.length);for(var r=t-this.blockSize,n=0,o=this.I,i=this.L;n=56;r--)this.I[r]=255&t,t/=256;this.B(this.I);for(var n=0,r=0;r<5;r++)for(var o=24;o>=0;o-=8)e[n]=this.D[r]>>o&255,++n;return e},t}(o.Hash);t.Sha1=i},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(){this.blockSize=-1}return e}();t.Hash=n},function(e,t,r){"use strict";function n(e,t){var r=new c(e,t);return r.subscribe.bind(r)}function o(e,t){return function(){for(var r=[],n=0;n 4. Need to update it?")}var o=e+" failed: ";return o+=n+" argument "}function o(e,t,r,o){if((!o||r)&&"string"!=typeof r)throw Error(n(e,t,o)+"must be a valid firebase namespace.")}function i(e,t,r,o){if((!o||r)&&"function"!=typeof r)throw Error(n(e,t,o)+"must be a valid function.")}function a(e,t,r,o){if((!o||r)&&("object"!=typeof r||null===r))throw Error(n(e,t,o)+"must be a valid context object.")}Object.defineProperty(t,"__esModule",{value:!0}),t.validateArgCount=function(e,t,r,n){var o;if(nr&&(o=0===r?"none":"no more than "+r),o){var i=e+" failed: Was called with "+n+(1===n?" argument.":" arguments.")+" Expects "+o+".";throw Error(i)}},t.errorPrefix=n,t.validateNamespace=o,t.validateCallback=i,t.validateContextObject=a},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(28);t.stringToByteArray=function(e){for(var t=[],r=0,o=0;o=55296&&i<=56319){var a=i-55296;o++,n.assert(o>6|192,t[r++]=63&i|128):i<65536?(t[r++]=i>>12|224,t[r++]=i>>6&63|128,t[r++]=63&i|128):(t[r++]=i>>18|240,t[r++]=i>>12&63|128,t[r++]=i>>6&63|128,t[r++]=63&i|128)}return t},t.stringLength=function(e){for(var t=0,r=0;r=55296&&n<=56319?(t+=4,r++):t+=3}return t}}])}().default; + +/*! + * @license Firebase v4.6.2 + * Build: rev-cbb07d3 + * Terms: https://firebase.google.com/terms/ + */ +try{webpackJsonpFirebase([4],{76:function(t,n,e){e(77)},77:function(t,n,e){(function(t){(function(){function t(t){return"string"==typeof t}function n(t){return"boolean"==typeof t}function i(){}function r(t){var n=typeof t;if("object"==n){if(!t)return"null";if(t instanceof Array)return"array";if(t instanceof Object)return n;var e=Object.prototype.toString.call(t);if("[object Window]"==e)return"object";if("[object Array]"==e||"number"==typeof t.length&&void 0!==t.splice&&void 0!==t.propertyIsEnumerable&&!t.propertyIsEnumerable("splice"))return"array";if("[object Function]"==e||void 0!==t.call&&void 0!==t.propertyIsEnumerable&&!t.propertyIsEnumerable("call"))return"function"}else if("function"==n&&void 0===t.call)return"object";return n}function o(t){return null===t}function a(t){return"array"==r(t)}function s(t){var n=r(t);return"array"==n||"object"==n&&"number"==typeof t.length}function u(t){return"function"==r(t)}function c(t){var n=typeof t;return"object"==n&&null!=t||"function"==n}function h(t,n,e){return t.call.apply(t.bind,arguments)}function f(t,n,e){if(!t)throw Error();if(2")&&(t=t.replace(vu,">")),-1!=t.indexOf('"')&&(t=t.replace(mu,""")),-1!=t.indexOf("'")&&(t=t.replace(gu,"'")),-1!=t.indexOf("\0")&&(t=t.replace(bu,"�")),t):t}function b(t,n){return-1!=t.indexOf(n)}function w(t,n){return tn?1:0}function y(t,n){n.unshift(t),v.call(this,m.apply(null,n)),n.shift()}function I(t,n){throw new y("Failure"+(t?": "+t:""),Array.prototype.slice.call(arguments,1))}function T(n,e){var i=n.length,r=t(n)?n.split(""):n;for(--i;0<=i;--i)i in r&&e.call(void 0,r[i],i,n)}function k(n){t:{for(var e=ke,i=n.length,r=t(n)?n.split(""):n,o=0;oe?null:t(n)?n.charAt(e):n[e]}function A(t,n){return 0<=Iu(t,n)}function E(t,n){n=Iu(t,n);var e;return(e=0<=n)&&Array.prototype.splice.call(t,n,1),e}function N(t,n){var e=0;T(t,function(i,r){n.call(void 0,i,r,t)&&1==Array.prototype.splice.call(t,r,1).length&&e++})}function S(t){return Array.prototype.concat.apply([],arguments)}function O(t){var n=t.length;if(0"),s=s.join("")}return s=o.createElement(s),u&&(t(u)?s.className=u:a(u)?s.className=u.join(" "):Lt(s,u)),2i.keyCode||void 0!=i.returnValue)){t:{var r=!1;if(0==i.keyCode)try{i.keyCode=-1;break t}catch(t){r=!0}(r||void 0==i.returnValue)&&(i.returnValue=!0)}for(i=[],r=n.b;r;r=r.parentNode)i.push(r);for(t=t.type,r=i.length-1;0<=r;r--){n.b=i[r];var o=an(i[r],t,!0,n);e=e&&o}for(r=0;r>4),64!=a&&(n(o<<4&240|a>>2),64!=s&&n(a<<6&192|s))}}function Cn(){if(!Sc){Sc={},Oc={};for(var t=0;65>t;t++)Sc[t]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(t),Oc[Sc[t]]=t,62<=t&&(Oc["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.".charAt(t)]=t)}}function _n(t,n){this.g=[],this.v=t,this.o=n||null,this.f=this.a=!1,this.c=void 0,this.u=this.w=this.i=!1,this.h=0,this.b=null,this.l=0}function Rn(t,n,e){t.a=!0,t.c=e,t.f=!n,Un(t)}function Dn(t){if(t.a){if(!t.u)throw new Mn;t.u=!1}}function Ln(t,n){xn(t,null,n,void 0)}function xn(t,n,e,i){t.g.push([n,e,i]),t.a&&Un(t)}function jn(t){return Au(t.g,function(t){return u(t[1])})}function Un(t){if(t.h&&t.a&&jn(t)){var n=t.h,e=Cc[n];e&&(uu.clearTimeout(e.a),delete Cc[n]),t.h=0}t.b&&(t.b.l--,delete t.b),n=t.c;for(var i=e=!1;t.g.length&&!t.i;){var r=t.g.shift(),o=r[0],a=r[1];if(r=r[2],o=t.f?a:o)try{var s=o.call(r||t.o,n);void 0!==s&&(t.f=t.f&&(s==n||s instanceof Error),t.c=n=s),(q(n)||"function"==typeof uu.Promise&&n instanceof uu.Promise)&&(i=!0,t.i=!0)}catch(i){n=i,t.f=!0,jn(t)||(e=!0)}}t.c=n,i&&(s=l(t.m,t,!0),i=l(t.m,t,!1),n instanceof _n?(xn(n,s,i),n.w=!0):n.then(s,i)),e&&(n=new Fn(n),Cc[n.a]=n,t.h=n.a)}function Mn(){v.call(this)}function Vn(){v.call(this)}function Fn(t){this.a=uu.setTimeout(l(this.c,this),0),this.b=t}function Kn(){this.b=-1}function qn(t,n){this.b=-1,this.b=_c,this.f=uu.Uint8Array?new Uint8Array(this.b):Array(this.b),this.g=this.c=0,this.a=[],this.i=t,this.h=n,this.l=uu.Int32Array?new Int32Array(64):Array(64),Pc||(Pc=uu.Int32Array?new Int32Array(jc):jc),this.reset()}function Xn(t){for(var n=t.f,e=t.l,i=0,r=0;rn;n++){r=0|e[n-15],i=0|e[n-2];var o=(0|e[n-16])+((r>>>7|r<<25)^(r>>>18|r<<14)^r>>>3)|0,a=(0|e[n-7])+((i>>>17|i<<15)^(i>>>19|i<<13)^i>>>10)|0;e[n]=o+a|0}i=0|t.a[0],r=0|t.a[1];var s=0|t.a[2],u=0|t.a[3],c=0|t.a[4],h=0|t.a[5],f=0|t.a[6];for(o=0|t.a[7],n=0;64>n;n++){var l=((i>>>2|i<<30)^(i>>>13|i<<19)^(i>>>22|i<<10))+(i&r^i&s^r&s)|0;a=c&h^~c&f,o=o+((c>>>6|c<<26)^(c>>>11|c<<21)^(c>>>25|c<<7))|0,a=a+(0|Pc[n])|0,a=o+(a+(0|e[n])|0)|0,o=f,f=h,h=c,c=u+a|0,u=s,s=r,r=i,i=a+l|0}t.a[0]=t.a[0]+i|0,t.a[1]=t.a[1]+r|0,t.a[2]=t.a[2]+s|0,t.a[3]=t.a[3]+u|0,t.a[4]=t.a[4]+c|0,t.a[5]=t.a[5]+h|0,t.a[6]=t.a[6]+f|0,t.a[7]=t.a[7]+o|0}function Bn(n,e,i){void 0===i&&(i=e.length);var r=0,o=n.c;if(t(e))for(;r=a&&a==(0|a)))throw Error("message must be a byte array");n.f[o++]=a,o==n.b&&(Xn(n),o=0)}}n.c=o,n.g+=i}function Hn(){qn.call(this,8,Uc)}function Wn(n){if(n.P&&"function"==typeof n.P)return n.P();if(t(n))return n.split("");if(s(n)){for(var e=[],i=n.length,r=0;rn)throw Error("Bad port number "+n);t.i=n}else t.i=null}function Qn(t,n,e){n instanceof se?(t.a=n,ve(t.a,t.f)):(e||(n=oe(n,qc)),t.a=new se(n,0,t.f))}function te(t,n,e){t.a.set(n,e)}function ne(t,n){return t.a.get(n)}function ee(t){return t instanceof Yn?new Yn(t):new Yn(t,void 0)}function ie(t,n){var e=new Yn(null,void 0);return $n(e,"https"),t&&(e.b=t),n&&(e.g=n),e}function re(t,n){return t?n?decodeURI(t.replace(/%25/g,"%2525")):decodeURIComponent(t):""}function oe(n,e,i){return t(n)?(n=encodeURI(n).replace(e,ae),i&&(n=n.replace(/%25([0-9a-fA-F]{2})/g,"%$1")),n):null}function ae(t){return t=t.charCodeAt(0),"%"+(t>>4&15).toString(16)+(15&t).toString(16)}function se(t,n,e){this.b=this.a=null,this.c=t||null,this.f=!!e}function ue(t){t.a||(t.a=new kn,t.b=0,t.c&&Jn(t.c,function(n,e){he(t,decodeURIComponent(n.replace(/\+/g," ")),e)}))}function ce(t){var n=Gn(t);if(void 0===n)throw Error("Keys are undefined");var e=new se(null,0,void 0);t=Wn(t);for(var i=0;i2*t.c&&An(t)))}function le(t,n){return ue(t),n=de(t,n),En(t.a.b,n)}function pe(t,n,e){fe(t,n),0t||Cu&&Mu&&!(9',t=Rt(t),a.document.write(_t(t)),a.document.close())):a=t.open(St(n),e,a),a)try{a.focus()}catch(t){}return a}function Je(t){return new Z(function(n){function e(){gn(2e3).then(function(){if(t&&!t.closed)return e();n()})}return e()})}function Ye(){var t=null;return new Z(function(n){"complete"==uu.document.readyState?n():(t=function(){n()},nn(window,"load",t))}).s(function(n){throw en(window,"load",t),n})}function $e(){return Ze(void 0)?Ye().then(function(){return new Z(function(t,n){var e=uu.document,i=setTimeout(function(){n(Error("Cordova framework is not ready."))},1e3);e.addEventListener("deviceready",function(){clearTimeout(i),t()},!1)})}):et(Error("Cordova must run in an Android or iOS file scheme."))}function Ze(t){return t=t||ri(),!("file:"!==ci()||!t.toLowerCase().match(/iphone|ipad|ipod|android/))}function Qe(){var t=uu.window;try{return!(!t||t==t.top)}catch(t){return!1}}function ti(){return au.INTERNAL.hasOwnProperty("reactNative")?"ReactNative":au.INTERNAL.hasOwnProperty("node")?"Node":"Browser"}function ni(){var t=ti();return"ReactNative"===t||"Node"===t}function ei(t){var n=t.toLowerCase();return b(n,"opera/")||b(n,"opr/")||b(n,"opios/")?"Opera":b(n,"iemobile")?"IEMobile":b(n,"msie")||b(n,"trident/")?"IE":b(n,"edge/")?"Edge":b(n,"firefox/")?th:b(n,"silk/")?"Silk":b(n,"blackberry")?"Blackberry":b(n,"webos")?"Webos":!b(n,"safari/")||b(n,"chrome/")||b(n,"crios/")||b(n,"android")?!b(n,"chrome/")&&!b(n,"crios/")||b(n,"edge/")?b(n,"android")?"Android":(t=t.match(/([a-zA-Z\d\.]+)\/[a-zA-Z\d\.]*$/))&&2==t.length?t[1]:"Other":nh:"Safari"}function ii(t,n){n=n||[];var e,i=[],r={};for(e in eh)r[eh[e]]=!0;for(e=0;en)throw Error("Short delay should be less than long delay!");this.c=t,this.b=n,t=e||ri(),i=i||ti(),this.a=We(t)||"ReactNative"===i}function wi(){var t=uu.document;return!t||void 0===t.visibilityState||"visible"==t.visibilityState}function yi(){var t=uu.document,n=null;return wi()||!t?nt():new Z(function(e){n=function(){wi()&&(t.removeEventListener("visibilitychange",n,!1),e())},t.addEventListener("visibilitychange",n,!1)}).s(function(e){throw t.removeEventListener("visibilitychange",n,!1),e})}function Ii(t){try{var n=new Date(parseInt(t,10));if(!isNaN(n.getTime())&&!/[^0-9]/.test(t))return n.toUTCString()}catch(t){}return null}function Ti(t,n,e){ih?Object.defineProperty(t,n,{configurable:!0,enumerable:!0,value:e}):t[n]=e}function ki(t,n){if(n)for(var e in n)n.hasOwnProperty(e)&&Ti(t,e,n[e])}function Ai(t){var n={};return ki(n,t),n}function Ei(t){var n,e={};for(n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}function Ni(t,n){if(!n||!n.length)return!0;if(!t)return!1;for(var e=0;e Auth section -> Sign in method tab.",t):"http"==i||"https"==i?e=m("This domain (%s) is not authorized to run this operation. Add it to the OAuth redirect domains list in the Firebase console -> Auth section -> Sign in method tab.",t):n="operation-not-supported-in-this-environment",Pi.call(this,n,e)}function pr(t,n,e){Pi.call(this,t,e),t=n||{},t.rb&&Ti(this,"email",t.rb),t.Y&&Ti(this,"phoneNumber",t.Y),t.credential&&Ti(this,"credential",t.credential)}function dr(t){if(t.code){var n=t.code||"";0==n.indexOf(ph)&&(n=n.substring(ph.length));var e={credential:ur(t)};if(t.email)e.rb=t.email;else{if(!t.phoneNumber)return new Pi(n,t.message||void 0);e.Y=t.phoneNumber}return new pr(n,e,t.message)}return null}function vr(t){this.f=t}function mr(t,n,e){var i="Node"==ti();if(!(i=uu.XMLHttpRequest||i&&au.INTERNAL.node&&au.INTERNAL.node.XMLHttpRequest))throw new Pi("internal-error","The XMLHttpRequest compatibility library was not found.");this.b=t,t=n||{},this.i=t.secureTokenEndpoint||"https://securetoken.googleapis.com/v1/token",this.l=t.secureTokenTimeout||Ch,this.c=x(t.secureTokenHeaders||_h),this.g=t.firebaseEndpoint||"https://www.googleapis.com/identitytoolkit/v3/relyingparty/",this.h=t.firebaseTimeout||Rh,this.a=x(t.firebaseHeaders||Dh),e&&(this.a["X-Client-Version"]=e,this.c["X-Client-Version"]=e),this.f=new Me,this.o=new vr(i)}function gr(t,n){n?t.a["X-Firebase-Locale"]=n:delete t.a["X-Firebase-Locale"]}function br(t,n){n?(t.a["X-Client-Version"]=n,t.c["X-Client-Version"]=n):(delete t.a["X-Client-Version"],delete t.c["X-Client-Version"])}function wr(t,n,e,i,r,o,a){gi()?(He()?t=l(t.m,t):(Oh||(Oh=new Z(function(t,n){yr(t,n)})),t=l(t.u,t)),t(n,e,i,r,o,a)):e&&e(null)}function yr(t,n){((window.gapi||{}).client||{}).request?t():(uu[xh]=function(){((window.gapi||{}).client||{}).request?t():n(Error("CORS_UNSUPPORTED"))},Ln(De(At(Lh,{onload:xh})),function(){n(Error("CORS_UNSUPPORTED"))}))}function Ir(t,n){return new Z(function(e,i){"refresh_token"==n.grant_type&&n.refresh_token||"authorization_code"==n.grant_type&&n.code?wr(t,t.i+"?key="+encodeURIComponent(t.b),function(t){t?t.error?i(Vr(t)):t.access_token&&t.refresh_token?e(t):i(new Pi("internal-error")):i(new Pi("network-request-failed"))},"POST",""+ce(n),t.c,t.l.get()):i(new Pi("internal-error"))})}function Tr(t,n,e,i,r,o){var a=ee(t.g+n);te(a,"key",t.b),o&&te(a,"cb",""+fu());var s="GET"==e;if(s)for(var u in i)i.hasOwnProperty(u)&&te(a,u,i[u]);return new Z(function(n,o){wr(t,""+a,function(t){t?t.error?o(Vr(t,r||{})):n(t):o(new Pi("network-request-failed"))},e,s?void 0:Mt(li(i)),t.a,t.h.get())})}function kr(t){if(!Yc.test(t.email))throw new Pi("invalid-email")}function Ar(t){"email"in t&&kr(t)}function Er(t,n){return Ur(t,Kh,{identifier:n,continueUri:ui()?qe():"http://localhost"}).then(function(t){return t.allProviders||[]})}function Nr(t){return Ur(t,Gh,{}).then(function(t){return t.authorizedDomains||[]})}function Sr(t){if(!t[Ph])throw new Pi("internal-error")}function Or(t){if(t.phoneNumber||t.temporaryProof){if(!t.phoneNumber||!t.temporaryProof)throw new Pi("internal-error")}else{if(!t.sessionInfo)throw new Pi("missing-verification-id");if(!t.code)throw new Pi("missing-verification-code")}}function Pr(t,n){return Ur(t,Yh,n)}function Cr(t,n,e){return Ur(t,Xh,{idToken:n,deleteProvider:e})}function _r(t){if(!t.requestUri||!t.sessionId&&!t.postBody)throw new Pi("internal-error")}function Rr(t){var n=null;if(t.needConfirmation?(t.code="account-exists-with-different-credential",n=dr(t)):"FEDERATED_USER_ID_ALREADY_LINKED"==t.errorMessage?(t.code="credential-already-in-use",n=dr(t)):"EMAIL_EXISTS"==t.errorMessage?(t.code="email-already-in-use",n=dr(t)):t.errorMessage&&(n=Mr(t.errorMessage)),n)throw n;if(!t[Ph])throw new Pi("internal-error")}function Dr(t,n){return n.returnIdpCredential=!0,Ur(t,tf,n)}function Lr(t,n){return n.returnIdpCredential=!0,Ur(t,ef,n)}function xr(t,n){return n.returnIdpCredential=!0,n.autoCreate=!1,Ur(t,nf,n)}function jr(t){if(!t.oobCode)throw new Pi("invalid-action-code")}function Ur(t,n,e){if(!Ni(e,n.ea))return et(new Pi("internal-error"));var i,r=n.yb||"POST";return nt(e).then(n.D).then(function(){return n.T&&(e.returnSecureToken=!0),Tr(t,n.endpoint,r,e,n.Lb,n.nb||!1)}).then(function(t){return i=t}).then(n.O).then(function(){if(!n.ga)return i;if(!(n.ga in i))throw new Pi("internal-error");return i[n.ga]})}function Mr(t){return Vr({error:{errors:[{message:t}],code:400,message:t}})}function Vr(t,n){var e=(t.error&&t.error.errors&&t.error.errors[0]||{}).reason||"",i={keyInvalid:"invalid-api-key",ipRefererBlocked:"app-not-authorized"};if(e=i[e]?new Pi(i[e]):null)return e;e=t.error&&t.error.message||"",i={INVALID_CUSTOM_TOKEN:"invalid-custom-token",CREDENTIAL_MISMATCH:"custom-token-mismatch",MISSING_CUSTOM_TOKEN:"internal-error",INVALID_IDENTIFIER:"invalid-email",MISSING_CONTINUE_URI:"internal-error",INVALID_EMAIL:"invalid-email",INVALID_PASSWORD:"wrong-password",USER_DISABLED:"user-disabled",MISSING_PASSWORD:"internal-error",EMAIL_EXISTS:"email-already-in-use",PASSWORD_LOGIN_DISABLED:"operation-not-allowed",INVALID_IDP_RESPONSE:"invalid-credential",FEDERATED_USER_ID_ALREADY_LINKED:"credential-already-in-use",INVALID_MESSAGE_PAYLOAD:"invalid-message-payload",INVALID_RECIPIENT_EMAIL:"invalid-recipient-email",INVALID_SENDER:"invalid-sender",EMAIL_NOT_FOUND:"user-not-found",EXPIRED_OOB_CODE:"expired-action-code",INVALID_OOB_CODE:"invalid-action-code",MISSING_OOB_CODE:"internal-error",CREDENTIAL_TOO_OLD_LOGIN_AGAIN:"requires-recent-login",INVALID_ID_TOKEN:"invalid-user-token",TOKEN_EXPIRED:"user-token-expired",USER_NOT_FOUND:"user-token-expired",CORS_UNSUPPORTED:"cors-unsupported",DYNAMIC_LINK_NOT_ACTIVATED:"dynamic-link-not-activated",INVALID_APP_ID:"invalid-app-id",TOO_MANY_ATTEMPTS_TRY_LATER:"too-many-requests",WEAK_PASSWORD:"weak-password",OPERATION_NOT_ALLOWED:"operation-not-allowed",USER_CANCELLED:"user-cancelled",CAPTCHA_CHECK_FAILED:"captcha-check-failed",INVALID_APP_CREDENTIAL:"invalid-app-credential",INVALID_CODE:"invalid-verification-code",INVALID_PHONE_NUMBER:"invalid-phone-number",INVALID_SESSION_INFO:"invalid-verification-id",INVALID_TEMPORARY_PROOF:"invalid-credential",MISSING_APP_CREDENTIAL:"missing-app-credential",MISSING_CODE:"missing-verification-code",MISSING_PHONE_NUMBER:"missing-phone-number",MISSING_SESSION_INFO:"missing-verification-id",QUOTA_EXCEEDED:"quota-exceeded",SESSION_EXPIRED:"code-expired",INVALID_CONTINUE_URI:"invalid-continue-uri",MISSING_ANDROID_PACKAGE_NAME:"missing-android-pkg-name",MISSING_IOS_BUNDLE_ID:"missing-ios-bundle-id",UNAUTHORIZED_DOMAIN:"unauthorized-continue-uri",INVALID_OAUTH_CLIENT_ID:"invalid-oauth-client-id",INVALID_CERT_HASH:"invalid-cert-hash"},j(i,n||{}),n=(n=e.match(/^[^\s]+\s*:\s*(.*)$/))&&1n.c?Bn(n,xc,56-n.c):Bn(n,xc,n.b-(n.c-56));for(var i=63;56<=i;i--)n.f[i]=255&e,e/=256;for(Xn(n),i=e=0;i>r&255;return Sn(t)}function Mo(t,n,e,i){var r=jo(),o=new hr(n,i,null,r,new Pi("no-auth-event")),a=oi("BuildInfo.packageName",uu);if("string"!=typeof a)throw new Pi("invalid-cordova-configuration");var s=oi("BuildInfo.displayName",uu),u={};if(ri().toLowerCase().match(/iphone|ipad|ipod/))u.ibi=a;else{if(!ri().toLowerCase().match(/android/))return et(new Pi("operation-not-supported-in-this-environment"));u.apn=a}s&&(u.appDisplayName=s),r=Uo(r),u.sessionId=r;var c=Qr(t.u,t.i,t.l,n,e,null,i,t.m,u,t.o);return t.ba().then(function(){var n=t.h;return t.A.a.set(If,o.B(),n)}).then(function(){var n=oi("cordova.plugins.browsertab.isAvailable",uu);if("function"!=typeof n)throw new Pi("invalid-cordova-configuration");var e=null;n(function(n){if(n){if("function"!=typeof(e=oi("cordova.plugins.browsertab.openUrl",uu)))throw new Pi("invalid-cordova-configuration");e(c)}else{if("function"!=typeof(e=oi("cordova.InAppBrowser.open",uu)))throw new Pi("invalid-cordova-configuration");n=ri(),n=!(!n.match(/(iPad|iPhone|iPod).*OS 7_\d/i)&&!n.match(/(iPad|iPhone|iPod).*OS 8_\d/i)),t.a=e(c,n?"_blank":"_system","location=yes")}})})}function Vo(t,n){for(var e=0;et.f&&(t.a=t.f),n)}function pa(t,n){da(t),t.b=gn(la(t,n)).then(function(){return t.l?nt():yi()}).then(function(){return t.h()}).then(function(){pa(t,!0)}).s(function(n){t.i(n)&&pa(t,!1)})}function da(t){t.b&&(t.b.cancel(),t.b=null)}function va(t){this.f=t,this.b=this.a=null,this.c=0}function ma(t,n){var e=n[Ph],i=n.refreshToken;n=ga(n.expiresIn),t.b=e,t.c=n,t.a=i}function ga(t){return fu()+1e3*parseInt(t,10)}function ba(t,n){return Ir(t.f,n).then(function(n){return t.b=n.access_token,t.c=ga(n.expires_in),t.a=n.refresh_token,{accessToken:t.b,expirationTime:t.c,refreshToken:t.a}}).s(function(n){throw"auth/user-token-expired"==n.code&&(t.a=null),n})}function wa(t,n){this.a=t||null,this.b=n||null,ki(this,{lastSignInTime:Ii(n||null),creationTime:Ii(t||null)})}function ya(t){return new wa(t.a,t.b)}function Ia(t,n,e,i,r,o){ki(this,{uid:t,displayName:i||null,photoURL:r||null,email:e||null,phoneNumber:o||null,providerId:n})}function Ta(t,n){Bt.call(this,t);for(var e in n)this[e]=n[e]}function ka(t,n,e){this.A=[],this.G=t.apiKey,this.o=t.appName,this.w=t.authDomain||null,t=au.SDK_VERSION?ii(au.SDK_VERSION):null,this.c=new mr(this.G,Fr(Uh),t),this.h=new va(this.c),_a(this,n[Ph]),ma(this.h,n),Ti(this,"refreshToken",this.h.a),xa(this,e||{}),fn.call(this),this.I=!1,this.w&&si()&&(this.a=Qo(this.w,this.G,this.o)),this.N=[],this.i=null,this.l=Oa(this),this.U=l(this.Ga,this);var i=this;this.ha=null,this.ra=function(t){i.na(t.h)},this.W=null,this.R=[],this.qa=function(t){Ea(i,t.f)},this.V=null}function Aa(t,n){t.W&&en(t.W,"languageCodeChanged",t.ra),(t.W=n)&&Zt(n,"languageCodeChanged",t.ra)}function Ea(t,n){t.R=n,br(t.c,au.SDK_VERSION?ii(au.SDK_VERSION,t.R):null)}function Na(t,n){t.V&&en(t.V,"frameworkChanged",t.qa),(t.V=n)&&Zt(n,"frameworkChanged",t.qa)}function Sa(t){try{return au.app(t.o).auth()}catch(n){throw new Pi("internal-error","No firebase.auth.Auth instance is available for the Firebase App '"+t.o+"'!")}}function Oa(t){return new fa(function(){return t.F(!0)},function(t){return!(!t||"auth/network-request-failed"!=t.code)},function(){var n=t.h.c-fu()-3e5;return 0r||r>=Of.length)throw new Pi("internal-error","Argument validator received an unsupported number of arguments.");e=Of[r],i=(i?"":e+" argument ")+(n.name?'"'+n.name+'" ':"")+"must be "+n.K+".";break t}i=null}}if(i)throw new Pi("argument-error",t+" failed: "+i)}function Ls(n,e){return{name:n||"",K:"a valid string",optional:!!e,M:t}}function xs(){return{name:"opt_forceRefresh",K:"a boolean",optional:!0,M:n}}function js(t,n){return{name:t||"",K:"a valid object",optional:!!n,M:c}}function Us(t,n){return{name:t||"",K:"a function",optional:!!n,M:u}}function Ms(t,n){return{name:t||"",K:"null",optional:!!n,M:o}}function Vs(){return{name:"",K:"an HTML element",optional:!1,M:function(t){return!!(t&&t instanceof Element)}}}function Fs(){return{name:"auth",K:"an instance of Firebase Auth",optional:!0,M:function(t){return!!(t&&t instanceof vs)}}}function Ks(){return{name:"app",K:"an instance of Firebase App",optional:!0,M:function(t){return!!(t&&t instanceof au.app.App)}}}function qs(t){return{name:t?t+"Credential":"credential",K:t?"a valid "+t+" credential":"a valid credential",optional:!1,M:function(n){if(!n)return!1;var e=!t||n.providerId===t;return!(!n.wa||!e)}}}function Xs(){return{name:"authProvider",K:"a valid Auth provider",optional:!1,M:function(t){return!!(t&&t.providerId&&t.hasOwnProperty&&t.hasOwnProperty("isOAuthProvider"))}}}function Bs(){return{name:"applicationVerifier",K:"an implementation of firebase.auth.ApplicationVerifier",optional:!1,M:function(n){return!!(n&&t(n.type)&&u(n.verify))}}}function Hs(t,n,e,i){return{name:e||"",K:t.K+" or "+n.K,optional:!!i,M:function(e){return t.M(e)||n.M(e)}}}function Ws(t,n,e,i,r,o){if(Ti(this,"type","recaptcha"),this.b=this.c=null,this.m=!1,this.l=n,this.a=e||{theme:"light",type:"image"},this.g=[],this.a[_f])throw new Pi("argument-error","sitekey should not be provided for reCAPTCHA as one is automatically provisioned for the current project.");if(this.h="invisible"===this.a[Rf],!Dt(n)||!this.h&&Dt(n).hasChildNodes())throw new Pi("argument-error","reCAPTCHA container is either not found or already contains inner elements!");this.u=new mr(t,o||null,r||null),this.o=i||function(){return null};var a=this;this.i=[];var s=this.a[Pf];this.a[Pf]=function(t){if(Gs(a,t),"function"==typeof s)s(t);else if("string"==typeof s){var n=oi(s,uu);"function"==typeof n&&n(t)}};var u=this.a[Cf];this.a[Cf]=function(){if(Gs(a,null),"function"==typeof u)u();else if("string"==typeof u){var t=oi(u,uu);"function"==typeof t&&t()}}}function Gs(t,n){for(var e=0;e>>0),hu=0,fu=Date.now||function(){return+new Date};d(v,Error),v.prototype.name="CustomError";var lu=String.prototype.trim?function(t){return t.trim()}:function(t){return t.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},pu=/&/g,du=//g,mu=/"/g,gu=/'/g,bu=/\x00/g,wu=/[\x00&<>"']/;d(y,v),y.prototype.name="AssertionError";var yu,Iu=Array.prototype.indexOf?function(t,n,e){return Array.prototype.indexOf.call(t,n,e)}:function(n,e,i){if(i=null==i?0:0>i?Math.max(0,n.length+i):i,t(n))return t(e)&&1==e.length?n.indexOf(e,i):-1;for(;iparseFloat(xu)){Ou=Uu+"";break t}}Ou=xu}var Mu,Vu={},Fu=uu.document;Mu=Fu&&Cu?V()||("CSS1Compat"==Fu.compatMode?parseInt(Ou,10):5):void 0,X.prototype.get=function(){if(0"),Rt(""),Rt("
");var oc={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",nonce:"nonce",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",width:"width"},ac={'"':'\\"',"\\":"\\\\","/":"\\/","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\u000b"},sc=/\uffff/.test("￿")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g,uc=0,cc={};qt.prototype.oa=!1,qt.prototype.ta=function(){if(this.Fa)for(;this.Fa.length;)this.Fa.shift()()};var hc=Object.freeze||function(t){return t},fc=!Cu||9<=+Mu,lc=Cu&&!F("9"),pc=function(){if(!uu.addEventListener||!Object.defineProperty)return!1;var t=!1,n=Object.defineProperty({},"passive",{get:function(){t=!0}});return uu.addEventListener("test",i,n),uu.removeEventListener("test",i,n),t}();Bt.prototype.c=function(){this.Ab=!1},d(Ht,Bt);var dc=hc({2:"touch",3:"pen",4:"mouse"});Ht.prototype.c=function(){Ht.ib.c.call(this);var t=this.a;if(t.preventDefault)t.preventDefault();else if(t.returnValue=!1,lc)try{(t.ctrlKey||112<=t.keyCode&&123>=t.keyCode)&&(t.keyCode=-1)}catch(t){}},Ht.prototype.g=function(){return this.a};var vc="closure_listenable_"+(1e6*Math.random()|0),mc=0,gc="closure_lm_"+(1e6*Math.random()|0),bc={},wc=0,yc="__closure_events_fn_"+(1e9*Math.random()>>>0);d(fn,qt),fn.prototype[vc]=!0,fn.prototype.removeEventListener=function(t,n,e,i){en(this,t,n,e,i)},fn.prototype.ta=function(){if(fn.ib.ta.call(this),this.u){var t,n=this.u,e=0;for(t in n.a){for(var i=n.a[t],r=0;r=In(this).value)for(u(n)&&(n=n()),t=new bn(t,n+"",this.f),e&&(t.a=e),e="log:"+t.b,(t=uu.console)&&t.timeStamp&&t.timeStamp(e),(t=uu.msWriteProfilerMark)&&t(e),e=this;e;)e=e.a};var Ec={},Nc=null;ou=kn.prototype,ou.P=function(){An(this);for(var t=[],n=0;n=--n.l&&n.cancel()}this.v?this.v.call(this.o,this):this.u=!0,this.a||(t=new Vn,Dn(this),Rn(this,!1,t))}},_n.prototype.m=function(t,n){this.i=!1,Rn(this,t,n)},_n.prototype.A=function(t){Dn(this),Rn(this,!0,t)},_n.prototype.then=function(t,n,e){var i,r,o=new Z(function(t,n){i=t,r=n});return xn(this,i,function(t){t instanceof Vn?o.cancel():r(t)}),o.then(t,n,e)},K(_n),d(Mn,v),Mn.prototype.message="Deferred has already fired",Mn.prototype.name="AlreadyCalledError",d(Vn,v),Vn.prototype.message="Deferred was canceled",Vn.prototype.name="CanceledError",Fn.prototype.c=function(){throw delete Cc[this.a],this.b};var Pc,Cc={};d(qn,Kn);for(var _c=64,Rc=_c-1,Dc=[],Lc=0;Lcthis.c-3e4?this.a?ba(this,{grant_type:"refresh_token",refresh_token:this.a}):nt(null):nt({accessToken:this.b,expirationTime:this.c,refreshToken:this.a})},wa.prototype.B=function(){return{lastLoginAt:this.b,createdAt:this.a}},d(Ta,Bt),d(ka,fn),ka.prototype.na=function(t){this.ha=t,gr(this.c,t)},ka.prototype.$=function(){return this.ha},ka.prototype.Ka=function(){return O(this.R)},ka.prototype.Ga=function(){this.l.b&&(da(this.l),this.l.start())},Ti(ka.prototype,"providerId","firebase"),ou=ka.prototype,ou.reload=function(){var t=this;return Qa(this,Ua(this).then(function(){return Xa(t).then(function(){return Da(t)}).then(ja)}))},ou.F=function(t){var n=this;return Qa(this,Ua(this).then(function(){return n.h.getToken(t)}).then(function(t){if(!t)throw new Pi("internal-error");return t.accessToken!=n.pa&&(_a(n,t.accessToken),ln(n,new Ta("tokenChanged"))),Ka(n,"refreshToken",t.refreshToken),t.accessToken}))},ou.getToken=function(t){return rh["firebase.User.prototype.getToken is deprecated. Please use firebase.User.prototype.getIdToken instead."]||(rh["firebase.User.prototype.getToken is deprecated. Please use firebase.User.prototype.getIdToken instead."]=!0,"undefined"!=typeof console&&"function"==typeof console.warn&&console.warn("firebase.User.prototype.getToken is deprecated. Please use firebase.User.prototype.getIdToken instead.")),this.F(t)},ou.gc=function(t){if(!(t=t.users)||!t.length)throw new Pi("internal-error");t=t[0],xa(this,{uid:t.localId,displayName:t.displayName,photoURL:t.photoUrl,email:t.email,emailVerified:!!t.emailVerified,phoneNumber:t.phoneNumber,lastLoginAt:t.lastLoginAt,createdAt:t.createdAt});for(var n=Wa(t),e=0;ethis.o&&(this.o=0),0==this.o&&Os(this)&&Ca(Os(this)),this.removeAuthTokenListener(t)},ou.addAuthTokenListener=function(t){var n=this;this.m.push(t),Rs(this,this.i.then(function(){n.l||A(n.m,t)&&t(Ps(n))}))},ou.removeAuthTokenListener=function(t){N(this.m,function(n){return n==t})},ou.delete=function(){this.l=!0;for(var t=0;tn?r.push(e.substring(i,n)):r.push(e.substring(i,i+t));return r},t.each=function(e,t){if(Array.isArray(e))for(var n=0;n=Math.pow(2,-1022)?(a=Math.min(Math.floor(Math.log(e)/Math.LN2),1023),i=a+1023,o=Math.round(e*Math.pow(2,52-a)-Math.pow(2,52))):(i=0,o=Math.round(e/Math.pow(2,-1074)))),u=[],s=52;s;s-=1)u.push(o%2?1:0),o=Math.floor(o/2);for(s=11;s;s-=1)u.push(i%2?1:0),i=Math.floor(i/2);u.push(n?1:0),u.reverse(),l=u.join("");var h="";for(s=0;s<64;s+=8){var c=parseInt(l.substr(s,8),2).toString(16);1===c.length&&(c="0"+c),h+=c}return h.toLowerCase()},t.isChromeExtensionContentScript=function(){return!("object"!=typeof window||!window.chrome||!window.chrome.extension||/^chrome/.test(window.location.href))},t.isWindowsStoreApp=function(){return"object"==typeof Windows&&"object"==typeof Windows.UI},t.errorForServerCode=function(e,t){var n="Unknown Error";"too_big"===e?n="The data requested exceeds the maximum size that can be accessed with a single request.":"permission_denied"==e?n="Client doesn't have permission to access the desired data.":"unavailable"==e&&(n="The service is unavailable");var r=Error(e+" at "+t.path+": "+n);return r.code=e.toUpperCase(),r},t.e=RegExp("^-?\\d{1,10}$"),t.tryParseInt=function(e){if(t.e.test(e)){var n=+e;if(n>=-2147483648&&n<=2147483647)return n}return null},t.exceptionGuard=function(e){try{e()}catch(e){setTimeout(function(){var n=e.stack||"";throw t.warn("Exception was thrown by user callback.",n),e},Math.floor(0))}},t.callUserCallback=function(e){for(var n=[],r=1;r=0},t.exportPropGetter=function(e,t,n){Object.defineProperty(e,t,{get:n})},t.setTimeoutNonBlocking=function(e,t){var n=setTimeout(e,t);return"object"==typeof n&&n.unref&&n.unref(),n}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),i=n(0),o=function(){function e(e,t){if(void 0===t){this.n=e.split("/");for(var n=0,r=0;r0&&(this.n[n]=this.n[r],n++);this.n.length=n,this.i=0}else this.n=e,this.i=t}return Object.defineProperty(e,"Empty",{get:function(){return new e("")},enumerable:!0,configurable:!0}),e.prototype.getFront=function(){return this.i>=this.n.length?null:this.n[this.i]},e.prototype.getLength=function(){return this.n.length-this.i},e.prototype.popFront=function(){var t=this.i;return t=this.n.length)return null;for(var t=[],n=this.i;n0&&n.push(i[r]);return new e(n,0)},e.prototype.isEmpty=function(){return this.i>=this.n.length},e.relativePath=function(t,n){var r=t.getFront(),i=n.getFront();if(null===r)return n;if(r===i)return e.relativePath(t.popFront(),n.popFront());throw Error("INTERNAL ERROR: innerPath ("+n+") is not within outerPath ("+t+")")},e.comparePaths=function(e,t){for(var n=e.slice(),i=t.slice(),o=0;oe.getLength())return!1;for(;t0&&(this.l+=1),this.u.push(e),this.l+=i.stringLength(e),this.f()},e.prototype.pop=function(){var e=this.u.pop();this.l-=i.stringLength(e),this.u.length>0&&(this.l-=1)},e.prototype.f=function(){if(this.l>e.MAX_PATH_LENGTH_BYTES)throw Error(this.o+"has a key path longer than "+e.MAX_PATH_LENGTH_BYTES+" bytes ("+this.l+").");if(this.u.length>e.MAX_PATH_DEPTH)throw Error(this.o+"path specified exceeds the maximum depth that can be written ("+e.MAX_PATH_DEPTH+") or object contains a cycle "+this.toErrorString())},e.prototype.toErrorString=function(){return 0==this.u.length?"":"in property '"+this.u.join(".")+"'"},e}();t.ValidationPath=a},function(e,t,n){"use strict";function r(e){a=e}function i(e){s=e}var o=this&&this.__extends||function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();Object.defineProperty(t,"__esModule",{value:!0});var a,s,u=n(14),l=n(1),h=n(5),c=n(15);t.setNodeFromJSON=r,t.setMaxNode=i;var p=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return o(t,e),t.prototype.compare=function(e,t){var n=e.node.getPriority(),r=t.node.getPriority(),i=n.compareTo(r);return 0===i?l.nameCompare(e.name,t.name):i},t.prototype.isDefinedOn=function(e){return!e.getPriority().isEmpty()},t.prototype.indexedValueChanged=function(e,t){return!e.getPriority().equals(t.getPriority())},t.prototype.minPost=function(){return h.NamedNode.MIN},t.prototype.maxPost=function(){return new h.NamedNode(l.MAX_NAME,new c.LeafNode("[PRIORITY-POST]",s))},t.prototype.makePost=function(e,t){var n=a(e);return new h.NamedNode(t,new c.LeafNode("[PRIORITY-POST]",n))},t.prototype.toString=function(){return".priority"},t}(u.Index);t.PriorityIndex=p,t.PRIORITY_INDEX=new p},function(e,t,n){"use strict";var r=this&&this.__extends||function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();Object.defineProperty(t,"__esModule",{value:!0});var i,o=n(0),a=n(1),s=n(16),u=n(5),l=n(37),h=n(3),c=n(10),p=n(39),d=n(15),f=n(41),_=function(){function e(e,t,n){this._=e,this.y=t,this.g=n,this.m=null,this.y&&l.validatePriorityNode(this.y),this._.isEmpty()&&o.assert(!this.y||this.y.isEmpty(),"An empty node cannot have a priority")}return Object.defineProperty(e,"EMPTY_NODE",{get:function(){return i||(i=new e(new s.SortedMap(f.NAME_COMPARATOR),null,p.IndexMap.Default))},enumerable:!0,configurable:!0}),e.prototype.isLeafNode=function(){return!1},e.prototype.getPriority=function(){return this.y||i},e.prototype.updatePriority=function(t){return this._.isEmpty()?this:new e(this._,t,this.g)},e.prototype.getImmediateChild=function(e){if(".priority"===e)return this.getPriority();var t=this._.get(e);return null===t?i:t},e.prototype.getChild=function(e){var t=e.getFront();return null===t?this:this.getImmediateChild(t).getChild(e.popFront())},e.prototype.hasChild=function(e){return null!==this._.get(e)},e.prototype.updateImmediateChild=function(t,n){if(o.assert(n,"We should always be passing snapshot nodes"),".priority"===t)return this.updatePriority(n);var r=new u.NamedNode(t,n),a=void 0,s=void 0,l=void 0;return n.isEmpty()?(a=this._.remove(t),s=this.g.removeFromIndexes(r,this._)):(a=this._.insert(t,n),s=this.g.addToIndexes(r,this._)),l=a.isEmpty()?i:this.y,new e(a,l,s)},e.prototype.updateChild=function(e,t){var n=e.getFront();if(null===n)return t;o.assert(".priority"!==e.getFront()||1===e.getLength(),".priority must be the last token in a path");var r=this.getImmediateChild(n).updateChild(e.popFront(),t);return this.updateImmediateChild(n,r)},e.prototype.isEmpty=function(){return this._.isEmpty()},e.prototype.numChildren=function(){return this._.count()},e.prototype.val=function(t){if(this.isEmpty())return null;var n={},r=0,i=0,o=!0;if(this.forEachChild(h.PRIORITY_INDEX,function(a,s){n[a]=s.val(t),r++,o&&e.e.test(a)?i=Math.max(i,+a):o=!1}),!t&&o&&i<2*r){var a=[];for(var s in n)a[s]=n[s];return a}return t&&!this.getPriority().isEmpty()&&(n[".priority"]=this.getPriority().val()),n},e.prototype.hash=function(){if(null===this.m){var e="";this.getPriority().isEmpty()||(e+="priority:"+l.priorityHashText(this.getPriority().val())+":"),this.forEachChild(h.PRIORITY_INDEX,function(t,n){var r=n.hash();""!==r&&(e+=":"+t+":"+r)}),this.m=""===e?"":a.sha1(e)}return this.m},e.prototype.getPredecessorChildName=function(e,t,n){var r=this.C(n);if(r){var i=r.getPredecessorKey(new u.NamedNode(e,t));return i?i.name:null}return this._.getPredecessorKey(e)},e.prototype.getFirstChildName=function(e){var t=this.C(e);if(t){var n=t.minKey();return n&&n.name}return this._.minKey()},e.prototype.getFirstChild=function(e){var t=this.getFirstChildName(e);return t?new u.NamedNode(t,this._.get(t)):null},e.prototype.getLastChildName=function(e){var t=this.C(e);if(t){var n=t.maxKey();return n&&n.name}return this._.maxKey()},e.prototype.getLastChild=function(e){var t=this.getLastChildName(e);return t?new u.NamedNode(t,this._.get(t)):null},e.prototype.forEachChild=function(e,t){var n=this.C(e);return n?n.inorderTraversal(function(e){return t(e.name,e.node)}):this._.inorderTraversal(t)},e.prototype.getIterator=function(e){return this.getIteratorFrom(e.minPost(),e)},e.prototype.getIteratorFrom=function(e,t){var n=this.C(t);if(n)return n.getIteratorFrom(e,function(e){return e});for(var r=this._.getIteratorFrom(e.name,u.NamedNode.Wrap),i=r.peek();null!=i&&t.compare(i,e)<0;)r.getNext(),i=r.peek();return r},e.prototype.getReverseIterator=function(e){return this.getReverseIteratorFrom(e.maxPost(),e)},e.prototype.getReverseIteratorFrom=function(e,t){var n=this.C(t);if(n)return n.getReverseIteratorFrom(e,function(e){return e});for(var r=this._.getReverseIteratorFrom(e.name,u.NamedNode.Wrap),i=r.peek();null!=i&&t.compare(i,e)>0;)r.getNext(),i=r.peek();return r},e.prototype.compareTo=function(e){return this.isEmpty()?e.isEmpty()?0:-1:e.isLeafNode()||e.isEmpty()?1:e===t.MAX_NODE?-1:0},e.prototype.withIndex=function(t){if(t===c.KEY_INDEX||this.g.hasIndex(t))return this;var n=this.g.addIndex(t,this._);return new e(this._,this.y,n)},e.prototype.isIndexed=function(e){return e===c.KEY_INDEX||this.g.hasIndex(e)},e.prototype.equals=function(e){if(e===this)return!0;if(e.isLeafNode())return!1;var t=e;if(this.getPriority().equals(t.getPriority())){if(this._.count()===t._.count()){for(var n=this.getIterator(h.PRIORITY_INDEX),r=t.getIterator(h.PRIORITY_INDEX),i=n.getNext(),o=r.getNext();i&&o;){if(i.name!==o.name||!i.node.equals(o.node))return!1;i=n.getNext(),o=r.getNext()}return null===i&&null===o}return!1}return!1},e.prototype.C=function(e){return e===c.KEY_INDEX?null:this.g.get(""+e)},e.e=/^(0|[1-9]\d*)$/,e}();t.ChildrenNode=_;var y=function(e){function t(){return e.call(this,new s.SortedMap(f.NAME_COMPARATOR),_.EMPTY_NODE,p.IndexMap.Default)||this}return r(t,e),t.prototype.compareTo=function(e){return e===this?0:1},t.prototype.equals=function(e){return e===this},t.prototype.getPriority=function(){return this},t.prototype.getImmediateChild=function(e){return _.EMPTY_NODE},t.prototype.isEmpty=function(){return!1},t}(_);t.MaxNode=y,t.MAX_NODE=new y,Object.defineProperties(u.NamedNode,{MIN:{value:new u.NamedNode(a.MIN_NAME,_.EMPTY_NODE)},MAX:{value:new u.NamedNode(a.MAX_NAME,t.MAX_NODE)}}),c.KeyIndex.__EMPTY_NODE=_.EMPTY_NODE,d.LeafNode.__childrenNodeConstructor=_,l.setMaxNode(t.MAX_NODE),h.setMaxNode(t.MAX_NODE)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){this.name=e,this.node=t}return e.Wrap=function(t,n){return new e(t,n)},e}();t.NamedNode=r},,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(2),i=n(0),o=n(1),a=n(0),s=n(0);t.N=/[\[\].#$\/\u0000-\u001F\u007F]/,t.P=/[\[\].#$\u0000-\u001F\u007F]/,t.S=10485760,t.isValidKey=function(e){return"string"==typeof e&&0!==e.length&&!t.N.test(e)},t.isValidPathString=function(e){return"string"==typeof e&&0!==e.length&&!t.P.test(e)},t.isValidRootPathString=function(e){return e&&(e=e.replace(/^\/*\.info(\/|$)/,"/")),t.isValidPathString(e)},t.isValidPriority=function(e){return null===e||"string"==typeof e||"number"==typeof e&&!o.isInvalidJSONNumber(e)||e&&"object"==typeof e&&i.contains(e,".sv")},t.validateFirebaseDataArg=function(e,n,r,i,o){o&&void 0===r||t.validateFirebaseData(a.errorPrefix(e,n,o),r,i)},t.validateFirebaseData=function(e,n,a){var u=a instanceof r.Path?new r.ValidationPath(a,e):a;if(void 0===n)throw Error(e+"contains undefined "+u.toErrorString());if("function"==typeof n)throw Error(e+"contains a function "+u.toErrorString()+" with contents = "+n);if(o.isInvalidJSONNumber(n))throw Error(e+"contains "+n+" "+u.toErrorString());if("string"==typeof n&&n.length>t.S/3&&s.stringLength(n)>t.S)throw Error(e+"contains a string greater than "+t.S+" utf8 bytes "+u.toErrorString()+" ('"+n.substring(0,50)+"...')");if(n&&"object"==typeof n){var l=!1,h=!1;if(i.forEach(n,function(n,r){if(".value"===n)l=!0;else if(".priority"!==n&&".sv"!==n&&(h=!0,!t.isValidKey(n)))throw Error(e+" contains an invalid key ("+n+") "+u.toErrorString()+'. Keys must be non-empty strings and can\'t contain ".", "#", "$", "/", "[", or "]"');u.push(n),t.validateFirebaseData(e,r,u),u.pop()}),l&&h)throw Error(e+' contains ".value" child '+u.toErrorString()+" in addition to actual children.")}},t.validateFirebaseMergePaths=function(e,n){var i,o;for(i=0;i=0,"Unknown leaf type: "+n),i.assert(a>=0,"Unknown leaf type: "+r),o===a?"object"===r?0:this.T0},e.prototype.peek=function(){if(0===this.O.length)return null;var e=this.O[this.O.length-1];return this.R?this.R(e.key,e.value):{key:e.key,value:e.value}},e}();t.SortedMapIterator=r;var i=function(){function e(t,n,r,i,o){this.key=t,this.value=n,this.color=null!=r?r:e.RED,this.left=null!=i?i:a.EMPTY_NODE,this.right=null!=o?o:a.EMPTY_NODE}return e.prototype.copy=function(t,n,r,i,o){return new e(null!=t?t:this.key,null!=n?n:this.value,null!=r?r:this.color,null!=i?i:this.left,null!=o?o:this.right)},e.prototype.count=function(){return this.left.count()+1+this.right.count()},e.prototype.isEmpty=function(){return!1},e.prototype.inorderTraversal=function(e){return this.left.inorderTraversal(e)||e(this.key,this.value)||this.right.inorderTraversal(e)},e.prototype.reverseTraversal=function(e){return this.right.reverseTraversal(e)||e(this.key,this.value)||this.left.reverseTraversal(e)},e.prototype.A=function(){return this.left.isEmpty()?this:this.left.A()},e.prototype.minKey=function(){return this.A().key},e.prototype.maxKey=function(){return this.right.isEmpty()?this.key:this.right.maxKey()},e.prototype.insert=function(e,t,n){var r,i;return i=this,r=n(e,i.key),i=r<0?i.copy(null,null,null,i.left.insert(e,t,n),null):0===r?i.copy(null,t,null,null,null):i.copy(null,null,null,null,i.right.insert(e,t,n)),i.D()},e.prototype.M=function(){if(this.left.isEmpty())return a.EMPTY_NODE;var e=this;return e.left.L()||e.left.left.L()||(e=e.F()),e=e.copy(null,null,null,e.left.M(),null),e.D()},e.prototype.remove=function(e,t){var n,r;if(n=this,t(e,n.key)<0)n.left.isEmpty()||n.left.L()||n.left.left.L()||(n=n.F()),n=n.copy(null,null,null,n.left.remove(e,t),null);else{if(n.left.L()&&(n=n.x()),n.right.isEmpty()||n.right.L()||n.right.left.L()||(n=n.k()),0===t(e,n.key)){if(n.right.isEmpty())return a.EMPTY_NODE;r=n.right.A(),n=n.copy(r.key,r.value,null,null,n.right.M())}n=n.copy(null,null,null,null,n.right.remove(e,t))}return n.D()},e.prototype.L=function(){return this.color},e.prototype.D=function(){var e=this;return e.right.L()&&!e.left.L()&&(e=e.W()),e.left.L()&&e.left.left.L()&&(e=e.x()),e.left.L()&&e.right.L()&&(e=e.j()),e},e.prototype.F=function(){var e=this.j();return e.right.left.L()&&(e=e.copy(null,null,null,null,e.right.x()),e=e.W(),e=e.j()),e},e.prototype.k=function(){var e=this.j();return e.left.left.L()&&(e=e.x(),e=e.j()),e},e.prototype.W=function(){var t=this.copy(null,null,e.RED,null,this.right.left);return this.right.copy(null,null,this.color,t,null)},e.prototype.x=function(){var t=this.copy(null,null,e.RED,this.left.right,null);return this.left.copy(null,null,this.color,null,t)},e.prototype.j=function(){var e=this.left.copy(null,null,!this.left.color,null,null),t=this.right.copy(null,null,!this.right.color,null,null);return this.copy(null,null,!this.color,e,t)},e.prototype.V=function(){var e=this.Q();return Math.pow(2,e)<=this.count()+1},e.prototype.Q=function(){var e;if(this.L()&&this.left.L())throw Error("Red node has red child("+this.key+","+this.value+")");if(this.right.L())throw Error("Right child of ("+this.key+","+this.value+") is red");if((e=this.left.Q())!==this.right.Q())throw Error("Black depths differ");return e+(this.L()?0:1)},e.RED=!0,e.BLACK=!1,e}();t.LLRBNode=i;var o=function(){function e(){}return e.prototype.copy=function(e,t,n,r,i){return this},e.prototype.insert=function(e,t,n){return new i(e,t,null)},e.prototype.remove=function(e,t){return this},e.prototype.count=function(){return 0},e.prototype.isEmpty=function(){return!0},e.prototype.inorderTraversal=function(e){return!1},e.prototype.reverseTraversal=function(e){return!1},e.prototype.minKey=function(){return null},e.prototype.maxKey=function(){return null},e.prototype.Q=function(){return 0},e.prototype.L=function(){return!1},e}();t.LLRBEmptyNode=o;var a=function(){function e(t,n){void 0===n&&(n=e.EMPTY_NODE),this.U=t,this.B=n}return e.prototype.insert=function(t,n){return new e(this.U,this.B.insert(t,n,this.U).copy(null,null,i.BLACK,null,null))},e.prototype.remove=function(t){return new e(this.U,this.B.remove(t,this.U).copy(null,null,i.BLACK,null,null))},e.prototype.get=function(e){for(var t,n=this.B;!n.isEmpty();){if(0===(t=this.U(e,n.key)))return n.value;t<0?n=n.left:t>0&&(n=n.right)}return null},e.prototype.getPredecessorKey=function(e){for(var t,n=this.B,r=null;!n.isEmpty();){if(0===(t=this.U(e,n.key))){if(n.left.isEmpty())return r?r.key:null;for(n=n.left;!n.right.isEmpty();)n=n.right;return n.key}t<0?n=n.left:t>0&&(r=n,n=n.right)}throw Error("Attempted to find predecessor key for a nonexistent key. What gives?")},e.prototype.isEmpty=function(){return this.B.isEmpty()},e.prototype.count=function(){return this.B.count()},e.prototype.minKey=function(){return this.B.minKey()},e.prototype.maxKey=function(){return this.B.maxKey()},e.prototype.inorderTraversal=function(e){return this.B.inorderTraversal(e)},e.prototype.reverseTraversal=function(e){return this.B.reverseTraversal(e)},e.prototype.getIterator=function(e){return new r(this.B,null,this.U,!1,e)},e.prototype.getIteratorFrom=function(e,t){return new r(this.B,e,this.U,!1,t)},e.prototype.getReverseIteratorFrom=function(e,t){return new r(this.B,e,this.U,!0,t)},e.prototype.getReverseIterator=function(e){return new r(this.B,null,this.U,!0,e)},e.EMPTY_NODE=new o,e}();t.SortedMap=a},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(43),i=n(11),o=n(2),a=n(44),s=n(86),u=n(97),l=n(0),h=n(1),c=n(0),p=n(98),d=n(25),f=n(100),_=n(49),y=n(101),v=n(50),g=n(106),m=n(32),C=function(){function e(e,t,n){var r=this;this.H=e,this.app=n,this.dataUpdateCount=0,this.G=null,this.K=new y.EventQueue,this.Y=1,this.X=null,this.z=new a.SparseSnapshotTree,this.J=null;var i=new p.AuthTokenProvider(n);if(this.$=d.StatsManager.getCollection(e),t||h.beingCrawled())this.Z=new g.ReadonlyRestClient(this.H,this.ee.bind(this),i),setTimeout(this.te.bind(this,!0),0);else{var o=n.options.databaseAuthVariableOverride;if(void 0!==o&&null!==o){if("object"!=typeof o)throw Error("Only objects are supported for option databaseAuthVariableOverride");try{l.stringify(o)}catch(e){throw Error("Invalid authOverride provided: "+e)}}this.J=new v.PersistentConnection(this.H,this.ee.bind(this),this.te.bind(this),this.ne.bind(this),i,o),this.Z=this.J}i.addTokenChangeListener(function(e){r.Z.refreshAuthToken(e)}),this.re=d.StatsManager.getOrCreateReporter(e,function(){return new f.StatsReporter(r.$,r.Z)}),this.ie(),this.oe=new u.SnapshotHolder,this.ae=new s.SyncTree({startListening:function(e,t,n,i){var o=[],a=r.oe.getNode(e.path);return a.isEmpty()||(o=r.ae.applyServerOverwrite(e.path,a),setTimeout(function(){i("ok")},0)),o},stopListening:function(){}}),this.se("connected",!1),this.ue=new s.SyncTree({startListening:function(e,t,n,i){return r.Z.listen(e,n,t,function(t,n){var o=i(t,n);r.K.raiseEventsForChangedPath(e.path,o)}),[]},stopListening:function(e,t){r.Z.unlisten(e,t)}})}return e.prototype.toString=function(){return(this.H.secure?"https://":"http://")+this.H.host},e.prototype.name=function(){return this.H.namespace},e.prototype.serverTime=function(){var e=this.oe.getNode(new o.Path(".info/serverTimeOffset")),t=e.val()||0;return(new Date).getTime()+t},e.prototype.generateServerValues=function(){return r.generateWithValues({timestamp:this.serverTime()})},e.prototype.ee=function(e,t,n,r){this.dataUpdateCount++;var a=new o.Path(e);t=this.X?this.X(e,t):t;var s=[];if(r)if(n){var u=c.map(t,function(e){return i.nodeFromJSON(e)});s=this.ue.applyTaggedQueryMerge(a,u,r)}else{var l=i.nodeFromJSON(t);s=this.ue.applyTaggedQueryOverwrite(a,l,r)}else if(n){var h=c.map(t,function(e){return i.nodeFromJSON(e)});s=this.ue.applyServerMerge(a,h)}else{var p=i.nodeFromJSON(t);s=this.ue.applyServerOverwrite(a,p)}var d=a;s.length>0&&(d=this.le(a)),this.K.raiseEventsForChangedPath(d,s)},e.prototype.he=function(e){this.X=e},e.prototype.te=function(e){this.se("connected",e),!1===e&&this.ce()},e.prototype.ne=function(e){var t=this;h.each(e,function(e,n){t.se(n,e)})},e.prototype.se=function(e,t){var n=new o.Path("/.info/"+e),r=i.nodeFromJSON(t);this.oe.updateSnapshot(n,r);var a=this.ae.applyServerOverwrite(n,r);this.K.raiseEventsForChangedPath(n,a)},e.prototype.pe=function(){return this.Y++},e.prototype.setWithPriority=function(e,t,n,o){var a=this;this.de("set",{path:""+e,value:t,priority:n});var s=this.generateServerValues(),u=i.nodeFromJSON(t,n),l=r.resolveDeferredValueSnapshot(u,s),c=this.pe(),p=this.ue.applyUserOverwrite(e,l,c,!0);this.K.queueEvents(p),this.Z.put(""+e,u.val(!0),function(t,n){var r="ok"===t;r||h.warn("set at "+e+" failed: "+t);var i=a.ue.ackUserWrite(c,!r);a.K.raiseEventsForChangedPath(e,i),a.callOnCompleteCallback(o,t,n)});var d=this.fe(e);this.le(d),this.K.raiseEventsForChangedPath(d,[])},e.prototype.update=function(e,t,n){var o=this;this.de("update",{path:""+e,value:t});var a=!0,s=this.generateServerValues(),u={};if(c.forEach(t,function(e,t){a=!1;var n=i.nodeFromJSON(t);u[e]=r.resolveDeferredValueSnapshot(n,s)}),a)h.log("update() called with empty data. Don't do anything."),this.callOnCompleteCallback(n,"ok");else{var l=this.pe(),p=this.ue.applyUserMerge(e,u,l);this.K.queueEvents(p),this.Z.merge(""+e,t,function(t,r){var i="ok"===t;i||h.warn("update at "+e+" failed: "+t);var a=o.ue.ackUserWrite(l,!i),s=a.length>0?o.le(e):e;o.K.raiseEventsForChangedPath(s,a),o.callOnCompleteCallback(n,t,r)}),c.forEach(t,function(t){var n=o.fe(e.child(t));o.le(n)}),this.K.raiseEventsForChangedPath(e,[])}},e.prototype.ce=function(){var e=this;this.de("onDisconnectEvents");var t=this.generateServerValues(),n=r.resolveDeferredValueTree(this.z,t),i=[];n.forEachTree(o.Path.Empty,function(t,n){i=i.concat(e.ue.applyServerOverwrite(t,n));var r=e.fe(t);e.le(r)}),this.z=new a.SparseSnapshotTree,this.K.raiseEventsForChangedPath(o.Path.Empty,i)},e.prototype.onDisconnectCancel=function(e,t){var n=this;this.Z.onDisconnectCancel(""+e,function(r,i){"ok"===r&&n.z.forget(e),n.callOnCompleteCallback(t,r,i)})},e.prototype.onDisconnectSet=function(e,t,n){var r=this,o=i.nodeFromJSON(t);this.Z.onDisconnectPut(""+e,o.val(!0),function(t,i){"ok"===t&&r.z.remember(e,o),r.callOnCompleteCallback(n,t,i)})},e.prototype.onDisconnectSetWithPriority=function(e,t,n,r){var o=this,a=i.nodeFromJSON(t,n);this.Z.onDisconnectPut(""+e,a.val(!0),function(t,n){"ok"===t&&o.z.remember(e,a),o.callOnCompleteCallback(r,t,n)})},e.prototype.onDisconnectUpdate=function(e,t,n){var r=this;if(c.isEmpty(t))return h.log("onDisconnect().update() called with empty data. Don't do anything."),void this.callOnCompleteCallback(n,"ok");this.Z.onDisconnectMerge(""+e,t,function(o,a){"ok"===o&&c.forEach(t,function(t,n){var o=i.nodeFromJSON(n);r.z.remember(e.child(t),o)}),r.callOnCompleteCallback(n,o,a)})},e.prototype.addEventCallbackForQuery=function(e,t){var n;n=".info"===e.path.getFront()?this.ae.addEventRegistration(e,t):this.ue.addEventRegistration(e,t),this.K.raiseEventsAtPath(e.path,n)},e.prototype.removeEventCallbackForQuery=function(e,t){var n;n=".info"===e.path.getFront()?this.ae.removeEventRegistration(e,t):this.ue.removeEventRegistration(e,t),this.K.raiseEventsAtPath(e.path,n)},e.prototype.interrupt=function(){this.J&&this.J.interrupt("repo_interrupt")},e.prototype.resume=function(){this.J&&this.J.resume("repo_interrupt")},e.prototype.stats=function(e){if(void 0===e&&(e=!1),"undefined"!=typeof console){var t;e?(this.G||(this.G=new _.StatsListener(this.$)),t=this.G.get()):t=this.$.get();var n=Object.keys(t).reduce(function(e,t){return Math.max(t.length,e)},0);c.forEach(t,function(e,t){for(var r=e.length;r0){var i=n[r];try{i=decodeURIComponent(i.replace(/\+/g," "))}catch(e){}t+="/"+i}return t}Object.defineProperty(t,"__esModule",{value:!0});var i=n(2),o=n(34),a=n(1);t.parseRepoInfo=function(e){var n=t.parseURL(e),r=n.subdomain;"firebase"===n.domain&&a.fatal(n.host+" is no longer supported. Please use .firebaseio.com instead"),r&&"undefined"!=r||a.fatal("Cannot parse Firebase url. Please use https://.firebaseio.com"),n.secure||a.warnIfPageIsSecure();var s="ws"===n.scheme||"wss"===n.scheme;return{repoInfo:new o.RepoInfo(n.host,n.secure,r,s),path:new i.Path(n.pathString)}},t.parseURL=function(e){var t="",n="",i="",o="",a=!0,s="https",u=443;if("string"==typeof e){var l=e.indexOf("//");l>=0&&(s=e.substring(0,l-1),e=e.substring(l+2));var h=e.indexOf("/");-1===h&&(h=e.length),t=e.substring(0,h),o=r(e.substring(h));var c=t.split(".");3===c.length?(n=c[1],i=c[0].toLowerCase()):2===c.length&&(n=c[0]),(l=t.indexOf(":"))>=0&&(a="https"===s||"wss"===s,u=parseInt(t.substring(l+1),10))}return{host:t,port:u,domain:n,subdomain:i,secure:a,scheme:s,pathString:o}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),i=n(0),o=n(12),a=n(13),s=function(){function e(e,t,n,r,i){void 0===i&&(i=""),this.secure=t,this.namespace=n,this.webSocketOnly=r,this.persistenceKey=i,this.host=e.toLowerCase(),this.domain=this.host.substr(this.host.indexOf(".")+1),this.internalHost=o.PersistentStorage.get("host:"+e)||this.host}return e.prototype.needsQueryParam=function(){return this.host!==this.internalHost},e.prototype.isCacheableHost=function(){return"s-"===this.internalHost.substr(0,2)},e.prototype.isDemoHost=function(){return"firebaseio-demo.com"===this.domain},e.prototype.isCustomHost=function(){return"firebaseio.com"!==this.domain&&"firebaseio-demo.com"!==this.domain},e.prototype.updateHost=function(e){e!==this.internalHost&&(this.internalHost=e,this.isCacheableHost()&&o.PersistentStorage.set("host:"+this.host,this.internalHost))},e.prototype.connectionURL=function(e,t){r.assert("string"==typeof e,"typeof type must == string"),r.assert("object"==typeof t,"typeof params must == object");var n;if(e===a.WEBSOCKET)n=(this.secure?"wss://":"ws://")+this.internalHost+"/.ws?";else{if(e!==a.LONG_POLLING)throw Error("Unknown connection type: "+e);n=(this.secure?"https://":"http://")+this.internalHost+"/.lp?"}this.needsQueryParam()&&(t.ns=this.namespace);var o=[];return i.forEach(t,function(e,t){o.push(e+"="+t)}),n+o.join("&")},e.prototype.toString=function(){var e=this.toURLString();return this.persistenceKey&&(e+="<"+this.persistenceKey+">"),e},e.prototype.toURLString=function(){return(this.secure?"https://":"http://")+this.host},e}();t.RepoInfo=s},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),i=n(7),o=n(1),a=n(0),s=function(){function e(e,t){this.Ie=e,this.Oe=t}return e.prototype.cancel=function(e){r.validateArgCount("OnDisconnect.cancel",0,1,arguments.length),r.validateCallback("OnDisconnect.cancel",1,e,!0);var t=new a.Deferred;return this.Ie.onDisconnectCancel(this.Oe,t.wrapCallback(e)),t.promise},e.prototype.remove=function(e){r.validateArgCount("OnDisconnect.remove",0,1,arguments.length),i.validateWritablePath("OnDisconnect.remove",this.Oe),r.validateCallback("OnDisconnect.remove",1,e,!0);var t=new a.Deferred;return this.Ie.onDisconnectSet(this.Oe,null,t.wrapCallback(e)),t.promise},e.prototype.set=function(e,t){r.validateArgCount("OnDisconnect.set",1,2,arguments.length),i.validateWritablePath("OnDisconnect.set",this.Oe),i.validateFirebaseDataArg("OnDisconnect.set",1,e,this.Oe,!1),r.validateCallback("OnDisconnect.set",2,t,!0);var n=new a.Deferred;return this.Ie.onDisconnectSet(this.Oe,e,n.wrapCallback(t)),n.promise},e.prototype.setWithPriority=function(e,t,n){r.validateArgCount("OnDisconnect.setWithPriority",2,3,arguments.length),i.validateWritablePath("OnDisconnect.setWithPriority",this.Oe),i.validateFirebaseDataArg("OnDisconnect.setWithPriority",1,e,this.Oe,!1),i.validatePriority("OnDisconnect.setWithPriority",2,t,!1),r.validateCallback("OnDisconnect.setWithPriority",3,n,!0);var o=new a.Deferred;return this.Ie.onDisconnectSetWithPriority(this.Oe,e,t,o.wrapCallback(n)),o.promise},e.prototype.update=function(e,t){if(r.validateArgCount("OnDisconnect.update",1,2,arguments.length),i.validateWritablePath("OnDisconnect.update",this.Oe),Array.isArray(e)){for(var n={},s=0;s3e4&&(this.nt=v),this._t=null}}else this.de("Window isn't visible. Delaying reconnect."),this.nt=this.rt,this.ft=(new Date).getTime();var t=(new Date).getTime()-this.ft,n=Math.max(0,this.nt-t);n=Math.random()*n,this.de("Trying to reconnect in "+n+"ms"),this.yt(n),this.nt=Math.min(this.rt,1.3*this.nt)}this.te(!1)},t.prototype.Ft=function(){if(this.Wt()){this.de("Making a connection attempt"),this.ft=(new Date).getTime(),this._t=null;var e=this.wt.bind(this),n=this.At.bind(this),r=this.xt.bind(this),i=this.id+":"+t.jt++,o=this,a=this.lastSessionId,l=!1,h=null,c=function(){h?h.close():(l=!0,r())},p=function(e){s.assert(h,"sendRequest call when we're not connected not allowed."),h.sendRequest(e)};this.lt={close:c,sendRequest:p};var _=this.ct;this.ct=!1,this.Ke.getToken(_).then(function(t){l?u.log("getToken() completed but was canceled"):(u.log("getToken() completed. Creating connection."),o.ht=t&&t.accessToken,h=new d.Connection(i,o.H,e,n,r,function(e){u.warn(e+" ("+o.H+")"),o.interrupt("server_kill")},a))}).then(null,function(e){o.de("Failed to get token: "+e),l||(f.CONSTANTS.NODE_ADMIN&&u.warn(e),c())})}},t.prototype.interrupt=function(e){u.log("Interrupting connection for reason: "+e),this.ze[e]=!0,this.lt?this.lt.close():(this.ot&&(clearTimeout(this.ot),this.ot=null),this.tt&&this.xt())},t.prototype.resume=function(e){u.log("Resuming connection for reason: "+e),delete this.ze[e],o.isEmpty(this.ze)&&(this.nt=v,this.lt||this.yt(0))},t.prototype.Dt=function(e){var t=e-(new Date).getTime();this.ne({serverTimeOffset:t})},t.prototype.kt=function(){for(var e=0;e=3&&(this.nt=3e4,this.Ke.notifyForInvalidToken())},t.prototype.Ot=function(e){this.it?this.it(e):"msg"in e&&"undefined"!=typeof console&&console.log("FIREBASE: "+e.msg.replace("\n","\nFIREBASE: "))},t.prototype.Lt=function(){var e=this;this.tryAuth(),o.forEach(this.Je,function(t,n){o.forEach(n,function(t,n){e.mt(n)})});for(var t=0;t0,"Requires a non-empty array")}return e.prototype.trigger=function(e){for(var t=[],n=1;n0&&(this.rn=r.setTimeoutNonBlocking(function(){e.rn=null,e.nn||(e.Yt&&e.Yt.bytesReceived>102400?(e.de("Connection exceeded healthy timeout but has received "+e.Yt.bytesReceived+" bytes. Marking connection healthy."),e.nn=!0,e.Yt.markConnectionHealthy()):e.Yt&&e.Yt.bytesSent>10240?e.de("Connection exceeded healthy timeout but has sent "+e.Yt.bytesSent+" bytes. Leaving connection alive."):(e.de("Closing unhealthy connection after timeout."),e.close()))},Math.floor(o)))},e.prototype.Xt=function(){return"c:"+this.id+":"+this.connectionCount++},e.prototype.$t=function(e){var t=this;return function(n){e===t.Yt?t.in(n):e===t.tn?(t.de("Secondary connection lost."),t.an()):t.de("closing an old connection")}},e.prototype.Jt=function(e){var t=this;return function(n){2!=t.Ht&&(e===t.en?t.sn(n):e===t.tn?t.un(n):t.de("message on old connection"))}},e.prototype.sendRequest=function(e){var t={t:"d",d:e};this.ln(t)},e.prototype.tryCleanupConnection=function(){this.Zt===this.tn&&this.en===this.tn&&(this.de("cleaning up and promoting a connection: "+this.tn.connId),this.Yt=this.tn,this.tn=null)},e.prototype.hn=function(e){if("t"in e){var t=e.t;"a"===t?this.cn():"r"===t?(this.de("Got a reset on secondary, closing it"),this.tn.close(),this.Zt!==this.tn&&this.en!==this.tn||this.close()):"o"===t&&(this.de("got pong on secondary."),this.pn--,this.cn())}},e.prototype.un=function(e){var t=r.requireKey("t",e),n=r.requireKey("d",e);if("c"==t)this.hn(n);else{if("d"!=t)throw Error("Unknown protocol layer: "+t);this.pendingDataMessages.push(n)}},e.prototype.cn=function(){this.pn<=0?(this.de("Secondary connection is healthy."),this.nn=!0,this.tn.markConnectionHealthy(),this.dn()):(this.de("sending ping on secondary."),this.tn.send({t:"c",d:{t:"p",d:{}}}))},e.prototype.dn=function(){this.tn.start(),this.de("sending client ack on secondary"),this.tn.send({t:"c",d:{t:"a",d:{}}}),this.de("Ending transmission on primary"),this.Yt.send({t:"c",d:{t:"n",d:{}}}),this.Zt=this.tn,this.tryCleanupConnection()},e.prototype.sn=function(e){var t=r.requireKey("t",e),n=r.requireKey("d",e);"c"==t?this.fn(n):"d"==t&&this.wt(n)},e.prototype.wt=function(e){this._n(),this.Ut(e)},e.prototype._n=function(){this.nn||--this.zt<=0&&(this.de("Primary connection is healthy."),this.nn=!0,this.Yt.markConnectionHealthy())},e.prototype.fn=function(e){var t=r.requireKey("t",e);if("d"in e){var n=e.d;if("h"===t)this.yn(n);else if("n"===t){this.de("recvd end transmission on primary"),this.en=this.tn;for(var i=0;idocument.domain="'+document.domain+'";<\/script>');var h=""+u+"";try{this.myIFrame.doc.open(),this.myIFrame.doc.write(h),this.myIFrame.doc.close()}catch(e){r.log("frame writing exception"),e.stack&&r.log(e.stack),r.log(e)}}}return e.Dn=function(){var e=document.createElement("iframe");if(e.style.display="none",!document.body)throw"Document body has not initialized. Wait to initialize Firebase until after the document is ready.";document.body.appendChild(e);try{e.contentWindow.document||r.log("No IE domain setting required")}catch(n){var t=document.domain;e.src="javascript:void((function(){document.open();document.domain='"+t+"';document.close();})())"}return e.contentDocument?e.doc=e.contentDocument:e.contentWindow?e.doc=e.contentWindow.document:e.document&&(e.doc=e.document),e},e.prototype.close=function(){var n=this;if(this.alive=!1,this.myIFrame&&(this.myIFrame.doc.body.innerHTML="",setTimeout(function(){null!==n.myIFrame&&(document.body.removeChild(n.myIFrame),n.myIFrame=null)},Math.floor(0))),l.isNodeSdk()&&this.myID){var r={};r[t.FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM]="t",r[t.FIREBASE_LONGPOLL_ID_PARAM]=this.myID,r[t.FIREBASE_LONGPOLL_PW_PARAM]=this.myPW;var i=this.urlFn(r);e.nodeRestRequest(i)}var o=this.onDisconnect;o&&(this.onDisconnect=null,o())},e.prototype.startLongPoll=function(e,t){for(this.myID=e,this.myPW=t,this.alive=!0;this.Mn(););},e.prototype.Mn=function(){if(this.alive&&this.sendNewPolls&&this.outstandingRequests.count()<(this.pendingSegs.length>0?2:1)){this.currentSerial++;var e={};e[t.FIREBASE_LONGPOLL_ID_PARAM]=this.myID,e[t.FIREBASE_LONGPOLL_PW_PARAM]=this.myPW,e[t.FIREBASE_LONGPOLL_SERIAL_PARAM]=this.currentSerial;for(var n=this.urlFn(e),r="",i=0;this.pendingSegs.length>0&&this.pendingSegs[0].d.length+30+r.length<=1870;){var o=this.pendingSegs.shift();r=r+"&"+t.FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM+i+"="+o.seg+"&"+t.FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET+i+"="+o.ts+"&"+t.FIREBASE_LONGPOLL_DATA_PARAM+i+"="+o.d,i++}return n+=r,this.Ln(n,this.currentSerial),!0}return!1},e.prototype.enqueueSegment=function(e,t,n){this.pendingSegs.push({seg:e,ts:t,d:n}),this.alive&&this.Mn()},e.prototype.Ln=function(e,t){var n=this;this.outstandingRequests.add(t,1);var r=function(){n.outstandingRequests.remove(t),n.Mn()},i=setTimeout(r,Math.floor(25e3)),o=function(){clearTimeout(i),r()};this.addTag(e,o)},e.prototype.addTag=function(e,t){var n=this;l.isNodeSdk()?this.doNodeLongPoll(e,t):setTimeout(function(){try{if(!n.sendNewPolls)return;var i=n.myIFrame.doc.createElement("script");i.type="text/javascript",i.async=!0,i.src=e,i.onload=i.onreadystatechange=function(){var e=i.readyState;e&&"loaded"!==e&&"complete"!==e||(i.onload=i.onreadystatechange=null,i.parentNode&&i.parentNode.removeChild(i),t())},i.onerror=function(){r.log("Long-poll script failed to load: "+e),n.sendNewPolls=!1,n.close()},n.myIFrame.doc.body.appendChild(i)}catch(e){}},Math.floor(1))},e}();t.FirebaseIFrameScriptHolder=c},function(e,t,n){"use strict";(function(e){function r(e){d=e}Object.defineProperty(t,"__esModule",{value:!0});var i=n(6),o=n(0),a=n(1),s=n(25),u=n(13),l=n(0),h=n(12),c=n(0),p=n(0),d=null;"undefined"!=typeof MozWebSocket?d=MozWebSocket:"undefined"!=typeof WebSocket&&(d=WebSocket),t.setWebSocketImpl=r;var f=function(){function t(e,n,r,i){this.connId=e,this.keepaliveTimer=null,this.frames=null,this.totalFrames=0,this.bytesSent=0,this.bytesReceived=0,this.de=a.logWrapper(this.connId),this.$=s.StatsManager.getCollection(n),this.connURL=t.Fn(n,r,i)}return t.Fn=function(e,t,n){var r={};return r[u.VERSION_PARAM]=u.PROTOCOL_VERSION,!p.isNodeSdk()&&"undefined"!=typeof location&&location.href&&-1!==location.href.indexOf(u.FORGE_DOMAIN)&&(r[u.REFERER_PARAM]=u.FORGE_REF),t&&(r[u.TRANSPORT_SESSION_PARAM]=t),n&&(r[u.LAST_SESSION_PARAM]=n),e.connectionURL(u.WEBSOCKET,r)},t.prototype.open=function(t,n){var r=this;this.onDisconnect=n,this.onMessage=t,this.de("Websocket connecting to "+this.connURL),this.bn=!1,h.PersistentStorage.set("previous_websocket_failure",!0);try{if(p.isNodeSdk()){var o=l.CONSTANTS.NODE_ADMIN?"AdminNode":"Node",a={headers:{"User-Agent":"Firebase/"+u.PROTOCOL_VERSION+"/"+i.default.SDK_VERSION+"/"+e.platform+"/"+o}},s=e.env,c=0==this.connURL.indexOf("wss://")?s.HTTPS_PROXY||s.https_proxy:s.HTTP_PROXY||s.http_proxy;c&&(a.proxy={origin:c}),this.mySock=new d(this.connURL,[],a)}else this.mySock=new d(this.connURL)}catch(e){this.de("Error instantiating WebSocket.");var f=e.message||e.data;return f&&this.de(f),void this.wn()}this.mySock.onopen=function(){r.de("Websocket connected."),r.bn=!0},this.mySock.onclose=function(){r.de("Websocket connection was disconnected."),r.mySock=null,r.wn()},this.mySock.onmessage=function(e){r.handleIncomingFrame(e)},this.mySock.onerror=function(e){r.de("WebSocket error. Closing connection.");var t=e.message||e.data;t&&r.de(t),r.wn()}},t.prototype.start=function(){},t.forceDisallow=function(){t.On=!0},t.isAvailable=function(){var e=!1;if("undefined"!=typeof navigator&&navigator.userAgent){var n=/Android ([0-9]{0,}\.[0-9]{0,})/,r=navigator.userAgent.match(n);r&&r.length>1&&parseFloat(r[1])<4.4&&(e=!0)}return!e&&null!==d&&!t.On},t.previouslyFailed=function(){return h.PersistentStorage.isInMemoryStorage||!0===h.PersistentStorage.get("previous_websocket_failure")},t.prototype.markConnectionHealthy=function(){h.PersistentStorage.remove("previous_websocket_failure")},t.prototype.xn=function(e){if(this.frames.push(e),this.frames.length==this.totalFrames){var t=this.frames.join("");this.frames=null;var n=c.jsonEval(t);this.onMessage(n)}},t.prototype.kn=function(e){this.totalFrames=e,this.frames=[]},t.prototype.Wn=function(e){if(o.assert(null===this.frames,"We already have a frame buffer"),e.length<=6){var t=+e;if(!isNaN(t))return this.kn(t),null}return this.kn(1),e},t.prototype.handleIncomingFrame=function(e){if(null!==this.mySock){var t=e.data;if(this.bytesReceived+=t.length,this.$.incrementCounter("bytes_received",t.length),this.resetKeepAlive(),null!==this.frames)this.xn(t);else{var n=this.Wn(t);null!==n&&this.xn(n)}}},t.prototype.send=function(e){this.resetKeepAlive();var t=c.stringify(e);this.bytesSent+=t.length,this.$.incrementCounter("bytes_sent",t.length);var n=a.splitStringBySize(t,16384);n.length>1&&this.jn(n.length+"");for(var r=0;r=0;a--)s[a]=e.charAt(i%64),i=Math.floor(i/64);r.assert(0===i,"Cannot push at time == 0");var u=s.join("");if(o){for(a=11;a>=0&&63===n[a];a--)n[a]=0;n[a]++}else for(a=0;a<12;a++)n[a]=Math.floor(64*Math.random());for(a=0;a<12;a++)u+=e.charAt(n[a]);return r.assert(20===u.length,"nextPushId: Length should be 20."),u}}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(22),i=n(85),o=n(0),a=n(0),s=function(){function e(e,t,n){this.Xn=e,this.zn=t,this.Jn=n}return e.prototype.respondsTo=function(e){return"value"===e},e.prototype.createEvent=function(e,t){var n=t.getQueryParams().getIndex();return new i.DataEvent("value",this,new r.DataSnapshot(e.snapshotNode,t.getRef(),n))},e.prototype.getEventRunner=function(e){var t=this.Jn;if("cancel"===e.getEventType()){a.assert(this.zn,"Raising a cancel event on a listener with no cancel callback");var n=this.zn;return function(){n.call(t,e.error)}}var r=this.Xn;return function(){r.call(t,e.snapshot)}},e.prototype.createCancelEvent=function(e,t){return this.zn?new i.CancelEvent(this,e,t):null},e.prototype.matches=function(t){return t instanceof e&&(!t.Xn||!this.Xn||t.Xn===this.Xn&&t.Jn===this.Jn)},e.prototype.hasAnyCallback=function(){return null!==this.Xn},e}();t.ValueEventRegistration=s;var u=function(){function e(e,t,n){this.$n=e,this.zn=t,this.Jn=n}return e.prototype.respondsTo=function(e){var t="children_added"===e?"child_added":e;return t="children_removed"===t?"child_removed":t,o.contains(this.$n,t)},e.prototype.createCancelEvent=function(e,t){return this.zn?new i.CancelEvent(this,e,t):null},e.prototype.createEvent=function(e,t){a.assert(null!=e.childName,"Child events should have a childName.");var n=t.getRef().child(e.childName),o=t.getQueryParams().getIndex();return new i.DataEvent(e.type,this,new r.DataSnapshot(e.snapshotNode,n,o),e.prevName)},e.prototype.getEventRunner=function(e){var t=this.Jn;if("cancel"===e.getEventType()){a.assert(this.zn,"Raising a cancel event on a listener with no cancel callback");var n=this.zn;return function(){n.call(t,e.error)}}var r=this.$n[e.eventType];return function(){r.call(t,e.snapshot,e.prevName)}},e.prototype.matches=function(t){if(t instanceof e){if(!this.$n||!t.$n)return!0;if(this.Jn===t.Jn){var n=o.getCount(t.$n);if(n===o.getCount(this.$n)){if(1===n){var r=o.getAnyKey(t.$n),i=o.getAnyKey(this.$n);return!(i!==r||t.$n[r]&&this.$n[i]&&t.$n[r]!==this.$n[i])}return o.every(this.$n,function(e,n){return t.$n[e]===n})}}}return!1},e.prototype.hasAnyCallback=function(){return null!==this.$n},e}();t.ChildEventRegistration=u},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),i=function(){function e(e,t,n,r){this.eventType=e,this.eventRegistration=t,this.snapshot=n,this.prevName=r}return e.prototype.getPath=function(){var e=this.snapshot.getRef();return"value"===this.eventType?e.path:e.getParent().path},e.prototype.getEventType=function(){return this.eventType},e.prototype.getEventRunner=function(){return this.eventRegistration.getEventRunner(this)},e.prototype.toString=function(){return this.getPath()+":"+this.eventType+":"+r.stringify(this.snapshot.exportVal())},e}();t.DataEvent=i;var o=function(){function e(e,t,n){this.eventRegistration=e,this.error=t,this.path=n}return e.prototype.getPath=function(){return this.path},e.prototype.getEventType=function(){return"cancel"},e.prototype.getEventRunner=function(){return this.eventRegistration.getEventRunner(this)},e.prototype.toString=function(){return this.path+":cancel"},e}();t.CancelEvent=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),i=n(1),o=n(87),a=n(4),s=n(0),u=n(23),l=n(88),h=n(89),c=n(8),p=n(46),d=n(2),f=n(47),_=n(95),y=function(){function e(e){this.Zn=e,this.er=u.ImmutableTree.Empty,this.tr=new _.WriteTree,this.nr={},this.rr={}}return e.prototype.applyUserOverwrite=function(e,t,n,r){return this.tr.addOverwrite(e,t,n,r),r?this.ir(new p.Overwrite(c.OperationSource.User,e,t)):[]},e.prototype.applyUserMerge=function(e,t,n){this.tr.addMerge(e,t,n);var r=u.ImmutableTree.fromObject(t);return this.ir(new h.Merge(c.OperationSource.User,e,r))},e.prototype.ackUserWrite=function(e,t){void 0===t&&(t=!1);var n=this.tr.getWrite(e);if(this.tr.removeWrite(e)){var r=u.ImmutableTree.Empty;return null!=n.snap?r=r.set(d.Path.Empty,!0):s.forEach(n.children,function(e,t){r=r.set(new d.Path(e),t)}),this.ir(new o.AckUserWrite(n.path,r,t))}return[]},e.prototype.applyServerOverwrite=function(e,t){return this.ir(new p.Overwrite(c.OperationSource.Server,e,t))},e.prototype.applyServerMerge=function(e,t){var n=u.ImmutableTree.fromObject(t);return this.ir(new h.Merge(c.OperationSource.Server,e,n))},e.prototype.applyListenComplete=function(e){return this.ir(new l.ListenComplete(c.OperationSource.Server,e))},e.prototype.applyTaggedQueryOverwrite=function(t,n,r){var i=this.or(r);if(null!=i){var o=e.ar(i),a=o.path,s=o.queryId,u=d.Path.relativePath(a,t),l=new p.Overwrite(c.OperationSource.forServerTaggedQuery(s),u,n);return this.sr(a,l)}return[]},e.prototype.applyTaggedQueryMerge=function(t,n,r){var i=this.or(r);if(i){var o=e.ar(i),a=o.path,s=o.queryId,l=d.Path.relativePath(a,t),p=u.ImmutableTree.fromObject(n),f=new h.Merge(c.OperationSource.forServerTaggedQuery(s),l,p);return this.sr(a,f)}return[]},e.prototype.applyTaggedListenComplete=function(t,n){var r=this.or(n);if(r){var i=e.ar(r),o=i.path,a=i.queryId,s=d.Path.relativePath(o,t),u=new l.ListenComplete(c.OperationSource.forServerTaggedQuery(a),s);return this.sr(o,u)}return[]},e.prototype.addEventRegistration=function(t,n){var i=t.path,o=null,s=!1;this.er.foreachOnPath(i,function(e,t){var n=d.Path.relativePath(e,i);o=o||t.getCompleteServerCache(n),s=s||t.hasCompleteView()});var u=this.er.get(i);u?(s=s||u.hasCompleteView(),o=o||u.getCompleteServerCache(d.Path.Empty)):(u=new f.SyncPoint,this.er=this.er.set(i,u));var l;null!=o?l=!0:(l=!1,o=a.ChildrenNode.EMPTY_NODE,this.er.subtree(i).foreachChild(function(e,t){var n=t.getCompleteServerCache(d.Path.Empty);n&&(o=o.updateImmediateChild(e,n))}));var h=u.viewExistsForQuery(t);if(!h&&!t.getQueryParams().loadsAllData()){var c=e.ur(t);r.assert(!(c in this.rr),"View does not exist, but we have a tag");var p=e.lr();this.rr[c]=p,this.nr["_"+p]=c}var _=this.tr.childWrites(i),y=u.addEventRegistration(t,n,_,o,l);if(!h&&!s){var v=u.viewForQuery(t);y=y.concat(this.hr(t,v))}return y},e.prototype.removeEventRegistration=function(t,n,r){var i=this,o=t.path,a=this.er.get(o),s=[];if(a&&("default"===t.queryIdentifier()||a.viewExistsForQuery(t))){var u=a.removeEventRegistration(t,n,r);a.isEmpty()&&(this.er=this.er.remove(o));var l=u.removed;s=u.events;var h=-1!==l.findIndex(function(e){return e.getQueryParams().loadsAllData()}),c=this.er.findOnPath(o,function(e,t){return t.hasCompleteView()});if(h&&!c){var p=this.er.subtree(o);if(!p.isEmpty())for(var d=this.cr(p),f=0;f0&&!r&&(h?this.Zn.stopListening(e.dr(t),null):l.forEach(function(t){var n=i.rr[e.ur(t)];i.Zn.stopListening(e.dr(t),n)})),this._r(l)}return s},e.prototype.calcCompleteEventCache=function(e,t){var n=this.tr,r=this.er.findOnPath(e,function(t,n){var r=d.Path.relativePath(t,e),i=n.getCompleteServerCache(r);if(i)return i});return n.calcCompleteEventCache(e,r,t,!0)},e.prototype.cr=function(e){return e.fold(function(e,t,n){if(t&&t.hasCompleteView())return[t.getCompleteView()];var r=[];return t&&(r=t.getQueryViews()),s.forEach(n,function(e,t){r=r.concat(t)}),r})},e.prototype._r=function(t){for(var n=0;n0||!e.getEventCache().isFullyInitialized()||i&&!r.getNode().equals(o)||!r.getNode().getPriority().equals(o.getPriority()))&&n.push(a.Change.valueChange(t.getCompleteEventSnap()))}},e.prototype.Lr=function(e,t,n,r,o){var a=e.getEventCache();if(null!=n.shadowingWrite(t))return e;var u=void 0,l=void 0;if(t.isEmpty())if(i.assert(e.getServerCache().isFullyInitialized(),"If change path is empty, we must have complete server data"),e.getServerCache().isFiltered()){var h=e.getCompleteServerSnap(),c=h instanceof s.ChildrenNode?h:s.ChildrenNode.EMPTY_NODE,p=n.calcCompleteEventChildren(c);u=this.Sr.updateFullNode(e.getEventCache().getNode(),p,o)}else{var d=n.calcCompleteEventCache(e.getCompleteServerSnap());u=this.Sr.updateFullNode(e.getEventCache().getNode(),d,o)}else{var f=t.getFront();if(".priority"==f){i.assert(1==t.getLength(),"Can't have a priority with additional path components");var _=a.getNode();l=e.getServerCache().getNode();var y=n.calcEventCacheAfterServerOverwrite(t,_,l);u=null!=y?this.Sr.updatePriority(_,y):a.getNode()}else{var v=t.popFront(),g=void 0;if(a.isCompleteForChild(f)){l=e.getServerCache().getNode();var m=n.calcEventCacheAfterServerOverwrite(t,a.getNode(),l);g=null!=m?a.getNode().getImmediateChild(f).updateChild(v,m):a.getNode().getImmediateChild(f)}else g=n.calcCompleteChild(f,e.getServerCache());u=null!=g?this.Sr.updateChild(a.getNode(),f,g,v,r,o):a.getNode()}}return e.updateEventSnap(u,a.isFullyInitialized()||t.isEmpty(),this.Sr.filtersNodes())},e.prototype.wr=function(e,t,n,r,i,o,a){var s,u=e.getServerCache(),l=o?this.Sr:this.Sr.getIndexedFilter();if(t.isEmpty())s=l.updateFullNode(u.getNode(),n,null);else if(l.filtersNodes()&&!u.isFiltered()){var h=u.getNode().updateChild(t,n);s=l.updateFullNode(u.getNode(),h,null)}else{var p=t.getFront();if(!u.isCompleteForPath(t)&&t.getLength()>1)return e;var d=t.popFront(),f=u.getNode().getImmediateChild(p),_=f.updateChild(d,n);s=".priority"==p?l.updatePriority(u.getNode(),_):l.updateChild(u.getNode(),p,_,d,c.NO_COMPLETE_CHILD_SOURCE,null)}var y=e.updateServerSnap(s,u.isFullyInitialized()||t.isEmpty(),l.filtersNodes()),v=new c.WriteTreeCompleteChildSource(r,y,i);return this.Lr(y,t,r,v,a)},e.prototype.Tr=function(e,t,n,r,i,o){var a,u,l=e.getEventCache(),h=new c.WriteTreeCompleteChildSource(r,e,i);if(t.isEmpty())u=this.Sr.updateFullNode(e.getEventCache().getNode(),n,o),a=e.updateEventSnap(u,!0,this.Sr.filtersNodes());else{var p=t.getFront();if(".priority"===p)u=this.Sr.updatePriority(e.getEventCache().getNode(),n),a=e.updateEventSnap(u,l.isFullyInitialized(),l.isFiltered());else{var d=t.popFront(),f=l.getNode().getImmediateChild(p),_=void 0;if(d.isEmpty())_=n;else{var y=h.getCompleteChild(p);_=null!=y?".priority"===d.getBack()&&y.getChild(d.parent()).isEmpty()?y:y.updateChild(d,n):s.ChildrenNode.EMPTY_NODE}if(f.equals(_))a=e;else{var v=this.Sr.updateChild(l.getNode(),p,_,d,h,o);a=e.updateEventSnap(v,l.isFullyInitialized(),this.Sr.filtersNodes())}}}return a},e.Fr=function(e,t){return e.getEventCache().isCompleteForChild(t)},e.prototype.Ir=function(t,n,r,i,o,a){var s=this,u=t;return r.foreach(function(r,l){var h=n.child(r);e.Fr(t,h.getFront())&&(u=s.Tr(u,h,l,i,o,a))}),r.foreach(function(r,l){var h=n.child(r);e.Fr(t,h.getFront())||(u=s.Tr(u,h,l,i,o,a))}),u},e.prototype.xr=function(e,t){return t.foreach(function(t,n){e=e.updateChild(t,n)}),e},e.prototype.Rr=function(e,t,n,r,i,o,a){var s=this;if(e.getServerCache().getNode().isEmpty()&&!e.getServerCache().isFullyInitialized())return e;var u,c=e;u=t.isEmpty()?n:l.ImmutableTree.Empty.setTree(t,n);var p=e.getServerCache().getNode();return u.children.inorderTraversal(function(t,n){if(p.hasChild(t)){var u=e.getServerCache().getNode().getImmediateChild(t),l=s.xr(u,n);c=s.wr(c,new h.Path(t),l,r,i,o,a)}}),u.children.inorderTraversal(function(t,n){var u=!e.getServerCache().isCompleteForChild(t)&&null==n.value;if(!p.hasChild(t)&&!u){var l=e.getServerCache().getNode().getImmediateChild(t),d=s.xr(l,n);c=s.wr(c,new h.Path(t),d,r,i,o,a)}}),c},e.prototype.Ar=function(e,t,n,r,i,o){if(null!=r.shadowingWrite(t))return e;var a=e.getServerCache().isFiltered(),s=e.getServerCache();if(null!=n.value){if(t.isEmpty()&&s.isFullyInitialized()||s.isCompleteForPath(t))return this.wr(e,t,s.getNode().getChild(t),r,i,a,o);if(t.isEmpty()){var c=l.ImmutableTree.Empty;return s.getNode().forEachChild(u.KEY_INDEX,function(e,t){c=c.set(new h.Path(e),t)}),this.Rr(e,t,c,r,i,a,o)}return e}var p=l.ImmutableTree.Empty;return n.foreach(function(e,n){var r=t.child(e);s.isCompleteForPath(r)&&(p=p.set(e,s.getNode().getChild(r)))}),this.Rr(e,t,p,r,i,a,o)},e.prototype.Dr=function(e,t,n,r){var i=e.getServerCache(),o=e.updateServerSnap(i.getNode(),i.isFullyInitialized()||t.isEmpty(),i.isFiltered());return this.Lr(o,t,n,c.NO_COMPLETE_CHILD_SOURCE,r)},e.prototype.Or=function(e,t,n,r,o){var a;if(null!=n.shadowingWrite(t))return e;var u=new c.WriteTreeCompleteChildSource(n,e,r),l=e.getEventCache().getNode(),p=void 0;if(t.isEmpty()||".priority"===t.getFront()){var d=void 0;if(e.getServerCache().isFullyInitialized())d=n.calcCompleteEventCache(e.getCompleteServerSnap());else{var f=e.getServerCache().getNode();i.assert(f instanceof s.ChildrenNode,"serverChildren would be complete if leaf node"),d=n.calcCompleteEventChildren(f)}d=d,p=this.Sr.updateFullNode(l,d,o)}else{var _=t.getFront(),y=n.calcCompleteChild(_,e.getServerCache());null==y&&e.getServerCache().isCompleteForChild(_)&&(y=l.getImmediateChild(_)),p=null!=y?this.Sr.updateChild(l,_,y,t.popFront(),u,o):e.getEventCache().getNode().hasChild(_)?this.Sr.updateChild(l,_,s.ChildrenNode.EMPTY_NODE,t.popFront(),u,o):l,p.isEmpty()&&e.getServerCache().isFullyInitialized()&&(a=n.calcCompleteEventCache(e.getCompleteServerSnap()),a.isLeafNode()&&(p=this.Sr.updateFullNode(p,a,o)))}return a=e.getServerCache().isFullyInitialized()||null!=n.shadowingWrite(h.Path.Empty),e.updateEventSnap(p,a,this.Sr.filtersNodes())},e}();t.ViewProcessor=d},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),i=n(9),o=n(0),a=function(){function e(){this.kr={}}return e.prototype.trackChildChange=function(e){var t=e.type,n=e.childName;o.assert(t==i.Change.CHILD_ADDED||t==i.Change.CHILD_CHANGED||t==i.Change.CHILD_REMOVED,"Only child changes supported for tracking"),o.assert(".priority"!==n,"Only non-priority child changes can be tracked.");var a=r.safeGet(this.kr,n);if(a){var s=a.type;if(t==i.Change.CHILD_ADDED&&s==i.Change.CHILD_REMOVED)this.kr[n]=i.Change.childChangedChange(n,e.snapshotNode,a.snapshotNode);else if(t==i.Change.CHILD_REMOVED&&s==i.Change.CHILD_ADDED)delete this.kr[n];else if(t==i.Change.CHILD_REMOVED&&s==i.Change.CHILD_CHANGED)this.kr[n]=i.Change.childRemovedChange(n,a.oldSnap);else if(t==i.Change.CHILD_CHANGED&&s==i.Change.CHILD_ADDED)this.kr[n]=i.Change.childAddedChange(n,e.snapshotNode);else{if(t!=i.Change.CHILD_CHANGED||s!=i.Change.CHILD_CHANGED)throw o.assertionError("Illegal combination of changes: "+e+" occurred after "+a);this.kr[n]=i.Change.childChangedChange(n,e.snapshotNode,a.oldSnap)}}else this.kr[n]=e},e.prototype.getChanges=function(){return r.getValues(this.kr)},e}();t.ChildChangeAccumulator=a},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(18),i=function(){function e(){}return e.prototype.getCompleteChild=function(e){return null},e.prototype.getChildAfterChild=function(e,t,n){return null},e}();t.Wr=i,t.NO_COMPLETE_CHILD_SOURCE=new i;var o=function(){function e(e,t,n){void 0===n&&(n=null),this.jr=e,this.Nr=t,this.Vr=n}return e.prototype.getCompleteChild=function(e){var t=this.Nr.getEventCache();if(t.isCompleteForChild(e))return t.getNode().getImmediateChild(e);var n=null!=this.Vr?new r.CacheNode(this.Vr,!0,!1):this.Nr.getServerCache();return this.jr.calcCompleteChild(e,n)},e.prototype.getChildAfterChild=function(e,t,n){var r=null!=this.Vr?this.Vr:this.Nr.getCompleteServerSnap(),i=this.jr.calcIndexedSlice(r,t,1,n,e);return 0===i.length?null:i[0]},e}();t.WriteTreeCompleteChildSource=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(5),i=n(9),o=n(0),a=function(){function e(e){this.mr=e,this.me=this.mr.getQueryParams().getIndex()}return e.prototype.generateEventsForChanges=function(e,t,n){var r=this,o=[],a=[];return e.forEach(function(e){e.type===i.Change.CHILD_CHANGED&&r.me.indexedValueChanged(e.oldSnap,e.snapshotNode)&&a.push(i.Change.childMovedChange(e.childName,e.snapshotNode))}),this.Qr(o,i.Change.CHILD_REMOVED,e,n,t),this.Qr(o,i.Change.CHILD_ADDED,e,n,t),this.Qr(o,i.Change.CHILD_MOVED,a,n,t),this.Qr(o,i.Change.CHILD_CHANGED,e,n,t),this.Qr(o,i.Change.VALUE,e,n,t),o},e.prototype.Qr=function(e,t,n,r,i){var o=this,a=n.filter(function(e){return e.type===t});a.sort(this.qr.bind(this)),a.forEach(function(t){var n=o.Ur(t,i);r.forEach(function(r){r.respondsTo(t.type)&&e.push(r.createEvent(n,o.mr))})})},e.prototype.Ur=function(e,t){return"value"===e.type||"child_removed"===e.type?e:(e.prevName=t.getPredecessorChildName(e.childName,e.snapshotNode,this.me),e)},e.prototype.qr=function(e,t){if(null==e.childName||null==t.childName)throw o.assertionError("Should only compare child_ events.");var n=new r.NamedNode(e.childName,e.snapshotNode),i=new r.NamedNode(t.childName,t.snapshotNode);return this.me.compare(n,i)},e}();t.EventGenerator=a},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),i=n(0),o=n(2),a=n(96),s=n(3),u=n(4),l=function(){function e(){this.Br=a.CompoundWrite.Empty,this.Hr=[],this.Gr=-1}return e.prototype.childWrites=function(e){return new h(e,this)},e.prototype.addOverwrite=function(e,t,n,r){i.assert(n>this.Gr,"Stacking an older write on top of newer ones"),void 0===r&&(r=!0),this.Hr.push({path:e,snap:t,writeId:n,visible:r}),r&&(this.Br=this.Br.addWrite(e,t)),this.Gr=n},e.prototype.addMerge=function(e,t,n){i.assert(n>this.Gr,"Stacking an older merge on top of newer ones"),this.Hr.push({path:e,children:t,writeId:n,visible:!0}),this.Br=this.Br.addWrites(e,t),this.Gr=n},e.prototype.getWrite=function(e){for(var t=0;t=0,"removeWrite called with nonexistent writeId.");var o=this.Hr[n];this.Hr.splice(n,1);for(var a=o.visible,s=!1,u=this.Hr.length-1;a&&u>=0;){var l=this.Hr[u];l.visible&&(u>=n&&this.Kr(l,o.path)?a=!1:o.path.contains(l.path)&&(s=!0)),u--}if(a){if(s)return this.Yr(),!0;if(o.snap)this.Br=this.Br.removeWrite(o.path);else{var h=o.children;r.forEach(h,function(e){t.Br=t.Br.removeWrite(o.path.child(e))})}return!0}return!1},e.prototype.getCompleteWriteData=function(e){return this.Br.getCompleteNode(e)},e.prototype.calcCompleteEventCache=function(t,n,r,i){if(r||i){var a=this.Br.childCompoundWrite(t);if(!i&&a.isEmpty())return n;if(i||null!=n||a.hasCompleteWrite(o.Path.Empty)){var s=function(e){return(e.visible||i)&&(!r||!~r.indexOf(e.writeId))&&(e.path.contains(t)||t.contains(e.path))},l=e.Xr(this.Hr,s,t),h=n||u.ChildrenNode.EMPTY_NODE;return l.apply(h)}return null}var c=this.Br.getCompleteNode(t);if(null!=c)return c;var p=this.Br.childCompoundWrite(t);if(p.isEmpty())return n;if(null!=n||p.hasCompleteWrite(o.Path.Empty)){var h=n||u.ChildrenNode.EMPTY_NODE;return p.apply(h)}return null},e.prototype.calcCompleteEventChildren=function(e,t){var n=u.ChildrenNode.EMPTY_NODE,r=this.Br.getCompleteNode(e);if(r)return r.isLeafNode()||r.forEachChild(s.PRIORITY_INDEX,function(e,t){n=n.updateImmediateChild(e,t)}),n;if(t){var i=this.Br.childCompoundWrite(e);return t.forEachChild(s.PRIORITY_INDEX,function(e,t){var r=i.childCompoundWrite(new o.Path(e)).apply(t);n=n.updateImmediateChild(e,r)}),i.getCompleteChildren().forEach(function(e){n=n.updateImmediateChild(e.name,e.node)}),n}return this.Br.childCompoundWrite(e).getCompleteChildren().forEach(function(e){n=n.updateImmediateChild(e.name,e.node)}),n},e.prototype.calcEventCacheAfterServerOverwrite=function(e,t,n,r){i.assert(n||r,"Either existingEventSnap or existingServerSnap must exist");var o=e.child(t);if(this.Br.hasCompleteWrite(o))return null;var a=this.Br.childCompoundWrite(o);return a.isEmpty()?r.getChild(t):a.apply(r.getChild(t))},e.prototype.calcCompleteChild=function(e,t,n){var r=e.child(t),i=this.Br.getCompleteNode(r);return null!=i?i:n.isCompleteForChild(t)?this.Br.childCompoundWrite(r).apply(n.getNode().getImmediateChild(t)):null},e.prototype.shadowingWrite=function(e){return this.Br.getCompleteNode(e)},e.prototype.calcIndexedSlice=function(e,t,n,r,i,a){var s,u=this.Br.childCompoundWrite(e),l=u.getCompleteNode(o.Path.Empty);if(null!=l)s=l;else{if(null==t)return[];s=u.apply(t)}if(s=s.withIndex(a),s.isEmpty()||s.isLeafNode())return[];for(var h=[],c=a.getCompare(),p=i?s.getReverseIteratorFrom(n,a):s.getIteratorFrom(n,a),d=p.getNext();d&&h.length0?this.Gr=this.Hr[this.Hr.length-1].writeId:this.Gr=-1},e.zr=function(e){return e.visible},e.Xr=function(e,t,n){for(var s=a.CompoundWrite.Empty,u=0;u0&&r.contains(e.ri,t)&&(n[t]=i,o=!0)}),o&&this.Z.reportStats(n),i.setTimeoutNonBlocking(this.ii.bind(this),Math.floor(2*Math.random()*3e5))},e}();t.StatsReporter=u},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),i=function(){function e(){this.oi=[],this.ai=0}return e.prototype.queueEvents=function(e){for(var t=null,n=0;n0)return this.ci[0];throw Error("No transports available")},e.prototype.upgradeTransport=function(){return this.ci.length>1?this.ci[1]:null},e}();t.TransportManager=a},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),i=function(){function e(e){this.Ut=e,this.pendingResponses=[],this.currentResponseNum=0,this.closeAfterResponse=-1,this.onClose=null}return e.prototype.closeAfter=function(e,t){this.closeAfterResponse=e,this.onClose=t,this.closeAfterResponse=200&&h.status<300){try{e=a.jsonEval(h.responseText)}catch(e){o.warn("Failed to parse JSON response for "+l+": "+h.responseText)}n(null,e)}else 401!==h.status&&404!==h.status&&o.warn("Got unsuccessful REST response for "+l+" Status: "+h.status),n(h.status);n=null}},h.open("GET",l,!0),h.send()})},t}(l.ServerActions);t.ReadonlyRestClient=h},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),i=n(1),o=n(10),a=n(3),s=n(38),u=n(42),l=n(24),h=n(108),c=n(56),p=n(0),d=function(){function e(){this.fi=!1,this._i=!1,this.yi=!1,this.vi=!1,this.gi=!1,this.mi=0,this.Ci="",this.Ei=null,this.Ni="",this.Pi=null,this.bi="",this.me=a.PRIORITY_INDEX}return e.prototype.hasStart=function(){return this._i},e.prototype.isViewFromLeft=function(){return""===this.Ci?this._i:this.Ci===e.Si.VIEW_FROM_LEFT},e.prototype.getIndexStartValue=function(){return r.assert(this._i,"Only valid if start has been set"),this.Ei},e.prototype.getIndexStartName=function(){return r.assert(this._i,"Only valid if start has been set"),this.yi?this.Ni:i.MIN_NAME},e.prototype.hasEnd=function(){return this.vi},e.prototype.getIndexEndValue=function(){return r.assert(this.vi,"Only valid if end has been set"),this.Pi},e.prototype.getIndexEndName=function(){return r.assert(this.vi,"Only valid if end has been set"),this.gi?this.bi:i.MAX_NAME},e.prototype.hasLimit=function(){return this.fi},e.prototype.hasAnchoredLimit=function(){return this.fi&&""!==this.Ci},e.prototype.getLimit=function(){return r.assert(this.fi,"Only valid if limit has been set"),this.mi},e.prototype.getIndex=function(){return this.me},e.prototype.Ti=function(){var t=new e;return t.fi=this.fi,t.mi=this.mi,t._i=this._i,t.Ei=this.Ei,t.yi=this.yi,t.Ni=this.Ni,t.vi=this.vi,t.Pi=this.Pi,t.gi=this.gi,t.bi=this.bi,t.me=this.me,t.Ci=this.Ci,t},e.prototype.limit=function(e){var t=this.Ti();return t.fi=!0,t.mi=e,t.Ci="",t},e.prototype.limitToFirst=function(t){var n=this.Ti();return n.fi=!0,n.mi=t,n.Ci=e.Si.VIEW_FROM_LEFT,n},e.prototype.limitToLast=function(t){var n=this.Ti();return n.fi=!0,n.mi=t,n.Ci=e.Si.VIEW_FROM_RIGHT,n},e.prototype.startAt=function(e,t){var n=this.Ti();return n._i=!0,void 0===e&&(e=null),n.Ei=e,null!=t?(n.yi=!0,n.Ni=t):(n.yi=!1,n.Ni=""),n},e.prototype.endAt=function(e,t){var n=this.Ti();return n.vi=!0,void 0===e&&(e=null),n.Pi=e,void 0!==t?(n.gi=!0,n.bi=t):(n.gi=!1,n.bi=""),n},e.prototype.orderBy=function(e){var t=this.Ti();return t.me=e,t},e.prototype.getQueryObject=function(){var t=e.Si,n={};if(this._i&&(n[t.INDEX_START_VALUE]=this.Ei,this.yi&&(n[t.INDEX_START_NAME]=this.Ni)),this.vi&&(n[t.INDEX_END_VALUE]=this.Pi,this.gi&&(n[t.INDEX_END_NAME]=this.bi)),this.fi){n[t.LIMIT]=this.mi;var r=this.Ci;""===r&&(r=this.isViewFromLeft()?t.VIEW_FROM_LEFT:t.VIEW_FROM_RIGHT),n[t.VIEW_FROM]=r}return this.me!==a.PRIORITY_INDEX&&(n[t.INDEX]=""+this.me),n},e.prototype.loadsAllData=function(){return!(this._i||this.vi||this.fi)},e.prototype.isDefault=function(){return this.loadsAllData()&&this.me==a.PRIORITY_INDEX},e.prototype.getNodeFilter=function(){return this.loadsAllData()?new l.IndexedFilter(this.getIndex()):this.hasLimit()?new h.LimitedFilter(this):new c.RangedFilter(this)},e.prototype.toRestQueryStringParameters=function(){var t=e.wi,n={};if(this.isDefault())return n;var i;return this.me===a.PRIORITY_INDEX?i=t.PRIORITY_INDEX:this.me===s.VALUE_INDEX?i=t.VALUE_INDEX:this.me===o.KEY_INDEX?i=t.KEY_INDEX:(r.assert(this.me instanceof u.PathIndex,"Unrecognized index type!"),i=""+this.me),n[t.ORDER_BY]=p.stringify(i),this._i&&(n[t.START_AT]=p.stringify(this.Ei),this.yi&&(n[t.START_AT]+=","+p.stringify(this.Ni))),this.vi&&(n[t.END_AT]=p.stringify(this.Pi),this.gi&&(n[t.END_AT]+=","+p.stringify(this.bi))),this.fi&&(this.isViewFromLeft()?n[t.LIMIT_TO_FIRST]=this.mi:n[t.LIMIT_TO_LAST]=this.mi),n},e.Si={INDEX_START_VALUE:"sp",INDEX_START_NAME:"sn",INDEX_END_VALUE:"ep",INDEX_END_NAME:"en",LIMIT:"l",VIEW_FROM:"vf",VIEW_FROM_LEFT:"l",VIEW_FROM_RIGHT:"r",INDEX:"i"},e.wi={ORDER_BY:"orderBy",PRIORITY_INDEX:"$priority",VALUE_INDEX:"$value",KEY_INDEX:"$key",START_AT:"startAt",END_AT:"endAt",LIMIT_TO_FIRST:"limitToFirst",LIMIT_TO_LAST:"limitToLast"},e.DEFAULT=new e,e}();t.QueryParams=d},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(56),i=n(4),o=n(5),a=n(0),s=n(9),u=function(){function e(e){this.Ii=new r.RangedFilter(e),this.me=e.getIndex(),this.mi=e.getLimit(),this.Ri=!e.isViewFromLeft()}return e.prototype.updateChild=function(e,t,n,r,a,s){return this.Ii.matches(new o.NamedNode(t,n))||(n=i.ChildrenNode.EMPTY_NODE),e.getImmediateChild(t).equals(n)?e:e.numChildren()=0)return null!=u&&u.trackChildChange(s.Change.childChangedChange(t,n,_)),c.updateImmediateChild(t,n);null!=u&&u.trackChildChange(s.Change.childRemovedChange(t,_));var g=c.updateImmediateChild(t,i.ChildrenNode.EMPTY_NODE);return null!=y&&this.Ii.matches(y)?(null!=u&&u.trackChildChange(s.Change.childAddedChange(y.name,y.node)),g.updateImmediateChild(y.name,y.node)):g}return n.isEmpty()?e:f&&l(d,p)>=0?(null!=u&&(u.trackChildChange(s.Change.childRemovedChange(d.name,d.node)),u.trackChildChange(s.Change.childAddedChange(t,n))),c.updateImmediateChild(t,n).updateImmediateChild(d.name,i.ChildrenNode.EMPTY_NODE)):e},e}();t.LimitedFilter=u},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,i=n(0),o=n(21),a=n(22),s=n(2),u=n(110),l=n(3),h=n(1),c=n(43),p=n(7),d=n(0),f=n(11),_=n(4),y=n(17);!function(e){e[e.RUN=0]="RUN",e[e.SENT=1]="SENT",e[e.COMPLETED=2]="COMPLETED",e[e.SENT_NEEDS_ABORT=3]="SENT_NEEDS_ABORT",e[e.NEEDS_ABORT=4]="NEEDS_ABORT"}(r=t.TransactionStatus||(t.TransactionStatus={})),y.Repo.Ai=25,y.Repo.prototype.ie=function(){this.Di=new u.Tree},y.Repo.prototype.startTransaction=function(e,t,n,s){this.de("transaction on "+e);var u=function(){},y=new o.Reference(this,e);y.on("value",u);var v=function(){y.off("value",u)},g={path:e,update:t,onComplete:n,status:null,order:h.LUIDGenerator(),applyLocally:s,retryCount:0,unwatcher:v,abortReason:null,currentWriteId:null,currentInputSnapshot:null,currentOutputSnapshotRaw:null,currentOutputSnapshotResolved:null},m=this.Mi(e);g.currentInputSnapshot=m;var C=g.update(m.val());if(void 0===C){if(g.unwatcher(),g.currentOutputSnapshotRaw=null,g.currentOutputSnapshotResolved=null,g.onComplete){var E=new a.DataSnapshot(g.currentInputSnapshot,new o.Reference(this,g.path),l.PRIORITY_INDEX);g.onComplete(null,!1,E)}}else{p.validateFirebaseData("transaction failed: Data returned ",C,g.path),g.status=r.RUN;var N=this.Di.subTree(e),P=N.getValue()||[];P.push(g),N.setValue(P);var b=void 0;"object"==typeof C&&null!==C&&d.contains(C,".priority")?(b=d.safeGet(C,".priority"),i.assert(p.isValidPriority(b),"Invalid priority returned by transaction. Priority must be a valid string, finite number, server value, or null.")):b=(this.ue.calcCompleteEventCache(e)||_.ChildrenNode.EMPTY_NODE).getPriority().val(),b=b;var S=this.generateServerValues(),T=f.nodeFromJSON(C,b),w=c.resolveDeferredValueSnapshot(T,S);g.currentOutputSnapshotRaw=T,g.currentOutputSnapshotResolved=w,g.currentWriteId=this.pe();var I=this.ue.applyUserOverwrite(e,w,g.currentWriteId,g.applyLocally);this.K.raiseEventsForChangedPath(e,I),this.Li()}},y.Repo.prototype.Mi=function(e,t){return this.ue.calcCompleteEventCache(e,t)||_.ChildrenNode.EMPTY_NODE},y.Repo.prototype.Li=function(e){var t=this;if(void 0===e&&(e=this.Di),e||this.Fi(e),null!==e.getValue()){var n=this.xi(e);i.assert(n.length>0,"Sending zero length transaction queue"),n.every(function(e){return e.status===r.RUN})&&this.ki(e.path(),n)}else e.hasChildren()&&e.forEachChild(function(e){t.Li(e)})},y.Repo.prototype.ki=function(e,t){for(var n=this,u=t.map(function(e){return e.currentWriteId}),c=this.Mi(e,u),p=c,d=c.hash(),f=0;f=y.Repo.Ai)E=!0,N="maxretry",u=u.concat(this.ue.ackUserWrite(m.currentWriteId,!0));else{var P=this.Mi(m.path,v);m.currentInputSnapshot=P;var b=e[g].update(P.val());if(void 0!==b){p.validateFirebaseData("transaction failed: Data returned ",b,m.path);var S=f.nodeFromJSON(b),T="object"==typeof b&&null!=b&&d.contains(b,".priority");T||(S=S.updatePriority(P.getPriority()));var w=m.currentWriteId,I=this.generateServerValues(),R=c.resolveDeferredValueSnapshot(S,I);m.currentOutputSnapshotRaw=S,m.currentOutputSnapshotResolved=R,m.currentWriteId=this.pe(),v.splice(v.indexOf(w),1),u=u.concat(this.ue.applyUserOverwrite(m.path,R,m.currentWriteId,m.applyLocally)),u=u.concat(this.ue.ackUserWrite(w,!0))}else E=!0,N="nodata",u=u.concat(this.ue.ackUserWrite(m.currentWriteId,!0))}if(this.K.raiseEventsForChangedPath(t,u),u=[],E&&(e[g].status=r.COMPLETED,function(e){setTimeout(e,Math.floor(0))}(e[g].unwatcher),e[g].onComplete))if("nodata"===N){var O=new o.Reference(this,e[g].path),A=e[g].currentInputSnapshot,D=new a.DataSnapshot(A,O,l.PRIORITY_INDEX);n.push(e[g].onComplete.bind(null,null,!1,D))}else n.push(e[g].onComplete.bind(null,Error(N),!1,null))}this.Fi(this.Di);for(var g=0;g0?n:null)}e.forEachChild(function(e){t.Fi(e)})},y.Repo.prototype.fe=function(e){var t=this,n=this.Wi(e).path(),r=this.Di.subTree(e);return r.forEachAncestor(function(e){t.Qi(e)}),this.Qi(r),r.forEachDescendant(function(e){t.Qi(e)}),n},y.Repo.prototype.Qi=function(e){var t=e.getValue();if(null!==t){for(var n=[],o=[],a=-1,s=0;s0},e.prototype.isEmpty=function(){return null===this.getValue()&&!this.hasChildren()},e.prototype.forEachChild=function(t){var n=this;o.forEach(this._e.children,function(r,i){t(new e(r,n,i))})},e.prototype.forEachDescendant=function(e,t,n){t&&!n&&e(this),this.forEachChild(function(t){t.forEachDescendant(e,!0,n)}),t&&n&&e(this)},e.prototype.forEachAncestor=function(e,t){for(var n=t?this:this.parent();null!==n;){if(e(n))return!0;n=n.parent()}return!1},e.prototype.forEachImmediateDescendantWithValue=function(e){this.forEachChild(function(t){null!==t.getValue()?e(t):t.forEachImmediateDescendantWithValue(e)})},e.prototype.path=function(){return new i.Path(null===this.Ui?this.qi:this.Ui.path()+"/"+this.qi)},e.prototype.name=function(){return this.qi},e.prototype.parent=function(){return this.Ui},e.prototype.Bi=function(){null!==this.Ui&&this.Ui.Hi(this.qi,this)},e.prototype.Hi=function(e,t){var n=t.isEmpty(),r=o.contains(this._e.children,e);n&&r?(delete this._e.children[e],this._e.childCount--,this.Bi()):n||r||(this._e.children[e]=t._e,this._e.childCount++,this.Bi())},e}();t.Tree=s},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(54),i=n(53);t.forceLongPolling=function(){r.WebSocketConnection.forceDisallow(),i.BrowserPollConnection.forceAllow()},t.forceWebSockets=function(){i.BrowserPollConnection.forceDisallow()},t.isWebSocketsAvailable=function(){return r.WebSocketConnection.isAvailable()},t.setSecurityDebugCallback=function(e,t){e.repo.J.it=t},t.stats=function(e,t){e.repo.stats(t)},t.statsIncrementCounter=function(e,t){e.repo.statsIncrementCounter(t)},t.dataUpdateCount=function(e){return e.repo.dataUpdateCount},t.interceptServerData=function(e,t){return e.repo.he(t)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(34),i=n(50),o=n(26),a=n(52);t.DataConnection=i.PersistentConnection,i.PersistentConnection.prototype.simpleListen=function(e,t){this.sendRequest("q",{p:e},t)},i.PersistentConnection.prototype.echo=function(e,t){this.sendRequest("echo",{d:e},t)},t.RealTimeConnection=a.Connection,t.hijackHash=function(e){var t=i.PersistentConnection.prototype.put;return i.PersistentConnection.prototype.put=function(n,r,i,o){void 0!==o&&(o=e()),t.call(this,n,r,i,o)},function(){i.PersistentConnection.prototype.put=t}},t.ConnectionTarget=r.RepoInfo,t.queryIdentifier=function(e){return e.queryIdentifier()},t.listens=function(e){return e.repo.J.Je},t.forceRestClient=function(e){o.RepoManager.getInstance().forceRestClient(e)}}],[78])}catch(e){throw Error("Cannot instantiate firebase-database.js - be sure to load firebase-app.js first.")} + +/*! + * @license Firebase v4.6.2 + * Build: rev-cbb07d3 + * Terms: https://firebase.google.com/terms/ + */ +try{webpackJsonpFirebase([3],{116:function(e,t,r){r(117)},117:function(e,t,r){"use strict";function n(e){var t=new Uint8Array(e);return window.btoa(String.fromCharCode.apply(null,t))}function o(e){var t=function(e){return self&&"ServiceWorkerGlobalScope"in self?new A(e):new k(e)},r={Messaging:k};e.INTERNAL.registerService("messaging",t,r)}Object.defineProperty(t,"__esModule",{value:!0});var i,s=r(0),a={AVAILABLE_IN_WINDOW:"only-available-in-window",AVAILABLE_IN_SW:"only-available-in-sw",SHOULD_BE_INHERITED:"should-be-overriden",BAD_SENDER_ID:"bad-sender-id",INCORRECT_GCM_SENDER_ID:"incorrect-gcm-sender-id",PERMISSION_DEFAULT:"permission-default",PERMISSION_BLOCKED:"permission-blocked",UNSUPPORTED_BROWSER:"unsupported-browser",NOTIFICATIONS_BLOCKED:"notifications-blocked",FAILED_DEFAULT_REGISTRATION:"failed-serviceworker-registration",SW_REGISTRATION_EXPECTED:"sw-registration-expected",GET_SUBSCRIPTION_FAILED:"get-subscription-failed",INVALID_SAVED_TOKEN:"invalid-saved-token",SW_REG_REDUNDANT:"sw-reg-redundant",TOKEN_SUBSCRIBE_FAILED:"token-subscribe-failed",TOKEN_SUBSCRIBE_NO_TOKEN:"token-subscribe-no-token",TOKEN_SUBSCRIBE_NO_PUSH_SET:"token-subscribe-no-push-set",USE_SW_BEFORE_GET_TOKEN:"use-sw-before-get-token",INVALID_DELETE_TOKEN:"invalid-delete-token",DELETE_TOKEN_NOT_FOUND:"delete-token-not-found",DELETE_SCOPE_NOT_FOUND:"delete-scope-not-found",BG_HANDLER_FUNCTION_EXPECTED:"bg-handler-function-expected",NO_WINDOW_CLIENT_TO_MSG:"no-window-client-to-msg",UNABLE_TO_RESUBSCRIBE:"unable-to-resubscribe",NO_FCM_TOKEN_FOR_RESUBSCRIBE:"no-fcm-token-for-resubscribe",FAILED_TO_DELETE_TOKEN:"failed-to-delete-token",NO_SW_IN_REG:"no-sw-in-reg",BAD_SCOPE:"bad-scope",BAD_VAPID_KEY:"bad-vapid-key",BAD_SUBSCRIPTION:"bad-subscription",BAD_TOKEN:"bad-token",BAD_PUSH_SET:"bad-push-set",FAILED_DELETE_VAPID_KEY:"failed-delete-vapid-key"},c=(i={},i[a.AVAILABLE_IN_WINDOW]="This method is available in a Window context.",i[a.AVAILABLE_IN_SW]="This method is available in a service worker context.",i["should-be-overriden"]="This method should be overriden by extended classes.",i["bad-sender-id"]="Please ensure that 'messagingSenderId' is set correctly in the options passed into firebase.initializeApp().",i["permission-default"]="The required permissions were not granted and dismissed instead.",i["permission-blocked"]="The required permissions were not granted and blocked instead.",i["unsupported-browser"]="This browser doesn't support the API's required to use the firebase SDK.",i["notifications-blocked"]="Notifications have been blocked.",i[a.FAILED_DEFAULT_REGISTRATION]="We are unable to register the default service worker. {$browserErrorMessage}",i["sw-registration-expected"]="A service worker registration was the expected input.",i["get-subscription-failed"]="There was an error when trying to get any existing Push Subscriptions.",i["invalid-saved-token"]="Unable to access details of the saved token.",i["sw-reg-redundant"]="The service worker being used for push was made redundant.",i["token-subscribe-failed"]="A problem occured while subscribing the user to FCM: {$message}",i["token-subscribe-no-token"]="FCM returned no token when subscribing the user to push.",i["token-subscribe-no-push-set"]="FCM returned an invalid response when getting an FCM token.",i["use-sw-before-get-token"]="You must call useServiceWorker() before calling getToken() to ensure your service worker is used.",i["invalid-delete-token"]="You must pass a valid token into deleteToken(), i.e. the token from getToken().",i["delete-token-not-found"]="The deletion attempt for token could not be performed as the token was not found.",i["delete-scope-not-found"]="The deletion attempt for service worker scope could not be performed as the scope was not found.",i["bg-handler-function-expected"]="The input to setBackgroundMessageHandler() must be a function.",i["no-window-client-to-msg"]="An attempt was made to message a non-existant window client.",i["unable-to-resubscribe"]="There was an error while re-subscribing the FCM token for push messaging. Will have to resubscribe the user on next visit. {$message}",i["no-fcm-token-for-resubscribe"]="Could not find an FCM token and as a result, unable to resubscribe. Will have to resubscribe the user on next visit.",i["failed-to-delete-token"]="Unable to delete the currently saved token.",i["no-sw-in-reg"]="Even though the service worker registration was successful, there was a problem accessing the service worker itself.",i["incorrect-gcm-sender-id"]="Please change your web app manifest's 'gcm_sender_id' value to '103953800507' to use Firebase messaging.",i["bad-scope"]="The service worker scope must be a string with at least one character.",i["bad-vapid-key"]="The public VAPID key must be a string with at least one character.",i["bad-subscription"]="The subscription must be a valid PushSubscription.",i["bad-token"]="The FCM Token used for storage / lookup was not a valid token string.",i["bad-push-set"]="The FCM push set used for storage / lookup was not not a valid push set string.",i["failed-delete-vapid-key"]="The VAPID key could not be deleted.",i),u={codes:a,map:c},_=function(e){return n(e).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")},d=[4,51,148,247,223,161,235,177,220,3,162,94,21,113,219,72,211,46,237,237,178,52,219,183,71,58,12,143,196,204,225,111,60,140,132,223,171,182,102,62,242,12,212,139,254,227,249,118,47,20,28,99,8,106,111,45,177,26,149,176,206,55,192,156,110],f={userVisibleOnly:!0,applicationServerKey:new Uint8Array(d)},h={ENDPOINT:"https://fcm.googleapis.com",APPLICATION_SERVER_KEY:d,SUBSCRIPTION_OPTIONS:f},p="fcm_token_object_Store",l=function(){function e(){this.e=new s.ErrorFactory("messaging","Messaging",u.map),this.t=null}return e.prototype.r=function(){return this.t?this.t:(this.t=new Promise(function(t,r){var n=indexedDB.open(e.DB_NAME,1);n.onerror=function(e){r(e.target.error)},n.onsuccess=function(e){t(e.target.result)},n.onupgradeneeded=function(e){var t=e.target.result,r=t.createObjectStore(p,{keyPath:"swScope"});r.createIndex("fcmSenderId","fcmSenderId",{unique:!1}),r.createIndex("fcmToken","fcmToken",{unique:!0})}}),this.t)},e.prototype.closeDatabase=function(){var e=this;return this.t?this.t.then(function(t){t.close(),e.t=null}):Promise.resolve()},e.prototype.getTokenDetailsFromToken=function(e){return this.r().then(function(t){return new Promise(function(r,n){var o=t.transaction([p]),i=o.objectStore(p),s=i.index("fcmToken"),a=s.get(e);a.onerror=function(e){n(e.target.error)},a.onsuccess=function(e){r(e.target.result)}})})},e.prototype.n=function(e){return this.r().then(function(t){return new Promise(function(r,n){var o=t.transaction([p]),i=o.objectStore(p),s=i.get(e);s.onerror=function(e){n(e.target.error)},s.onsuccess=function(e){r(e.target.result)}})})},e.prototype.o=function(e){return this.r().then(function(t){return new Promise(function(r,n){var o=t.transaction([p]),i=o.objectStore(p),s=[],a=i.openCursor();a.onerror=function(e){n(e.target.error)},a.onsuccess=function(t){var n=t.target.result;n?(n.value.fcmSenderId===e&&s.push(n.value),n.continue()):r(s)}})})},e.prototype.subscribeToFCM=function(e,t,r){var n=this,o=_(t.getKey("p256dh")),i=_(t.getKey("auth")),s="authorized_entity="+e+"&endpoint="+t.endpoint+"&encryption_key="+o+"&encryption_auth="+i;r&&(s+="&pushSet="+r);var a=new Headers;a.append("Content-Type","application/x-www-form-urlencoded");var c={method:"POST",headers:a,body:s};return fetch(h.ENDPOINT+"/fcm/connect/subscribe",c).then(function(e){return e.json()}).then(function(e){var t=e;if(t.error){var r=t.error.message;throw n.e.create(u.codes.TOKEN_SUBSCRIBE_FAILED,{message:r})}if(!t.token)throw n.e.create(u.codes.TOKEN_SUBSCRIBE_NO_TOKEN);if(!t.pushSet)throw n.e.create(u.codes.TOKEN_SUBSCRIBE_NO_PUSH_SET);return{token:t.token,pushSet:t.pushSet}})},e.prototype.i=function(e,t){return e.endpoint===t.endpoint&&_(e.getKey("auth"))===t.auth&&_(e.getKey("p256dh"))===t.p256dh},e.prototype.s=function(e,t,r,n,o){var i={swScope:t.scope,endpoint:r.endpoint,auth:_(r.getKey("auth")),p256dh:_(r.getKey("p256dh")),fcmToken:n,fcmPushSet:o,fcmSenderId:e};return this.r().then(function(e){return new Promise(function(t,r){var n=e.transaction([p],"readwrite"),o=n.objectStore(p),s=o.put(i);s.onerror=function(e){r(e.target.error)},s.onsuccess=function(e){t()}})})},e.prototype.getSavedToken=function(e,t){var r=this;return t instanceof ServiceWorkerRegistration?"string"!=typeof e||0===e.length?Promise.reject(this.e.create(u.codes.BAD_SENDER_ID)):this.o(e).then(function(r){if(0!==r.length){var n=r.findIndex(function(r){return t.scope===r.swScope&&e===r.fcmSenderId});if(-1!==n)return r[n]}}).then(function(e){if(e)return t.pushManager.getSubscription().catch(function(e){throw r.e.create(u.codes.GET_SUBSCRIPTION_FAILED)}).then(function(t){if(t&&r.i(t,e))return e.fcmToken})}):Promise.reject(this.e.create(u.codes.SW_REGISTRATION_EXPECTED))},e.prototype.createToken=function(e,t){var r=this;if("string"!=typeof e||0===e.length)return Promise.reject(this.e.create(u.codes.BAD_SENDER_ID));if(!(t instanceof ServiceWorkerRegistration))return Promise.reject(this.e.create(u.codes.SW_REGISTRATION_EXPECTED));var n,o;return t.pushManager.getSubscription().then(function(e){return e||t.pushManager.subscribe(h.SUBSCRIPTION_OPTIONS)}).then(function(t){return n=t,r.subscribeToFCM(e,n)}).then(function(i){return o=i,r.s(e,t,n,o.token,o.pushSet)}).then(function(){return o.token})},e.prototype.deleteToken=function(e){var t=this;return"string"!=typeof e||0===e.length?Promise.reject(this.e.create(u.codes.INVALID_DELETE_TOKEN)):this.getTokenDetailsFromToken(e).then(function(e){if(!e)throw t.e.create(u.codes.DELETE_TOKEN_NOT_FOUND);return t.r().then(function(r){return new Promise(function(n,o){var i=r.transaction([p],"readwrite"),s=i.objectStore(p),a=s.delete(e.swScope);a.onerror=function(e){o(e.target.error)},a.onsuccess=function(r){if(0===r.target.result)return void o(t.e.create(u.codes.FAILED_TO_DELETE_TOKEN));n(e)}})})})},e}(),g=l,E="messagingSenderId",T=function(){function e(e){var t=this;if(this.e=new s.ErrorFactory("messaging","Messaging",u.map),!e.options[E]||"string"!=typeof e.options[E])throw this.e.create(u.codes.BAD_SENDER_ID);this.a=e.options[E],this.c=new g,this.app=e,this.INTERNAL={},this.INTERNAL.delete=function(){return t.delete}}return e.prototype.getToken=function(){var e=this,t=this.u();return"granted"!==t?"denied"===t?Promise.reject(this.e.create(u.codes.NOTIFICATIONS_BLOCKED)):Promise.resolve(null):this._().then(function(t){return e.c.getSavedToken(e.a,t).then(function(r){return r||e.c.createToken(e.a,t)})})},e.prototype.deleteToken=function(e){var t=this;return this.c.deleteToken(e).then(function(){return t._().then(function(e){if(e)return e.pushManager.getSubscription()}).then(function(e){if(e)return e.unsubscribe()})})},e.prototype._=function(){throw this.e.create(u.codes.SHOULD_BE_INHERITED)},e.prototype.requestPermission=function(){throw this.e.create(u.codes.AVAILABLE_IN_WINDOW)},e.prototype.useServiceWorker=function(e){throw this.e.create(u.codes.AVAILABLE_IN_WINDOW)},e.prototype.onMessage=function(e,t,r){throw this.e.create(u.codes.AVAILABLE_IN_WINDOW)},e.prototype.onTokenRefresh=function(e,t,r){throw this.e.create(u.codes.AVAILABLE_IN_WINDOW)},e.prototype.setBackgroundMessageHandler=function(e){throw this.e.create(u.codes.AVAILABLE_IN_SW)},e.prototype.delete=function(){return this.c.closeDatabase()},e.prototype.u=function(){return Notification.permission},e.prototype.getTokenManager=function(){return this.c},e}(),S=T,b={TYPE_OF_MSG:"firebase-messaging-msg-type",DATA:"firebase-messaging-msg-data"},v={PUSH_MSG_RECEIVED:"push-msg-received",NOTIFICATION_CLICKED:"notification-clicked"},I=function(e,t){return r={},r[b.TYPE_OF_MSG]=e,r[b.DATA]=t,r;var r},m={PARAMS:b,TYPES_OF_MSG:v,createNewMsg:I},y={path:"/firebase-messaging-sw.js",scope:"/firebase-cloud-messaging-push-scope"},N=this&&this.__extends||function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])};return function(t,r){function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),w=function(e){function t(t){var r=e.call(this,t)||this;return r.d,r.f,r.h=null,r.p=Object(s.createSubscribe)(function(e){r.h=e}),r.l=null,r.g=Object(s.createSubscribe)(function(e){r.l=e}),r.T(),r}return N(t,e),t.prototype.getToken=function(){var t=this;return this.S()?this.b().then(function(){return e.prototype.getToken.call(t)}):Promise.reject(this.e.create(u.codes.UNSUPPORTED_BROWSER))},t.prototype.b=function(){var e=this;if(this.f)return this.f;var t=document.querySelector('link[rel="manifest"]');return this.f=t?fetch(t.href).then(function(e){return e.json()}).catch(function(){return Promise.resolve()}).then(function(t){if(t&&t.gcm_sender_id&&"103953800507"!==t.gcm_sender_id)throw e.e.create(u.codes.INCORRECT_GCM_SENDER_ID)}):Promise.resolve(),this.f},t.prototype.requestPermission=function(){var e=this;return"granted"===Notification.permission?Promise.resolve():new Promise(function(t,r){var n=function(n){return"granted"===n?t():r("denied"===n?e.e.create(u.codes.PERMISSION_BLOCKED):e.e.create(u.codes.PERMISSION_DEFAULT))},o=Notification.requestPermission(function(e){o||n(e)});o&&o.then(n)})},t.prototype.useServiceWorker=function(e){if(!(e instanceof ServiceWorkerRegistration))throw this.e.create(u.codes.SW_REGISTRATION_EXPECTED);if(void 0!==this.d)throw this.e.create(u.codes.USE_SW_BEFORE_GET_TOKEN);this.d=e},t.prototype.onMessage=function(e,t,r){return this.p(e,t,r)},t.prototype.onTokenRefresh=function(e,t,r){return this.g(e,t,r)},t.prototype.v=function(e){var t=this,r=e.installing||e.waiting||e.active;return new Promise(function(n,o){if(!r)return void o(t.e.create(u.codes.NO_SW_IN_REG));if("activated"===r.state)return void n(e);if("redundant"===r.state)return void o(t.e.create(u.codes.SW_REG_REDUNDANT));var i=function(){if("activated"===r.state)n(e);else{if("redundant"!==r.state)return;o(t.e.create(u.codes.SW_REG_REDUNDANT))}r.removeEventListener("statechange",i)};r.addEventListener("statechange",i)})},t.prototype._=function(){var e=this;return this.d?this.v(this.d):(this.d=null,navigator.serviceWorker.register(y.path,{scope:y.scope}).catch(function(t){throw e.e.create(u.codes.FAILED_DEFAULT_REGISTRATION,{browserErrorMessage:t.message})}).then(function(t){return e.v(t).then(function(){return e.d=t,t.update(),t})}))},t.prototype.T=function(){var e=this;"serviceWorker"in navigator&&navigator.serviceWorker.addEventListener("message",function(t){if(t.data&&t.data[m.PARAMS.TYPE_OF_MSG]){var r=t.data;switch(r[m.PARAMS.TYPE_OF_MSG]){case m.TYPES_OF_MSG.PUSH_MSG_RECEIVED:case m.TYPES_OF_MSG.NOTIFICATION_CLICKED:var n=r[m.PARAMS.DATA];e.h.next(n)}}},!1)},t.prototype.S=function(){return"serviceWorker"in navigator&&"PushManager"in window&&"Notification"in window&&"fetch"in window&&ServiceWorkerRegistration.prototype.hasOwnProperty("showNotification")&&PushSubscription.prototype.hasOwnProperty("getKey")},t}(S),k=w,O=this&&this.__extends||function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])};return function(t,r){function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),D=function(e){function t(t){var r=e.call(this,t)||this;return self.addEventListener("push",function(e){return r.I(e)},!1),self.addEventListener("pushsubscriptionchange",function(e){return r.m(e)},!1),self.addEventListener("notificationclick",function(e){return r.y(e)},!1),r.N=null,r}return O(t,e),t.prototype.I=function(e){var t,r=this;try{t=e.data.json()}catch(e){return}var n=this.w().then(function(e){if(e){if(t.notification||r.N)return r.k(t)}else{var n=r.O(t);if(n){var o=n.title||"";return self.registration.showNotification(o,n)}if(r.N)return r.N(t)}});e.waitUntil(n)},t.prototype.m=function(e){var t=this,r=this.getToken().then(function(e){if(!e)throw t.e.create(u.codes.NO_FCM_TOKEN_FOR_RESUBSCRIBE);var r=null,n=t.getTokenManager();return n.getTokenDetailsFromToken(e).then(function(e){if(!(r=e))throw t.e.create(u.codes.INVALID_SAVED_TOKEN);return self.registration.pushManager.subscribe(h.SUBSCRIPTION_OPTIONS)}).then(function(e){return n.subscribeToFCM(r.fcmSenderId,e,r.fcmPushSet)}).catch(function(e){return n.deleteToken(r.fcmToken).then(function(){throw t.e.create(u.codes.UNABLE_TO_RESUBSCRIBE,{message:e})})})});e.waitUntil(r)},t.prototype.y=function(e){var t=this;if(e.notification&&e.notification.data&&e.notification.data.FCM_MSG){e.stopImmediatePropagation(),e.notification.close();var r=e.notification.data.FCM_MSG,n=r.notification.click_action;if(n){var o=this.D(n).then(function(e){return e||self.clients.openWindow(n)}).then(function(e){if(e){r.notification,delete r.notification;var n=m.createNewMsg(m.TYPES_OF_MSG.NOTIFICATION_CLICKED,r);return t.A(e,n)}});e.waitUntil(o)}}},t.prototype.O=function(e){if(e&&"object"==typeof e.notification){var t=Object.assign({},e.notification);return t.data=(r={},r.FCM_MSG=e,r),t;var r}},t.prototype.setBackgroundMessageHandler=function(e){if(e&&"function"!=typeof e)throw this.e.create(u.codes.BG_HANDLER_FUNCTION_EXPECTED);this.N=e},t.prototype.D=function(e){var t=new URL(e).href;return self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(function(e){for(var r=null,n=0;n>6,128|63&r);else if(55296==(64512&r)){var o=n>18,128|r>>12&63,128|r>>6&63,128|63&r)}else e.push(239,191,189)}else 56320==(64512&r)?e.push(239,191,189):e.push(224|r>>12,128|r>>6&63,128|63&r)}return new Uint8Array(e)}function T(t){var e;try{e=decodeURIComponent(t)}catch(t){throw y(ne.DATA_URL,"Malformed data URL.")}return U(e)}function A(t,e){switch(t){case ne.BASE64:var n=-1!==e.indexOf("-"),r=-1!==e.indexOf("_");if(n||r){var o=n?"-":"_";throw y(t,"Invalid character '"+o+"' found: is it base64url encoded?")}break;case ne.BASE64URL:var i=-1!==e.indexOf("+"),a=-1!==e.indexOf("/");if(i||a){var o=i?"+":"/";throw y(t,"Invalid character '"+o+"' found: is it base64 encoded?")}e=e.replace(/-/g,"+").replace(/_/g,"/")}var s;try{s=atob(e)}catch(e){throw y(t,"Invalid character found")}for(var u=new Uint8Array(s.length),c=0;c=e.length)&&t.substring(t.length-e.length)===e}function S(t){switch(t){case ae.RUNNING:case ae.PAUSING:case ae.CANCELING:return se.RUNNING;case ae.PAUSED:return se.PAUSED;case ae.SUCCESS:return se.SUCCESS;case ae.CANCELED:return se.CANCELED;case ae.ERROR:default:return se.ERROR}}function k(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function I(t,e){for(var n in t)k(t,n)&&e(n,t[n])}function L(t){if(null==t)return{};var e={};return I(t,function(t,n){e[t]=n}),e}function P(t){return new Promise(t)}function x(t){return Promise.resolve(t)}function D(t){return Promise.reject(t)}function M(t){return null!=t}function W(t){return void 0!==t}function B(t){return"function"==typeof t}function G(t){return"object"==typeof t}function j(t){return G(t)&&null!==t}function q(t){return G(t)&&!Array.isArray(t)}function F(t){return"string"==typeof t||t instanceof String}function H(t){return"number"==typeof t||t instanceof Number}function z(t){return X()&&t instanceof Blob}function X(){return"undefined"!=typeof Blob}function V(t){var e;try{e=JSON.parse(t)}catch(t){return null}return q(e)?e:null}function K(t){if(0==t.length)return null;var e=t.lastIndexOf("/");return-1===e?"":t.slice(0,e)}function Z(t,e){var n=e.split("/").filter(function(t){return t.length>0}).join("/");return 0===t.length?n:t+"/"+n}function J(t){var e=t.lastIndexOf("/",t.length-2);return-1===e?t:t.slice(e+1)}function Q(t){return Vt+Zt+t}function Y(t){return Kt+Zt+t}function $(t){return Vt+Jt+t}function tt(t){var e=encodeURIComponent,n="?";return I(t,function(t,r){var o=e(t)+"="+e(r);n=n+o+"&"}),n=n.slice(0,-1)}function et(t,e){return e}function nt(t){return!F(t)||t.length<2?t:(t=t,J(t))}function rt(){function t(t,e){return nt(e)}function e(t,e){return M(e)?+e:e}function n(t,e){if(!(F(e)&&e.length>0))return[];var n=encodeURIComponent;return e.split(",").map(function(e){var r=t.bucket,o=t.fullPath;return Y("/b/"+n(r)+"/o/"+n(o))+tt({alt:"media",token:e})})}if(pe)return pe;var r=[];r.push(new he("bucket")),r.push(new he("generation")),r.push(new he("metageneration")),r.push(new he("name","fullPath",!0));var o=new he("name");o.xform=t,r.push(o);var i=new he("size");return i.xform=e,r.push(i),r.push(new he("timeCreated")),r.push(new he("updated")),r.push(new he("md5Hash",null,!0)),r.push(new he("cacheControl",null,!0)),r.push(new he("contentDisposition",null,!0)),r.push(new he("contentEncoding",null,!0)),r.push(new he("contentLanguage",null,!0)),r.push(new he("contentType",null,!0)),r.push(new he("metadata","customMetadata",!0)),r.push(new he("downloadTokens","downloadURLs",!1,n)),pe=r}function ot(t,e){function n(){var n=t.bucket,r=t.fullPath,o=new le(n,r);return e.makeStorageReference(o)}Object.defineProperty(t,"ref",{get:n})}function it(t,e,n){var r={};r.type="file";for(var o=n.length,i=0;i=0))throw"Expected a number 0 or greater."}return new fe(t)}function _t(t,e){function n(e){if(!(null===e||M(e)&&e instanceof Object))throw"Expected an Object.";void 0!==t&&null!==t&&t(e)}return new fe(n,e)}function vt(t){function e(t){if(null!==t&&!B(t))throw"Expected a Function."}return new fe(e,t)}function bt(){return"undefined"!=typeof BlobBuilder?BlobBuilder:"undefined"!=typeof WebKitBlobBuilder?WebKitBlobBuilder:void 0}function mt(){for(var t=[],e=0;e0&&(h=Math.min(h,o));var p=c.current,_=p+h,v=h===l?"upload, finalize":"upload",b={"X-Goog-Upload-Command":v,"X-Goog-Upload-Offset":c.current},m=r.slice(p,_);if(null===m)throw f();var g=e.maxUploadRetryTime(),y=new _e(n,"POST",u,g);return y.headers=b,y.body=m.uploadData(),y.progressCallback=s||null,y.errorHandler=Tt(t),y}function Mt(t){return function(){for(var e=[],n=0;n0&&(t.Authorization="Firebase "+e)}function jt(t){var e=void 0!==Xt.default?Xt.default.SDK_VERSION:"AppManager";t["X-Firebase-Storage-Version"]="webjs/"+e}function qt(t,e,n){var r=tt(t.urlParams),o=t.url+r,i=L(t.headers);return Gt(i,e),jt(i),new Ue(o,t.method,i,t.body,t.successCodes,t.additionalRetryCodes,t.handler,t.errorHandler,t.timeout,t.progressCallback,n)}function Ft(t,e,n){return new Ae(t,new ce,n)}function Ht(t){var e={TaskState:se,TaskEvent:ie,StringFormat:ne,Storage:Ae,Reference:ye};t.INTERNAL.registerService(Oe,Ft,e,void 0,!0)}Object.defineProperty(e,"__esModule",{value:!0});var zt,Xt=n(6),Vt="https://firebasestorage.googleapis.com",Kt="https://firebasestorage.googleapis.com",Zt="/v0",Jt="/v0",Qt=12e4,Yt=6e4,$t=-9007199254740991,te=function(){function t(t,e){this.t=r(t),this.e="Firebase Storage: "+e,this.n=null,this.r="FirebaseError"}return t.prototype.codeProp=function(){return this.code},t.prototype.codeEquals=function(t){return r(t)===this.codeProp()},t.prototype.serverResponseProp=function(){return this.n},t.prototype.setServerResponseProp=function(t){this.n=t},Object.defineProperty(t.prototype,"name",{get:function(){return this.r},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"code",{get:function(){return this.t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"message",{get:function(){return this.e},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"serverResponse",{get:function(){return this.n},enumerable:!0,configurable:!0}),t}(),ee={UNKNOWN:"unknown",OBJECT_NOT_FOUND:"object-not-found",BUCKET_NOT_FOUND:"bucket-not-found",PROJECT_NOT_FOUND:"project-not-found",QUOTA_EXCEEDED:"quota-exceeded",UNAUTHENTICATED:"unauthenticated",UNAUTHORIZED:"unauthorized",RETRY_LIMIT_EXCEEDED:"retry-limit-exceeded",INVALID_CHECKSUM:"invalid-checksum",CANCELED:"canceled",INVALID_EVENT_NAME:"invalid-event-name",INVALID_URL:"invalid-url",INVALID_DEFAULT_BUCKET:"invalid-default-bucket",NO_DEFAULT_BUCKET:"no-default-bucket",CANNOT_SLICE_BLOB:"cannot-slice-blob",SERVER_FILE_WRONG_SIZE:"server-file-wrong-size",NO_DOWNLOAD_URL:"no-download-url",INVALID_ARGUMENT:"invalid-argument",INVALID_ARGUMENT_COUNT:"invalid-argument-count",APP_DELETED:"app-deleted",INVALID_ROOT_OPERATION:"invalid-root-operation",INVALID_FORMAT:"invalid-format",INTERNAL_ERROR:"internal-error"},ne={RAW:"raw",BASE64:"base64",BASE64URL:"base64url",DATA_URL:"data_url"},re=function(){function t(t,e){this.data=t,this.contentType=e||null}return t}(),oe=function(){function t(t){this.base64=!1,this.contentType=null;var e=t.match(/^data:([^,]+)?,/);if(null===e)throw y(ne.DATA_URL,"Must be formatted 'data:[][;base64],");var n=e[1]||null;null!=n&&(this.base64=C(n,";base64"),this.contentType=this.base64?n.substring(0,n.length-7):n),this.rest=t.substring(t.indexOf(",")+1)}return t}(),ie={STATE_CHANGED:"state_changed"},ae={RUNNING:"running",PAUSING:"pausing",PAUSED:"paused",SUCCESS:"success",CANCELING:"canceling",CANCELED:"canceled",ERROR:"error"},se={RUNNING:"running",PAUSED:"paused",SUCCESS:"success",CANCELED:"canceled",ERROR:"error"};!function(t){t[t.NO_ERROR=0]="NO_ERROR",t[t.NETWORK_ERROR=1]="NETWORK_ERROR",t[t.ABORT=2]="ABORT"}(zt=zt||(zt={}));var ue=function(){function t(){var t=this;this.o=!1,this.i=new XMLHttpRequest,this.a=zt.NO_ERROR,this.s=P(function(e,n){t.i.addEventListener("abort",function(n){t.a=zt.ABORT,e(t)}),t.i.addEventListener("error",function(n){t.a=zt.NETWORK_ERROR,e(t)}),t.i.addEventListener("load",function(n){e(t)})})}return t.prototype.send=function(t,e,n,r){var o=this;if(this.o)throw R("cannot .send() more than once");return this.o=!0,this.i.open(e,t,!0),M(r)&&I(r,function(t,e){o.i.setRequestHeader(t,""+e)}),M(n)?this.i.send(n):this.i.send(),this.s},t.prototype.getErrorCode=function(){if(!this.o)throw R("cannot .getErrorCode() before sending");return this.a},t.prototype.getStatus=function(){if(!this.o)throw R("cannot .getStatus() before sending");try{return this.i.status}catch(t){return-1}},t.prototype.getResponseText=function(){if(!this.o)throw R("cannot .getResponseText() before sending");return this.i.responseText},t.prototype.abort=function(){this.i.abort()},t.prototype.getResponseHeader=function(t){return this.i.getResponseHeader(t)},t.prototype.addUploadProgressListener=function(t){M(this.i.upload)&&this.i.upload.addEventListener("progress",t)},t.prototype.removeUploadProgressListener=function(t){M(this.i.upload)&&this.i.upload.removeEventListener("progress",t)},t}(),ce=function(){function t(){}return t.prototype.createXhrIo=function(){return new ue},t}(),le=function(){function t(t,e){this.bucket=t,this.u=e}return Object.defineProperty(t.prototype,"path",{get:function(){return this.u},enumerable:!0,configurable:!0}),t.prototype.fullServerUrl=function(){var t=encodeURIComponent;return"/b/"+t(this.bucket)+"/o/"+t(this.path)},t.prototype.bucketOnlyServerUrl=function(){return"/b/"+encodeURIComponent(this.bucket)+"/o"},t.makeFromBucketSpec=function(e){var n;try{n=t.makeFromUrl(e)}catch(n){return new t(e,"")}if(""===n.path)return n;throw p(e)},t.makeFromUrl=function(e){function n(t){"/"===t.path.charAt(t.path.length-1)&&(t.u=t.u.slice(0,-1))}function r(t){t.u=decodeURIComponent(t.path)}for(var o=null,i=RegExp("^gs://([A-Za-z0-9.\\-]+)(/(.*))?$","i"),a={bucket:1,path:3},s=RegExp("^https?://firebasestorage\\.googleapis\\.com/v[A-Za-z0-9_]+/b/([A-Za-z0-9.\\-]+)/o(/([^?#]*).*)?$","i"),u={bucket:1,path:3},c=[{regex:i,indices:a,postModify:n},{regex:s,indices:u,postModify:r}],l=0;l262144},t.prototype.M=function(){this.k===ae.RUNNING&&null===this.m&&(this.C?null===this.b?this.G():this.f?this.j():this.d?this.q():this.F():this.H())},t.prototype.z=function(t){var e=this;this.U.getAuthToken().then(function(n){switch(e.k){case ae.RUNNING:t(n);break;case ae.CANCELING:e.P(ae.CANCELED);break;case ae.PAUSING:e.P(ae.PAUSED)}})},t.prototype.G=function(){var t=this;this.z(function(e){var n=Pt(t.U,t.T,t.O,t.A,t.N),r=t.U.makeRequest(n,e);t.m=r,r.getPromise().then(function(e){t.m=null,t.b=e,t.f=!1,t.L()},t.I)})},t.prototype.j=function(){var t=this,e=this.b;this.z(function(n){var r=xt(t.U,t.T,e,t.A),o=t.U.makeRequest(r,n);t.m=o,o.getPromise().then(function(e){e=e,t.m=null,t.B(e.current),t.f=!1,e.finalized&&(t.d=!0),t.L()},t.I)})},t.prototype.F=function(){var t=this,e=262144*this.g,n=new ve(this.p,this.A.size()),r=this.b;this.z(function(o){var i;try{i=Dt(t.T,t.U,r,t.A,e,t.O,n,t.W())}catch(e){return t.v=e,void t.P(ae.ERROR)}var a=t.U.makeRequest(i,o);t.m=a,a.getPromise().then(function(e){t.X(),t.m=null,t.B(e.current),e.finalized?(t.N=e.metadata,t.P(ae.SUCCESS)):t.L()},t.I)})},t.prototype.X=function(){262144*this.g<33554432&&(this.g*=2)},t.prototype.q=function(){var t=this;this.z(function(e){var n=Nt(t.U,t.T,t.O),r=t.U.makeRequest(n,e);t.m=r,r.getPromise().then(function(e){t.m=null,t.N=e,t.P(ae.SUCCESS)},t.x)})},t.prototype.H=function(){var t=this;this.z(function(e){var n=It(t.U,t.T,t.O,t.A,t.N),r=t.U.makeRequest(n,e);t.m=r,r.getPromise().then(function(e){t.m=null,t.N=e,t.B(t.A.size()),t.P(ae.SUCCESS)},t.I)})},t.prototype.B=function(t){var e=this.p;this.p=t,this.p!==e&&this.V()},t.prototype.P=function(t){if(this.k!==t)switch(t){case ae.CANCELING:case ae.PAUSING:this.k=t,null!==this.m&&this.m.cancel();break;case ae.RUNNING:var e=this.k===ae.PAUSED;this.k=t,e&&(this.V(),this.M());break;case ae.PAUSED:this.k=t,this.V();break;case ae.CANCELED:this.v=l(),this.k=t,this.V();break;case ae.ERROR:case ae.SUCCESS:this.k=t,this.V()}},t.prototype.L=function(){switch(this.k){case ae.PAUSING:this.P(ae.PAUSED);break;case ae.CANCELING:this.P(ae.CANCELED);break;case ae.RUNNING:this.M()}},Object.defineProperty(t.prototype,"snapshot",{get:function(){var t=S(this.k);return new me(this.p,this.A.size(),t,this.N,this,this.w)},enumerable:!0,configurable:!0}),t.prototype.on=function(t,e,n,r){function o(e){if(t!==ie.STATE_CHANGED)throw"Expected one of the event types: ["+ie.STATE_CHANGED+"]."}function i(t){try{return void c(t)}catch(t){}try{if(l(t),!(W(t.next)||W(t.error)||W(t.complete)))throw"";return}catch(t){throw u}}function a(t){function e(e,n,o){null!==t&&ct("on",t,arguments);var i=new be(e,n,r);return h.K(i),function(){h.Z(i)}}return e}function s(t){if(null===t)throw u;i(t)}void 0===e&&(e=void 0),void 0===n&&(n=void 0),void 0===r&&(r=void 0);var u="Expected a function or an Object with one of `next`, `error`, `complete` properties.",c=vt(!0).validator,l=_t(null,!0).validator;ct("on",[ht(o),_t(i,!0),vt(!0),vt(!0)],arguments);var h=this,p=[_t(s),vt(!0),vt(!0)];return W(e)||W(n)||W(r)?a(null)(e,n,r):a(p)},t.prototype.then=function(t,e){return this.D.then(t,e)},t.prototype.catch=function(t){return this.then(null,t)},t.prototype.K=function(t){this._.push(t),this.J(t)},t.prototype.Z=function(t){Et(this._,t)},t.prototype.V=function(){var t=this;this.Q(),Rt(this._).forEach(function(e){t.J(e)})},t.prototype.Q=function(){if(null!==this.y){var t=!0;switch(S(this.k)){case se.SUCCESS:Mt(this.y.bind(null,this.snapshot))();break;case se.CANCELED:case se.ERROR:Mt(this.R.bind(null,this.v))();break;default:t=!1}t&&(this.y=null,this.R=null)}},t.prototype.J=function(t){switch(S(this.k)){case se.RUNNING:case se.PAUSED:null!==t.next&&Mt(t.next.bind(t,this.snapshot))();break;case se.SUCCESS:null!==t.complete&&Mt(t.complete.bind(t))();break;case se.CANCELED:case se.ERROR:null!==t.error&&Mt(t.error.bind(t,this.v))();break;default:null!==t.error&&Mt(t.error.bind(t,this.v))()}},t.prototype.resume=function(){ct("resume",[],arguments);var t=this.k===ae.PAUSED||this.k===ae.PAUSING;return t&&this.P(ae.RUNNING),t},t.prototype.pause=function(){ct("pause",[],arguments);var t=this.k===ae.RUNNING;return t&&this.P(ae.PAUSING),t},t.prototype.cancel=function(){ct("cancel",[],arguments);var t=this.k===ae.RUNNING||this.k===ae.PAUSING;return t&&this.P(ae.CANCELING),t},t}(),ye=function(){function t(t,e){this.authWrapper=t,this.location=e instanceof le?e:le.makeFromUrl(e)}return t.prototype.toString=function(){return ct("toString",[],arguments),"gs://"+this.location.bucket+"/"+this.location.path},t.prototype.newRef=function(e,n){return new t(e,n)},t.prototype.mappings=function(){return rt()},t.prototype.child=function(t){ct("child",[ht()],arguments);var e=Z(this.location.path,t),n=new le(this.location.bucket,e);return this.newRef(this.authWrapper,n)},Object.defineProperty(t.prototype,"parent",{get:function(){var t=K(this.location.path);if(null===t)return null;var e=new le(this.location.bucket,t);return this.newRef(this.authWrapper,e)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"root",{get:function(){var t=new le(this.location.bucket,"");return this.newRef(this.authWrapper,t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"bucket",{get:function(){return this.location.bucket},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"fullPath",{get:function(){return this.location.path},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"name",{get:function(){return J(this.location.path)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"storage",{get:function(){return this.authWrapper.service()},enumerable:!0,configurable:!0}),t.prototype.put=function(t,e){return void 0===e&&(e=null),ct("put",[pt(),ft(!0)],arguments),this.Y("put"),new ge(this,this.authWrapper,this.location,this.mappings(),new de(t),e)},t.prototype.putString=function(t,e,n){void 0===e&&(e=ne.RAW),ct("putString",[ht(),ht(E,!0),ft(!0)],arguments),this.Y("putString");var r=w(e,t),o=L(n);return!M(o.contentType)&&M(r.contentType)&&(o.contentType=r.contentType),new ge(this,this.authWrapper,this.location,this.mappings(),new de(r.data,!0),o)},t.prototype.delete=function(){ct("delete",[],arguments),this.Y("delete");var t=this;return this.authWrapper.getAuthToken().then(function(e){var n=Ct(t.authWrapper,t.location);return t.authWrapper.makeRequest(n,e).getPromise()})},t.prototype.getMetadata=function(){ct("getMetadata",[],arguments),this.Y("getMetadata");var t=this;return this.authWrapper.getAuthToken().then(function(e){var n=Nt(t.authWrapper,t.location,t.mappings());return t.authWrapper.makeRequest(n,e).getPromise()})},t.prototype.updateMetadata=function(t){ct("updateMetadata",[ft()],arguments),this.Y("updateMetadata");var e=this;return this.authWrapper.getAuthToken().then(function(n){var r=Ot(e.authWrapper,e.location,t,e.mappings());return e.authWrapper.makeRequest(r,n).getPromise()})},t.prototype.getDownloadURL=function(){return ct("getDownloadURL",[],arguments),this.Y("getDownloadURL"),this.getMetadata().then(function(t){var e=t.downloadURLs[0];if(M(e))return e;throw _()})},t.prototype.Y=function(t){if(""===this.location.path)throw g(t)},t}(),Re=function(){function t(t){this.D=D(t)}return t.prototype.getPromise=function(){return this.D},t.prototype.cancel=function(t){void 0===t&&(t=!1)},t}(),Ee=function(){function t(){this.$={},this.tt=$t}return t.prototype.addRequest=function(t){function e(){delete r.$[n]}var n=this.tt;this.tt++,this.$[n]=t;var r=this;t.getPromise().then(e,e)},t.prototype.clear=function(){I(this.$,function(t,e){e&&e.cancel(!0)}),this.$={}},t}(),we=function(){function t(e,n,r,o,i){if(this.et=null,this.nt=!1,this.rt=e,null!==this.rt){var a=this.rt.options;M(a)&&(this.et=t.ot(a))}this.it=n,this.at=r,this.st=i,this.ut=o,this.ct=Qt,this.lt=Yt,this.ht=new Ee}return t.ot=function(t){var e=t.storageBucket||null;return null==e?null:le.makeFromBucketSpec(e).bucket},t.prototype.getAuthToken=function(){return null!==this.rt&&M(this.rt.INTERNAL)&&M(this.rt.INTERNAL.getToken)?this.rt.INTERNAL.getToken().then(function(t){return null!==t?t.accessToken:null},function(t){return null}):x(null)},t.prototype.bucket=function(){if(this.nt)throw m();return this.et},t.prototype.service=function(){return this.ut},t.prototype.makeStorageReference=function(t){return this.it(this,t)},t.prototype.makeRequest=function(t,e){if(this.nt)return new Re(m());var n=this.at(t,e,this.st);return this.ht.addRequest(n),n},t.prototype.deleteApp=function(){this.nt=!0,this.rt=null,this.ht.clear()},t.prototype.maxUploadRetryTime=function(){return this.lt},t.prototype.setMaxUploadRetryTime=function(t){this.lt=t},t.prototype.maxOperationRetryTime=function(){return this.ct},t.prototype.setMaxOperationRetryTime=function(t){this.ct=t},t}(),Ue=function(){function t(t,e,n,r,o,i,a,s,u,c,l){this.pt=null,this.ft=null,this.y=null,this.R=null,this.dt=!1,this._t=!1,this.vt=t,this.bt=e,this.mt=n,this.gt=r,this.yt=o.slice(),this.Rt=i.slice(),this.Et=a,this.wt=s,this.Ut=c,this.Tt=u,this.st=l;var h=this;this.D=P(function(t,e){h.y=t,h.R=e,h.M()})}return t.prototype.M=function(){function t(t,e){function r(t){var e=t.loaded,r=t.lengthComputable?t.total:-1;null!==n.Ut&&n.Ut(e,r)}if(e)return void t(!1,new Te(!1,null,!0));var o=n.st.createXhrIo();n.pt=o,null!==n.Ut&&o.addUploadProgressListener(r),o.send(n.vt,n.bt,n.gt,n.mt).then(function(e){null!==n.Ut&&e.removeUploadProgressListener(r),n.pt=null,e=e;var o=e.getErrorCode()===zt.NO_ERROR,i=e.getStatus();if(!o||n.At(i)){var a=e.getErrorCode()===zt.ABORT;return void t(!1,new Te(!1,null,a))}var s=yt(n.yt,i);t(!0,new Te(s,e))})}function e(t,e){var r=n.y,i=n.R,a=e.xhr;if(e.wasSuccessCode)try{var s=n.Et(a,a.getResponseText());W(s)?r(s):r()}catch(t){i(t)}else if(null!==a){var u=o();u.setServerResponseProp(a.getResponseText()),i(n.wt?n.wt(a,u):u)}else if(e.canceled){var u=n._t?m():l();i(u)}else{var u=c();i(u)}}var n=this;this.dt?e(!1,new Te(!1,null,!0)):this.ft=Wt(t,e,this.Tt)},t.prototype.getPromise=function(){return this.D},t.prototype.cancel=function(t){this.dt=!0,this._t=t||!1,null!==this.ft&&Bt(this.ft),null!==this.pt&&this.pt.abort()},t.prototype.At=function(t){var e=t>=500&&t<600,n=[408,429],r=yt(n,t),o=yt(this.Rt,t);return e||r||o},t}(),Te=function(){function t(t,e,n){this.wasSuccessCode=t,this.xhr=e,this.canceled=!!n}return t}(),Ae=function(){function t(t,e,n){function r(t,e){return new ye(t,e)}if(this.et=null,this.U=new we(t,r,qt,this,e),this.rt=t,null!=n)this.et=le.makeFromBucketSpec(n);else{var o=this.U.bucket();null!=o&&(this.et=new le(o,""))}this.Nt=new Ne(this)}return t.prototype.ref=function(t){function e(t){if(/^[A-Za-z]+:\/\//.test(t))throw"Expected child path but got a URL, use refFromURL instead."}if(ct("ref",[ht(e,!0)],arguments),null==this.et)throw Error("No Storage Bucket defined in Firebase Options.");var n=new ye(this.U,this.et);return null!=t?n.child(t):n},t.prototype.refFromURL=function(t){function e(t){if(!/^[A-Za-z]+:\/\//.test(t))throw"Expected full URL but got a child path, use ref instead.";try{le.makeFromUrl(t)}catch(t){throw"Expected valid full URL but got an invalid one."}}return ct("refFromURL",[ht(e,!1)],arguments),new ye(this.U,t)},Object.defineProperty(t.prototype,"maxUploadRetryTime",{get:function(){return this.U.maxUploadRetryTime()},enumerable:!0,configurable:!0}),t.prototype.setMaxUploadRetryTime=function(t){ct("setMaxUploadRetryTime",[dt()],arguments),this.U.setMaxUploadRetryTime(t)},Object.defineProperty(t.prototype,"maxOperationRetryTime",{get:function(){return this.U.maxOperationRetryTime()},enumerable:!0,configurable:!0}),t.prototype.setMaxOperationRetryTime=function(t){ct("setMaxOperationRetryTime",[dt()],arguments),this.U.setMaxOperationRetryTime(t)},Object.defineProperty(t.prototype,"app",{get:function(){return this.rt},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"INTERNAL",{get:function(){return this.Nt},enumerable:!0,configurable:!0}),t}(),Ne=function(){function t(t){this.ut=t}return t.prototype.delete=function(){return this.ut.U.deleteApp(),x(void 0)},t}();e.registerStorage=Ht;var Oe="storage";Ht(Xt.default)}},[118])}catch(t){throw Error("Cannot instantiate firebase-storage.js - be sure to load firebase-app.js first.")} + +//# sourceMappingURL=firebase.js.map diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/icon.png new file mode 100755 index 0000000..d5dee1b Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/instance.js new file mode 100755 index 0000000..f32a808 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_FirebaseAPIV3; + + PLUGIN_CLASS.Instance = class Rex_FirebaseAPIV3Instance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/lang/en-US.json new file mode 100755 index 0000000..661e6b7 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/lang/en-US.json @@ -0,0 +1,59 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Firebase API v3.", + "text": { + "plugins": { + "rex_firebaseapiv3": { + "name": "Firebase API v3", + "description": "3.x API of real time database-as-a-service. https://firebase.google.com/", + "help-url": "http://c2rexplugins.weebly.com/rex_firebaseapiv3.html", + "properties": { + "api-key": { + "name": "Api key", + "desc": "APi key." + }, + "auth-domain": { + "name": "Auth domain", + "desc": "Auth domain." + }, + "database-url": { + "name": "Database URL", + "desc": "Database URL." + }, + "storage-bucket": { + "name": "Storage bucket", + "desc": "Storage bucket." + }, + "log": { + "name": "Log", + "desc": "Enable log.", + "items": { + "no":"No", + "yes":"Yes" + } + } + }, + "aceCategories": { + "ınitialize": "Initialize" + }, + "conditions": { + }, + "actions": { + "initializeapp1": { + "list-name": "Initialize", + "display-text": "Initialize with Api key: [i]{0}[/i], Auth domain: [i]{1}[/i], Database URL: [i]{2}[/i], Storage bucket: [i]{3}[/i]", + "description": "Initialize connection.", + "params": { + "api_key0": { "name":"Api key", "desc":"Api key"}, + "auth_domain1": { "name":"Auth domain", "desc":"Auth domain"}, + "database_url2": { "name":"Database URL", "desc":"Database URL"}, + "storage_bucket3": { "name":"Storage bucket", "desc":"Storage bucket"} + } + } + }, + "expressions": { + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/plugin.js new file mode 100755 index 0000000..55d1840 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/plugin.js @@ -0,0 +1,49 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_FirebaseAPIV3"; + const PLUGIN_VERSION = "3.3.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_FirebaseAPIV3 = class Rex_FirebaseAPIV3 extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "api-key", ""), + new SDK.PluginProperty("text", "auth-domain", ""), + new SDK.PluginProperty("text", "database-url", ""), + new SDK.PluginProperty("text", "storage-bucket", ""), + new SDK.PluginProperty("combo", "log", {initialValue:"no", items:["no","yes"]}) + ]); + this._info.AddFileDependency({ + filename: "firebase.js", + type: "external-script" + }); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/type.js new file mode 100755 index 0000000..c3818da --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_apiv3/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_FirebaseAPIV3; + + PLUGIN_CLASS.Type = class Rex_FirebaseAPIV3Type extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/dist/rex_firebase_authentication.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/dist/rex_firebase_authentication.c3addon new file mode 100644 index 0000000..f9198d8 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/dist/rex_firebase_authentication.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/aces.json new file mode 100755 index 0000000..949761b --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/aces.json @@ -0,0 +1,588 @@ +{ + "email_&_password": { + "conditions": [ + ], + "actions": [ + { + "c2id": 1, + "id": "emailpassword_createaccount1", + "scriptName": "EmailPassword_CreateAccount", + "highlight": false, + "params": [ + {"id":"email0", "type":"string", "initialValue":"\"\""}, + {"id":"password1", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 2, + "id": "emailpassword_login2", + "scriptName": "EmailPassword_Login", + "highlight": false, + "params": [ + {"id":"email0", "type":"string", "initialValue":"\"\""}, + {"id":"password1", "type":"string", "initialValue":"\"\""}, + {"id":"remember5", "type":"combo", "items":["default","sessiononly","never"]} + ] + }, + { + "c2id": 3, + "id": "emailpassword_changepassword3", + "scriptName": "EmailPassword_ChangePassword", + "highlight": false, + "params": [ + {"id":"email0", "type":"string", "initialValue":"\"\""}, + {"id":"old_password1", "type":"string", "initialValue":"\"\""}, + {"id":"new_password2", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 4, + "id": "emailpassword_sendpasswordresetemail4", + "scriptName": "EmailPassword_SendPasswordResetEmail", + "highlight": false, + "params": [ + {"id":"email0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 5, + "id": "emailpassword_deleteuser5", + "scriptName": "EmailPassword_DeleteUser", + "highlight": false, + "params": [ + {"id":"email0", "type":"string", "initialValue":"\"\""}, + {"id":"password1", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 61, + "id": "updateprofile61", + "scriptName": "UpdateProfile", + "highlight": false, + "params": [ + {"id":"display_name0", "type":"string", "initialValue":"\"\""}, + {"id":"photo_url1", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 62, + "id": "updateemail62", + "scriptName": "UpdateEmail", + "highlight": false, + "params": [ + {"id":"email0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 63, + "id": "sendemailverification63", + "scriptName": "SendEmailVerification", + "highlight": false + } + ], + "expressions": [ + ] + }, + "anonymous": { + "conditions": [ + { + "c2id": 21, + "id": "ısanonymous21", + "scriptName": "IsAnonymous", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 11, + "id": "anonymous_login11", + "scriptName": "Anonymous_Login", + "highlight": false, + "params": [ + {"id":"remember3", "type":"combo", "items":["default","sessiononly","never"]} + ] + } + ], + "expressions": [ + ] + }, + "authentication_token": { + "conditions": [ + ], + "actions": [ + { + "c2id": 12, + "id": "authenticationtoken_login12", + "scriptName": "AuthenticationToken_Login", + "highlight": false, + "params": [ + {"id":"token0", "type":"string", "initialValue":"\"\""}, + {"id":"remember4", "type":"combo", "items":["default","sessiononly","never"]} + ] + } + ], + "expressions": [ + ] + }, + "authentication_provider": { + "conditions": [ + ], + "actions": [ + { + "c2id": 21, + "id": "providerauthentication_login21", + "scriptName": "ProviderAuthentication_Login", + "highlight": false, + "params": [ + {"id":"provider4", "type":"combo", "items":["facebook","twitter","github","google"]}, + {"id":"type7", "type":"combo", "items":["popup","redirect"]}, + {"id":"remember11", "type":"combo", "items":["default","sessiononly","never"]}, + {"id":"scope12", "type":"string"} + ] + }, + { + "c2id": 23, + "id": "providerauthentication_login23", + "scriptName": "ProviderAuthentication_Login", + "highlight": false, + "params": [ + {"id":"provider0", "type":"string", "initialValue":"\"\""}, + {"id":"type3", "type":"combo", "items":["popup","redirect"]}, + {"id":"remember7", "type":"combo", "items":["default","sessiononly","never"]}, + {"id":"scope8", "type":"string"} + ] + } + ], + "expressions": [ + ] + }, + "authentication_with_token": { + "conditions": [ + ], + "actions": [ + { + "c2id": 22, + "id": "authwithoauthtoken_fb22", + "scriptName": "AuthWithOAuthToken_FB", + "highlight": false, + "params": [ + {"id":"access_token0", "type":"string", "initialValue":"\"\""}, + {"id":"remember4", "type":"combo", "items":["default","sessiononly","never"]}, + {"id":"scope5", "type":"string"} + ] + } + ], + "expressions": [ + ] + }, + "general": { + "conditions": [ + ], + "actions": [ + { + "c2id": 31, + "id": "loggingout31", + "scriptName": "LoggingOut", + "highlight": false + } + ], + "expressions": [ + ] + }, + "online": { + "conditions": [ + ], + "actions": [ + { + "c2id": 41, + "id": "gooffline41", + "scriptName": "GoOffline", + "highlight": false + }, + { + "c2id": 42, + "id": "goonline42", + "scriptName": "GoOnline", + "highlight": false + } + ], + "expressions": [ + ] + }, + "link_multiple_auth_providers": { + "conditions": [ + { + "c2id": 51, + "id": "onlinksuccessful51", + "scriptName": "OnLinkSuccessful", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 52, + "id": "onlinkerror52", + "scriptName": "OnLinkError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 51, + "id": "linktofb51", + "scriptName": "LinkToFB", + "highlight": false, + "params": [ + {"id":"access_token0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 52, + "id": "linktogoogle52", + "scriptName": "LinkToGoogle", + "highlight": false, + "params": [ + {"id":"ıd_token0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 53, + "id": "linktoemailpassword53", + "scriptName": "LinkToEmailPassword", + "highlight": false, + "params": [ + {"id":"email0", "type":"string", "initialValue":"\"\""}, + {"id":"password1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "email_&_password_-_create_account": { + "conditions": [ + { + "c2id": 1, + "id": "emailpassword_oncreateaccountsuccessful1", + "scriptName": "EmailPassword_OnCreateAccountSuccessful", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 2, + "id": "emailpassword_oncreateaccounterror2", + "scriptName": "EmailPassword_OnCreateAccountError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "email_&_password_-_change_password": { + "conditions": [ + { + "c2id": 3, + "id": "emailpassword_onchangingpasswordsuccessful3", + "scriptName": "EmailPassword_OnChangingPasswordSuccessful", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 4, + "id": "emailpassword_onchangingpassworderror4", + "scriptName": "EmailPassword_OnChangingPasswordError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "email_&_password_-_send_password_reset_email": { + "conditions": [ + { + "c2id": 5, + "id": "emailpassword_onsendpasswordresetemailsuccessful5", + "scriptName": "EmailPassword_OnSendPasswordResetEmailSuccessful", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 6, + "id": "emailpassword_onsendpasswordresetemailerror6", + "scriptName": "EmailPassword_OnSendPasswordResetEmailError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "email_&_password_-_delete_user": { + "conditions": [ + { + "c2id": 7, + "id": "emailpassword_ondeleteusersuccessful7", + "scriptName": "EmailPassword_OnDeleteUserSuccessful", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 8, + "id": "emailpassword_ondeleteusererror8", + "scriptName": "EmailPassword_OnDeleteUserError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "email_&_password_-_update_profile": { + "conditions": [ + { + "c2id": 9, + "id": "emailpassword_onupdatingprofilesuccessful9", + "scriptName": "EmailPassword_OnUpdatingProfileSuccessful", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 10, + "id": "emailpassword_onupdatingprofileerror10", + "scriptName": "EmailPassword_OnUpdatingProfileError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "email_&_password_-_update_email": { + "conditions": [ + { + "c2id": 11, + "id": "emailpassword_onupdatingemailsuccessful11", + "scriptName": "EmailPassword_OnUpdatingEmailSuccessful", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 12, + "id": "emailpassword_onupdatingemailerror12", + "scriptName": "EmailPassword_OnUpdatingEmailError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "email_&_password_-_send_verification_email": { + "conditions": [ + { + "c2id": 13, + "id": "emailpassword_onsendverificationemailsuccessful13", + "scriptName": "EmailPassword_OnSendVerificationEmailSuccessful", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 14, + "id": "emailpassword_onsendverificationemailerror14", + "scriptName": "EmailPassword_OnSendVerificationEmailError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "general_-_login": { + "conditions": [ + { + "c2id": 31, + "id": "onloginsuccessful31", + "scriptName": "OnLoginSuccessful", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 32, + "id": "onloginerror32", + "scriptName": "OnLoginError", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 34, + "id": "ıslogin34", + "scriptName": "IsLogin", + "highlight": false + }, + { + "c2id": 41, + "id": "onloginbyother41", + "scriptName": "OnLoginByOther", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "general_-_logged_out": { + "conditions": [ + { + "c2id": 33, + "id": "onloggedout33", + "scriptName": "OnLoggedOut", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 42, + "id": "onloggedoutbyother42", + "scriptName": "OnLoggedOutByOther", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "error": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 1, + "id": "errorcode1", + "expressionName": "ErrorCode", + "scriptName": "ErrorCode", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 2, + "id": "errormessage2", + "expressionName": "ErrorMessage", + "scriptName": "ErrorMessage", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 11, + "id": "errordetail11", + "expressionName": "ErrorDetail", + "scriptName": "ErrorDetail", + "highlight": false, + "returnType": "string" + } + ] + }, + "general_auth_data": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 3, + "id": "userıd3", + "expressionName": "UserID", + "scriptName": "UserID", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 4, + "id": "provider4", + "expressionName": "Provider", + "scriptName": "Provider", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 5, + "id": "displayname5", + "expressionName": "DisplayName", + "scriptName": "DisplayName", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 6, + "id": "userıdfromprovider6", + "expressionName": "UserIDFromProvider", + "scriptName": "UserIDFromProvider", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 7, + "id": "accesstoken7", + "expressionName": "AccessToken", + "scriptName": "AccessToken", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 8, + "id": "cacheduserprofile8", + "expressionName": "CachedUserProfile", + "scriptName": "CachedUserProfile", + "isDeprecated": "true", + "highlight": false, + "returnType": "any" + }, + { + "c2id": 9, + "id": "email9", + "expressionName": "Email", + "scriptName": "Email", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 10, + "id": "username10", + "expressionName": "UserName", + "scriptName": "UserName", + "isDeprecated": "true", + "highlight": false, + "returnType": "any" + }, + { + "c2id": 12, + "id": "photourl12", + "expressionName": "PhotoURL", + "scriptName": "PhotoURL", + "highlight": false, + "returnType": "string" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/addon.json new file mode 100755 index 0000000..288401f --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/addon.json @@ -0,0 +1,26 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Authentication", + "id": "Rex_Firebase_Authentication", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "http://c2rexplugins.weebly.com/rex_firebase_authentication.html", + "documentation": "http://c2rexplugins.weebly.com/rex_firebase_authentication.html", + "description": "Authentication which is provided by firebase. https://www.firebase.com/", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c2runtime/runtime.js new file mode 100755 index 0000000..11ec703 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c2runtime/runtime.js @@ -0,0 +1,1076 @@ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_Authentication = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_Authentication.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0]; + this.isMyLoginCall = false; + this.isMyLogOutCall = false; + this.lastError = null; + this.lastAuthData = null; // only used in 2.x + this.lastLoginResult = null; // only used in 3.x + + var self=this; + var setupFn = function () + { + self.setOnLogoutHandler(); + } + window.FirebaseAddAfterInitializeHandler(setupFn); + + + window.FirebaseGetCurrentUserID = function() + { + return self.getCurrentUserID(); + }; + }; + + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + // 2.x + instanceProto.get_ref = function(k) + { + + if (k == null) + k = ""; + + var path; + if (k.substring(0,8) == "https://") + path = k; + else + path = this.rootpath + k + "/"; + + return new window["Firebase"](path); + }; + + // 3.x + var getAuthObj = function() + { + return window["Firebase"]["auth"](); + }; + + instanceProto.setOnLogoutHandler = function() + { + var self = this; + var onAuthStateChanged = function (authData) + { + if (authData) + { + // user authenticated with Firebase + //console.log("User ID: " + authData.uid + ", Provider: " + authData.provider); + + var isMyLoginCall = self.isMyLoginCall && !self.isMyLogOutCall; + self.lastError = null; + self.lastAuthData = authData; + + if (!isMyLoginCall) + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLoginByOther, self); + else + { + self.isMyLoginCall = false; + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLoginSuccessful, self); + } + + } + else + { + var isMyLogOutCall = self.isMyLogOutCall; + self.isMyLogOutCall = false; + self.lastAuthData = null; + self.lastLoginResult = null; + + // user is logged out + if (!isMyLogOutCall) + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLoggedOutByOther, self); + else + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLoggedOut, self); + + } + }; + + // 2.x + if (!isFirebase3x()) + { + this.lastAuthData = this.get_ref()["getAuth"](); + this.get_ref()["onAuth"](onAuthStateChanged); + } + + // 3.x + else + { + getAuthObj()["onAuthStateChanged"](onAuthStateChanged); + } + }; + + instanceProto.getCurrentUserID = function() + { + var uid; + // 2.x + if (!isFirebase3x()) + uid = (this.lastAuthData)? this.lastAuthData["uid"]:""; + + // 3.x + else + uid = getUserProperty3x("uid"); + + return uid; + } + + /**BEGIN-PREVIEWONLY**/ + var fake_ret = { + value:0, + set_any: function(value){this.value=value;}, + set_int: function(value){this.value=value;}, + set_float: function(value){this.value=value;}, + set_string: function(value) {this.value=value;}, + }; + + instanceProto.getDebuggerValues = function (propsections) + { + var provider; + if (Cnds.prototype.IsAnonymous.call(this)) + { + provider = "anonymous"; + } + else + { + cr.plugins_.Rex_Firebase_Authentication.prototype.exps.Provider.call(this, fake_ret); + var provider = fake_ret.value; + } + + cr.plugins_.Rex_Firebase_Authentication.prototype.exps.DisplayName.call(this, fake_ret); + var displayname = fake_ret.value; + + cr.plugins_.Rex_Firebase_Authentication.prototype.exps.Email.call(this, fake_ret); + var email = fake_ret.value; + + cr.plugins_.Rex_Firebase_Authentication.prototype.exps.PhotoURL.call(this, fake_ret); + var photoURL = fake_ret.value; + + cr.plugins_.Rex_Firebase_Authentication.prototype.exps.AccessToken.call(this, fake_ret); + var accessToken = fake_ret.value; + + var self = this; + propsections.push({ + "title": this.type.name, + "properties": [ + {"name":"UserID", "value":this.getCurrentUserID() ,"readonly":true}, + {"name":"Provider", "value":provider ,"readonly":true}, + {"name":"Display name", "value":displayname ,"readonly":true}, + {"name":"Email", "value":email ,"readonly":true}, + {"name":"PhotoURL", "value":photoURL ,"readonly":true}, + {"name":"AccessToken", "value":accessToken ,"readonly":true}, + ] + }); + }; + + instanceProto.onDebugValueEdited = function (header, name, value) + { + }; + /**END-PREVIEWONLY**/ + + ////////////////////////////////////// + // Conditions + function Cnds() {}; + pluginProto.cnds = new Cnds(); + + Cnds.prototype.EmailPassword_OnCreateAccountSuccessful = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnCreateAccountError = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnChangingPasswordSuccessful = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnChangingPasswordError = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnSendPasswordResetEmailSuccessful = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnSendPasswordResetEmailError = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnDeleteUserSuccessful = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnDeleteUserError = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnUpdatingProfileSuccessful = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnUpdatingProfileError = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnUpdatingEmailSuccessful = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnUpdatingEmailError = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnSendVerificationEmailSuccessful = function () + { + return true; + }; + + Cnds.prototype.EmailPassword_OnSendVerificationEmailError = function () + { + return true; + }; + + + Cnds.prototype.IsAnonymous = function () + { + var val; + if (!isFirebase3x()) + { + var user = this.lastAuthData; + if (user) + val = (user["provider"] === "anonymous"); + else + val = false; + } + else + { + var user = getAuthObj()["currentUser"]; + val = user && user["isAnonymous"]; + } + + return val; + }; + + Cnds.prototype.OnLoginSuccessful = function () + { + return true; + }; + + Cnds.prototype.OnLoginError = function () + { + return true; + }; + + Cnds.prototype.OnLoggedOut = function () + { + return true; + }; + + Cnds.prototype.IsLogin = function () + { + if (!isFirebase3x()) + return (this.lastAuthData != null); + else + return (getAuthObj()["currentUser"] != null); + }; + + Cnds.prototype.OnLoginByOther = function () + { + return true; + }; + + Cnds.prototype.OnLoggedOutByOther = function () + { + return true; + }; + + Cnds.prototype.OnLinkSuccessful = function () + { + return true; + }; + + Cnds.prototype.OnLinkError = function () + { + return true; + }; + + + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + // 2.x + var getHandler2x = function(self, successTrig, errorTrig) + { + var handler = function(error, authData) + { + self.lastError = error; + self.lastAuthData = authData; + if (error == null) + { + // get auth data by expression:UserID, and expression:Provider + self.runtime.trigger(successTrig, self); + } + else + { + // get error message by expression:ErrorCode and expression:ErrorMessage + self.runtime.trigger(errorTrig, self); + } + }; + return handler; + }; + + var getLoginHandler2x = function(self) + { + var handler = function(error, authData) + { + self.lastError = error; + self.lastAuthData = authData; + if (error == null) + { + // self.isMyLoginCall = false; // set it in onAuthStateChanged + // get auth data by expression:UserID, and expression:Provider + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLoginSuccessful, self); + } + else + { + self.isMyLoginCall = false; + // get error message by expression:ErrorCode and expression:ErrorMessage + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLoginError, self); + } + }; + self.isMyLoginCall = true; + return handler; + }; + + // 3.x + var addHandler = function (self, authObj, successTrig, errorTrig) + { + var onSuccess = function (result) + { + self.lastError = null; + self.lastAuthData = result; + if (successTrig) + self.runtime.trigger(successTrig, self); + }; + var onError = function (error) + { + self.lastError = error; + self.lastAuthData = null; + if (errorTrig) + self.runtime.trigger(errorTrig, self); + }; + authObj["then"](onSuccess)["catch"](onError); + }; + + var addLoginHandler = function (self, authObj) + { + var onSuccess = function (result) + { + self.lastLoginResult = result; + }; + var onError = function (error) + { + self.isMyLoginCall = false; + self.lastError = error; + self.lastLoginResult = null; + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLoginError, self); + }; + self.isMyLoginCall = true; + authObj["then"](onSuccess)["catch"](onError); + } + + Acts.prototype.EmailPassword_CreateAccount = function (e_, p_) + { + // 2.x + if (!isFirebase3x()) + { + var reg_data = {"email":e_, "password":p_ }; + var handler = getHandler2x(this, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnCreateAccountSuccessful, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnCreateAccountError); + this.get_ref()["createUser"](reg_data, handler); + } + + // 3.x + else + { + var authObj = getAuthObj()["createUserWithEmailAndPassword"](e_, p_); + addHandler(this, authObj, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnCreateAccountSuccessful, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnCreateAccountError + ); + } + }; + + var PRESISTING_TYPE = ["default", "sessionOnly", "never"]; + Acts.prototype.EmailPassword_Login = function (e_, p_, r_) + { + // 2.x + if (!isFirebase3x()) + { + var reg_data = {"email":e_, "password":p_ }; + var handler = getLoginHandler2x(this); + var d = {"remember":PRESISTING_TYPE[r_]}; + this.get_ref()["authWithPassword"](reg_data, handler, d); + } + + // 3.x + else + { + var authObj = getAuthObj(); + addLoginHandler(this, authObj["signInWithEmailAndPassword"](e_, p_)); + } + }; + + Acts.prototype.EmailPassword_ChangePassword = function (e_, old_p_, new_p_) + { + // 2.x + if (!isFirebase3x()) + { + var reg_data = {"email":e_, "oldPassword ":old_p_, "newPassword":new_p_}; + var handler = getHandler2x(this, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnChangingPasswordSuccessful, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnChangingPasswordError); + this.get_ref()["changePassword"](reg_data, handler); + } + + // 3.x + else + { + var authObj = getAuthObj()["currentUser"]["updatePassword"](new_p_); + addHandler(this, authObj, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnChangingPasswordSuccessful, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnChangingPasswordError + ); + } + }; + + Acts.prototype.EmailPassword_SendPasswordResetEmail = function (e_) + { + // 2.x + if (!isFirebase3x()) + { + var reg_data = {"email":e_}; + var handler = getHandler2x(this, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnSendPasswordResetEmailSuccessful, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnSendPasswordResetEmailError); + this.get_ref()["resetPassword"](reg_data, handler); + } + + // 3.x + else + { + var authObj = getAuthObj()["sendPasswordResetEmail"](e_); + addHandler(this, authObj, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnSendPasswordResetEmailSuccessful, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnSendPasswordResetEmailError + ); + } + }; + + Acts.prototype.EmailPassword_DeleteUser = function (e_, p_) + { + // 2.x + if (!isFirebase3x()) + { + var reg_data = {"email":e_, "password":p_}; + var handler = getHandler2x(this, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnDeleteUserSuccessful, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnDeleteUserError); + this.get_ref()["removeUser"](reg_data, handler); + } + + // 3.x + else + { + var authObj = getAuthObj()["currentUser"]["delete"](); + addHandler(this, authObj, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnDeleteUserSuccessful, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnDeleteUserError + ); + } + }; + + Acts.prototype.Anonymous_Login = function (r_) + { + // 2.x + if (!isFirebase3x()) + { + var handler = getLoginHandler2x(this); + var d = {"remember":PRESISTING_TYPE[r_]}; + this.get_ref()["authAnonymously"](handler, d); + } + + // 3.x + else + { + var authObj = getAuthObj(); + addLoginHandler(this, authObj["signInAnonymously"]()); + } + }; + + Acts.prototype.AuthenticationToken_Login = function (t_, r_) + { + // 2.x + if (!isFirebase3x()) + { + var handler = getLoginHandler2x(this); + var d = {"remember":PRESISTING_TYPE[r_]}; + this.get_ref()["authWithCustomToken"](t_, handler, d); + } + + // 3.x + else + { + var authObj = getAuthObj(); + addLoginHandler(this, authObj["signInWithCustomToken"]()); + } + }; + + var PROVIDER_TYPE2x = ["facebook", "twitter", "github", "google"]; + // 3.x + var capitalizeFirstLetter = function (s) + { + return s.charAt(0).toUpperCase() + s.slice(1); + }; + Acts.prototype.ProviderAuthentication_Login = function (provider, t_, r_, scope_) + { + // 2.x + if (!isFirebase3x()) + { + if (typeof(provider) === "number") + provider = PROVIDER_TYPE2x[provider]; + + var loginType = (t_ === 0)? "authWithOAuthPopup":"authWithOAuthRedirect"; + var handler = getLoginHandler2x(this); + var d = {"remember":PRESISTING_TYPE[r_], + "scope":scope_}; + this.get_ref()[loginType](provider, handler, d); + } + + // 3.x + else + { + if (typeof(provider) === "number") + provider = PROVIDER_TYPE2x[provider]; + + provider = capitalizeFirstLetter( provider) + "AuthProvider"; + var providerObj = new window["Firebase"]["auth"][provider](); + if (scope_ !== "") + providerObj["addScope"](scope_); + + var authObj = getAuthObj(); + if (t_ === 0) // signInWithPopup + { + addLoginHandler(this, authObj["signInWithPopup"](providerObj)); + } + else // signInWithRedirect + { + authObj["signInWithRedirect"](providerObj); + addLoginHandler(this, authObj["getRedirectResult"]()); + } + } + }; + + Acts.prototype.AuthWithOAuthToken_FB = function (access_token, r_, scope_) + { + if (access_token == "") + { + if (typeof (FB) == null) + return; + + var auth_response = FB["getAuthResponse"](); + if (!auth_response) + return; + + access_token = auth_response["accessToken"]; + } + + // 2.x + if (!isFirebase3x()) + { + var handler = getLoginHandler2x(this); + var d = {"remember":PRESISTING_TYPE[r_], + "scope":scope_}; + this.get_ref()["authWithOAuthToken"]("facebook", access_token, handler, d); + } + + // 3.x + else + { + var credential = window["Firebase"]["auth"]["FacebookAuthProvider"]["credential"](access_token); + var authObj = getAuthObj(); + addLoginHandler(this, authObj["signInWithCredential"](credential)); + } + }; + + Acts.prototype.LoggingOut = function () + { + this.isMyLogOutCall = true; + // 2.x + if (!isFirebase3x()) + { + this.get_ref()["unauth"](); + } + + // 3.x + else + { + var authObj = getAuthObj()["signOut"](); + } + }; + + Acts.prototype.GoOffline = function () + { + // 2.x + if (!isFirebase3x()) + { + window["Firebase"]["goOffline"](); + } + + // 3.x + else + { + window["Firebase"]["database"]()["goOffline"](); + } + }; + + Acts.prototype.GoOnline = function () + { + // 2.x + if (!isFirebase3x()) + { + window["Firebase"]["goOnline"](); + + } + + // 3.x + else + { + window["Firebase"]["database"]()["goOnline"](); + } + }; + + Acts.prototype.LinkToFB = function (access_token) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + var user = getAuthObj()["currentUser"]; + if (user == null) + { + return; + } + + if (access_token == "") + { + if (typeof (FB) == null) + return; + + var auth_response = FB["getAuthResponse"](); + if (!auth_response) + return; + + access_token = auth_response["accessToken"]; + } + + // 3.x + var credential = window["Firebase"]["auth"]["FacebookAuthProvider"]["credential"](access_token); + var authObj = user["link"](credential); + addHandler(this, authObj, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLinkSuccessful, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLinkError + ); + }; + + Acts.prototype.LinkToGoogle = function (id_token) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + var user = getAuthObj()["currentUser"]; + if (user == null) + { + return; + } + + // 3.x + var credential = window["Firebase"]["auth"]["GoogleAuthProvider"]["credential"](id_token); + var authObj = user["link"](credential); + addHandler(this, authObj, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLinkSuccessful, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLinkError + ); + }; + + Acts.prototype.LinkToEmailPassword = function (e_, p_) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + var user = getAuthObj()["currentUser"]; + if (user == null) + { + return; + } + + // 3.x + var credential = window["Firebase"]["auth"]["EmailAuthProvider"]["credential"](e_, p_); + var authObj = user["link"](credential); + addHandler(this, authObj, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLinkSuccessful, + cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.OnLinkError + ); + }; + + Acts.prototype.UpdateProfile = function (displayName, photoURL) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + // 3.x + else + { + var self = this; + var user = getAuthObj()["currentUser"]; + var data = { + "displayName": displayName, + "photoURL": photoURL, + } + var onSuccess = function () + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnUpdatingProfileSuccessful, self); + }; + var onError = function () + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnUpdatingProfileError, self); + }; + user["updateProfile"](data)["then"](onSuccess)["catch"](onError); + } + }; + + Acts.prototype.UpdateEmail = function (email) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + // 3.x + else + { + var self = this; + var user = getAuthObj()["currentUser"]; + var onSuccess = function () + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnUpdatingEmailSuccessful, self); + }; + var onError = function () + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnUpdatingEmailError, self); + }; + user["updateEmail"](email)["then"](onSuccess)["catch"](onError); + } + }; + + Acts.prototype.SendEmailVerification = function (email) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + // 3.x + else + { + var self = this; + var user = getAuthObj()["currentUser"]; + var onSuccess = function () + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnSendVerificationEmailSuccessful, self); + }; + var onError = function () + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Authentication.prototype.cnds.EmailPassword_OnSendVerificationEmailError, self); + }; + user["sendEmailVerification"]()["then"](onSuccess)["catch"](onError); + } + }; + + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + // 2.x + var getProviderProperty = function (authData, p) + { + if (authData == null) + return ""; + + var provide_type = authData["provider"]; + var provider_info = authData[provide_type]; + if (provider_info == null) + return ""; + + var val = provider_info[p]; + if (val == null) + val = ""; + + return val; + }; + + // 3.x + var getUserProperty3x = function(p) + { + var user = getAuthObj()["currentUser"]; + return (user)? user[p]:""; + }; + var getProviderProperty3x = function (p, idx) + { + var user = getAuthObj()["currentUser"]; + if (!user) + return ""; + + if (idx == null) idx = 0; + var providerData = user["providerData"][idx]; + var val = (providerData)? providerData[p]:""; + return val; + }; + + + Exps.prototype.ErrorCode = function (ret) + { + // 2.x , 3.x + var val = (!this.lastError)? "": this.lastError["code"]; + ret.set_string(val || ""); + }; + + Exps.prototype.ErrorMessage = function (ret) + { + // 2.x , 3.x + var val = (!this.lastError)? "": this.lastError["message"]; + ret.set_string(val || ""); + }; + + Exps.prototype.UserID = function (ret) + { + ret.set_string(this.getCurrentUserID() || ""); + }; + Exps.prototype.Provider = function (ret) + { + var pid; + // 2.x + if (!isFirebase3x()) + { + pid = (!this.lastAuthData)? "": this.lastAuthData["provider"]; + } + + // 3.x + else + { + pid = getProviderProperty3x("providerId"); + } + ret.set_string(pid); + }; + + Exps.prototype.DisplayName = function (ret) + { + var name; + // 2.x + if (!isFirebase3x()) + { + name = getProviderProperty(this.lastAuthData, "displayName"); + } + + // 3.x + else + { + name = getUserProperty3x("displayName"); + } + ret.set_string(name || ""); + }; + Exps.prototype.UserIDFromProvider = function (ret) + { + var uid; + // 2.x + if (!isFirebase3x()) + { + uid = getProviderProperty(this.lastAuthData, "id"); + } + + // 3.x + else + { + uid = getProviderProperty3x("uid"); + } + ret.set_string(uid || ""); + }; + Exps.prototype.AccessToken = function (ret) + { + var token; + // 2.x + if (!isFirebase3x()) + { + token = getProviderProperty(this.lastAuthData, "accessToken"); + } + + // 3.x + else + { + if (this.lastLoginResult && this.lastLoginResult["credential"]) + token = this.lastLoginResult["credential"]["accessToken"]; + } + ret.set_string(token || ""); + }; + Exps.prototype.CachedUserProfile = function (ret) + { + var profile; + // 2.x + if (!isFirebase3x()) + { + profile = getProviderProperty(this.lastAuthData, "cachedUserProfile"); + } + + // 3.x + else + { + alert("CachedUserProfile had not implemented in firebase 3.x"); + } + // ?? + ret.set_string( profile || "" ); + }; + Exps.prototype.Email = function (ret) + { + var email; + // 2.x + if ((!isFirebase3x())) + { + email = getProviderProperty(this.lastAuthData, "email"); + } + + // 3.x + else + { + email = getProviderProperty3x("email"); + } + ret.set_string(email || ""); + }; + Exps.prototype.UserName = function (ret) + { + var name; + // 2.x + if (!isFirebase3x()) + { + name = getProviderProperty(this.lastAuthData, "username"); + } + + // 3.x + else + { + name = getUserProperty3x("displayName"); + } + + ret.set_string(name || ""); + }; + Exps.prototype.ErrorDetail = function (ret) + { + // 2.x , 3.x + var val = (!this.lastError)? "": this.lastError["detail"]; + if (val == null) + val = ""; + ret.set_string(val); + }; + Exps.prototype.PhotoURL = function (ret) + { + var photoUrl; + // 2.x + if (!isFirebase3x()) + { + photoUrl = ""; + } + + // 3.x + else + { + photoUrl = getProviderProperty3x("photoURL"); + } + ret.set_string(photoUrl || ""); + }; +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/actions.js new file mode 100755 index 0000000..d11e815 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/actions.js @@ -0,0 +1,439 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Authentication.Acts = + { + EmailPassword_CreateAccount(e_, p_) + { + // 2.x + if (!isFirebase3x()) + { + var reg_data = {"email":e_, "password":p_ }; + var handler = getHandler2x(this, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnCreateAccountSuccessful, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnCreateAccountError); + this.get_ref()["createUser"](reg_data, handler); + } + + // 3.x + else + { + var authObj = getAuthObj()["createUserWithEmailAndPassword"](e_, p_); + addHandler(this, authObj, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnCreateAccountSuccessful, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnCreateAccountError + ); + } + }, + + EmailPassword_Login(e_, p_, r_) + { + // 2.x + if (!isFirebase3x()) + { + var reg_data = {"email":e_, "password":p_ }; + var handler = getLoginHandler2x(this); + var d = {"remember":PRESISTING_TYPE[r_]}; + this.get_ref()["authWithPassword"](reg_data, handler, d); + } + + // 3.x + else + { + var authObj = getAuthObj(); + addLoginHandler(this, authObj["signInWithEmailAndPassword"](e_, p_)); + } + }, + + EmailPassword_ChangePassword(e_, old_p_, new_p_) + { + // 2.x + if (!isFirebase3x()) + { + var reg_data = {"email":e_, "oldPassword ":old_p_, "newPassword":new_p_}; + var handler = getHandler2x(this, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnChangingPasswordSuccessful, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnChangingPasswordError); + this.get_ref()["changePassword"](reg_data, handler); + } + + // 3.x + else + { + var authObj = getAuthObj()["currentUser"]["updatePassword"](new_p_); + addHandler(this, authObj, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnChangingPasswordSuccessful, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnChangingPasswordError + ); + } + }, + + EmailPassword_SendPasswordResetEmail(e_) + { + // 2.x + if (!isFirebase3x()) + { + var reg_data = {"email":e_}; + var handler = getHandler2x(this, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnSendPasswordResetEmailSuccessful, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnSendPasswordResetEmailError); + this.get_ref()["resetPassword"](reg_data, handler); + } + + // 3.x + else + { + var authObj = getAuthObj()["sendPasswordResetEmail"](e_); + addHandler(this, authObj, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnSendPasswordResetEmailSuccessful, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnSendPasswordResetEmailError + ); + } + }, + + EmailPassword_DeleteUser(e_, p_) + { + // 2.x + if (!isFirebase3x()) + { + var reg_data = {"email":e_, "password":p_}; + var handler = getHandler2x(this, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnDeleteUserSuccessful, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnDeleteUserError); + this.get_ref()["removeUser"](reg_data, handler); + } + + // 3.x + else + { + var authObj = getAuthObj()["currentUser"]["delete"](); + addHandler(this, authObj, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnDeleteUserSuccessful, + C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnDeleteUserError + ); + } + }, + + Anonymous_Login(r_) + { + // 2.x + if (!isFirebase3x()) + { + var handler = getLoginHandler2x(this); + var d = {"remember":PRESISTING_TYPE[r_]}; + this.get_ref()["authAnonymously"](handler, d); + } + + // 3.x + else + { + var authObj = getAuthObj(); + addLoginHandler(this, authObj["signInAnonymously"]()); + } + }, + + AuthenticationToken_Login(t_, r_) + { + // 2.x + if (!isFirebase3x()) + { + var handler = getLoginHandler2x(this); + var d = {"remember":PRESISTING_TYPE[r_]}; + this.get_ref()["authWithCustomToken"](t_, handler, d); + } + + // 3.x + else + { + var authObj = getAuthObj(); + addLoginHandler(this, authObj["signInWithCustomToken"]()); + } + }, + + + ProviderAuthentication_Login(provider, t_, r_, scope_) + { + // 2.x + if (!isFirebase3x()) + { + if (typeof(provider) === "number") + provider = PROVIDER_TYPE2x[provider]; + + var loginType = (t_ === 0)? "authWithOAuthPopup":"authWithOAuthRedirect"; + var handler = getLoginHandler2x(this); + var d = {"remember":PRESISTING_TYPE[r_], + "scope":scope_}; + this.get_ref()[loginType](provider, handler, d); + } + + // 3.x + else + { + if (typeof(provider) === "number") + provider = PROVIDER_TYPE2x[provider]; + + provider = capitalizeFirstLetter( provider) + "AuthProvider"; + var providerObj = new window["Firebase"]["auth"][provider](); + if (scope_ !== "") + providerObj["addScope"](scope_); + + var authObj = getAuthObj(); + if (t_ === 0) // signInWithPopup + { + addLoginHandler(this, authObj["signInWithPopup"](providerObj)); + } + else // signInWithRedirect + { + authObj["signInWithRedirect"](providerObj); + addLoginHandler(this, authObj["getRedirectResult"]()); + } + } + }, + + AuthWithOAuthToken_FB(access_token, r_, scope_) + { + if (access_token == "") + { + if (typeof (FB) == null) + return; + + var auth_response = FB["getAuthResponse"](); + if (!auth_response) + return; + + access_token = auth_response["accessToken"]; + } + + // 2.x + if (!isFirebase3x()) + { + var handler = getLoginHandler2x(this); + var d = {"remember":PRESISTING_TYPE[r_], + "scope":scope_}; + this.get_ref()["authWithOAuthToken"]("facebook", access_token, handler, d); + } + + // 3.x + else + { + var credential = window["Firebase"]["auth"]["FacebookAuthProvider"]["credential"](access_token); + var authObj = getAuthObj(); + addLoginHandler(this, authObj["signInWithCredential"](credential)); + } + }, + + LoggingOut() + { + this.isMyLogOutCall = true; + // 2.x + if (!isFirebase3x()) + { + this.get_ref()["unauth"](); + } + + // 3.x + else + { + var authObj = getAuthObj()["signOut"](); + } + }, + + GoOffline() + { + // 2.x + if (!isFirebase3x()) + { + window["Firebase"]["goOffline"](); + } + + // 3.x + else + { + window["Firebase"]["database"]()["goOffline"](); + } + }, + + GoOnline() + { + // 2.x + if (!isFirebase3x()) + { + window["Firebase"]["goOnline"](); + + } + + // 3.x + else + { + window["Firebase"]["database"]()["goOnline"](); + } + }, + + LinkToFB(access_token) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + var user = getAuthObj()["currentUser"]; + if (user == null) + { + return; + } + + if (access_token == "") + { + if (typeof (FB) == null) + return; + + var auth_response = FB["getAuthResponse"](); + if (!auth_response) + return; + + access_token = auth_response["accessToken"]; + } + + // 3.x + var credential = window["Firebase"]["auth"]["FacebookAuthProvider"]["credential"](access_token); + var authObj = user["link"](credential); + addHandler(this, authObj, + C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLinkSuccessful, + C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLinkError + ); + }, + + LinkToGoogle(id_token) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + var user = getAuthObj()["currentUser"]; + if (user == null) + { + return; + } + + // 3.x + var credential = window["Firebase"]["auth"]["GoogleAuthProvider"]["credential"](id_token); + var authObj = user["link"](credential); + addHandler(this, authObj, + C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLinkSuccessful, + C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLinkError + ); + }, + + LinkToEmailPassword(e_, p_) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + var user = getAuthObj()["currentUser"]; + if (user == null) + { + return; + } + + // 3.x + var credential = window["Firebase"]["auth"]["EmailAuthProvider"]["credential"](e_, p_); + var authObj = user["link"](credential); + addHandler(this, authObj, + C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLinkSuccessful, + C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLinkError + ); + }, + + UpdateProfile(displayName, photoURL) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + // 3.x + else + { + var self = this; + var user = getAuthObj()["currentUser"]; + var data = { + "displayName": displayName, + "photoURL": photoURL, + } + var onSuccess = function () + { + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnUpdatingProfileSuccessful, self); + }; + var onError = function () + { + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnUpdatingProfileError, self); + }; + user["updateProfile"](data)["then"](onSuccess)["catch"](onError); + } + }, + + UpdateEmail(email) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + // 3.x + else + { + var self = this; + var user = getAuthObj()["currentUser"]; + var onSuccess = function () + { + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnUpdatingEmailSuccessful, self); + }; + var onError = function () + { + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnUpdatingEmailError, self); + }; + user["updateEmail"](email)["then"](onSuccess)["catch"](onError); + } + }, + + SendEmailVerification(email) + { + // 2.x + if (!isFirebase3x()) + { + alert("Does not support in firebase 2.x api"); + return; + } + + // 3.x + else + { + var self = this; + var user = getAuthObj()["currentUser"]; + var onSuccess = function () + { + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnSendVerificationEmailSuccessful, self); + }; + var onError = function () + { + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.EmailPassword_OnSendVerificationEmailError, self); + }; + user["sendEmailVerification"]()["then"](onSuccess)["catch"](onError); + } + } + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/conditions.js new file mode 100755 index 0000000..ed09404 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/conditions.js @@ -0,0 +1,142 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Authentication.Cnds = + { + EmailPassword_OnCreateAccountSuccessful() + { + return true; + }, + + EmailPassword_OnCreateAccountError() + { + return true; + }, + + EmailPassword_OnChangingPasswordSuccessful() + { + return true; + }, + + EmailPassword_OnChangingPasswordError() + { + return true; + }, + + EmailPassword_OnSendPasswordResetEmailSuccessful() + { + return true; + }, + + EmailPassword_OnSendPasswordResetEmailError() + { + return true; + }, + + EmailPassword_OnDeleteUserSuccessful() + { + return true; + }, + + EmailPassword_OnDeleteUserError() + { + return true; + }, + + EmailPassword_OnUpdatingProfileSuccessful() + { + return true; + }, + + EmailPassword_OnUpdatingProfileError() + { + return true; + }, + + EmailPassword_OnUpdatingEmailSuccessful() + { + return true; + }, + + EmailPassword_OnUpdatingEmailError() + { + return true; + }, + + EmailPassword_OnSendVerificationEmailSuccessful() + { + return true; + }, + + EmailPassword_OnSendVerificationEmailError() + { + return true; + }, + + + IsAnonymous() + { + var val; + if (!isFirebase3x()) + { + var user = this.lastAuthData; + if (user) + val = (user["provider"] === "anonymous"); + else + val = false; + } + else + { + var user = getAuthObj()["currentUser"]; + val = user && user["isAnonymous"]; + } + + return val; + }, + + OnLoginSuccessful() + { + return true; + }, + + OnLoginError() + { + return true; + }, + + OnLoggedOut() + { + return true; + }, + + IsLogin() + { + if (!isFirebase3x()) + return (this.lastAuthData != null); + else + return (getAuthObj()["currentUser"] != null); + }, + + OnLoginByOther() + { + return true; + }, + + OnLoggedOutByOther() + { + return true; + }, + + OnLinkSuccessful() + { + return true; + }, + + OnLinkError() + { + return true; + } + + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/expressions.js new file mode 100755 index 0000000..9f6e963 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/expressions.js @@ -0,0 +1,165 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Authentication.Exps = + { + ErrorCode() + { + // 2.x , 3.x + var val = (!this.lastError)? "": this.lastError["code"]; + return (val || ""); + }, + + ErrorMessage() + { + // 2.x , 3.x + var val = (!this.lastError)? "": this.lastError["message"]; + return (val || ""); + }, + + UserID() + { + return (this.getCurrentUserID() || ""); + }, + Provider() + { + var pid; + // 2.x + if (!isFirebase3x()) + { + pid = (!this.lastAuthData)? "": this.lastAuthData["provider"]; + } + + // 3.x + else + { + pid = getProviderProperty3x("providerId"); + } + return (pid); + }, + + DisplayName() + { + var name; + // 2.x + if (!isFirebase3x()) + { + name = getProviderProperty(this.lastAuthData, "displayName"); + } + + // 3.x + else + { + name = getUserProperty3x("displayName"); + } + return (name || ""); + }, + UserIDFromProvider() + { + var uid; + // 2.x + if (!isFirebase3x()) + { + uid = getProviderProperty(this.lastAuthData, "id"); + } + + // 3.x + else + { + uid = getProviderProperty3x("uid"); + } + return (uid || ""); + }, + AccessToken() + { + var token; + // 2.x + if (!isFirebase3x()) + { + token = getProviderProperty(this.lastAuthData, "accessToken"); + } + + // 3.x + else + { + if (this.lastLoginResult && this.lastLoginResult["credential"]) + token = this.lastLoginResult["credential"]["accessToken"]; + } + return (token || ""); + }, + CachedUserProfile() + { + var profile; + // 2.x + if (!isFirebase3x()) + { + profile = getProviderProperty(this.lastAuthData, "cachedUserProfile"); + } + + // 3.x + else + { + alert("CachedUserProfile had not implemented in firebase 3.x"); + } + // ?? + return ( profile || "" ); + }, + Email() + { + var email; + // 2.x + if ((!isFirebase3x())) + { + email = getProviderProperty(this.lastAuthData, "email"); + } + + // 3.x + else + { + email = getProviderProperty3x("email"); + } + return (email || ""); + }, + UserName() + { + var name; + // 2.x + if (!isFirebase3x()) + { + name = getProviderProperty(this.lastAuthData, "username"); + } + + // 3.x + else + { + name = getUserProperty3x("displayName"); + } + + return (name || ""); + }, + ErrorDetail() + { + // 2.x , 3.x + var val = (!this.lastError)? "": this.lastError["detail"]; + if (val == null) + val = ""; + return (val); + }, + PhotoURL() + { + var photoUrl; + // 2.x + if (!isFirebase3x()) + { + photoUrl = ""; + } + + // 3.x + else + { + photoUrl = getProviderProperty3x("photoURL"); + } + return (photoUrl || ""); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/instance.js new file mode 100755 index 0000000..f9c5dae --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/instance.js @@ -0,0 +1,137 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Authentication.Instance = class Rex_Firebase_AuthenticationInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + // Initialise object properties + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0]; + } + this.isMyLoginCall = false; + this.isMyLogOutCall = false; + this.lastError = null; + this.lastAuthData = null; // only used in 2.x + this.lastLoginResult = null; // only used in 3.x + + var self=this; + var setupFn = function () + { + self.setOnLogoutHandler(); + } + window.FirebaseAddAfterInitializeHandler(setupFn); + + + window.FirebaseGetCurrentUserID = function() + { + return self.getCurrentUserID(); + }; + + + + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + Oncreate() + { + + } + get_ref(k) + { + if (k == null) + k = ""; + + var path; + if (k.substring(0,8) == "https://") + path = k; + else + path = this.rootpath + k + "/"; + + return new window["Firebase"](path); + } + setOnLogoutHandler() + { + var self = this; + var onAuthStateChanged = function (authData) + { + if (authData) + { + // user authenticated with Firebase + //console.log("User ID: " + authData.uid + ", Provider: " + authData.provider); + + var isMyLoginCall = self.isMyLoginCall && !self.isMyLogOutCall; + self.lastError = null; + self.lastAuthData = authData; + + if (!isMyLoginCall) + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLoginByOther, self); + else + { + self.isMyLoginCall = false; + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLoginSuccessful, self); + } + + } + else + { + var isMyLogOutCall = self.isMyLogOutCall; + self.isMyLogOutCall = false; + self.lastAuthData = null; + self.lastLoginResult = null; + + // user is logged out + if (!isMyLogOutCall) + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLoggedOutByOther, self); + else + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLoggedOut, self); + + } + }; + + // 2.x + if (!isFirebase3x()) + { + this.lastAuthData = this.get_ref()["getAuth"](); + this.get_ref()["onAuth"](onAuthStateChanged); + } + + // 3.x + else + { + getAuthObj()["onAuthStateChanged"](onAuthStateChanged); + } + } + + getCurrentUserID() + { + var uid; + // 2.x + if (!isFirebase3x()) + uid = (this.lastAuthData)? this.lastAuthData["uid"]:""; + + // 3.x + else + uid = getUserProperty3x("uid"); + + return uid; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/plugin.js new file mode 100755 index 0000000..edc9de6 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/plugin.js @@ -0,0 +1,153 @@ +"use strict"; + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + // 2.x + + // 3.x + var getAuthObj = function() + { + return window["Firebase"]["auth"](); + }; + + //acts var + // 2.x + var getHandler2x = function(self, successTrig, errorTrig) + { + var handler = function(error, authData) + { + self.lastError = error; + self.lastAuthData = authData; + if (error == null) + { + // get auth data by expression:UserID, and expression:Provider + self.Trigger(successTrig, self); + } + else + { + // get error message by expression:ErrorCode and expression:ErrorMessage + self.Trigger(errorTrig, self); + } + }; + return handler; + }; + + var getLoginHandler2x = function(self) + { + var handler = function(error, authData) + { + self.lastError = error; + self.lastAuthData = authData; + if (error == null) + { + // self.isMyLoginCall = false; // set it in onAuthStateChanged + // get auth data by expression:UserID, and expression:Provider + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLoginSuccessful, self); + } + else + { + self.isMyLoginCall = false; + // get error message by expression:ErrorCode and expression:ErrorMessage + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLoginError, self); + } + }; + self.isMyLoginCall = true; + return handler; + }; + + // 3.x + var addHandler = function (self, authObj, successTrig, errorTrig) + { + var onSuccess = function (result) + { + self.lastError = null; + self.lastAuthData = result; + if (successTrig) + self.Trigger(successTrig, self); + }; + var onError = function (error) + { + self.lastError = error; + self.lastAuthData = null; + if (errorTrig) + self.Trigger(errorTrig, self); + }; + authObj["then"](onSuccess)["catch"](onError); + }; + + var addLoginHandler = function (self, authObj) + { + var onSuccess = function (result) + { + self.lastLoginResult = result; + }; + var onError = function (error) + { + self.isMyLoginCall = false; + self.lastError = error; + self.lastLoginResult = null; + self.Trigger(C3.Plugins.Rex_Firebase_Authentication.Cnds.OnLoginError, self); + }; + self.isMyLoginCall = true; + authObj["then"](onSuccess)["catch"](onError); + }; + var PRESISTING_TYPE = ["default", "sessionOnly", "never"]; + var PROVIDER_TYPE2x = ["facebook", "twitter", "github", "google"]; + // 3.x + var capitalizeFirstLetter = function (s) + { + return s.charAt(0).toUpperCase() + s.slice(1); + }; + //exps + // 2.x + var getProviderProperty = function (authData, p) + { + if (authData == null) + return ""; + + var provide_type = authData["provider"]; + var provider_info = authData[provide_type]; + if (provider_info == null) + return ""; + + var val = provider_info[p]; + if (val == null) + val = ""; + + return val; + }; + + // 3.x + var getUserProperty3x = function(p) + { + var user = getAuthObj()["currentUser"]; + return (user)? user[p]:""; + }; + var getProviderProperty3x = function (p, idx) + { + var user = getAuthObj()["currentUser"]; + if (!user) + return ""; + + if (idx == null) idx = 0; + var providerData = user["providerData"][idx]; + var val = (providerData)? providerData[p]:""; + return val; + }; + +{ + C3.Plugins.Rex_Firebase_Authentication = class Rex_Firebase_AuthenticationPlugin extends C3.SDKPluginBase + { + constructor(opts) + { + super(opts); + } + + Release() + { + super.Release(); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/type.js new file mode 100755 index 0000000..1826103 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/c3runtime/type.js @@ -0,0 +1,20 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Authentication.Type = class Rex_Firebase_AuthenticationType extends C3.SDKTypeBase + { + constructor(objectClass) + { + super(objectClass); + } + + Release() + { + super.Release(); + } + + OnCreate() + { + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/icon.png new file mode 100755 index 0000000..960c98b Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/instance.js new file mode 100755 index 0000000..7c3ab25 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Authentication; + + PLUGIN_CLASS.Instance = class Rex_Firebase_AuthenticationInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/lang/en-US.json new file mode 100755 index 0000000..45f0073 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/lang/en-US.json @@ -0,0 +1,366 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Authentication.", + "text": { + "plugins": { + "rex_firebase_authentication": { + "name": "Authentication", + "description": "Authentication which is provided by firebase. https://www.firebase.com/", + "help-url": "http://c2rexplugins.weebly.com/rex_firebase_authentication.html", + "properties": { + "domain": { + "name": "Domain", + "desc": "The root location of the Firebase data. Deprecated in firebase3.x." + } + }, + "aceCategories": { + "email_&_password": "Email & Password", + "anonymous": "Anonymous", + "authentication_token": "Authentication token", + "authentication_provider": "Authentication provider", + "authentication_with_token": "Authentication with token", + "general": "General", + "online": "Online", + "link_multiple_auth_providers": "Link multiple auth providers", + "email_&_password_-_create_account": "Email & Password - create account", + "email_&_password_-_change_password": "Email & Password - change password", + "email_&_password_-_send_password_reset_email": "Email & Password - send password reset email", + "email_&_password_-_delete_user": "Email & Password - delete user", + "email_&_password_-_update_profile": "Email & Password - update profile", + "email_&_password_-_update_email": "Email & Password - update email", + "email_&_password_-_send_verification_email": "Email & Password - send verification email", + "general_-_login": "General - login", + "general_-_logged_out": "General - logged out", + "error": "Error", + "general_auth_data": "General auth data" + }, + "conditions": { + "emailpassword_oncreateaccountsuccessful1": { + "list-name": "On created account", + "display-text": "On created account success", + "description": "Triggered when created account success." + }, + "emailpassword_oncreateaccounterror2": { + "list-name": "On created account error", + "display-text": "On create account error", + "description": "Triggered when created account error." + }, + "emailpassword_onchangingpasswordsuccessful3": { + "list-name": "On changed password", + "display-text": "On changed password success", + "description": "Triggered when changed password success." + }, + "emailpassword_onchangingpassworderror4": { + "list-name": "On changed password error", + "display-text": "On changed password error", + "description": "Triggered when changed password error." + }, + "emailpassword_onsendpasswordresetemailsuccessful5": { + "list-name": "On sent password reset email", + "display-text": "On sent password reset email success", + "description": "Triggered when sent password reset email success." + }, + "emailpassword_onsendpasswordresetemailerror6": { + "list-name": "On sent password reset email error", + "display-text": "On sent password reset email error", + "description": "Triggered when sent password reset email error." + }, + "emailpassword_ondeleteusersuccessful7": { + "list-name": "On deleted user", + "display-text": "On deleted user", + "description": "Triggered when deleted user success." + }, + "emailpassword_ondeleteusererror8": { + "list-name": "On deleted user error", + "display-text": "On deleted user error", + "description": "Triggered when deleted user error." + }, + "emailpassword_onupdatingprofilesuccessful9": { + "list-name": "On updated profile", + "display-text": "On update profile success", + "description": "Triggered when updated profile success." + }, + "emailpassword_onupdatingprofileerror10": { + "list-name": "On updated profile error", + "display-text": "On update profile error", + "description": "Triggered when updated profile error." + }, + "emailpassword_onupdatingemailsuccessful11": { + "list-name": "On updated email", + "display-text": "On update email success", + "description": "Triggered when updated email success." + }, + "emailpassword_onupdatingemailerror12": { + "list-name": "On updated email error", + "display-text": "On update email error", + "description": "Triggered when updated email error." + }, + "emailpassword_onsendverificationemailsuccessful13": { + "list-name": "On send verification email", + "display-text": "On send verification email success", + "description": "Triggered when send verification email success." + }, + "emailpassword_onsendverificationemailerror14": { + "list-name": "On send verification email error", + "display-text": "On send verification email error", + "description": "Triggered when send verification email error." + }, + "ısanonymous21": { + "list-name": "Is anonymous", + "display-text": "Is anonymous login", + "description": "Return true if current user is anonymous." + }, + "onloginsuccessful31": { + "list-name": "On login", + "display-text": "On login success", + "description": "Triggered when login success." + }, + "onloginerror32": { + "list-name": "On login error", + "display-text": "On login error", + "description": "Triggered when login error." + }, + "onloggedout33": { + "list-name": "On logged out", + "display-text": "On logged out", + "description": "Triggered when logged out." + }, + "ıslogin34": { + "list-name": "Is login", + "display-text": "Is login", + "description": "Return true if logging now." + }, + "onloginbyother41": { + "list-name": "On login by other app", + "display-text": "On login by other app", + "description": "Triggered when login by other app." + }, + "onloggedoutbyother42": { + "list-name": "On logged out by other app", + "display-text": "On logged out by other app", + "description": "Triggered when logged out by other app." + }, + "onlinksuccessful51": { + "list-name": "On link", + "display-text": "On link success", + "description": "Triggered when link success." + }, + "onlinkerror52": { + "list-name": "On link error", + "display-text": "On link error", + "description": "Triggered when link error." + } + }, + "actions": { + "emailpassword_createaccount1": { + "list-name": "Create account", + "display-text": "Create account with email: [i]{0}[/i], password: [i]{1}[/i]", + "description": "Create account with email & password.", + "params": { + "email0": { "name":"Email", "desc":"User email"}, + "password1": { "name":"Password", "desc":"User password"} + } + }, + "emailpassword_login2": { + "list-name": "Login", + "display-text": "Login with email: [i]{0}[/i], password: [i]{1}[/i], persisting type to [i]{2}[/i]", + "description": "Login with email & password.", + "params": { + "email0": { "name":"Email", "desc":"User email"}, + "password1": { "name":"Password", "desc":"User password"}, + "remember5": { "name":"Remember", "desc":"Persisting type", "items":{"default":"default","sessiononly":"sessionOnly","never":"never"}} + } + }, + "emailpassword_changepassword3": { + "list-name": "Change password", + "display-text": "Change password to [i]{1}[/i] {0} {2}", + "description": "Change password of current user.", + "params": { + "email0": { "name":"Email", "desc":"(2.x) User email"}, + "old_password1": { "name":"Old password", "desc":"(2.x) Old password"}, + "new_password2": { "name":"New password", "desc":"New password"} + } + }, + "emailpassword_sendpasswordresetemail4": { + "list-name": "Send password reset email", + "display-text": "Send password reset email: [i]{0}[/i]", + "description": "Send password reset email", + "params": { + "email0": { "name":"Email", "desc":"User email"} + } + }, + "emailpassword_deleteuser5": { + "list-name": "Delete user", + "display-text": "Delete current user {0} {1}", + "description": "Delete current user.", + "params": { + "email0": { "name":"Email", "desc":"(2.x) User email"}, + "password1": { "name":"Password", "desc":"(2.x) User password"} + } + }, + "anonymous_login11": { + "list-name": "Login", + "display-text": "Login with anonymous, persisting type to [i]{0}[/i]", + "description": "Login with anonymous.", + "params": { + "remember3": { "name":"Remember", "desc":"Persisting type", "items":{"default":"default","sessiononly":"sessionOnly","never":"never"}} + } + }, + "authenticationtoken_login12": { + "list-name": "Login", + "display-text": "Login with token [i]{0}[/i], persisting type to [i]{1}[/i]", + "description": "Login with authentication token.", + "params": { + "token0": { "name":"Token", "desc":"Token"}, + "remember4": { "name":"Remember", "desc":"Persisting type", "items":{"default":"default","sessiononly":"sessionOnly","never":"never"}} + } + }, + "providerauthentication_login21": { + "list-name": "Login", + "display-text": "Login by [i]{0}[/i] with [i]{1}[/i], persisting type to [i]{2}[/i], scope to [i]{3}[/i]", + "description": "Login by authentication provider.", + "params": { + "provider4": { "name":"Provider", "desc":"Authentication provider", "items":{"facebook":"Facebook","twitter":"Twitter","github":"Github","google":"Google"}}, + "type7": { "name":"Type", "desc":"Type of login window", "items":{"popup":"popup","redirect":"redirect"}}, + "remember11": { "name":"Remember", "desc":"Persisting type", "items":{"default":"default","sessiononly":"sessionOnly","never":"never"}}, + "scope12": { "name":"scope", "desc":"A comma-delimited list of requested extended permissions"} + } + }, + "authwithoauthtoken_fb22": { + "list-name": "Connect Facebook", + "display-text": "Authentication with Facebook access token [i]{0}[/i], persisting type to [i]{1}[/i], scope to [i]{2}[/i]", + "description": "Authentication with Facebook access token, call it after facebook login.", + "params": { + "access_token0": { "name":"Access token", "desc":"Access token from other plugin. Set \"\" if using official facebook to login."}, + "remember4": { "name":"Remember", "desc":"Persisting type", "items":{"default":"default","sessiononly":"sessionOnly","never":"never"}}, + "scope5": { "name":"scope", "desc":"A comma-delimited list of requested extended permissions"} + } + }, + "providerauthentication_login23": { + "list-name": "Login (provider name)", + "display-text": "Login by [i]{0}[/i] with [i]{1}[/i], persisting type to [i]{2}[/i], scope to [i]{3}[/i]", + "description": "Login by authentication provider.", + "params": { + "provider0": { "name":"Provider", "desc":"Code of authentication provider."}, + "type3": { "name":"Type", "desc":"Type of login window", "items":{"popup":"popup","redirect":"redirect"}}, + "remember7": { "name":"Remember", "desc":"Persisting type", "items":{"default":"default","sessiononly":"sessionOnly","never":"never"}}, + "scope8": { "name":"scope", "desc":"A comma-delimited list of requested extended permissions"} + } + }, + "loggingout31": { + "list-name": "Logging out", + "display-text": "Logging out current account", + "description": "Logging out current account." + }, + "gooffline41": { + "list-name": "Go offline", + "display-text": "Go offline", + "description": "Manually disconnect the Firebase client from the server and disable automatic reconnection." + }, + "goonline42": { + "list-name": "Go online", + "display-text": "Go online", + "description": "Manually reestablish a connection to the Firebase server and enable automatic reconnection." + }, + "linktofb51": { + "list-name": "Link to facebook", + "display-text": "Link to facebook account by access token: [i]{0}[/i]", + "description": "Link to facebook account by access token.", + "params": { + "access_token0": { "name":"Access token", "desc":"Access token from other plugin. Set \"\" if using official facebook to login."} + } + }, + "linktogoogle52": { + "list-name": "Link to google", + "display-text": "Link to google account by ID token: [i]{0}[/i]", + "description": "Link to google account by ID token.", + "params": { + "ıd_token0": { "name":"ID token", "desc":"ID token from other plugin."} + } + }, + "linktoemailpassword53": { + "list-name": "Link to email-password", + "display-text": "Link to email: [i]{0}[/i], password: [i]{1}[/i]", + "description": "Link to email-password.", + "params": { + "email0": { "name":"Email", "desc":"User email"}, + "password1": { "name":"Password", "desc":"User password"} + } + }, + "updateprofile61": { + "list-name": "Update profile", + "display-text": "Update display name to [i]{0}[/i], photo URL to [i]{1}[/i]", + "description": "Update profile. 3.x only.", + "params": { + "display_name0": { "name":"Display name", "desc":"Display name of current user."}, + "photo_url1": { "name":"Photo URL", "desc":"Photo URL of current user"} + } + }, + "updateemail62": { + "list-name": "Update email", + "display-text": "Update email to [i]{0}[/i]", + "description": "Update email. 3.x only.", + "params": { + "email0": { "name":"Email", "desc":"User email"} + } + }, + "sendemailverification63": { + "list-name": "Send verification email", + "display-text": "Send verification email", + "description": "Send verification email. 3.x only." + } + }, + "expressions": { + "errorcode1": { + "description": "Error code.", + "translated-name": "ErrorCode" + }, + "errormessage2": { + "description": "Error message.", + "translated-name": "ErrorMessage" + }, + "userıd3": { + "description": "Unique user ID, intended as the user's unique key across all providers.", + "translated-name": "UserID" + }, + "provider4": { + "description": "The authentication method used.", + "translated-name": "Provider" + }, + "displayname5": { + "description": "Display name.", + "translated-name": "DisplayName" + }, + "userıdfromprovider6": { + "description": "User ID from provider.", + "translated-name": "UserIDFromProvider" + }, + "accesstoken7": { + "description": "The FOAuth 2.0 access token granted by provider during user authentication.", + "translated-name": "AccessToken" + }, + "cacheduserprofile8": { + "description": "Cached user profile from provier.", + "translated-name": "CachedUserProfile" + }, + "email9": { + "description": "The user's primary email address as listed on their profile. Returned only if a valid email address is available, and the email permission was granted by the user.", + "translated-name": "Email" + }, + "username10": { + "description": "The user's screen name, handle, or alias. Twitter screen names are unique, but subject to change. .", + "translated-name": "UserName" + }, + "errordetail11": { + "description": "Error detail.", + "translated-name": "ErrorDetail" + }, + "photourl12": { + "description": "Photo URL.", + "translated-name": "PhotoURL" + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/plugin.js new file mode 100755 index 0000000..a7087c1 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/plugin.js @@ -0,0 +1,41 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase_Authentication"; + const PLUGIN_VERSION = "0.1.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Authentication = class Rex_Firebase_Authentication extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "domain", "") + ]); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/type.js new file mode 100755 index 0000000..75cb4d6 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_authentication/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Authentication; + + PLUGIN_CLASS.Type = class Rex_Firebase_AuthenticationType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/dist/rex_firebase_counter.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/dist/rex_firebase_counter.c3addon new file mode 100644 index 0000000..930836a Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/dist/rex_firebase_counter.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/aces.json new file mode 100755 index 0000000..7cc5cae --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/aces.json @@ -0,0 +1,222 @@ +{ + "domain": { + "conditions": [ + ], + "actions": [ + { + "c2id": 0, + "id": "setdomainref0", + "scriptName": "SetDomainRef", + "highlight": false, + "params": [ + {"id":"domain0", "type":"string", "initialValue":"\"\""}, + {"id":"sub_domain1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "update": { + "conditions": [ + { + "c2id": 1, + "id": "onupdate1", + "scriptName": "OnUpdate", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 1, + "id": "startupdate1", + "scriptName": "StartUpdate", + "highlight": false + }, + { + "c2id": 2, + "id": "stopupdate2", + "scriptName": "StopUpdate", + "highlight": false + } + ], + "expressions": [ + ] + }, + "configure": { + "conditions": [ + ], + "actions": [ + { + "c2id": 3, + "id": "setınit3", + "scriptName": "SetInit", + "highlight": false, + "params": [ + {"id":"ınit0", "type":"number", "initialValue":"0"}, + {"id":"upper_bound1", "type":"any", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "add": { + "conditions": [ + { + "c2id": 2, + "id": "onmywriting2", + "scriptName": "OnMyWriting", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 3, + "id": "comparelastwrotevalue3", + "scriptName": "CompareLastWroteValue", + "highlight": false, + "params": [ + {"id":"comparison0", "type":"cmp"}, + {"id":"value1", "type":"number"} + ] + }, + { + "c2id": 4, + "id": "comparelastvalue4", + "scriptName": "CompareLastValue", + "highlight": false, + "params": [ + {"id":"comparison0", "type":"cmp"}, + {"id":"value1", "type":"number"} + ] + }, + { + "c2id": 5, + "id": "onmywritingabort5", + "scriptName": "OnMyWritingAbort", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 6, + "id": "onmywritingerror6", + "scriptName": "OnMyWritingError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 11, + "id": "add11", + "scriptName": "Add", + "highlight": false, + "params": [ + {"id":"value0", "type":"any", "initialValue":"1"} + ] + } + ], + "expressions": [ + { + "c2id": 2, + "id": "lastwrotevalue2", + "expressionName": "LastWroteValue", + "scriptName": "LastWroteValue", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 3, + "id": "lastaddedvalue3", + "expressionName": "LastAddedValue", + "scriptName": "LastAddedValue", + "highlight": false, + "returnType": "number" + } + ] + }, + "set": { + "conditions": [ + ], + "actions": [ + { + "c2id": 12, + "id": "forceset12", + "scriptName": "ForceSet", + "highlight": false, + "params": [ + {"id":"value0", "type":"number", "initialValue":"0"} + ] + } + ], + "expressions": [ + ] + }, + "custom_add": { + "conditions": [ + { + "c2id": 21, + "id": "onaddfn21", + "scriptName": "OnAddFn", + "isTrigger": "true", + "highlight": false, + "params": [ + {"id":"function0", "type":"string", "initialValue":"\"_\""} + ] + } + ], + "actions": [ + { + "c2id": 21, + "id": "customaddbyfn21", + "scriptName": "CustomAddByFn", + "highlight": false, + "params": [ + {"id":"function0", "type":"string", "initialValue":"\"_\""} + ] + }, + { + "c2id": 22, + "id": "customaddadd22", + "scriptName": "CustomAddAdd", + "highlight": false, + "params": [ + {"id":"value0", "type":"number", "initialValue":"1"} + ] + }, + { + "c2id": 23, + "id": "customaddabort23", + "scriptName": "CustomAddAbort", + "highlight": false + } + ], + "expressions": [ + { + "c2id": 21, + "id": "customaddın21", + "expressionName": "CustomAddIn", + "scriptName": "CustomAddIn", + "highlight": false, + "returnType": "number" + } + ] + }, + "counter": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 1, + "id": "lastvalue1", + "expressionName": "LastValue", + "scriptName": "LastValue", + "highlight": false, + "returnType": "number" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/addon.json new file mode 100755 index 0000000..89097bb --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/addon.json @@ -0,0 +1,26 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Counter", + "id": "Rex_Firebase_Counter", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_counter.html", + "documentation": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_counter.html", + "description": "Counter to increase or decrease value.", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c2runtime/runtime.js new file mode 100755 index 0000000..1fe4749 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c2runtime/runtime.js @@ -0,0 +1,429 @@ +/* +- counter value +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_Counter = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_Counter.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + this.set_init(this.properties[2], this.properties[3]); + + this.exp_LastTransactionIn = null; + this.exp_LastValue = this.init_value; + this.exp_MyLastWroteValue = null; + this.exp_MyLastAddedValue = 0; + + // custom add + this.onCustomAdd_cb = ""; + + + this.query = null; + this.read_value_handler = null; + }; + + instanceProto.onDestroy = function () + { + this.stop_update(); + }; + + instanceProto.set_init = function (init_value, upper_bound) + { + this.init_value = init_value; + if ((upper_bound == "") || (upper_bound == '""')) + upper_bound = null; + else if (typeof (upper_bound) == "string") + upper_bound = parseFloat(upper_bound); + + this.upper_bound = upper_bound; + this.set_range(this.init_value, this.upper_bound); + }; + + instanceProto.set_range = function(v0, v1) + { + if ((v0 == null) || (v1 == null)) + { + this.counter_max = null; + this.counter_min = null; + } + else + { + this.counter_max = Math.max(v0, v1); + this.counter_min = Math.min(v0, v1); + } + }; + + + instanceProto.has_bound = function() + { + return (this.upper_bound != null); + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + instanceProto.clamp_result = function(current_value, wrote_value) + { + // no upper bound + if (!this.has_bound()) + return wrote_value; + + // has upper bound + // current value is equal to upper bound + else if (this.upper_bound == current_value) + return null; // Abort the transaction + + else + { + if (this.upper_bound > this.init_value) + { + if (wrote_value <= this.upper_bound) + return wrote_value; + else if (wrote_value > this.upper_bound) + return this.upper_bound; + else + return null; // Abort the transaction + } + else // (this.upper_bound < this.init_value) + { + if (wrote_value >= this.upper_bound) + return wrote_value; + else if (wrote_value < this.upper_bound) + return this.upper_bound; + else + return null; // Abort the transaction + } + } + }; + + instanceProto.on_transaction_complete = function(error, committed, snapshot) + { + if (error) + { + this.runtime.trigger(cr.plugins_.Rex_Firebase_Counter.prototype.cnds.OnMyWritingError, this); + } + else if (!committed) + { + this.runtime.trigger(cr.plugins_.Rex_Firebase_Counter.prototype.cnds.OnMyWritingAbort, this); + } + else + { + this.exp_MyLastWroteValue = snapshot["val"](); + this.exp_MyLastAddedValue = this.exp_MyLastWroteValue - this.exp_LastTransactionIn; + this.runtime.trigger(cr.plugins_.Rex_Firebase_Counter.prototype.cnds.OnMyWriting, this); + } + }; + + instanceProto.start_update = function () + { + this.stop_update(); + + var self = this; + var on_read = function (snapshot) + { + var counter_value = snapshot["val"](); + if (counter_value == null) + counter_value = self.init_value; + + self.exp_LastValue = counter_value; + self.runtime.trigger(cr.plugins_.Rex_Firebase_Counter.prototype.cnds.OnUpdate, self); + }; + + var query = this.get_ref(); + query["on"]("value", on_read); + + this.query = query; + this.read_value_handler = on_read; + }; + + instanceProto.stop_update = function () + { + if (this.query) + { + this.query["off"]("value", this.read_value_handler); + this.read_value_handler = null; + //this.get_ref()["off"](); + this.query = null; + } + }; + ////////////////////////////////////// + // Conditions + function Cnds() {}; + pluginProto.cnds = new Cnds(); + + Cnds.prototype.OnUpdate = function () + { + return true; + }; + + Cnds.prototype.OnMyWriting = function () + { + return true; + }; + + Cnds.prototype.CompareLastWroteValue = function (cmp, s) + { + if (this.exp_MyLastWroteValue == null) + return false; + return cr.do_cmp(this.exp_MyLastWroteValue, cmp, s); + }; + + Cnds.prototype.CompareLastValue = function (cmp, s) + { + return cr.do_cmp(this.exp_LastValue, cmp, s); + }; + + Cnds.prototype.OnMyWritingAbort = function () + { + return true; + }; + + Cnds.prototype.OnAddFn = function (cb) + { + return cr.equals_nocase(cb, this.onCustomAdd_cb); + }; + + Cnds.prototype.OnMyWritingError = function () + { + return true; + }; + + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetDomainRef = function (domain_ref, sub_domain_ref) + { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + }; + + Acts.prototype.StartUpdate = function () + { + this.start_update(); + }; + + Acts.prototype.StopUpdate = function () + { + this.stop_update(); + }; + + Acts.prototype.SetInit = function (init_value, upper_bound) + { + this.set_init(init_value, upper_bound); + }; + + Acts.prototype.Add = function (value_) + { + var is_numbe = typeof(value_) == "number"; + var self = this; + + var get_value = function(value_, current_value) + { + if (is_numbe) + return value_; + + return (parseFloat(value_)/100 * current_value); + }; + + var on_complete = function(error, committed, snapshot) + { + self.on_transaction_complete(error, committed, snapshot) ; + }; + + var on_add = function (current_value) + { + if (current_value == null) + current_value = self.init_value; + + self.exp_LastTransactionIn = current_value; + var added_value = get_value(value_, current_value); + var wrote_value = current_value + added_value; + var result = self.clamp_result(current_value, wrote_value); + if (result == null) + return; // Abort the transaction + else + return result; + }; + this.get_ref()["transaction"](on_add, on_complete); + }; + + Acts.prototype.ForceSet = function (value_) + { + this.get_ref()["set"](value_); + }; + + Acts.prototype.CustomAddByFn = function (cb) + { + var self = this; + + var on_complete = function(error, committed, snapshot) + { + self.on_transaction_complete(error, committed, snapshot) ; + }; + + var get_value = function (current_value) + { + self.exp_LastTransactionIn = current_value; + self.transactionOut = null; + self.onCustomAdd_cb = cb; + self.runtime.trigger(cr.plugins_.Rex_Firebase_Counter.prototype.cnds.OnAddFn, self); + return self.transactionOut; + }; + + var on_add = function (current_value) + { + if (current_value == null) + current_value = self.init_value; + + var added_value = get_value(current_value); + if (added_value == null) + return; // Abort the transaction + + var wrote_value = current_value + added_value; + var result = self.clamp_result(current_value, wrote_value); + if (result == null) + return; // Abort the transaction + else + return result; + }; + this.get_ref()["transaction"](on_add, on_complete); + }; + + Acts.prototype.CustomAddAdd = function (value_) + { + this.transactionOut = value_; + }; + + Acts.prototype.CustomAddAbort = function () + { + this.transactionOut = null; + }; + + + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.LastValue = function (ret) + { + ret.set_float(this.exp_LastValue); + }; + + Exps.prototype.LastWroteValue = function (ret) + { + ret.set_float(this.exp_MyLastWroteValue || 0); + }; + + Exps.prototype.LastAddedValue = function (ret) + { + ret.set_float(this.exp_MyLastAddedValue); + }; + + Exps.prototype.CustomAddIn = function (ret) + { + ret.set_float(this.exp_LastTransactionIn); + }; + +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/actions.js new file mode 100755 index 0000000..b1636f3 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/actions.js @@ -0,0 +1,115 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Counter.Acts = + { + SetDomainRef(domain_ref, sub_domain_ref) + { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + }, + + StartUpdate() + { + this.start_update(); + }, + + StopUpdate() + { + this.stop_update(); + }, + + SetInit(init_value, upper_bound) + { + this.set_init(init_value, upper_bound); + }, + + Add(value_) + { + var is_numbe = typeof(value_) == "number"; + var self = this; + + var get_value = function(value_, current_value) + { + if (is_numbe) + return value_; + + return (parseFloat(value_)/100 * current_value); + }; + + var on_complete = function(error, committed, snapshot) + { + self.on_transaction_complete(error, committed, snapshot) ; + }; + + var on_add = function (current_value) + { + if (current_value == null) + current_value = self.init_value; + + self.exp_LastTransactionIn = current_value; + var added_value = get_value(value_, current_value); + var wrote_value = current_value + added_value; + var result = self.clamp_result(current_value, wrote_value); + if (result == null) + return; // Abort the transaction + else + return result; + }; + this.get_ref()["transaction"](on_add, on_complete); + }, + + ForceSet(value_) + { + this.get_ref()["set"](value_); + }, + + CustomAddByFn(cb) + { + var self = this; + + var on_complete = function(error, committed, snapshot) + { + self.on_transaction_complete(error, committed, snapshot) ; + }; + + var get_value = function (current_value) + { + self.exp_LastTransactionIn = current_value; + self.transactionOut = null; + self.onCustomAdd_cb = cb; + self.Trigger(C3.Plugins.Rex_Firebase_Counter.Cnds.OnAddFn); + return self.transactionOut; + }; + + var on_add = function (current_value) + { + if (current_value == null) + current_value = self.init_value; + + var added_value = get_value(current_value); + if (added_value == null) + return; // Abort the transaction + + var wrote_value = current_value + added_value; + var result = self.clamp_result(current_value, wrote_value); + if (result == null) + return; // Abort the transaction + else + return result; + }; + this.get_ref()["transaction"](on_add, on_complete); + }, + + CustomAddAdd(value_) + { + this.transactionOut = value_; + }, + + CustomAddAbort() + { + this.transactionOut = null; + } + + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/conditions.js new file mode 100755 index 0000000..be693a0 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/conditions.js @@ -0,0 +1,43 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Counter.Cnds = + { + OnUpdate() + { + return true; + }, + + OnMyWriting() + { + return true; + }, + + CompareLastWroteValue(cmp, s) + { + if (this.exp_MyLastWroteValue == null) + return false; + return do_cmp(this.exp_MyLastWroteValue, cmp, s); + }, + + CompareLastValue(cmp, s) + { + return do_cmp(this.exp_LastValue, cmp, s); + }, + + OnMyWritingAbort() + { + return true; + }, + + OnAddFn(cb) + { + return C3.equalsNoCase(cb, this.onCustomAdd_cb); + }, + + OnMyWritingError() + { + return true; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/expressions.js new file mode 100755 index 0000000..9542530 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/expressions.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Counter.Exps = + { + LastValue() + { + return (this.exp_LastValue); + }, + + LastWroteValue() + { + return (this.exp_MyLastWroteValue || 0); + }, + + LastAddedValue() + { + return (this.exp_MyLastAddedValue); + }, + + CustomAddIn() + { + return (this.exp_LastTransactionIn); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/instance.js new file mode 100755 index 0000000..a0b5ede --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/instance.js @@ -0,0 +1,196 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Counter.Instance = class Rex_Firebase_CounterInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/" + properties[1] + "/"; + this.set_init(properties[2], properties[3]); + } + + + this.exp_LastTransactionIn = null; + this.exp_LastValue = this.init_value; + this.exp_MyLastWroteValue = null; + this.exp_MyLastAddedValue = 0; + + // custom add + this.onCustomAdd_cb = ""; + + + this.query = null; + this.read_value_handler = null; + + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + OnDestroyed() + { + this.stop_update(); + } + set_init (init_value, upper_bound) + { + this.init_value = init_value; + if ((upper_bound == "") || (upper_bound == '""')) + upper_bound = null; + else if (typeof (upper_bound) == "string") + upper_bound = parseFloat(upper_bound); + + this.upper_bound = upper_bound; + this.set_range(this.init_value, this.upper_bound); + } + + set_range(v0, v1) + { + if ((v0 == null) || (v1 == null)) + { + this.counter_max = null; + this.counter_min = null; + } + else + { + this.counter_max = Math.max(v0, v1); + this.counter_min = Math.min(v0, v1); + } + } + + has_bound() + { + return (this.upper_bound != null); + } + get_ref(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + } + + + // 2.x , 3.x + + clamp_result(current_value, wrote_value) + { + // no upper bound + if (!this.has_bound()) + return wrote_value; + + // has upper bound + // current value is equal to upper bound + else if (this.upper_bound == current_value) + return null; // Abort the transaction + + else + { + if (this.upper_bound > this.init_value) + { + if (wrote_value <= this.upper_bound) + return wrote_value; + else if (wrote_value > this.upper_bound) + return this.upper_bound; + else + return null; // Abort the transaction + } + else // (this.upper_bound < this.init_value) + { + if (wrote_value >= this.upper_bound) + return wrote_value; + else if (wrote_value < this.upper_bound) + return this.upper_bound; + else + return null; // Abort the transaction + } + } + } + + on_transaction_complete(error, committed, snapshot) + { + if (error) + { + this.Trigger(C3.Plugins.Rex_Firebase_Counter.Cnds.OnMyWritingError); + } + else if (!committed) + { + this.Trigger(C3.Plugins.Rex_Firebase_Counter.Cnds.OnMyWritingAbort); + } + else + { + this.exp_MyLastWroteValue = snapshot["val"](); + this.exp_MyLastAddedValue = this.exp_MyLastWroteValue - this.exp_LastTransactionIn; + this.Trigger(C3.Plugins.Rex_Firebase_Counter.Cnds.OnMyWriting); + } + } + + start_update () + { + this.stop_update(); + + var self = this; + var on_read = function (snapshot) + { + var counter_value = snapshot["val"](); + if (counter_value == null) + counter_value = self.init_value; + + self.exp_LastValue = counter_value; + self.Trigger(C3.Plugins.Rex_Firebase_Counter.Cnds.OnUpdate); + }; + + var query = this.get_ref(); + query["on"]("value", on_read); + + this.query = query; + this.read_value_handler = on_read; + } + + stop_update() + { + if (this.query) + { + this.query["off"]("value", this.read_value_handler); + this.read_value_handler = null; + //this.get_ref()["off"](); + this.query = null; + } + } + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/plugin.js new file mode 100755 index 0000000..029441a --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/plugin.js @@ -0,0 +1,77 @@ +"use strict"; + var do_cmp = function (x, cmp, y) + { + if (typeof x === "undefined" || typeof y === "undefined") + return false; + switch (cmp) + { + case 0: // equal + return x === y; + case 1: // not equal + return x !== y; + case 2: // less + return x < y; + case 3: // less/equal + return x <= y; + case 4: // greater + return x > y; + case 5: // greater/equal + return x >= y; + default: + return false; + } + }; + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + +{ + C3.Plugins.Rex_Firebase_Counter = class Rex_Firebase_CounterPlugin extends C3.SDKPluginBase + { + constructor(opts) + { + super(opts); + } + + Release() + { + super.Release(); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/type.js new file mode 100755 index 0000000..8951d04 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/c3runtime/type.js @@ -0,0 +1,20 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Counter.Type = class Rex_Firebase_CounterType extends C3.SDKTypeBase + { + constructor(objectClass) + { + super(objectClass); + } + + Release() + { + super.Release(); + } + + OnCreate() + { + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/icon.png new file mode 100755 index 0000000..9220dcf Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/instance.js new file mode 100755 index 0000000..cea5dbc --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/instance.js @@ -0,0 +1,30 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Counter; + + PLUGIN_CLASS.Instance = class Rex_Firebase_CounterInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnDestroyed() + { + + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/lang/en-US.json new file mode 100755 index 0000000..2b309bd --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/lang/en-US.json @@ -0,0 +1,173 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Counter.", + "text": { + "plugins": { + "rex_firebase_counter": { + "name": "Counter", + "description": "Counter to increase or decrease value.", + "help-url": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_counter.html", + "properties": { + "domain": { + "name": "Domain", + "desc": "The root location of the Firebase data." + }, + "sub-domain": { + "name": "Sub domain", + "desc": "Sub domain for this function." + }, + "ınitial": { + "name": "Initial", + "desc": "Initial value if counter value is null." + }, + "upper-bound": { + "name": "Upper bound", + "desc": "Upper bound of counter, \"\" is none. Counter value will be clamped at upper bound." + } + }, + "aceCategories": { + "domain": "Domain", + "update": "Update", + "configure": "Configure", + "add": "Add", + "set": "Set", + "custom_add": "Custom add", + "counter": "Counter" + }, + "conditions": { + "onupdate1": { + "list-name": "On update", + "display-text": "On update", + "description": "Triggered when counter updated." + }, + "onmywriting2": { + "list-name": "On my writing", + "display-text": "On my writing", + "description": "Triggered when my writing successfully." + }, + "comparelastwrotevalue3": { + "list-name": "Compare my last wrote value", + "display-text": "My last wrote value {0} {1}", + "description": "Compare my last wrote value.", + "params": { + "comparison0": { "name":"Comparison", "desc":"Choose the way to compare my last wrote value."}, + "value1": { "name":"Value", "desc":"The value to compare my last wrote value to."} + } + }, + "comparelastvalue4": { + "list-name": "Compare last counter value", + "display-text": "Last counter value {0} {1}", + "description": "Compare last counter value.", + "params": { + "comparison0": { "name":"Comparison", "desc":"Choose the way to compare last counter value."}, + "value1": { "name":"Value", "desc":"The value to compare last counter value to."} + } + }, + "onmywritingabort5": { + "list-name": "On my writing abort", + "display-text": "On my writing abort", + "description": "Triggered when my writing abort." + }, + "onmywritingerror6": { + "list-name": "On my writing error", + "display-text": "On my writing error", + "description": "Triggered when my writing error." + }, + "onaddfn21": { + "list-name": "On custom add", + "display-text": "On custom add function: [i]{0}[/i]", + "description": "Custom add function.", + "params": { + "function0": { "name":"Function", "desc":"Function for increasing counter."} + } + } + }, + "actions": { + "setdomainref0": { + "list-name": "Set domain", + "display-text": "Set domain to [i]{0}[/i], sub domain to [i]{1}[/i]", + "description": "Set domain ref.", + "params": { + "domain0": { "name":"Domain", "desc":"The root location of the Firebase data."}, + "sub_domain1": { "name":"Sub domain", "desc":"Sub domain for this function."} + } + }, + "startupdate1": { + "list-name": "Start", + "display-text": "Start update", + "description": "Start update." + }, + "stopupdate2": { + "list-name": "Stop", + "display-text": "Stop update", + "description": "Stop update." + }, + "setınit3": { + "list-name": "Set boundaries", + "display-text": "Set initial value to [i]{0}[/i], upper bound to [i]{1}[/i]", + "description": "Set initial value and upper bound. \"\" is none.", + "params": { + "ınit0": { "name":"Init", "desc":"Initial value."}, + "upper_bound1": { "name":"Upper bound", "desc":"Upper bound value. \"\" is none."} + } + }, + "add11": { + "list-name": "Try add to", + "display-text": "Try add [i]{0}[/i]", + "description": "Try add to.", + "params": { + "value0": { "name":"Value", "desc":"Value to add. Positive or negative number, or \"+10%\" string based on current value."} + } + }, + "forceset12": { + "list-name": "Force set to", + "display-text": "Force set value to [i]{0}[/i]", + "description": "Force set value, it will cancel any pending adding action.", + "params": { + "value0": { "name":"Value", "desc":"Value to set."} + } + }, + "customaddbyfn21": { + "list-name": "Try add by function", + "display-text": "Try add by function: [i]{0}[/i]", + "description": "Try add by function.", + "params": { + "function0": { "name":"Function", "desc":"Function for increasing counter."} + } + }, + "customaddadd22": { + "list-name": "Add to", + "display-text": "Custom add: add [i]{0}[/i]", + "description": "Try add to, used under \"Condition:On custom add\".", + "params": { + "value0": { "name":"Value", "desc":"Value to add. Positive or negative number."} + } + }, + "customaddabort23": { + "list-name": "Abort", + "display-text": "Custom add:: abort", + "description": "Abort current action, used under \"Condition:On custom add\"." + } + }, + "expressions": { + "lastvalue1": { + "description": "Get last value. Return Init value if last value is null.", + "translated-name": "LastValue" + }, + "lastwrotevalue2": { + "description": "Get my last wrote value. Valid under \"condition:On my writing\".", + "translated-name": "LastWroteValue" + }, + "lastaddedvalue3": { + "description": "Get my last added value. Valid under \"condition:On my writing\".", + "translated-name": "LastAddedValue" + }, + "customaddın21": { + "description": "Get current value, used under \"Condition:On custom add\".", + "translated-name": "CustomAddIn" + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/plugin.js new file mode 100755 index 0000000..2d6f6ed --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/plugin.js @@ -0,0 +1,44 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase_Counter"; + const PLUGIN_VERSION = "0.1.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Counter = class Rex_Firebase_Counter extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "domain", ""), + new SDK.PluginProperty("text", "sub-domain", "Counter"), + new SDK.PluginProperty("float", "ınitial", 0), + new SDK.PluginProperty("text", "upper-bound", "") + ]); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/type.js new file mode 100755 index 0000000..55cdf42 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_counter/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Counter; + + PLUGIN_CLASS.Type = class Rex_Firebase_CounterType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/dist/rex_firebase_curTime.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/dist/rex_firebase_curTime.c3addon new file mode 100644 index 0000000..70d45f8 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/dist/rex_firebase_curTime.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/aces.json new file mode 100755 index 0000000..6408447 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/aces.json @@ -0,0 +1,96 @@ +{ + "domain": { + "conditions": [ + ], + "actions": [ + { + "c2id": 0, + "id": "setdomainref0", + "scriptName": "SetDomainRef", + "highlight": false, + "params": [ + {"id":"domain0", "type":"string", "initialValue":"\"\""}, + {"id":"sub_domain1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "control": { + "conditions": [ + ], + "actions": [ + { + "c2id": 1, + "id": "start1", + "scriptName": "Start", + "highlight": false, + "params": [ + {"id":"user_ıd0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 2, + "id": "stop2", + "scriptName": "Stop", + "highlight": false + } + ], + "expressions": [ + ] + }, + "updating": { + "conditions": [ + { + "c2id": 1, + "id": "ısupdating1", + "scriptName": "IsUpdating", + "highlight": false + }, + { + "c2id": 2, + "id": "onstart2", + "scriptName": "OnStart", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "current": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 1, + "id": "timestamp1", + "expressionName": "Timestamp", + "scriptName": "Timestamp", + "highlight": false, + "returnType": "number" + } + ] + }, + "error": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 2, + "id": "lastpredictederror2", + "expressionName": "LastPredictedError", + "scriptName": "LastPredictedError", + "highlight": false, + "returnType": "number" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/addon.json new file mode 100755 index 0000000..53ac2b4 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/addon.json @@ -0,0 +1,26 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Current timestamp", + "id": "Rex_Firebase_CurTime", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "http://c2rexplugins.weebly.com/rex_firebase_curTime.html", + "documentation": "http://c2rexplugins.weebly.com/rex_firebase_curTime.html", + "description": "Get server timestamp periodically.", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c2runtime/runtime.js new file mode 100755 index 0000000..fb7b40d --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c2runtime/runtime.js @@ -0,0 +1,226 @@ +/* +- counter value +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_CurTime = function (runtime) { + this.runtime = runtime; +}; + +(function () { + var pluginProto = cr.plugins_.Rex_Firebase_CurTime.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function (plugin) { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function () { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function (type) { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function () { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + this.updatingPeriod = this.properties[2]; // seconds + this.timestamp_ref = null; + this.lastServerTimestamp = null; + this.lastLocalTimestamp = null; + this.lastPredictErr = 0; + }; + + instanceProto.onDestroy = function () { + }; + + // 2.x , 3.x + var isFirebase3x = function () { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) { + return (p.substring(0, 8) === "https://"); + }; + + instanceProto.get_ref = function (k) { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) { + return new window["Firebase"](path); + } + + // 3.x + else { + var fnName = (isFullPath(path)) ? "refFromURL" : "ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) { + return (!isFirebase3x()) ? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) { + return (!isFirebase3x()) ? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) { + return (!isFirebase3x()) ? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) { + return (!isFirebase3x()) ? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + // export + instanceProto.UpdatingTimestamp = function (onComplete) { + var self = this; + var onRead = function (snapshot) { + var ts = snapshot["val"](); + if (ts != null) { + ts = get_timestamp(ts); + var isFirstUpdating = (self.lastServerTimestamp === null); + if (!isFirstUpdating) { + var predictTS = self.getCurTimestamp(); + self.lastPredictErr = (ts - predictTS) / 1000; + } + else { + self.lastPredictErr = 0; + } + self.lastServerTimestamp = ts; + + if (onComplete) + onComplete(self.lastServerTimestamp); + else if (isFirstUpdating) + self.runtime.trigger(cr.plugins_.Rex_Firebase_CurTime.prototype.cnds.OnStart, self); + } + else // run again + setTimeout(function () { + self.UpdatingTimestamp(); + }, 0); + }; + var onWrite = function (error) { + if (!error) + self.timestamp_ref["once"]("value", onRead); + else // run again + setTimeout(function () { + self.UpdatingTimestamp(); + }, 0); + }; + this.timestamp_ref["set"](serverTimeStamp(), onWrite); + }; + + instanceProto.getCurTimestamp = function () { + var ts; + if (this.lastServerTimestamp == null) { + ts = 0; // invalid + } + if (this.lastLocalTimestamp == null) { + ts = this.lastServerTimestamp; + } + else { + var curLocalTS = (new Date()).getTime(); + var dt = curLocalTS - this.lastLocalTimestamp; + ts = this.lastServerTimestamp + dt; + } + return ts; + }; + // export + + /**BEGIN-PREVIEWONLY**/ + instanceProto.getDebuggerValues = function (propsections) { + var curDate; + if (this.lastServerTimestamp !== null) + curDate = (new Date(this.lastServerTimestamp)).toLocaleString(); + else + curDate = " - "; + + propsections.push({ + "title": this.type.name, + "properties": [ + { "name": "Current date", "value": curDate }, + { "name": "Last predicted error", "value": this.lastPredictErr }, + ] + }); + }; + /**END-PREVIEWONLY**/ + ////////////////////////////////////// + // Conditions + function Cnds() { }; + pluginProto.cnds = new Cnds(); + + Cnds.prototype.IsUpdating = function () { + return (this.lastServerTimestamp != null); + }; + + Cnds.prototype.OnStart = function () { + return true; + }; + + ////////////////////////////////////// + // Actions + function Acts() { }; + pluginProto.acts = new Acts(); + + Acts.prototype.SetDomainRef = function (domain_ref, sub_domain_ref) { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + }; + + Acts.prototype.Start = function (userID) { + this.timestamp_ref = this.get_ref(userID); + var self = this; + setInterval(function () { + self.UpdatingTimestamp(); + }, self.updatingPeriod); + }; + + Acts.prototype.Stop = function () { + this.timestamp_ref = null; + this.lastServerTimestamp = null; + }; + + ////////////////////////////////////// + // Expressions + function Exps() { }; + pluginProto.exps = new Exps(); + + Exps.prototype.Timestamp = function (ret) { + ret.set_int(Math.floor(this.getCurTimestamp())); + }; + + Exps.prototype.LastPredictedError = function (ret) { + ret.set_float(this.lastPredictErr); + }; +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/actions.js new file mode 100755 index 0000000..a7849c8 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/actions.js @@ -0,0 +1,25 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_CurTime.Acts = + { + + SetDomainRef(domain_ref, sub_domain_ref) { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + }, + + Start(userID) { + this.timestamp_ref = this.get_ref(userID); + var self = this; + setInterval(function () { + self.UpdatingTimestamp(); + }, self.updatingPeriod); + }, + + Stop() { + this.timestamp_ref = null; + this.lastServerTimestamp = null; + } + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/conditions.js new file mode 100755 index 0000000..78867d5 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/conditions.js @@ -0,0 +1,14 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_CurTime.Cnds = + { + IsUpdating() { + return (this.lastServerTimestamp != null); + }, + + OnStart() { + return true; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/expressions.js new file mode 100755 index 0000000..09fdf15 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/expressions.js @@ -0,0 +1,14 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_CurTime.Exps = + { + Timestamp() { + return (Math.floor(this.getCurTimestamp())); + }, + + LastPredictedError() { + return (this.lastPredictErr); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/instance.js new file mode 100755 index 0000000..6ad648b --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/instance.js @@ -0,0 +1,115 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_CurTime.Instance = class Rex_Firebase_CurTimeInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + + this.timestamp_ref = null; + this.lastServerTimestamp = null; + this.lastLocalTimestamp = null; + this.lastPredictErr = 0; + + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/" + properties[1] + "/"; + this.updatingPeriod = properties[2]; // seconds + } + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + get_ref(k) { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) { + return new window["Firebase"](path); + } + + // 3.x + else { + var fnName = (isFullPath(path)) ? "refFromURL" : "ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + } + UpdatingTimestamp(onComplete) { + var self = this; + var onRead = function (snapshot) { + var ts = snapshot["val"](); + if (ts != null) { + ts = get_timestamp(ts); + var isFirstUpdating = (self.lastServerTimestamp === null); + if (!isFirstUpdating) { + var predictTS = self.getCurTimestamp(); + self.lastPredictErr = (ts - predictTS) / 1000; + } + else { + self.lastPredictErr = 0; + } + self.lastServerTimestamp = ts; + + if (onComplete) + onComplete(self.lastServerTimestamp); + else if (isFirstUpdating) + self.Trigger(C3.Plugins.Rex_Firebase_CurTime.Cnds.OnStart); + } + else // run again + setTimeout(function () { + self.UpdatingTimestamp(); + }, 0); + }; + var onWrite = function (error) { + if (!error) + self.timestamp_ref["once"]("value", onRead); + else // run again + setTimeout(function () { + self.UpdatingTimestamp(); + }, 0); + }; + this.timestamp_ref["set"](serverTimeStamp(), onWrite); + } + + getCurTimestamp() { + var ts; + if (this.lastServerTimestamp == null) { + ts = 0; // invalid + } + if (this.lastLocalTimestamp == null) { + ts = this.lastServerTimestamp; + } + else { + var curLocalTS = (new Date()).getTime(); + var dt = curLocalTS - this.lastLocalTimestamp; + ts = this.lastServerTimestamp + dt; + } + return ts; + } + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/plugin.js new file mode 100755 index 0000000..7f35dbd --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/plugin.js @@ -0,0 +1,44 @@ +"use strict"; + var isFirebase3x = function () { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) { + return (p.substring(0, 8) === "https://"); + }; + var get_key = function (obj) { + return (!isFirebase3x()) ? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) { + return (!isFirebase3x()) ? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) { + return (!isFirebase3x()) ? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) { + return (!isFirebase3x()) ? obj : obj["TIMESTAMP"]; + }; +{ + C3.Plugins.Rex_Firebase_CurTime = class Rex_Firebase_CurTimePlugin extends C3.SDKPluginBase + { + constructor(opts) + { + super(opts); + } + + Release() + { + super.Release(); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/type.js new file mode 100755 index 0000000..1dd9116 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/c3runtime/type.js @@ -0,0 +1,20 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_CurTime.Type = class Rex_Firebase_CurTimeType extends C3.SDKTypeBase + { + constructor(objectClass) + { + super(objectClass); + } + + Release() + { + super.Release(); + } + + OnCreate() + { + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/icon.png new file mode 100755 index 0000000..eddd771 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/instance.js new file mode 100755 index 0000000..b747513 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_CurTime; + + PLUGIN_CLASS.Instance = class Rex_Firebase_CurTimeInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/lang/en-US.json new file mode 100755 index 0000000..dea0e17 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/lang/en-US.json @@ -0,0 +1,80 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Current timestamp.", + "text": { + "plugins": { + "rex_firebase_curtime": { + "name": "Current timestamp", + "description": "Get server timestamp periodically.", + "help-url": "http://c2rexplugins.weebly.com/rex_firebase_curTime.html", + "properties": { + "domain": { + "name": "Domain", + "desc": "The root location of the Firebase data." + }, + "sub-domain": { + "name": "Sub domain", + "desc": "Sub domain for this function." + }, + "updating-period": { + "name": "Updating period", + "desc": "Updating period of server timestamp, in secondes." + } + }, + "aceCategories": { + "domain": "Domain", + "control": "Control", + "updating": "Updating", + "current": "Current", + "error": "Error" + }, + "conditions": { + "ısupdating1": { + "list-name": "Is updating", + "display-text": "Is updating", + "description": "Return true if timestamp is valid." + }, + "onstart2": { + "list-name": "On start", + "display-text": "On updating start", + "description": "Triggered when updating start." + } + }, + "actions": { + "setdomainref0": { + "list-name": "Set domain", + "display-text": "Set domain to [i]{0}[/i], sub domain to [i]{1}[/i]", + "description": "Set domain ref.", + "params": { + "domain0": { "name":"Domain", "desc":"The root location of the Firebase data."}, + "sub_domain1": { "name":"Sub domain", "desc":"Sub domain for this function."} + } + }, + "start1": { + "list-name": "Start", + "display-text": "Start updating server timestamp of user ID: [i]{0}[/i]", + "description": "Start updating server timestamp.", + "params": { + "user_ıd0": { "name":"User ID", "desc":"Key of User ID."} + } + }, + "stop2": { + "list-name": "Stop", + "display-text": "Stop updating server timestamp", + "description": "Stop updating server timestamp." + } + }, + "expressions": { + "timestamp1": { + "description": "Get current timestamp, in milliseconds.", + "translated-name": "Timestamp" + }, + "lastpredictederror2": { + "description": "Get last predicted error, in seconds", + "translated-name": "LastPredictedError" + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/plugin.js new file mode 100755 index 0000000..77966bb --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/plugin.js @@ -0,0 +1,42 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase_CurTime"; + const PLUGIN_VERSION = "0.1.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_CurTime = class Rex_Firebase_CurTime extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(true); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "domain", ""), + new SDK.PluginProperty("text", "sub-domain", "CurTime"), + new SDK.PluginProperty("float", "updating-period", 1) + ]); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/type.js new file mode 100755 index 0000000..c6ec7b5 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_curTime/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_CurTime; + + PLUGIN_CLASS.Type = class Rex_Firebase_CurTimeType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/dist/rex_firebase_geofire.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/dist/rex_firebase_geofire.c3addon new file mode 100644 index 0000000..49fcccd Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/dist/rex_firebase_geofire.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/aces.json new file mode 100755 index 0000000..02cc0b5 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/aces.json @@ -0,0 +1,346 @@ +{ + "domain": { + "conditions": [ + ], + "actions": [ + { + "c2id": 0, + "id": "setsubdomainref0", + "scriptName": "SetSubDomainRef", + "highlight": false, + "params": [ + {"id":"sub_domain0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "set": { + "conditions": [ + { + "c2id": 1, + "id": "onupdatecomplete1", + "scriptName": "OnUpdateComplete", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 2, + "id": "onupdateerror2", + "scriptName": "OnUpdateError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 1, + "id": "setlocation1", + "scriptName": "SetLocation", + "highlight": false, + "params": [ + {"id":"ıd0", "type":"string", "initialValue":"\"\""}, + {"id":"latitude1", "type":"number", "initialValue":"0"}, + {"id":"longitude2", "type":"number", "initialValue":"0"} + ] + }, + { + "c2id": 3, + "id": "removeıtem3", + "scriptName": "RemoveItem", + "highlight": false, + "params": [ + {"id":"ıd0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "on_disconnected": { + "conditions": [ + ], + "actions": [ + { + "c2id": 2, + "id": "ondisconnectedremove2", + "scriptName": "OnDisconnectedRemove", + "highlight": false, + "params": [ + {"id":"ıd0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 5, + "id": "ondisconnectedcancel5", + "scriptName": "OnDisconnectedCancel", + "highlight": false, + "params": [ + {"id":"ıd0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "get": { + "conditions": [ + { + "c2id": 3, + "id": "ongetıtemcomplete3", + "scriptName": "OnGetItemComplete", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 4, + "id": "ongetıtemerror4", + "scriptName": "OnGetItemError", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 5, + "id": "ısıtemnotfound5", + "scriptName": "IsItemNotFound", + "highlight": false + } + ], + "actions": [ + { + "c2id": 4, + "id": "getıtem4", + "scriptName": "GetItem", + "highlight": false, + "params": [ + {"id":"ıd0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "monitor": { + "conditions": [ + { + "c2id": 11, + "id": "onıtementered11", + "scriptName": "OnItemEntered", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 12, + "id": "onıtemexisted12", + "scriptName": "OnItemExisted", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 13, + "id": "onıtemmoved13", + "scriptName": "OnItemMoved", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 14, + "id": "onready14", + "scriptName": "OnReady", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 15, + "id": "foreachıtemıd15", + "scriptName": "ForEachItemID", + "isLooping": "true", + "isInvertible": "false", + "highlight": false, + "params": [ + {"id":"order4", "type":"combo", "items":["descending","ascending","logical descending","logical ascending"]} + ] + } + ], + "actions": [ + { + "c2id": 11, + "id": "monitorat11", + "scriptName": "MonitorAt", + "highlight": false, + "params": [ + {"id":"latitude0", "type":"number", "initialValue":"0"}, + {"id":"longitude1", "type":"number", "initialValue":"0"}, + {"id":"radius2", "type":"number", "initialValue":"0"} + ] + }, + { + "c2id": 12, + "id": "monitorstop12", + "scriptName": "MonitorStop", + "highlight": false + } + ], + "expressions": [ + ] + }, + "ıtemıd": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 1, + "id": "generatekey1", + "expressionName": "GenerateKey", + "scriptName": "GenerateKey", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 2, + "id": "lastgeneratedkey2", + "expressionName": "LastGeneratedKey", + "scriptName": "LastGeneratedKey", + "highlight": false, + "returnType": "string" + } + ] + }, + "event": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 11, + "id": "lastıtemıd11", + "expressionName": "LastItemID", + "scriptName": "LastItemID", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 12, + "id": "lastlatitude12", + "expressionName": "LastLatitude", + "scriptName": "LastLatitude", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 13, + "id": "lastlongitude13", + "expressionName": "LastLongitude", + "scriptName": "LastLongitude", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 14, + "id": "lastdistance14", + "expressionName": "LastDistance", + "scriptName": "LastDistance", + "highlight": false, + "returnType": "number" + } + ] + }, + "monitor_area": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 21, + "id": "monitorlatitude21", + "expressionName": "MonitorLatitude", + "scriptName": "MonitorLatitude", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 22, + "id": "monitorlongitude22", + "expressionName": "MonitorLongitude", + "scriptName": "MonitorLongitude", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 23, + "id": "monitorradius23", + "expressionName": "MonitorRadius", + "scriptName": "MonitorRadius", + "highlight": false, + "returnType": "number" + } + ] + }, + "for_each": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 31, + "id": "curıtemıd31", + "expressionName": "CurItemID", + "scriptName": "CurItemID", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 32, + "id": "curlatitude32", + "expressionName": "CurLatitude", + "scriptName": "CurLatitude", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 33, + "id": "curlongitude33", + "expressionName": "CurLongitude", + "scriptName": "CurLongitude", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 34, + "id": "curdistance34", + "expressionName": "CurDistance", + "scriptName": "CurDistance", + "highlight": false, + "returnType": "number" + } + ] + }, + "helper": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 51, + "id": "distance51", + "expressionName": "Distance", + "scriptName": "Distance", + "highlight": false, + "returnType": "number", + "params": [ + {"id":"latitude_a0", "type":"number", "initialValue":"0"}, + {"id":"longitude_a1", "type":"number", "initialValue":"0"}, + {"id":"latitude_b2", "type":"number", "initialValue":"0"}, + {"id":"longitude_b3", "type":"number", "initialValue":"0"} + ] + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/addon.json new file mode 100755 index 0000000..2666bbb --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/addon.json @@ -0,0 +1,27 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Geofire", + "id": "Rex_Firebase_Geofire", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_geofire.html", + "documentation": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_geofire.html", + "description": "Realtime location queries with Firebase.", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "geofire.js", + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c2runtime/runtime.js new file mode 100755 index 0000000..cc5abfe --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c2runtime/runtime.js @@ -0,0 +1,411 @@ +/* +- counter value +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_Geofire = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_Geofire.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" ; + this.exp_LastGeneratedKey = ""; + + this.geoQuery = null; + this.current_items = {}; + this.exp_LastItemID = ""; + this.exp_LastLocation = null; + this.exp_LastDistance = 0; + this.exp_CurItemID = ""; + this.exp_CurItemContent = null; + + }; + + instanceProto.onDestroy = function () + { + this.queryStop(); + this.current_items = {}; + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path = this.rootpath + k + "/"; + + return window["Firebase"]["database"]()["ref"](path); + + }; + + instanceProto.getGeo = function() + { + return new window["GeoFire"](this.get_ref()); + }; + + instanceProto.setValue = function (itemID, location) + { + var self=this; + var onComplete = function () + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Geofire.prototype.cnds.OnUpdateComplete, self); + }; + + var onError= function (error) + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Geofire.prototype.cnds.OnUpdateError, self); + }; + var geo = this.getGeo(); + geo["set"](itemID, location)["then"](onComplete, onError); + }; + + instanceProto.getValue = function (itemID) + { + var self=this; + var onComplete = function (location) + { + self.exp_LastItemID = itemID; + self.exp_LastLocation = location; + self.runtime.trigger(cr.plugins_.Rex_Firebase_Geofire.prototype.cnds.OnGetItemComplete, self); + }; + + var onError= function (error) + { + self.exp_LastItemID = itemID; + self.runtime.trigger(cr.plugins_.Rex_Firebase_Geofire.prototype.cnds.OnGetItemError, self); + }; + var geo = this.getGeo(); + geo["get"](itemID)["then"](onComplete, onError); + }; + + + instanceProto.queryStart = function (lat, lng, r) + { + var d = { "center": [lat, lng], "radius": r }; + if (!this.geoQuery) + { + this.geoQuery = this.getGeo()["query"](d); + + var trig = cr.plugins_.Rex_Firebase_Geofire.prototype.cnds; + var self = this; + var onReady = function () + { + self.runtime.trigger(trig.OnReady, self); + }; + var onEntered = function (itemID, location, distance) + { + self.exp_LastItemID = itemID; + self.exp_LastLocation = location; + self.exp_LastDistance = distance; + self.current_items[itemID] = [location, distance]; + self.runtime.trigger(trig.OnItemEntered, self); + }; + var onExisted = function (itemID, location, distance) + { + self.exp_LastItemID = itemID; + self.exp_LastLocation = location; + self.exp_LastDistance = distance; + if (self.current_items.hasOwnProperty(itemID)) + delete self.current_items[itemID]; + self.runtime.trigger(trig.OnItemExisted, self); + }; + var onMoved = function (itemID, location, distance) + { + self.exp_LastItemID = itemID; + self.exp_LastLocation = location; + self.exp_LastDistance = distance; + self.current_items[itemID] = [location, distance]; + self.runtime.trigger(trig.OnItemMoved, self); + }; + + this.geoQuery.on("ready", onReady); + this.geoQuery.on("key_entered", onEntered ); + this.geoQuery.on("key_exited", onExisted ); + this.geoQuery.on("key_moved", onMoved ); + + } + else + this.geoQuery["updateCriteria"](d); + }; + + instanceProto.queryStop= function () + { + if (!this.geoQuery) + return; + + this.geoQuery["cancel"](); + this.geoQuery = null; + }; + + instanceProto.ForEachItemID = function (itemIDList, items) + { + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var i, cnt=itemIDList.length; + for(i=0; i= 2) // logical descending, logical ascending + { + valA = parseFloat(valA); + valB = parseFloat(valB); + m -= 2; + } + + switch (m) + { + case 0: // descending + if (valA === valB) return 0; + else if (valA < valB) return 1; + else return -1; + break; + + case 1: // ascending + if (valA === valB) return 0; + else if (valA > valB) return 1; + else return -1; + break; + + } + }; + + itemIDList.sort(sortFn); + return this.ForEachItemID(itemIDList, table); + }; + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetSubDomainRef = function (ref) + { + this.rootpath = ref + "/"; + + }; + + Acts.prototype.SetLocation = function (itemID, lat, lng) + { + this.setValue(itemID, [lat, lng]); + }; + + Acts.prototype.OnDisconnectedRemove = function (itemID) + { + var geo = this.getGeo(); + geo["ref"]()["child"](itemID)["onDisconnect"]()["remove"](); + }; + + Acts.prototype.RemoveItem = function (itemID) + { + this.setValue(itemID, null); + }; + + Acts.prototype.GetItem = function (itemID) + { + this.getValue(itemID); + }; + + Acts.prototype.OnDisconnectedCancel = function (itemID) + { + var geo = this.getGeo(); + geo["ref"]()["child"](itemID)["onDisconnect"]()["cancel"](); + }; + + Acts.prototype.MonitorAt = function (lat, lng, r) + { + this.queryStart(lat, lng, r); + }; + + Acts.prototype.MonitorStop = function () + { + this.queryStop(); + }; + + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.GenerateKey = function (ret) + { + var ref = this.get_ref()["push"](); + this.exp_LastGeneratedKey = ref["key"]; + ret.set_string(this.exp_LastGeneratedKey); + }; + + Exps.prototype.LastGeneratedKey = function (ret) + { + ret.set_string(this.exp_LastGeneratedKey); + }; + + Exps.prototype.LastItemID = function (ret) + { + ret.set_string(this.exp_LastItemID); + }; + + Exps.prototype.LastLatitude = function (ret) + { + var lat = (this.exp_LastLocation)? this.exp_LastLocation[0]:0; + ret.set_float(lat); + }; + + Exps.prototype.LastLongitude = function (ret) + { + var lng = (this.exp_LastLocation)? this.exp_LastLocation[1]:0; + ret.set_float(lng); + }; + + Exps.prototype.LastDistance = function (ret) + { + ret.set_float(this.exp_LastDistance); + }; + + Exps.prototype.CurItemID = function (ret) + { + ret.set_string(this.exp_CurItemID); + }; + + Exps.prototype.CurLatitude = function (ret) + { + var lat = (this.exp_CurItemContent)? this.exp_CurItemContent[0][0] : 0; + ret.set_float(lat); + }; + + Exps.prototype.CurLongitude = function (ret) + { + var lng = (this.exp_CurItemContent)? this.exp_CurItemContent[0][1] : 0; + ret.set_float(lng); + }; + + Exps.prototype.CurDistance = function (ret) + { + var d = (this.exp_CurItemContent)? this.exp_CurItemContent[1] : 0; + ret.set_float(d); + }; + + Exps.prototype.MonitorLatitude = function (ret) + { + var lat = (this.geoQuery)? this.geoQuery["center"]()[0]:0; + ret.set_float(lat); + }; + + Exps.prototype.MonitorLongitude = function (ret) + { + var lng = (this.geoQuery)? this.geoQuery["center"]()[1]:0; + ret.set_float(lng); + }; + + Exps.prototype.MonitorRadius = function (ret) + { + var r = (this.geoQuery)? this.geoQuery["radius"]():0; + ret.set_float(r); + }; + Exps.prototype.Distance = function (ret, latA, lngA, latB, lngB) + { + var d = window["GeoFire"]["distance"]([latA, lngA], [latB, lngB]); + ret.set_float(d); + }; + +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/actions.js new file mode 100755 index 0000000..d302927 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/actions.js @@ -0,0 +1,50 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Geofire.Acts = + { + SetSubDomainRef(ref) + { + this.rootpath = ref + "/"; + + }, + + SetLocation(itemID, lat, lng) + { + this.setValue(itemID, [lat, lng]); + }, + + OnDisconnectedRemove(itemID) + { + var geo = this.getGeo(); + geo["ref"]()["child"](itemID)["onDisconnect"]()["remove"](); + }, + + RemoveItem(itemID) + { + this.setValue(itemID, null); + }, + + GetItem(itemID) + { + this.getValue(itemID); + }, + + OnDisconnectedCancel(itemID) + { + var geo = this.getGeo(); + geo["ref"]()["child"](itemID)["onDisconnect"]()["cancel"](); + }, + + MonitorAt(lat, lng, r) + { + this.queryStart(lat, lng, r); + }, + + MonitorStop() + { + this.queryStop(); + } + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/conditions.js new file mode 100755 index 0000000..2b89f68 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/conditions.js @@ -0,0 +1,82 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Geofire.Cnds = + { + OnUpdateComplete() + { + return true; + }, + OnUpdateError() + { + return true; + }, + + OnGetItemComplete() + { + return true; + }, + OnGetItemError() + { + return true; + }, + IsItemNotFound() + { + return (this.exp_LastLocation == null); + }, + OnItemEntered() + { + return true; + }, + OnItemExisted() + { + return true; + }, + OnItemMoved() + { + return true; + }, + OnReady() + { + return true; + }, + + ForEachItemID(sortMode_) + { + var table = this.current_items; + var itemIDList = Object.keys(table); + + var self = this; + var sortFn = function (valA, valB) + { + var m = sortMode_; + + if (sortMode_ >= 2) // logical descending, logical ascending + { + valA = parseFloat(valA); + valB = parseFloat(valB); + m -= 2; + } + + switch (m) + { + case 0: // descending + if (valA === valB) return 0; + else if (valA < valB) return 1; + else return -1; + break; + + case 1: // ascending + if (valA === valB) return 0; + else if (valA > valB) return 1; + else return -1; + break; + + } + }; + + itemIDList.sort(sortFn); + return this.ForEachItemID(itemIDList, table); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/expressions.js new file mode 100755 index 0000000..f8478ce --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/expressions.js @@ -0,0 +1,86 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Geofire.Exps = + { + GenerateKey() + { + var ref = this.get_ref()["push"](); + this.exp_LastGeneratedKey = ref["key"]; + return (this.exp_LastGeneratedKey); + }, + + LastGeneratedKey() + { + return (this.exp_LastGeneratedKey); + }, + + LastItemID() + { + return (this.exp_LastItemID); + }, + + LastLatitude() + { + var lat = (this.exp_LastLocation)? this.exp_LastLocation[0]:0; + return (lat); + }, + + LastLongitude() + { + var lng = (this.exp_LastLocation)? this.exp_LastLocation[1]:0; + return (lng); + }, + + LastDistance() + { + return (this.exp_LastDistance); + }, + + CurItemID() + { + return (this.exp_CurItemID); + }, + + CurLatitude() + { + var lat = (this.exp_CurItemContent)? this.exp_CurItemContent[0][0] : 0; + return (lat); + }, + + CurLongitude() + { + var lng = (this.exp_CurItemContent)? this.exp_CurItemContent[0][1] : 0; + return (lng); + }, + + CurDistance() + { + var d = (this.exp_CurItemContent)? this.exp_CurItemContent[1] : 0; + return (d); + }, + + MonitorLatitude() + { + var lat = (this.geoQuery)? this.geoQuery["center"]()[0]:0; + return (lat); + }, + + MonitorLongitude() + { + var lng = (this.geoQuery)? this.geoQuery["center"]()[1]:0; + return (lng); + }, + + MonitorRadius() + { + var r = (this.geoQuery)? this.geoQuery["radius"]():0; + return (r); + }, + Distance(latA, lngA, latB, lngB) + { + var d = window["GeoFire"]["distance"]([latA, lngA], [latB, lngB]); + return (d); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/instance.js new file mode 100755 index 0000000..8f10b28 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/c3runtime/instance.js @@ -0,0 +1,182 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Geofire.Instance = class Rex_Firebase_GeofireInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + + this.exp_LastGeneratedKey = ""; + this.geoQuery = null; + this.current_items = {}; + this.exp_LastItemID = ""; + this.exp_LastLocation = null; + this.exp_LastDistance = 0; + this.exp_CurItemID = ""; + this.exp_CurItemContent = null; + + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/" ; + } + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + get_ref(k) + { + if (k == null) + k = ""; + var path = this.rootpath + k + "/"; + + return window["Firebase"]["database"]()["ref"](path); + + } + + getGeo() + { + return new window["GeoFire"](this.get_ref()); + } + + setValue (itemID, location) + { + var self=this; + var onComplete = function () + { + self.Trigger(C3.Plugins.Rex_Firebase_Geofire.Cnds.OnUpdateComplete, self); + }; + + var onError= function (error) + { + self.Trigger(C3.Plugins.Rex_Firebase_Geofire.Cnds.OnUpdateError, self); + }; + var geo = this.getGeo(); + geo["set"](itemID, location)["then"](onComplete, onError); + } + + getValue (itemID) + { + var self=this; + var onComplete = function (location) + { + self.exp_LastItemID = itemID; + self.exp_LastLocation = location; + self.Trigger(C3.Plugins.Rex_Firebase_Geofire.Cnds.OnGetItemComplete, self); + }; + + var onError= function (error) + { + self.exp_LastItemID = itemID; + self.Trigger(C3.Plugins.Rex_Firebase_Geofire.Cnds.OnGetItemError, self); + }; + var geo = this.getGeo(); + geo["get"](itemID)["then"](onComplete, onError); + } + + + queryStart (lat, lng, r) + { + var d = { "center": [lat, lng], "radius": r }; + if (!this.geoQuery) + { + this.geoQuery = this.getGeo()["query"](d); + + var trig = C3.Plugins.Rex_Firebase_Geofire.Cnds; + var self = this; + var onReady = function () + { + self.Trigger(trig.OnReady, self); + }; + var onEntered = function (itemID, location, distance) + { + self.exp_LastItemID = itemID; + self.exp_LastLocation = location; + self.exp_LastDistance = distance; + self.current_items[itemID] = [location, distance]; + self.Trigger(trig.OnItemEntered, self); + }; + var onExisted = function (itemID, location, distance) + { + self.exp_LastItemID = itemID; + self.exp_LastLocation = location; + self.exp_LastDistance = distance; + if (self.current_items.hasOwnProperty(itemID)) + delete self.current_items[itemID]; + self.Trigger(trig.OnItemExisted, self); + }; + var onMoved = function (itemID, location, distance) + { + self.exp_LastItemID = itemID; + self.exp_LastLocation = location; + self.exp_LastDistance = distance; + self.current_items[itemID] = [location, distance]; + self.Trigger(trig.OnItemMoved, self); + }; + + this.geoQuery.on("ready", onReady); + this.geoQuery.on("key_entered", onEntered ); + this.geoQuery.on("key_exited", onExisted ); + this.geoQuery.on("key_moved", onMoved ); + + } + else + this.geoQuery["updateCriteria"](d); + } + + queryStop () + { + if (!this.geoQuery) + return; + + this.geoQuery["cancel"](); + this.geoQuery = null; + } + + ForEachItemID (itemIDList, items) + { + var current_frame = this._runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = this._runtime.GetEventSheetManager().GetEventStack(); + var p = this._runtime.GetEventStack(); + var h = c.Push(current_event); + + var i, cnt=itemIDList.length; + for(i=0; i|undefined} location The [latitude, longitude] pair to add. + * @return {Promise.<>} A promise that is fulfilled when the write is complete. + */ + this.set = function(keyOrLocations, location) { + var locations; + if (typeof keyOrLocations === "string" && keyOrLocations.length !== 0) { + // If this is a set for a single location, convert it into a object + locations = {}; + locations[keyOrLocations] = location; + } else if (typeof keyOrLocations === "object") { + if (typeof location !== "undefined") { + throw new Error("The location argument should not be used if you pass an object to set()."); + } + locations = keyOrLocations; + } else { + throw new Error("keyOrLocations must be a string or a mapping of key - location pairs."); + } + + var newData = {}; + + Object.keys(locations).forEach(function(key) { + validateKey(key); + + var location = locations[key]; + if (location === null) { + // Setting location to null is valid since it will remove the key + newData[key] = null; + } else { + validateLocation(location); + + var geohash = encodeGeohash(location); + newData[key] = encodeGeoFireObject(location, geohash); + } + }); + + return _firebaseRef.update(newData); + }; + + /** + * Returns a promise fulfilled with the location corresponding to the provided key. + * + * If the provided key does not exist, the returned promise is fulfilled with null. + * + * @param {string} key The key of the location to retrieve. + * @return {Promise.>} A promise that is fulfilled with the location of the given key. + */ + this.get = function(key) { + validateKey(key); + return _firebaseRef.child(key).once("value").then(function(dataSnapshot) { + var snapshotVal = dataSnapshot.val(); + if (snapshotVal === null) { + return null; + } else { + return decodeGeoFireObject(snapshotVal); + } + }); + }; + + /** + * Removes the provided key from this GeoFire. Returns an empty promise fulfilled when the key has been removed. + * + * If the provided key is not in this GeoFire, the promise will still successfully resolve. + * + * @param {string} key The key of the location to remove. + * @return {Promise.} A promise that is fulfilled after the inputted key is removed. + */ + this.remove = function(key) { + return this.set(key, null); + }; + + /** + * Returns a new GeoQuery instance with the provided queryCriteria. + * + * @param {Object} queryCriteria The criteria which specifies the GeoQuery's center and radius. + * @return {GeoQuery} A new GeoQuery object. + */ + this.query = function(queryCriteria) { + return new GeoQuery(_firebaseRef, queryCriteria); + }; + + /*****************/ + /* CONSTRUCTOR */ + /*****************/ + if (Object.prototype.toString.call(firebaseRef) !== "[object Object]") { + throw new Error("firebaseRef must be an instance of Firebase"); + } + + var _firebaseRef = firebaseRef; +}; + +/** + * Static method which calculates the distance, in kilometers, between two locations, + * via the Haversine formula. Note that this is approximate due to the fact that the + * Earth's radius varies between 6356.752 km and 6378.137 km. + * + * @param {Array.} location1 The [latitude, longitude] pair of the first location. + * @param {Array.} location2 The [latitude, longitude] pair of the second location. + * @return {number} The distance, in kilometers, between the inputted locations. + */ +GeoFire.distance = function(location1, location2) { + validateLocation(location1); + validateLocation(location2); + + var radius = 6371; // Earth's radius in kilometers + var latDelta = degreesToRadians(location2[0] - location1[0]); + var lonDelta = degreesToRadians(location2[1] - location1[1]); + + var a = (Math.sin(latDelta / 2) * Math.sin(latDelta / 2)) + + (Math.cos(degreesToRadians(location1[0])) * Math.cos(degreesToRadians(location2[0])) * + Math.sin(lonDelta / 2) * Math.sin(lonDelta / 2)); + + var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + return radius * c; +}; + +// Default geohash length +var g_GEOHASH_PRECISION = 10; + +// Characters used in location geohashes +var g_BASE32 = "0123456789bcdefghjkmnpqrstuvwxyz"; + +// The meridional circumference of the earth in meters +var g_EARTH_MERI_CIRCUMFERENCE = 40007860; + +// Length of a degree latitude at the equator +var g_METERS_PER_DEGREE_LATITUDE = 110574; + +// Number of bits per geohash character +var g_BITS_PER_CHAR = 5; + +// Maximum length of a geohash in bits +var g_MAXIMUM_BITS_PRECISION = 22*g_BITS_PER_CHAR; + +// Equatorial radius of the earth in meters +var g_EARTH_EQ_RADIUS = 6378137.0; + +// The following value assumes a polar radius of +// var g_EARTH_POL_RADIUS = 6356752.3; +// The formulate to calculate g_E2 is +// g_E2 == (g_EARTH_EQ_RADIUS^2-g_EARTH_POL_RADIUS^2)/(g_EARTH_EQ_RADIUS^2) +// The exact value is used here to avoid rounding errors +var g_E2 = 0.00669447819799; + +// Cutoff for rounding errors on double calculations +var g_EPSILON = 1e-12; + +Math.log2 = Math.log2 || function(x) { + return Math.log(x)/Math.log(2); +}; + +/** + * Validates the inputted key and throws an error if it is invalid. + * + * @param {string} key The key to be verified. + */ +var validateKey = function(key) { + var error; + + if (typeof key !== "string") { + error = "key must be a string"; + } + else if (key.length === 0) { + error = "key cannot be the empty string"; + } + else if (1 + g_GEOHASH_PRECISION + key.length > 755) { + // Firebase can only stored child paths up to 768 characters + // The child path for this key is at the least: "i/key" + error = "key is too long to be stored in Firebase"; + } + else if (/[\[\].#$\/\u0000-\u001F\u007F]/.test(key)) { + // Firebase does not allow node keys to contain the following characters + error = "key cannot contain any of the following characters: . # $ ] [ /"; + } + + if (typeof error !== "undefined") { + throw new Error("Invalid GeoFire key '" + key + "': " + error); + } +}; + +/** + * Validates the inputted location and throws an error if it is invalid. + * + * @param {Array.} location The [latitude, longitude] pair to be verified. + */ +var validateLocation = function(location) { + var error; + + if (!Array.isArray(location)) { + error = "location must be an array"; + } + else if (location.length !== 2) { + error = "expected array of length 2, got length " + location.length; + } + else { + var latitude = location[0]; + var longitude = location[1]; + + if (typeof latitude !== "number" || isNaN(latitude)) { + error = "latitude must be a number"; + } + else if (latitude < -90 || latitude > 90) { + error = "latitude must be within the range [-90, 90]"; + } + else if (typeof longitude !== "number" || isNaN(longitude)) { + error = "longitude must be a number"; + } + else if (longitude < -180 || longitude > 180) { + error = "longitude must be within the range [-180, 180]"; + } + } + + if (typeof error !== "undefined") { + throw new Error("Invalid GeoFire location '" + location + "': " + error); + } +}; + +/** + * Validates the inputted geohash and throws an error if it is invalid. + * + * @param {string} geohash The geohash to be validated. + */ +var validateGeohash = function(geohash) { + var error; + + if (typeof geohash !== "string") { + error = "geohash must be a string"; + } + else if (geohash.length === 0) { + error = "geohash cannot be the empty string"; + } + else { + for (var i = 0, length = geohash.length; i < length; ++i) { + if (g_BASE32.indexOf(geohash[i]) === -1) { + error = "geohash cannot contain \"" + geohash[i] + "\""; + } + } + } + + if (typeof error !== "undefined") { + throw new Error("Invalid GeoFire geohash '" + geohash + "': " + error); + } +}; + +/** + * Validates the inputted query criteria and throws an error if it is invalid. + * + * @param {Object} newQueryCriteria The criteria which specifies the query's center and/or radius. + */ +var validateCriteria = function(newQueryCriteria, requireCenterAndRadius) { + if (typeof newQueryCriteria !== "object") { + throw new Error("query criteria must be an object"); + } + else if (typeof newQueryCriteria.center === "undefined" && typeof newQueryCriteria.radius === "undefined") { + throw new Error("radius and/or center must be specified"); + } + else if (requireCenterAndRadius && (typeof newQueryCriteria.center === "undefined" || typeof newQueryCriteria.radius === "undefined")) { + throw new Error("query criteria for a new query must contain both a center and a radius"); + } + + // Throw an error if there are any extraneous attributes + var keys = Object.keys(newQueryCriteria); + var numKeys = keys.length; + for (var i = 0; i < numKeys; ++i) { + var key = keys[i]; + if (key !== "center" && key !== "radius") { + throw new Error("Unexpected attribute '" + key + "'' found in query criteria"); + } + } + + // Validate the "center" attribute + if (typeof newQueryCriteria.center !== "undefined") { + validateLocation(newQueryCriteria.center); + } + + // Validate the "radius" attribute + if (typeof newQueryCriteria.radius !== "undefined") { + if (typeof newQueryCriteria.radius !== "number" || isNaN(newQueryCriteria.radius)) { + throw new Error("radius must be a number"); + } + else if (newQueryCriteria.radius < 0) { + throw new Error("radius must be greater than or equal to 0"); + } + } +}; + +/** + * Converts degrees to radians. + * + * @param {number} degrees The number of degrees to be converted to radians. + * @return {number} The number of radians equal to the inputted number of degrees. + */ +var degreesToRadians = function(degrees) { + if (typeof degrees !== "number" || isNaN(degrees)) { + throw new Error("Error: degrees must be a number"); + } + + return (degrees * Math.PI / 180); +}; + +/** + * Generates a geohash of the specified precision/string length from the [latitude, longitude] + * pair, specified as an array. + * + * @param {Array.} location The [latitude, longitude] pair to encode into a geohash. + * @param {number=} precision The length of the geohash to create. If no precision is + * specified, the global default is used. + * @return {string} The geohash of the inputted location. + */ +var encodeGeohash = function(location, precision) { + validateLocation(location); + if (typeof precision !== "undefined") { + if (typeof precision !== "number" || isNaN(precision)) { + throw new Error("precision must be a number"); + } + else if (precision <= 0) { + throw new Error("precision must be greater than 0"); + } + else if (precision > 22) { + throw new Error("precision cannot be greater than 22"); + } + else if (Math.round(precision) !== precision) { + throw new Error("precision must be an integer"); + } + } + + // Use the global precision default if no precision is specified + precision = precision || g_GEOHASH_PRECISION; + + var latitudeRange = { + min: -90, + max: 90 + }; + var longitudeRange = { + min: -180, + max: 180 + }; + var hash = ""; + var hashVal = 0; + var bits = 0; + var even = 1; + + while (hash.length < precision) { + var val = even ? location[1] : location[0]; + var range = even ? longitudeRange : latitudeRange; + var mid = (range.min + range.max) / 2; + + /* jshint -W016 */ + if (val > mid) { + hashVal = (hashVal << 1) + 1; + range.min = mid; + } + else { + hashVal = (hashVal << 1) + 0; + range.max = mid; + } + /* jshint +W016 */ + + even = !even; + if (bits < 4) { + bits++; + } + else { + bits = 0; + hash += g_BASE32[hashVal]; + hashVal = 0; + } + } + + return hash; +}; + +/** + * Calculates the number of degrees a given distance is at a given latitude. + * + * @param {number} distance The distance to convert. + * @param {number} latitude The latitude at which to calculate. + * @return {number} The number of degrees the distance corresponds to. + */ +var metersToLongitudeDegrees = function(distance, latitude) { + var radians = degreesToRadians(latitude); + var num = Math.cos(radians)*g_EARTH_EQ_RADIUS*Math.PI/180; + var denom = 1/Math.sqrt(1-g_E2*Math.sin(radians)*Math.sin(radians)); + var deltaDeg = num*denom; + if (deltaDeg < g_EPSILON) { + return distance > 0 ? 360 : 0; + } + else { + return Math.min(360, distance/deltaDeg); + } +}; + +/** + * Calculates the bits necessary to reach a given resolution, in meters, for the longitude at a + * given latitude. + * + * @param {number} resolution The desired resolution. + * @param {number} latitude The latitude used in the conversion. + * @return {number} The bits necessary to reach a given resolution, in meters. + */ +var longitudeBitsForResolution = function(resolution, latitude) { + var degs = metersToLongitudeDegrees(resolution, latitude); + return (Math.abs(degs) > 0.000001) ? Math.max(1, Math.log2(360/degs)) : 1; +}; + +/** + * Calculates the bits necessary to reach a given resolution, in meters, for the latitude. + * + * @param {number} resolution The bits necessary to reach a given resolution, in meters. + */ +var latitudeBitsForResolution = function(resolution) { + return Math.min(Math.log2(g_EARTH_MERI_CIRCUMFERENCE/2/resolution), g_MAXIMUM_BITS_PRECISION); +}; + +/** + * Wraps the longitude to [-180,180]. + * + * @param {number} longitude The longitude to wrap. + * @return {number} longitude The resulting longitude. + */ +var wrapLongitude = function(longitude) { + if (longitude <= 180 && longitude >= -180) { + return longitude; + } + var adjusted = longitude + 180; + if (adjusted > 0) { + return (adjusted % 360) - 180; + } + else { + return 180 - (-adjusted % 360); + } +}; + +/** + * Calculates the maximum number of bits of a geohash to get a bounding box that is larger than a + * given size at the given coordinate. + * + * @param {Array.} coordinate The coordinate as a [latitude, longitude] pair. + * @param {number} size The size of the bounding box. + * @return {number} The number of bits necessary for the geohash. + */ +var boundingBoxBits = function(coordinate, size) { + var latDeltaDegrees = size/g_METERS_PER_DEGREE_LATITUDE; + var latitudeNorth = Math.min(90, coordinate[0] + latDeltaDegrees); + var latitudeSouth = Math.max(-90, coordinate[0] - latDeltaDegrees); + var bitsLat = Math.floor(latitudeBitsForResolution(size))*2; + var bitsLongNorth = Math.floor(longitudeBitsForResolution(size, latitudeNorth))*2-1; + var bitsLongSouth = Math.floor(longitudeBitsForResolution(size, latitudeSouth))*2-1; + return Math.min(bitsLat, bitsLongNorth, bitsLongSouth, g_MAXIMUM_BITS_PRECISION); +}; + +/** + * Calculates eight points on the bounding box and the center of a given circle. At least one + * geohash of these nine coordinates, truncated to a precision of at most radius, are guaranteed + * to be prefixes of any geohash that lies within the circle. + * + * @param {Array.} center The center given as [latitude, longitude]. + * @param {number} radius The radius of the circle. + * @return {Array.>} The eight bounding box points. + */ +var boundingBoxCoordinates = function(center, radius) { + var latDegrees = radius/g_METERS_PER_DEGREE_LATITUDE; + var latitudeNorth = Math.min(90, center[0] + latDegrees); + var latitudeSouth = Math.max(-90, center[0] - latDegrees); + var longDegsNorth = metersToLongitudeDegrees(radius, latitudeNorth); + var longDegsSouth = metersToLongitudeDegrees(radius, latitudeSouth); + var longDegs = Math.max(longDegsNorth, longDegsSouth); + return [ + [center[0], center[1]], + [center[0], wrapLongitude(center[1] - longDegs)], + [center[0], wrapLongitude(center[1] + longDegs)], + [latitudeNorth, center[1]], + [latitudeNorth, wrapLongitude(center[1] - longDegs)], + [latitudeNorth, wrapLongitude(center[1] + longDegs)], + [latitudeSouth, center[1]], + [latitudeSouth, wrapLongitude(center[1] - longDegs)], + [latitudeSouth, wrapLongitude(center[1] + longDegs)] + ]; +}; + +/** + * Calculates the bounding box query for a geohash with x bits precision. + * + * @param {string} geohash The geohash whose bounding box query to generate. + * @param {number} bits The number of bits of precision. + * @return {Array.} A [start, end] pair of geohashes. + */ +var geohashQuery = function(geohash, bits) { + validateGeohash(geohash); + var precision = Math.ceil(bits/g_BITS_PER_CHAR); + if (geohash.length < precision) { + return [geohash, geohash+"~"]; + } + geohash = geohash.substring(0, precision); + var base = geohash.substring(0, geohash.length - 1); + var lastValue = g_BASE32.indexOf(geohash.charAt(geohash.length - 1)); + var significantBits = bits - (base.length*g_BITS_PER_CHAR); + var unusedBits = (g_BITS_PER_CHAR - significantBits); + /*jshint bitwise: false*/ + // delete unused bits + var startValue = (lastValue >> unusedBits) << unusedBits; + var endValue = startValue + (1 << unusedBits); + /*jshint bitwise: true*/ + if (endValue > 31) { + return [base+g_BASE32[startValue], base+"~"]; + } + else { + return [base+g_BASE32[startValue], base+g_BASE32[endValue]]; + } +}; + +/** + * Calculates a set of queries to fully contain a given circle. A query is a [start, end] pair + * where any geohash is guaranteed to be lexiographically larger then start and smaller than end. + * + * @param {Array.} center The center given as [latitude, longitude] pair. + * @param {number} radius The radius of the circle. + * @return {Array.>} An array of geohashes containing a [start, end] pair. + */ +var geohashQueries = function(center, radius) { + validateLocation(center); + var queryBits = Math.max(1, boundingBoxBits(center, radius)); + var geohashPrecision = Math.ceil(queryBits/g_BITS_PER_CHAR); + var coordinates = boundingBoxCoordinates(center, radius); + var queries = coordinates.map(function(coordinate) { + return geohashQuery(encodeGeohash(coordinate, geohashPrecision), queryBits); + }); + // remove duplicates + return queries.filter(function(query, index) { + return !queries.some(function(other, otherIndex) { + return index > otherIndex && query[0] === other[0] && query[1] === other[1]; + }); + }); +}; + +/** + * Encodes a location and geohash as a GeoFire object. + * + * @param {Array.} location The location as [latitude, longitude] pair. + * @param {string} geohash The geohash of the location. + * @return {Object} The location encoded as GeoFire object. + */ +function encodeGeoFireObject(location, geohash) { + validateLocation(location); + validateGeohash(geohash); + return { + ".priority": geohash, + "g": geohash, + "l": location + }; +} + +/** + * Decodes the location given as GeoFire object. Returns null if decoding fails. + * + * @param {Object} geoFireObj The location encoded as GeoFire object. + * @return {?Array.} location The location as [latitude, longitude] pair or null if + * decoding fails. + */ +function decodeGeoFireObject(geoFireObj) { + if (geoFireObj !== null && geoFireObj.hasOwnProperty("l") && Array.isArray(geoFireObj.l) && geoFireObj.l.length === 2) { + return geoFireObj.l; + } else { + throw new Error("Unexpected GeoFire location object encountered: " + JSON.stringify(geoFireObj)); + } +} + +/** + * Get the key of a Firebase snapshot across SDK versions + * + * @param {Object} snapshot A Firebase Snapshot + * @return {String} key The Firebase snapshot's key + */ + function getKey(snapshot) { + var key; + if (typeof snapshot.key === "function") { + key = snapshot.key(); + } else if (typeof snapshot.key === "string") { + key = snapshot.key; + } else { + key = snapshot.name(); + } + return key; + } + +/** + * Creates a GeoQuery instance. + * + * @constructor + * @this {GeoQuery} + * @param {Firebase} firebaseRef A Firebase reference. + * @param {Object} queryCriteria The criteria which specifies the query's center and radius. + */ +var GeoQuery = function (firebaseRef, queryCriteria) { + /*********************/ + /* PRIVATE METHODS */ + /*********************/ + /** + * Fires each callback for the provided eventType, passing it provided key's data. + * + * @param {string} eventType The event type whose callbacks to fire. One of "key_entered", "key_exited", or "key_moved". + * @param {string} key The key of the location for which to fire the callbacks. + * @param {?Array.} location The location as [latitude, longitude] pair + * @param {?double} distanceFromCenter The distance from the center or null. + */ + function _fireCallbacksForKey(eventType, key, location, distanceFromCenter) { + _callbacks[eventType].forEach(function(callback) { + if (typeof location === "undefined" || location === null) { + callback(key, null, null); + } + else { + callback(key, location, distanceFromCenter); + } + }); + } + + /** + * Fires each callback for the "ready" event. + */ + function _fireReadyEventCallbacks() { + _callbacks.ready.forEach(function(callback) { + callback(); + }); + } + + /** + * Decodes a query string to a query + * + * @param {string} str The encoded query. + * @return {Array.} The decoded query as a [start, end] pair. + */ + function _stringToQuery(string) { + var decoded = string.split(":"); + if (decoded.length !== 2) { + throw new Error("Invalid internal state! Not a valid geohash query: " + string); + } + return decoded; + } + + /** + * Encodes a query as a string for easier indexing and equality. + * + * @param {Array.} query The query to encode. + * @param {string} The encoded query as string. + */ + function _queryToString(query) { + if (query.length !== 2) { + throw new Error("Not a valid geohash query: " + query); + } + return query[0]+":"+query[1]; + } + + /** + * Turns off all callbacks for the provide geohash query. + * + * @param {Array.} query The geohash query. + * @param {Object} queryState An object storing the current state of the query. + */ + function _cancelGeohashQuery(query, queryState) { + var queryRef = _firebaseRef.orderByChild("g").startAt(query[0]).endAt(query[1]); + queryRef.off("child_added", queryState.childAddedCallback); + queryRef.off("child_removed", queryState.childRemovedCallback); + queryRef.off("child_changed", queryState.childChangedCallback); + queryRef.off("value", queryState.valueCallback); + } + + /** + * Removes unnecessary Firebase queries which are currently being queried. + */ + function _cleanUpCurrentGeohashesQueried() { + var keys = Object.keys(_currentGeohashesQueried); + var numKeys = keys.length; + for (var i = 0; i < numKeys; ++i) { + var geohashQueryStr = keys[i]; + var queryState = _currentGeohashesQueried[geohashQueryStr]; + if (queryState.active === false) { + var query = _stringToQuery(geohashQueryStr); + // Delete the geohash since it should no longer be queried + _cancelGeohashQuery(query, queryState); + delete _currentGeohashesQueried[geohashQueryStr]; + } + } + + // Delete each location which should no longer be queried + keys = Object.keys(_locationsTracked); + numKeys = keys.length; + for (i = 0; i < numKeys; ++i) { + var key = keys[i]; + if (!_geohashInSomeQuery(_locationsTracked[key].geohash)) { + if (_locationsTracked[key].isInQuery) { + throw new Error("Internal State error, trying to remove location that is still in query"); + } + delete _locationsTracked[key]; + } + } + + // Specify that this is done cleaning up the current geohashes queried + _geohashCleanupScheduled = false; + + // Cancel any outstanding scheduled cleanup + if (_cleanUpCurrentGeohashesQueriedTimeout !== null) { + clearTimeout(_cleanUpCurrentGeohashesQueriedTimeout); + _cleanUpCurrentGeohashesQueriedTimeout = null; + } + } + + /** + * Callback for any updates to locations. Will update the information about a key and fire any necessary + * events every time the key's location changes. + * + * When a key is removed from GeoFire or the query, this function will be called with null and performs + * any necessary cleanup. + * + * @param {string} key The key of the geofire location. + * @param {?Array.} location The location as [latitude, longitude] pair. + */ + function _updateLocation(key, location) { + validateLocation(location); + // Get the key and location + var distanceFromCenter, isInQuery; + var wasInQuery = (_locationsTracked.hasOwnProperty(key)) ? _locationsTracked[key].isInQuery : false; + var oldLocation = (_locationsTracked.hasOwnProperty(key)) ? _locationsTracked[key].location : null; + + // Determine if the location is within this query + distanceFromCenter = GeoFire.distance(location, _center); + isInQuery = (distanceFromCenter <= _radius); + + // Add this location to the locations queried dictionary even if it is not within this query + _locationsTracked[key] = { + location: location, + distanceFromCenter: distanceFromCenter, + isInQuery: isInQuery, + geohash: encodeGeohash(location, g_GEOHASH_PRECISION) + }; + + // Fire the "key_entered" event if the provided key has entered this query + if (isInQuery && !wasInQuery) { + _fireCallbacksForKey("key_entered", key, location, distanceFromCenter); + } else if (isInQuery && oldLocation !== null && (location[0] !== oldLocation[0] || location[1] !== oldLocation[1])) { + _fireCallbacksForKey("key_moved", key, location, distanceFromCenter); + } else if (!isInQuery && wasInQuery) { + _fireCallbacksForKey("key_exited", key, location, distanceFromCenter); + } + } + + /** + * Checks if this geohash is currently part of any of the geohash queries. + * + * @param {string} geohash The geohash. + * @param {boolean} Returns true if the geohash is part of any of the current geohash queries. + */ + function _geohashInSomeQuery(geohash) { + var keys = Object.keys(_currentGeohashesQueried); + var numKeys = keys.length; + for (var i = 0; i < numKeys; ++i) { + var queryStr = keys[i]; + if (_currentGeohashesQueried.hasOwnProperty(queryStr)) { + var query = _stringToQuery(queryStr); + if (geohash >= query[0] && geohash <= query[1]) { + return true; + } + } + } + return false; + } + + /** + * Removes the location from the local state and fires any events if necessary. + * + * @param {string} key The key to be removed. + * @param {?Array.} currentLocation The current location as [latitude, longitude] pair + * or null if removed. + */ + function _removeLocation(key, currentLocation) { + var locationDict = _locationsTracked[key]; + delete _locationsTracked[key]; + if (typeof locationDict !== "undefined" && locationDict.isInQuery) { + var distanceFromCenter = (currentLocation) ? GeoFire.distance(currentLocation, _center) : null; + _fireCallbacksForKey("key_exited", key, currentLocation, distanceFromCenter); + } + } + + /** + * Callback for child added events. + * + * @param {Firebase DataSnapshot} locationDataSnapshot A snapshot of the data stored for this location. + */ + function _childAddedCallback(locationDataSnapshot) { + _updateLocation(getKey(locationDataSnapshot), decodeGeoFireObject(locationDataSnapshot.val())); + } + + /** + * Callback for child changed events + * + * @param {Firebase DataSnapshot} locationDataSnapshot A snapshot of the data stored for this location. + */ + function _childChangedCallback(locationDataSnapshot) { + _updateLocation(getKey(locationDataSnapshot), decodeGeoFireObject(locationDataSnapshot.val())); + } + + /** + * Callback for child removed events + * + * @param {Firebase DataSnapshot} locationDataSnapshot A snapshot of the data stored for this location. + */ + function _childRemovedCallback(locationDataSnapshot) { + // edit by rex.rainbow + var key = getKey(locationDataSnapshot); + var preLocation = decodeGeoFireObject(locationDataSnapshot.val()); + if (_locationsTracked.hasOwnProperty(key)) { + _firebaseRef.child(key).once("value", function(snapshot) { + var location = snapshot.val() === null ? null : decodeGeoFireObject(snapshot.val()); + var geohash = (location !== null) ? encodeGeohash(location) : null; + // Only notify observers if key is not part of any other geohash query or this actually might not be + // a key exited event, but a key moved or entered event. These events will be triggered by updates + // to a different query + // edit by rex.rainbow + if (geohash === null) { + _removeLocation(key, preLocation); + } + // edit by rex.rainbow + else if (!_geohashInSomeQuery(geohash)) { + _removeLocation(key, location); + } + }); + } + } + + /** + * Called once all geohash queries have received all child added events and fires the ready + * event if necessary. + */ + function _geohashQueryReadyCallback(queryStr) { + var index = _outstandingGeohashReadyEvents.indexOf(queryStr); + if (index > -1) { + _outstandingGeohashReadyEvents.splice(index, 1); + } + _valueEventFired = (_outstandingGeohashReadyEvents.length === 0); + + // If all queries have been processed, fire the ready event + if (_valueEventFired) { + _fireReadyEventCallbacks(); + } + } + + /** + * Attaches listeners to Firebase which track when new geohashes are added within this query's + * bounding box. + */ + function _listenForNewGeohashes() { + // Get the list of geohashes to query + var geohashesToQuery = geohashQueries(_center, _radius*1000).map(_queryToString); + + // Filter out duplicate geohashes + geohashesToQuery = geohashesToQuery.filter(function(geohash, i){ + return geohashesToQuery.indexOf(geohash) === i; + }); + + // For all of the geohashes that we are already currently querying, check if they are still + // supposed to be queried. If so, don't re-query them. Otherwise, mark them to be un-queried + // next time we clean up the current geohashes queried dictionary. + var keys = Object.keys(_currentGeohashesQueried); + var numKeys = keys.length; + for (var i = 0; i < numKeys; ++i) { + var geohashQueryStr = keys[i]; + var index = geohashesToQuery.indexOf(geohashQueryStr); + if (index === -1) { + _currentGeohashesQueried[geohashQueryStr].active = false; + } + else { + _currentGeohashesQueried[geohashQueryStr].active = true; + geohashesToQuery.splice(index, 1); + } + } + + // If we are not already cleaning up the current geohashes queried and we have more than 25 of them, + // kick off a timeout to clean them up so we don't create an infinite number of unneeded queries. + if (_geohashCleanupScheduled === false && Object.keys(_currentGeohashesQueried).length > 25) { + _geohashCleanupScheduled = true; + _cleanUpCurrentGeohashesQueriedTimeout = setTimeout(_cleanUpCurrentGeohashesQueried, 10); + } + + // Keep track of which geohashes have been processed so we know when to fire the "ready" event + _outstandingGeohashReadyEvents = geohashesToQuery.slice(); + + // Loop through each geohash to query for and listen for new geohashes which have the same prefix. + // For every match, attach a value callback which will fire the appropriate events. + // Once every geohash to query is processed, fire the "ready" event. + geohashesToQuery.forEach(function(toQueryStr) { + // decode the geohash query string + var query = _stringToQuery(toQueryStr); + + // Create the Firebase query + var firebaseQuery = _firebaseRef.orderByChild("g").startAt(query[0]).endAt(query[1]); + + // For every new matching geohash, determine if we should fire the "key_entered" event + var childAddedCallback = firebaseQuery.on("child_added", _childAddedCallback); + var childRemovedCallback = firebaseQuery.on("child_removed", _childRemovedCallback); + var childChangedCallback = firebaseQuery.on("child_changed", _childChangedCallback); + + // Once the current geohash to query is processed, see if it is the last one to be processed + // and, if so, mark the value event as fired. + // Note that Firebase fires the "value" event after every "child_added" event fires. + var valueCallback = firebaseQuery.on("value", function() { + firebaseQuery.off("value", valueCallback); + _geohashQueryReadyCallback(toQueryStr); + }); + + // Add the geohash query to the current geohashes queried dictionary and save its state + _currentGeohashesQueried[toQueryStr] = { + active: true, + childAddedCallback: childAddedCallback, + childRemovedCallback: childRemovedCallback, + childChangedCallback: childChangedCallback, + valueCallback: valueCallback + }; + }); + // Based upon the algorithm to calculate geohashes, it's possible that no "new" + // geohashes were queried even if the client updates the radius of the query. + // This results in no "READY" event being fired after the .updateQuery() call. + // Check to see if this is the case, and trigger the "READY" event. + if(geohashesToQuery.length === 0) { + _geohashQueryReadyCallback(); + } + } + + /********************/ + /* PUBLIC METHODS */ + /********************/ + /** + * Returns the location signifying the center of this query. + * + * @return {Array.} The [latitude, longitude] pair signifying the center of this query. + */ + this.center = function() { + return _center; + }; + + /** + * Returns the radius of this query, in kilometers. + * + * @return {number} The radius of this query, in kilometers. + */ + this.radius = function() { + return _radius; + }; + + /** + * Updates the criteria for this query. + * + * @param {Object} newQueryCriteria The criteria which specifies the query's center and radius. + */ + this.updateCriteria = function(newQueryCriteria) { + // Validate and save the new query criteria + validateCriteria(newQueryCriteria); + _center = newQueryCriteria.center || _center; + _radius = newQueryCriteria.radius || _radius; + + // Loop through all of the locations in the query, update their distance from the center of the + // query, and fire any appropriate events + var keys = Object.keys(_locationsTracked); + var numKeys = keys.length; + for (var i = 0; i < numKeys; ++i) { + var key = keys[i]; + + // Get the cached information for this location + var locationDict = _locationsTracked[key]; + + // Save if the location was already in the query + var wasAlreadyInQuery = locationDict.isInQuery; + + // Update the location's distance to the new query center + locationDict.distanceFromCenter = GeoFire.distance(locationDict.location, _center); + + // Determine if the location is now in this query + locationDict.isInQuery = (locationDict.distanceFromCenter <= _radius); + + // If the location just left the query, fire the "key_exited" callbacks + if (wasAlreadyInQuery && !locationDict.isInQuery) { + _fireCallbacksForKey("key_exited", key, locationDict.location, locationDict.distanceFromCenter); + } + + // If the location just entered the query, fire the "key_entered" callbacks + else if (!wasAlreadyInQuery && locationDict.isInQuery) { + _fireCallbacksForKey("key_entered", key, locationDict.location, locationDict.distanceFromCenter); + } + } + + // Reset the variables which control when the "ready" event fires + _valueEventFired = false; + + // Listen for new geohashes being added to GeoFire and fire the appropriate events + _listenForNewGeohashes(); + }; + + /** + * Attaches a callback to this query which will be run when the provided eventType fires. Valid eventType + * values are "ready", "key_entered", "key_exited", and "key_moved". The ready event callback is passed no + * parameters. All other callbacks will be passed three parameters: (1) the location's key, (2) the location's + * [latitude, longitude] pair, and (3) the distance, in kilometers, from the location to this query's center + * + * "ready" is used to signify that this query has loaded its initial state and is up-to-date with its corresponding + * GeoFire instance. "ready" fires when this query has loaded all of the initial data from GeoFire and fired all + * other events for that data. It also fires every time updateQuery() is called, after all other events have + * fired for the updated query. + * + * "key_entered" fires when a key enters this query. This can happen when a key moves from a location outside of + * this query to one inside of it or when a key is written to GeoFire for the first time and it falls within + * this query. + * + * "key_exited" fires when a key moves from a location inside of this query to one outside of it. If the key was + * entirely removed from GeoFire, both the location and distance passed to the callback will be null. + * + * "key_moved" fires when a key which is already in this query moves to another location inside of it. + * + * Returns a GeoCallbackRegistration which can be used to cancel the callback. You can add as many callbacks + * as you would like for the same eventType by repeatedly calling on(). Each one will get called when its + * corresponding eventType fires. Each callback must be cancelled individually. + * + * @param {string} eventType The event type for which to attach the callback. One of "ready", "key_entered", + * "key_exited", or "key_moved". + * @callback callback Callback function to be called when an event of type eventType fires. + * @return {GeoCallbackRegistration} A callback registration which can be used to cancel the provided callback. + */ + this.on = function(eventType, callback) { + // Validate the inputs + if (["ready", "key_entered", "key_exited", "key_moved"].indexOf(eventType) === -1) { + throw new Error("event type must be \"ready\", \"key_entered\", \"key_exited\", or \"key_moved\""); + } + if (typeof callback !== "function") { + throw new Error("callback must be a function"); + } + + // Add the callback to this query's callbacks list + _callbacks[eventType].push(callback); + + // If this is a "key_entered" callback, fire it for every location already within this query + if (eventType === "key_entered") { + var keys = Object.keys(_locationsTracked); + var numKeys = keys.length; + for (var i = 0; i < numKeys; ++i) { + var key = keys[i]; + var locationDict = _locationsTracked[key]; + if (typeof locationDict !== "undefined" && locationDict.isInQuery) { + callback(key, locationDict.location, locationDict.distanceFromCenter); + } + } + } + + // If this is a "ready" callback, fire it if this query is already ready + if (eventType === "ready") { + if (_valueEventFired) { + callback(); + } + } + + // Return an event registration which can be used to cancel the callback + return new GeoCallbackRegistration(function() { + _callbacks[eventType].splice(_callbacks[eventType].indexOf(callback), 1); + }); + }; + + /** + * Terminates this query so that it no longer sends location updates. All callbacks attached to this + * query via on() will be cancelled. This query can no longer be used in the future. + */ + this.cancel = function () { + // Cancel all callbacks in this query's callback list + _callbacks = { + ready: [], + key_entered: [], + key_exited: [], + key_moved: [] + }; + + // Turn off all Firebase listeners for the current geohashes being queried + var keys = Object.keys(_currentGeohashesQueried); + var numKeys = keys.length; + for (var i = 0; i < numKeys; ++i) { + var geohashQueryStr = keys[i]; + var query = _stringToQuery(geohashQueryStr); + _cancelGeohashQuery(query, _currentGeohashesQueried[geohashQueryStr]); + delete _currentGeohashesQueried[geohashQueryStr]; + } + + // Delete any stored locations + _locationsTracked = {}; + + // Turn off the current geohashes queried clean up interval + clearInterval(_cleanUpCurrentGeohashesQueriedInterval); + }; + + + /*****************/ + /* CONSTRUCTOR */ + /*****************/ + // Firebase reference of the GeoFire which created this query + if (Object.prototype.toString.call(firebaseRef) !== "[object Object]") { + throw new Error("firebaseRef must be an instance of Firebase"); + } + var _firebaseRef = firebaseRef; + + // Event callbacks + var _callbacks = { + ready: [], + key_entered: [], + key_exited: [], + key_moved: [] + }; + + // Variables used to keep track of when to fire the "ready" event + var _valueEventFired = false; + var _outstandingGeohashReadyEvents; + + // A dictionary of locations that a currently active in the queries + // Note that not all of these are currently within this query + var _locationsTracked = {}; + + // A dictionary of geohash queries which currently have an active callbacks + var _currentGeohashesQueried = {}; + + // Every ten seconds, clean up the geohashes we are currently querying for. We keep these around + // for a little while since it's likely that they will need to be re-queried shortly after they + // move outside of the query's bounding box. + var _geohashCleanupScheduled = false; + var _cleanUpCurrentGeohashesQueriedTimeout = null; + var _cleanUpCurrentGeohashesQueriedInterval = setInterval(function() { + if (_geohashCleanupScheduled === false) { + _cleanUpCurrentGeohashesQueried(); + } + }, 10000); + + // Validate and save the query criteria + validateCriteria(queryCriteria, /* requireCenterAndRadius */ true); + var _center = queryCriteria.center; + var _radius = queryCriteria.radius; + + // Listen for new geohashes being added around this query and fire the appropriate events + _listenForNewGeohashes(); +}; + + return GeoFire; +})(); + +// Export GeoFire if this is being run in node +if (typeof module !== "undefined" && typeof process !== "undefined") { + module.exports = GeoFire; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/icon.png new file mode 100755 index 0000000..3003b89 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/instance.js new file mode 100755 index 0000000..be89906 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Geofire; + + PLUGIN_CLASS.Instance = class Rex_Firebase_GeofireInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/lang/en-US.json new file mode 100755 index 0000000..7c4a8b2 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/lang/en-US.json @@ -0,0 +1,217 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Geofire.", + "text": { + "plugins": { + "rex_firebase_geofire": { + "name": "Geofire", + "description": "Realtime location queries with Firebase.", + "help-url": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_geofire.html", + "properties": { + "sub-domain": { + "name": "Sub domain", + "desc": "Sub domain for this function." + } + }, + "aceCategories": { + "domain": "Domain", + "set": "Set", + "on_disconnected": "On disconnected", + "get": "Get", + "monitor": "Monitor", + "ıtemıd": "ItemID", + "event": "Event", + "monitor_area": "Monitor area", + "for_each": "For Each", + "helper": "Helper" + }, + "conditions": { + "onupdatecomplete1": { + "list-name": "On update", + "display-text": "On update", + "description": "Triggered when update location complete." + }, + "onupdateerror2": { + "list-name": "On update error", + "display-text": "On update error", + "description": "Triggered when update location error." + }, + "ongetıtemcomplete3": { + "list-name": "On get item", + "display-text": "On get item", + "description": "Triggered when get item." + }, + "ongetıtemerror4": { + "list-name": "On get item error", + "display-text": "On get item error", + "description": "Triggered when get item error." + }, + "ısıtemnotfound5": { + "list-name": "Item is not found", + "display-text": "Item is not found", + "description": "Return true if item is not found." + }, + "onıtementered11": { + "list-name": "On item entered", + "display-text": "On item entered", + "description": "Triggered when item entered." + }, + "onıtemexisted12": { + "list-name": "On item exited", + "display-text": "On item exited", + "description": "Triggered when item exited." + }, + "onıtemmoved13": { + "list-name": "On item moved", + "display-text": "On item moved", + "description": "Triggered when item moved." + }, + "onready14": { + "list-name": "On initial ready", + "display-text": "On initial ready", + "description": "Triggered when initial data has loaded and fired all other events." + }, + "foreachıtemıd15": { + "list-name": "For each itemID", + "display-text": "For each itemID [i]{0}[/i]", + "description": "Repeat the event for each itemID of monitor result.", + "params": { + "order4": { "name":"Order", "desc":"Order of itemID.", "items":{"descending":"descending","ascending":"ascending","logical descending":"logical descending","logical ascending":"logical ascending"}} + } + } + }, + "actions": { + "setsubdomainref0": { + "list-name": "Set sub domain", + "display-text": "Set sub domain to [i]{0}[/i]", + "description": "Set sub domain ref.", + "params": { + "sub_domain0": { "name":"Sub domain", "desc":"Sub domain for this function."} + } + }, + "setlocation1": { + "list-name": "Set location", + "display-text": "Set location of item [i]{0}[/i] to latitude-longitude ( [i]{1}[/i] , [i]{2}[/i] )", + "description": "Set location of an item.", + "params": { + "ıd0": { "name":"ID", "desc":"ItemID."}, + "latitude1": { "name":"Latitude", "desc":"Latitude."}, + "longitude2": { "name":"Longitude", "desc":"Longitude."} + } + }, + "ondisconnectedremove2": { + "list-name": "Remove item", + "display-text": "On disconnected- remove item [i]{0}[/i]", + "description": "Remove item on disconnected.", + "params": { + "ıd0": { "name":"ID", "desc":"ItemID."} + } + }, + "removeıtem3": { + "list-name": "Remove item", + "display-text": "Remove item [i]{0}[/i]", + "description": "Remove item.", + "params": { + "ıd0": { "name":"ID", "desc":"ItemID."} + } + }, + "getıtem4": { + "list-name": "Get item", + "display-text": "Get item [i]{0}[/i]", + "description": "Get item.", + "params": { + "ıd0": { "name":"ID", "desc":"ItemID."} + } + }, + "ondisconnectedcancel5": { + "list-name": "Cancel all handlers", + "display-text": "On disconnected- cancel all handlers {0}", + "description": "Cancel all handlers of disconnected.", + "params": { + "ıd0": { "name":"ID", "desc":"ItemID."} + } + }, + "monitorat11": { + "list-name": "Monitor at", + "display-text": "Monitor at latitude-longitude ( [i]{0}[/i] , [i]{1}[/i] ) with radius to [i]{2}[/i]", + "description": "Monitor an area", + "params": { + "latitude0": { "name":"Latitude", "desc":"Latitude of center."}, + "longitude1": { "name":"Longitude", "desc":"Longitude of center."}, + "radius2": { "name":"Radius", "desc":"Radius, in kilometers, from the center of this monitor in which to include results."} + } + }, + "monitorstop12": { + "list-name": "Stop", + "display-text": "Stop monitor", + "description": "Stop monitor" + } + }, + "expressions": { + "generatekey1": { + "description": "Generate new key from push action.", + "translated-name": "GenerateKey" + }, + "lastgeneratedkey2": { + "description": "Get last generate a key from push action.", + "translated-name": "LastGeneratedKey" + }, + "lastıtemıd11": { + "description": "Get itemID returned by the last triggered event.", + "translated-name": "LastItemID" + }, + "lastlatitude12": { + "description": "Get latitude returned by the last triggered event.", + "translated-name": "LastLatitude" + }, + "lastlongitude13": { + "description": "Get longitude returned by the last triggered event.", + "translated-name": "LastLongitude" + }, + "lastdistance14": { + "description": "Get distance between triggered item to monitor point returned by the last triggered event.", + "translated-name": "LastDistance" + }, + "monitorlatitude21": { + "description": "Get latitude of monitor center.", + "translated-name": "MonitorLatitude" + }, + "monitorlongitude22": { + "description": "Get longitude of monitor center.", + "translated-name": "MonitorLongitude" + }, + "monitorradius23": { + "description": "Get radius of monitor, in kilometers.", + "translated-name": "MonitorRadius" + }, + "curıtemıd31": { + "description": "Get current itemID in a For Each loop.", + "translated-name": "CurItemID" + }, + "curlatitude32": { + "description": "Get current latitude in a For Each loop.", + "translated-name": "CurLatitude" + }, + "curlongitude33": { + "description": "Get current longitude in a For Each loop.", + "translated-name": "CurLongitude" + }, + "curdistance34": { + "description": "Get current distance between triggered item to monitor point in a For Each loop.", + "translated-name": "CurDistance" + }, + "distance51": { + "description": "Get distance between two points, in kilometers.", + "translated-name": "Distance", + "params": { + "latitude_a0": { "name":"Latitude A", "desc":"Latitude of point A."}, + "longitude_a1": { "name":"Longitude A", "desc":"Longitude of point A."}, + "latitude_b2": { "name":"Latitude B", "desc":"Latitude of point B."}, + "longitude_b3": { "name":"Longitude B", "desc":"Longitude of point B."} + } + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/plugin.js new file mode 100755 index 0000000..34a8c4d --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/plugin.js @@ -0,0 +1,45 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase_Geofire"; + const PLUGIN_VERSION = "0.1.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Geofire = class Rex_Firebase_Geofire extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "sub-domain", "Geo") + ]); + this._info.AddFileDependency({ + filename: "geofire.js", + type: "external-script" + }); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/type.js new file mode 100755 index 0000000..7fd96b5 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_geofire/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Geofire; + + PLUGIN_CLASS.Type = class Rex_Firebase_GeofireType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/dist/rex_firebase_itembook.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/dist/rex_firebase_itembook.c3addon new file mode 100644 index 0000000..6a95420 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/dist/rex_firebase_itembook.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/aces.json new file mode 100755 index 0000000..3296a3e --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/aces.json @@ -0,0 +1,692 @@ +{ + "domain": { + "conditions": [ + ], + "actions": [ + { + "c2id": 0, + "id": "setsubdomainref0", + "scriptName": "SetSubDomainRef", + "highlight": false, + "params": [ + {"id":"sub_domain0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "prepare_-_tree": { + "conditions": [ + ], + "actions": [ + { + "c2id": 1, + "id": "treesetvalue1", + "scriptName": "TreeSetValue", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""}, + {"id":"value1", "type":"any", "initialValue":"0"} + ] + }, + { + "c2id": 2, + "id": "treesetbooleanvalue2", + "scriptName": "TreeSetBooleanValue", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""}, + {"id":"boolean3", "type":"combo", "items":["false","true"]} + ] + }, + { + "c2id": 3, + "id": "treesetnullvalue3", + "scriptName": "TreeSetNullValue", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""} + ] + }, + { + "c2id": 4, + "id": "cleanall4", + "scriptName": "CleanAll", + "highlight": false + }, + { + "c2id": 5, + "id": "treesetservertimestamp5", + "scriptName": "TreeSetServerTimestamp", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""} + ] + }, + { + "c2id": 6, + "id": "treesetjson6", + "scriptName": "TreeSetJSON", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""}, + {"id":"json1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "save": { + "conditions": [ + { + "c2id": 11, + "id": "onupdatecomplete11", + "scriptName": "OnUpdateComplete", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 12, + "id": "onupdateerror12", + "scriptName": "OnUpdateError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 11, + "id": "updatebook11", + "scriptName": "UpdateBook", + "highlight": false + } + ], + "expressions": [ + ] + }, + "prepare_-_enumeration": { + "conditions": [ + ], + "actions": [ + { + "c2id": 21, + "id": "enumsetvalue21", + "scriptName": "EnumSetValue", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"key2", "type":"any", "initialValue":"\"\""}, + {"id":"value3", "type":"any", "initialValue":"0"} + ] + }, + { + "c2id": 22, + "id": "enumsetbooleanvalue22", + "scriptName": "EnumSetBooleanValue", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"key2", "type":"any", "initialValue":"\"\""}, + {"id":"boolean5", "type":"combo", "items":["false","true"]} + ] + }, + { + "c2id": 23, + "id": "enumsetnullvalue23", + "scriptName": "EnumSetNullValue", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"key2", "type":"any", "initialValue":"\"\""} + ] + }, + { + "c2id": 24, + "id": "enumsetservertimestamp24", + "scriptName": "EnumSetServerTimestamp", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"key2", "type":"any", "initialValue":"\"\""} + ] + }, + { + "c2id": 25, + "id": "enumsetjson25", + "scriptName": "EnumSetJSON", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"key2", "type":"any", "initialValue":"\"\""}, + {"id":"json3", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "on_disconnected_-_tree": { + "conditions": [ + { + "c2id": 3, + "id": "treeondisconnectedremove3", + "scriptName": "TreeOnDisconnectedRemove", + "isInvertible": "false", + "highlight": false + }, + { + "c2id": 4, + "id": "treeondisconnectedcancel4", + "scriptName": "TreeOnDisconnectedCancel", + "isInvertible": "false", + "highlight": false + } + ], + "actions": [ + { + "c2id": 31, + "id": "treeondisconnectedremove31", + "scriptName": "TreeOnDisconnectedRemove", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""} + ] + }, + { + "c2id": 32, + "id": "treeondisconnectedsetservertimestamp32", + "scriptName": "TreeOnDisconnectedSetServerTimestamp", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""} + ] + }, + { + "c2id": 33, + "id": "treeondisconnectedsetvalue33", + "scriptName": "TreeOnDisconnectedSetValue", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""}, + {"id":"value1", "type":"any", "initialValue":"0"} + ] + }, + { + "c2id": 34, + "id": "treeondisconnectedsetbooleanvalue34", + "scriptName": "TreeOnDisconnectedSetBooleanValue", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""}, + {"id":"boolean3", "type":"combo", "items":["false","true"]} + ] + }, + { + "c2id": 36, + "id": "treeondisconnectedcancel36", + "scriptName": "TreeOnDisconnectedCancel", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "on_disconnected_-_enumeration": { + "conditions": [ + ], + "actions": [ + { + "c2id": 41, + "id": "enumondisconnectedremove41", + "scriptName": "EnumOnDisconnectedRemove", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"key2", "type":"any", "initialValue":"\"\""} + ] + }, + { + "c2id": 42, + "id": "enumondisconnectedsetservertimestamp42", + "scriptName": "EnumOnDisconnectedSetServerTimestamp", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"key2", "type":"any", "initialValue":"\"\""} + ] + }, + { + "c2id": 43, + "id": "enumondisconnectedsetvalue43", + "scriptName": "EnumOnDisconnectedSetValue", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"key2", "type":"any", "initialValue":"\"\""}, + {"id":"value3", "type":"any", "initialValue":"0"} + ] + }, + { + "c2id": 44, + "id": "enumondisconnectedsetbooleanvalue44", + "scriptName": "EnumOnDisconnectedSetBooleanValue", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"key2", "type":"any", "initialValue":"\"\""}, + {"id":"boolean5", "type":"combo", "items":["false","true"]} + ] + }, + { + "c2id": 45, + "id": "enumondisconnectedsetjson45", + "scriptName": "EnumOnDisconnectedSetJSON", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"key2", "type":"any", "initialValue":"\"\""}, + {"id":"json3", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 46, + "id": "enumondisconnectedcancel46", + "scriptName": "EnumOnDisconnectedCancel", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"key2", "type":"any", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "load_-_signle_query": { + "conditions": [ + ], + "actions": [ + { + "c2id": 51, + "id": "getıtemsbysingleconditionınrange51", + "scriptName": "GetItemsBySingleConditionInRange", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"key1", "type":"any", "initialValue":"\"\""}, + {"id":"start2", "type":"any", "initialValue":"0"}, + {"id":"end3", "type":"any", "initialValue":"0"}, + {"id":"limit6", "type":"combo", "items":["limit to first","limit to last"]}, + {"id":"count7", "type":"number", "initialValue":"-1"}, + {"id":"tag8", "type":"string", "initialValue":"\"_\""} + ] + }, + { + "c2id": 52, + "id": "getıtemsbysinglecondition52", + "scriptName": "GetItemsBySingleCondition", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"key1", "type":"any", "initialValue":"\"\""}, + {"id":"comparison5", "type":"combo", "items":["equal to","greater than or equal to","less than or equal to"]}, + {"id":"value6", "type":"any", "initialValue":"0"}, + {"id":"limit9", "type":"combo", "items":["limit to first","limit to last"]}, + {"id":"count10", "type":"number", "initialValue":"-1"}, + {"id":"tag11", "type":"string", "initialValue":"\"_\""} + ] + } + ], + "expressions": [ + ] + }, + "load_-_table/item": { + "conditions": [ + ], + "actions": [ + { + "c2id": 53, + "id": "loadıtem53", + "scriptName": "LoadItem", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""}, + {"id":"tag2", "type":"string", "initialValue":"\"_\""} + ] + } + ], + "expressions": [ + ] + }, + "load_-_queue": { + "conditions": [ + ], + "actions": [ + { + "c2id": 81, + "id": "startqueue81", + "scriptName": "StartQueue", + "highlight": false, + "params": [ + {"id":"tag0", "type":"string", "initialValue":"\"_\""} + ] + }, + { + "c2id": 82, + "id": "processqueue82", + "scriptName": "ProcessQueue", + "highlight": false + } + ], + "expressions": [ + ] + }, + "load": { + "conditions": [ + { + "c2id": 52, + "id": "foreachıtemıd52", + "scriptName": "ForEachItemID", + "isLooping": "true", + "isInvertible": "false", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"order5", "type":"combo", "items":["descending","ascending","logical descending","logical ascending"]} + ] + }, + { + "c2id": 53, + "id": "foreachkey53", + "scriptName": "ForEachKey", + "isLooping": "true", + "isInvertible": "false", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"\""} + ] + }, + { + "c2id": 54, + "id": "tableısempty54", + "scriptName": "TableIsEmpty", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""} + ] + } + ], + "actions": [ + { + "c2id": 83, + "id": "cleanresulttable83", + "scriptName": "CleanResultTable", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + { + "c2id": 4, + "id": "lasttableıd4", + "expressionName": "LastTableID", + "scriptName": "LastTableID", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 5, + "id": "lastıtemıd5", + "expressionName": "LastItemID", + "scriptName": "LastItemID", + "highlight": false, + "returnType": "string" + } + ] + }, + "convert_-_ıtem_list": { + "conditions": [ + ], + "actions": [ + { + "c2id": 91, + "id": "setconvertkeyname91", + "scriptName": "SetConvertKeyName", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"TableID\""}, + {"id":"ıtem1", "type":"any", "initialValue":"\"TItemID\""} + ] + } + ], + "expressions": [ + ] + }, + "prepare_-_tree_structure": { + "conditions": [ + { + "c2id": 1, + "id": "addtablenode1", + "scriptName": "AddTableNode", + "isInvertible": "false", + "highlight": false, + "params": [ + {"id":"table0", "type":"any", "initialValue":"\"\""} + ] + }, + { + "c2id": 2, + "id": "addıtemnode2", + "scriptName": "AddItemNode", + "isInvertible": "false", + "highlight": false, + "params": [ + {"id":"ıtemıd0", "type":"any", "initialValue":"\"\""} + ] + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "request": { + "conditions": [ + { + "c2id": 51, + "id": "onrequestcomplete51", + "scriptName": "OnRequestComplete", + "isTrigger": "true", + "highlight": false, + "params": [ + {"id":"tag0", "type":"any", "initialValue":"\"_\""} + ] + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "ıtemıd": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 1, + "id": "generatekey1", + "expressionName": "GenerateKey", + "scriptName": "GenerateKey", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 2, + "id": "lastgeneratedkey2", + "expressionName": "LastGeneratedKey", + "scriptName": "LastGeneratedKey", + "highlight": false, + "returnType": "string" + } + ] + }, + "value": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 3, + "id": "at3", + "expressionName": "At", + "scriptName": "At", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + } + ] + }, + "for_each": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 51, + "id": "curıtemıd51", + "expressionName": "CurItemID", + "scriptName": "CurItemID", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 52, + "id": "curkey52", + "expressionName": "CurKey", + "scriptName": "CurKey", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 54, + "id": "curvalue54", + "expressionName": "CurValue", + "scriptName": "CurValue", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + }, + { + "c2id": 55, + "id": "curıtemcontent55", + "expressionName": "CurItemContent", + "scriptName": "CurItemContent", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + } + ] + }, + "convert": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 91, + "id": "asıtemlist91", + "expressionName": "AsItemList", + "scriptName": "AsItemList", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + } + ] + }, + "ıtem_count": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 92, + "id": "ıtemcount92", + "expressionName": "ItemCount", + "scriptName": "ItemCount", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + } + ] + }, + "reference": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 101, + "id": "ref101", + "expressionName": "Ref", + "scriptName": "Ref", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + } + ] + }, + "random": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 201, + "id": "randombase32201", + "expressionName": "RandomBase32", + "scriptName": "RandomBase32", + "highlight": false, + "returnType": "string", + "params": [ + {"id":"length0", "type":"number", "initialValue":"1"} + ] + }, + { + "c2id": 202, + "id": "lastrandombase32202", + "expressionName": "LastRandomBase32", + "scriptName": "LastRandomBase32", + "highlight": false, + "returnType": "string" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/addon.json new file mode 100755 index 0000000..23b0260 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/addon.json @@ -0,0 +1,26 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Item book", + "id": "Rex_Firebase_ItemBook", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_itembook.html", + "documentation": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_itembook.html", + "description": "Item tables to save and query items. Each value is indexed by (tableID, itemID, key).", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/c2runtime/runtime.js new file mode 100755 index 0000000..350da39 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/c2runtime/runtime.js @@ -0,0 +1,877 @@ +/* +\ + : +*/ + +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_ItemBook = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_ItemBook.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/"; + + this.exp_LastGeneratedKey = ""; + this.exp_LastRandomBase32 = ""; + this.writeItems = {}; + this.writeTableID = null; + this.writeItemID = null; + + this.readTables = {}; + this.queueMode = false; + this.requestQueue = []; + this.onRequestComplete = null; + this.addToRequestQueue = null; + this.exp_LastTableID = ""; + this.exp_LastItemID = ""; + + this.trigTag = null; + + + this.exp_CurItemID = ""; + this.exp_CurItemContent = null; + this.exp_CurKey = ""; + this.exp_CurValue = 0; + + this.convertKeyTableID = "tableID"; + this.convertKeyItemID = "itemID"; + }; + + instanceProto.onDestroy = function () + { + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path = this.rootpath + k + "/"; + + return window["Firebase"]["database"]()["ref"](path); + + }; + + instanceProto.repeatEvents = function () + { + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + if (solModifierAfterCnds) + this.runtime.pushCopySol(current_event.solModifiers); + + current_event.retrigger(); + + if (solModifierAfterCnds) + this.runtime.popSol(current_event.solModifiers); + }; + + var getFullKey = function (prefix, tableID, itemID, key) + { + var k = prefix; + if (tableID != null) + k += "/" + tableID; + if (itemID != null) + k += "/" + itemID; + if (key != null) + { + key = key.replace(/\./g, "/"); + k += "/" + key; + } + + return k; + } + instanceProto.setValue = function (tableID_, itemID_, k_, v_) + { + // update tables + k_ = getFullKey("", tableID_, itemID_, k_); + this.writeItems[k_] = v_; + }; + + instanceProto.TreeSetValue = function (k_, v_) + { + if ((this.writeTableID === null) || (this.writeItemID === null)) + { + alert("ItemBook: key-value must be assigned under table and item."); + return; + } + this.setValue(this.writeTableID, this.writeItemID, k_, v_); + }; + + instanceProto.EnumSetValue = function (tableID_, itemID_, k_, v_) + { + if ((tableID_ === "") || (itemID_ === "")) + { + alert("ItemBook: key-value must be assigned under table and item."); + return; + } + this.setValue(tableID_, itemID_, k_, v_); + }; + + instanceProto.ForEachItemID = function (itemIDList, items) + { + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var i, cnt=itemIDList.length; + for(i=0; i= 2) // logical descending, logical ascending + { + valA = parseFloat(valA); + valB = parseFloat(valB); + m -= 2; + } + + switch (m) + { + case 0: // descending + if (valA === valB) return 0; + else if (valA < valB) return 1; + else return -1; + break; + + case 1: // ascending + if (valA === valB) return 0; + else if (valA > valB) return 1; + else return -1; + break; + + } + }; + + itemIDList.sort(sortFn); + return this.ForEachItemID(itemIDList, table); + }; + + Cnds.prototype.ForEachKey = function (tableID_, itemID) + { + var table = this.readTables[tableID_]; + if (table == null) + return false; + + var item_props = table[itemID]; + if (item_props == null) + return false; + + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var k, o=item_props; + for(k in o) + { + if (solModifierAfterCnds) + this.runtime.pushCopySol(current_event.solModifiers); + + this.exp_CurKey = k; + this.exp_CurValue = o[k]; + current_event.retrigger(); + + if (solModifierAfterCnds) + this.runtime.popSol(current_event.solModifiers); + } + + return false; + }; + + Cnds.prototype.TableIsEmpty = function (tableID_) + { + var table = this.readTables[tableID_]; + if (table == null) + return true; + + for (var k in table) + { + return false; + } + + return true; + }; + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetSubDomainRef = function (ref) + { + this.rootpath = ref + "/"; + this.readTables = {}; + }; + Acts.prototype.TreeSetValue = function (k_, v_) + { + this.TreeSetValue(k_, v_); + }; + + Acts.prototype.TreeSetBooleanValue = function (k_, v_) + { + this.TreeSetValue(k_, (v_ === 1)); + }; + + Acts.prototype.TreeSetNullValue = function (k_) + { + this.TreeSetValue(k_, null); + }; + + Acts.prototype.TreeCleanAll = function () + { + this.setValue(this.writeTableID, this.writeItemID, null, null); + }; + + Acts.prototype.TreeSetServerTimestamp = function (k_) + { + this.TreeSetValue(k_, window["Firebase"]["database"]["ServerValue"]); + }; + + Acts.prototype.TreeSetJSON = function (k_, v_) + { + v_ = JSON.parse(v_); + this.TreeSetValue(k_, v_); + }; + + Acts.prototype.UpdateBook = function () + { + var self=this; + var handler = function(error) + { + var trig = (error)? cr.plugins_.Rex_Firebase_ItemBook.prototype.cnds.OnUpdateError: + cr.plugins_.Rex_Firebase_ItemBook.prototype.cnds.OnUpdateComplete; + self.runtime.trigger(trig, self); + }; + var ref = this.get_ref(); + + if (isCleanBook(this.writeItems)) + { + ref["parent"]["set"](null, handler); + } + else + { + ref["update"](this.writeItems, handler); + } + this.writeItems = {}; + }; + + Acts.prototype.EnumSetValue = function (tableID_, itemID_, k_, v_) + { + this.EnumSetValue(tableID_, itemID_, k_, v_); + }; + + Acts.prototype.EnumSetBooleanValue = function (tableID_, itemID_, k_, v_) + { + this.EnumSetValue(tableID_, itemID_, k_, (v_ === 1)); + }; + + Acts.prototype.EnumSetNullValue = function (tableID_, itemID_, k_) + { + if (tableID_ === "") + this.setValue(null, null, null, null); + else if (itemID_ === "") + this.setValue(tableID_, null, null, null); + else if (k_ === "") + this.setValue(tableID_, itemID_, null, null); + else + this.setValue(tableID_, itemID_, k_, null); + }; + + Acts.prototype.EnumSetServerTimestamp = function (tableID_, itemID_, k_) + { + this.EnumSetValue(tableID_, itemID_, k_, window["Firebase"]["database"]["ServerValue"]); + }; + + Acts.prototype.EnumSetJSON = function (tableID_, itemID_, k_, v_) + { + v_ = JSON.parse(v_); + this.EnumSetValue(tableID_, itemID_, k_, v_); + }; + Acts.prototype.TreeOnDisconnectedCancel = function (k_) + { + var k = getFullKey("", this.writeTableID, this.writeItemID, k_); + var ref = this.get_ref(k); + ref["onDisconnect"]()["cancel"](); + }; + + Acts.prototype.TreeOnDisconnectedSetServerTimestamp = function (k_) + { + var k = getFullKey("", this.writeTableID, this.writeItemID, k_); + var ref = this.get_ref(k); + ref["onDisconnect"]()["set"](window["Firebase"]["database"]["ServerValue"]); + }; + + Acts.prototype.TreeOnDisconnectedSetValue = function (k_, v_) + { + var k = getFullKey("", this.writeTableID, this.writeItemID, k_); + var ref = this.get_ref(k); + ref["onDisconnect"]()["set"](v_); + }; + + Acts.prototype.TreeOnDisconnectedSetBooleanValue = function (k_, v_) + { + var k = getFullKey("", this.writeTableID, this.writeItemID, k_); + var ref = this.get_ref(k); + ref["onDisconnect"]()["set"](v_===1); + }; + + Acts.prototype.TreeOnDisconnectedSetJSON = function (k_, v_) + { + var k = getFullKey("", this.writeTableID, this.writeItemID, k_); + var ref = this.get_ref(k); + v_ = JSON.parse(v_); + ref["onDisconnect"]()["set"](v_); + }; + + Acts.prototype.EnumOnDisconnectedRemove = function (tableID_, itemID_, k_) + { + var k = getFullKey("", tableID_, itemID_, k_); + var ref = this.get_ref(k); + ref["onDisconnect"]()["remove"](); + }; + + Acts.prototype.EnumOnDisconnectedSetServerTimestamp = function (tableID_, itemID_, k_) + { + var k = getFullKey("", tableID_, itemID_, k_); + var ref = this.get_ref(k); + ref["onDisconnect"]()["set"](window["Firebase"]["database"]["ServerValue"]); + }; + + Acts.prototype.EnumOnDisconnectedSetValue = function (tableID_, itemID_, k_, v_) + { + var k = getFullKey("", tableID_, itemID_, k_); + var ref = this.get_ref(k); + ref["onDisconnect"]()["set"](v_); + }; + + Acts.prototype.EnumOnDisconnectedSetBooleanValue = function (tableID_, itemID_, k_, v_) + { + var k = getFullKey("", tableID_, itemID_, k_); + var ref = this.get_ref(k); + ref["onDisconnect"]()["set"](v_ === 1); + }; + + Acts.prototype.EnumOnDisconnectedSetJSON = function (tableID_, itemID_, k_, v_) + { + var k = getFullKey("", tableID_, itemID_, k_); + var ref = this.get_ref(k); + v_ = JSON.parse(v_); + ref["onDisconnect"]()["set"](v_); + }; + + Acts.prototype.EnumOnDisconnectedCancel = function (tableID_, itemID_, k_) + { + var k = getFullKey("", tableID_, itemID_, k_); + var ref = this.get_ref(k); + ref["onDisconnect"]()["cancel"](); + }; + + // query + var LIMITTYPE = ["limitToFirst", "limitToLast"]; + Acts.prototype.GetItemsBySingleConditionInRange = function (tableID_, key_, start, end, limit_type, limit_count, tag_) + { + var self=this; + var onReqDone = this.onRequestComplete; + var onRead = function (snapshot) + { + if (!self.readTables.hasOwnProperty(tableID_)) + self.readTables[tableID_] = {}; + var table = self.readTables[tableID_]; + var items = snapshot["val"]() || {}; + for (var k in items) + table[k] = items[k]; + + self.exp_LastTableID = tableID_; + self.trigTag = tag_; + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemBook.prototype.cnds.OnRequestComplete, self); + self.trigTag = null; + + if (onReqDone) + onReqDone(); + }; + + var query = this.get_ref()["child"](tableID_); + query = query["orderByChild"](key_); + query = query["startAt"](start)["endAt"](end); + if (limit_count > 0) + query = query[LIMITTYPE[limit_type]](limit_count); + + var qf = function() + { + query["once"]("value", onRead); + } + if (!onReqDone) + qf(); + else + this.addToRequestQueue(qf); + }; + + var COMPARSION_TYPE = ["equalTo", "startAt", "endAt", "startAt", "endAt"]; + Acts.prototype.GetItemsBySingleCondition = function (tableID_, key_, comparsion_type, value_, limit_type, limit_count, tag_) + { + var self=this; + var onReqDone = this.onRequestComplete; + var onRead = function (snapshot) + { + if (!self.readTables.hasOwnProperty(tableID_)) + self.readTables[tableID_] = {}; + var table = self.readTables[tableID_]; + var items = snapshot["val"]() || {}; + for (var k in items) + table[k] = items[k]; + + self.exp_LastTableID = tableID_; + self.trigTag = tag_; + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemBook.prototype.cnds.OnRequestComplete, self); + self.trigTag = null; + + if (onReqDone) + onReqDone(); + }; + + var query = this.get_ref()["child"](tableID_); + query = query["orderByChild"](key_); + query = query[COMPARSION_TYPE[comparsion_type]](value_); + if (limit_count > 0) + query = query[LIMITTYPE[limit_type]](limit_count); + + var qf = function() + { + query["once"]("value", onRead); + } + if (!onReqDone) + qf(); + else + this.addToRequestQueue(qf); + }; + + Acts.prototype.LoadItem = function (tableID_, itemID_, tag_) + { + if (tableID_ === "") + itemID_ = ""; + + var self=this; + var onReqDone = this.onRequestComplete; + var onRead = function (snapshot) + { + var o = snapshot["val"]() || {}; + if (tableID_ === "") + { + self.readTables = o; + } + else if (itemID_ === "") + { + self.readTables[tableID_] = o ; + } + else + { + if (!self.readTables.hasOwnProperty(tableID_)) + self.readTables[tableID_] = {}; + self.readTables[tableID_][itemID_] = o; + } + self.exp_LastTableID = tableID_; + self.exp_LastItemID = itemID_; + self.trigTag = tag_; + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemBook.prototype.cnds.OnRequestComplete, self); + self.trigTag = null; + + if (onReqDone) + onReqDone(); + }; + + + var query = this.get_ref(); + if (tableID_ !== "") + query = query["child"](tableID_); + if (itemID_ !== "") + query = query["child"](itemID_); + + var qf = function() + { + query["once"]("value", onRead); + } + if (!onReqDone) + qf(); + else + this.addToRequestQueue(qf); + }; + + + Acts.prototype.StartQueue = function (tag_) + { + this.queueMode = true; + this.requestQueue.length = 0; + + var self=this; + var queueCnt=0; + this.addToRequestQueue = function (qf) + { + this.requestQueue.push(qf); + queueCnt += 1; + } + this.onRequestComplete = function () + { + queueCnt -= 1; + if (queueCnt === 0) + { + self.trigTag = tag_; + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemBook.prototype.cnds.OnRequestComplete, self); + self.trigTag = null; + self.onRequestComplete = null; + } + } + }; + Acts.prototype.ProcessQueue = function () + { + for (var i in this.requestQueue) + this.requestQueue[i](); + + this.queueMode = false; + }; + + Acts.prototype.CleanResultTable = function (tableID_) + { + if (tableID_ === "") + this.readTables = {}; + else if (this.readTables.hasOwnProperty(tableID_)) + delete this.readTables[tableID_]; + + }; + // query + + Acts.prototype.SetConvertKeyName = function (keyTableID_, keyItemID_) + { + this.convertKeyTableID = keyTableID_; + this.convertKeyItemID = keyItemID_; + }; + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.GenerateKey = function (ret) + { + var ref = this.get_ref()["push"](); + this.exp_LastGeneratedKey = ref["key"]; + ret.set_string(this.exp_LastGeneratedKey); + }; + + Exps.prototype.LastGeneratedKey = function (ret) + { + ret.set_string(this.exp_LastGeneratedKey); + }; + + Exps.prototype.At = function (ret, tableID, itemID, key, default_value) + { + var item = this.readTables; + if (tableID) + { + item = item[tableID]; + if (item && itemID) + item = item[itemID]; + } + ret.set_any( window.FirebaseGetValueByKeyPath(item, key, default_value) ); + }; + + Exps.prototype.LastTableID = function (ret) + { + ret.set_string(this.exp_LastTableID); + } + Exps.prototype.LastItemID = function (ret) + { + ret.set_string(this.exp_LastItemID); + }; + + Exps.prototype.CurItemID = function (ret) + { + ret.set_string(this.exp_CurItemID); + }; + + Exps.prototype.CurKey = function (ret) + { + ret.set_string(this.exp_CurKey); + }; + + Exps.prototype.CurValue = function (ret, subKey, default_value) + { + ret.set_any( window.FirebaseGetValueByKeyPath(this.exp_CurValue, subKey, default_value ) ); + }; + + Exps.prototype.CurItemContent = function (ret, k, default_value) + { + ret.set_any( window.FirebaseGetValueByKeyPath(this.exp_CurItemContent, k, default_value ) ); + }; + + Exps.prototype.AsItemList = function (ret, tableID_, itemID_) + { + var itemList = []; + var table, item; + if (tableID_ == null) + { + // convert all tables into item list + for (var tableID in this.readTables) + { + table = this.readTables[tableID]; + for (var itemID in table) + { + item = table[itemID]; + itemList.push(this.ConvertItem(item, tableID, itemID)); + } + } + } + else if (itemID_ == null) + { + // convert a table into item list + table = this.readTables[tableID_]; + if (table) + { + for (var itemID in table) + { + item = table[itemID]; + itemList.push(this.ConvertItem(item, tableID_, itemID)); + } + } + } + else + { + // convert an item into item list + table = this.readTables[tableID_]; + if (table) + { + item = table[itemID_]; + if (item) + itemList.push(this.ConvertItem(item, tableID_, itemID_)); + } + + } + var json_ = JSON.stringify(itemList); + + var i, cnt=itemList.length; + for(i=0; i 0) + query = query[LIMITTYPE[limit_type]](limit_count); + + var qf = function() + { + query["once"]("value", onRead); + } + if (!onReqDone) + qf(); + else + this.addToRequestQueue(qf); + }, + + + GetItemsBySingleCondition(tableID_, key_, comparsion_type, value_, limit_type, limit_count, tag_) + { + var self=this; + var onReqDone = this.onRequestComplete; + var onRead = function (snapshot) + { + if (!self.readTables.hasOwnProperty(tableID_)) + self.readTables[tableID_] = {}; + var table = self.readTables[tableID_]; + var items = snapshot["val"]() || {}; + for (var k in items) + table[k] = items[k]; + + self.exp_LastTableID = tableID_; + self.trigTag = tag_; + self.Trigger(C3.Plugins.Rex_Firebase_ItemBook.Cnds.OnRequestComplete, self); + self.trigTag = null; + + if (onReqDone) + onReqDone(); + }; + + var query = this.get_ref()["child"](tableID_); + query = query["orderByChild"](key_); + query = query[COMPARSION_TYPE[comparsion_type]](value_); + if (limit_count > 0) + query = query[LIMITTYPE[limit_type]](limit_count); + + var qf = function() + { + query["once"]("value", onRead); + } + if (!onReqDone) + qf(); + else + this.addToRequestQueue(qf); + }, + + LoadItem(tableID_, itemID_, tag_) + { + if (tableID_ === "") + itemID_ = ""; + + var self=this; + var onReqDone = this.onRequestComplete; + var onRead = function (snapshot) + { + var o = snapshot["val"]() || {}; + if (tableID_ === "") + { + self.readTables = o; + } + else if (itemID_ === "") + { + self.readTables[tableID_] = o ; + } + else + { + if (!self.readTables.hasOwnProperty(tableID_)) + self.readTables[tableID_] = {}; + self.readTables[tableID_][itemID_] = o; + } + self.exp_LastTableID = tableID_; + self.exp_LastItemID = itemID_; + self.trigTag = tag_; + self.Trigger(C3.Plugins.Rex_Firebase_ItemBook.Cnds.OnRequestComplete, self); + self.trigTag = null; + + if (onReqDone) + onReqDone(); + }; + + + var query = this.get_ref(); + if (tableID_ !== "") + query = query["child"](tableID_); + if (itemID_ !== "") + query = query["child"](itemID_); + + var qf = function() + { + query["once"]("value", onRead); + } + if (!onReqDone) + qf(); + else + this.addToRequestQueue(qf); + }, + + + StartQueue(tag_) + { + this.queueMode = true; + this.requestQueue.length = 0; + + var self=this; + var queueCnt=0; + this.addToRequestQueue = function (qf) + { + this.requestQueue.push(qf); + queueCnt += 1; + } + this.onRequestComplete = function () + { + queueCnt -= 1; + if (queueCnt === 0) + { + self.trigTag = tag_; + self.Trigger(C3.Plugins.Rex_Firebase_ItemBook.Cnds.OnRequestComplete, self); + self.trigTag = null; + self.onRequestComplete = null; + } + } + }, + ProcessQueue() + { + for (var i in this.requestQueue) + this.requestQueue[i](); + + this.queueMode = false; + }, + + CleanResultTable(tableID_) + { + if (tableID_ === "") + this.readTables = {}; + else if (this.readTables.hasOwnProperty(tableID_)) + delete this.readTables[tableID_]; + + }, + + + SetConvertKeyName(keyTableID_, keyItemID_) + { + this.convertKeyTableID = keyTableID_; + this.convertKeyItemID = keyItemID_; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/c3runtime/conditions.js new file mode 100755 index 0000000..9ecdfd8 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/c3runtime/conditions.js @@ -0,0 +1,159 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_ItemBook.Cnds = + { + + AddTableNode(name_) + { + if (this.writeTableID !== null) + { + alert("ItemBook: nested table is not allowed."); + return; + } + this.writeTableID = name_; + this.repeatEvents(); + this.writeTableID = null; + return false; + }, + + AddItemNode(name_) + { + if (this.writeTableID === null) + { + alert("ItemBook: itemID should be put in a table."); + return; + } + if (this.writeItemID !== null) + { + alert("ItemBook: nested itemID is not allowed."); + return; + } + + this.writeItemID = name_; + this.repeatEvents(); + this.writeItemID = null; + return false; + }, + + TreeOnDisconnectedRemove() + { + var k = getFullKey("", this.writeTableID, this.writeItemID); + var ref = this.get_ref(k); + ref["onDisconnect"]()["remove"](); + return true; + }, + + TreeOnDisconnectedCancel() + { + var k = getFullKey("", this.writeTableID, this.writeItemID); + var ref = this.get_ref(k); + ref["onDisconnect"]()["cancel"](); + return true; + }, + + OnUpdateComplete() + { + return true; + }, + OnUpdateError() + { + return true; + }, + + OnRequestComplete(tag_) + { + return C3.equalsNoCase(tag_, this.trigTag); + }, + + ForEachItemID(tableID_, sortMode_) + { + var table = this.readTables[tableID_]; + if (table == null) + return false; + + var itemIDList = Object.keys(table); + + var self = this; + var sortFn = function (valA, valB) + { + var m = sortMode_; + + if (sortMode_ >= 2) // logical descending, logical ascending + { + valA = parseFloat(valA); + valB = parseFloat(valB); + m -= 2; + } + + switch (m) + { + case 0: // descending + if (valA === valB) return 0; + else if (valA < valB) return 1; + else return -1; + break; + + case 1: // ascending + if (valA === valB) return 0; + else if (valA > valB) return 1; + else return -1; + break; + + } + }; + + itemIDList.sort(sortFn); + return this.ForEachItemID(itemIDList, table); + }, + + ForEachKey(tableID_, itemID) + { + var table = this.readTables[tableID_]; + if (table == null) + return false; + + var item_props = table[itemID]; + if (item_props == null) + return false; + + var current_frame = this._runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = this._runtime.GetEventSheetManager().GetEventStack(); + var p = this._runtime.GetEventStack(); + var h = c.Push(current_event); + + var k, o=item_props; + for(k in o) + { + if (solModifierAfterCnds) + this._runtime.GetEventSheetManager().PushCopySol(solmod); + + this.exp_CurKey = k; + this.exp_CurValue = o[k]; + current_event.Retrigger(current_frame,h); + if (solModifierAfterCnds) + this._runtime.GetEventSheetManager().PopSol(solmod); + + } + p.Pop(); + return false; + }, + + TableIsEmpty(tableID_) + { + var table = this.readTables[tableID_]; + if (table == null) + return true; + + for (var k in table) + { + return false; + } + + return true; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/c3runtime/expressions.js new file mode 100755 index 0000000..0bf2caf --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itembook/source/c3runtime/expressions.js @@ -0,0 +1,161 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_ItemBook.Exps = + { + + GenerateKey() + { + var ref = this.get_ref()["push"](); + this.exp_LastGeneratedKey = ref["key"]; + return(this.exp_LastGeneratedKey); + }, + + LastGeneratedKey() + { + return(this.exp_LastGeneratedKey); + }, + + At(tableID, itemID, key, default_value) + { + var item = this.readTables; + if (tableID) + { + item = item[tableID]; + if (item && itemID) + item = item[itemID]; + } + return(window.FirebaseGetValueByKeyPath(item, key, default_value) ); + }, + + LastTableID() + { + return(this.exp_LastTableID); + }, + LastItemID() + { + return(this.exp_LastItemID); + }, + + CurItemID() + { + return(this.exp_CurItemID); + }, + + CurKey() + { + return(this.exp_CurKey); + }, + + CurValue(subKey, default_value) + { + return(window.FirebaseGetValueByKeyPath(this.exp_CurValue, subKey, default_value ) ); + }, + + CurItemContent(k, default_value) + { + return(window.FirebaseGetValueByKeyPath(this.exp_CurItemContent, k, default_value ) ); + }, + + AsItemList(tableID_, itemID_) + { + var itemList = []; + var table, item; + if (tableID_ == null) + { + // convert all tables into item list + for (var tableID in this.readTables) + { + table = this.readTables[tableID]; + for (var itemID in table) + { + item = table[itemID]; + itemList.push(this.ConvertItem(item, tableID, itemID)); + } + } + } + else if (itemID_ == null) + { + // convert a table into item list + table = this.readTables[tableID_]; + if (table) + { + for (var itemID in table) + { + item = table[itemID]; + itemList.push(this.ConvertItem(item, tableID_, itemID)); + } + } + } + else + { + // convert an item into item list + table = this.readTables[tableID_]; + if (table) + { + item = table[itemID_]; + if (item) + itemList.push(this.ConvertItem(item, tableID_, itemID_)); + } + + } + var json_ = JSON.stringify(itemList); + + var i, cnt=itemList.length; + for(i=0; i: true + +# for condition picking +filters\ + + : + +# for remove itemID +itemID-keys\ + \ + : true +*/ + +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_ItemFilter = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_ItemFilter.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + + this.prepared_item = {}; + this.request_itemIDs = {}; + + this.trig_tag = null; + this.exp_CurItemID = ""; + }; + + instanceProto.onDestroy = function () + { + this.prepared_item = {}; + this.request_itemIDs = {}; + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + var get_key_path = function(itemID, key_) + { + return "filters/" + key_ + "/" + itemID; + }; + + instanceProto.get_itemID2Keys_ref = function(itemID, key_) + { + var ref = this.get_ref("itemID-keys")["child"](itemID); + if (!key_) + ref = ref["child"](key_); + return ref; + }; + + var get_itemID2Keys_path = function(itemID, key_) + { + var p = "itemID-keys/" + itemID; + if (key_) + p += "/" + key_; + return p; + }; + + instanceProto.get_itemID_ref = function(itemID) + { + return this.get_ref("itemIDs")["child"](itemID); + }; + + var get_itemID_path = function(itemID) + { + return "itemIDs/" + itemID; + }; + + instanceProto.create_save_item = function (itemID, item_) + { + var save_item = {}; + save_item[ get_itemID_path(itemID) ] = true; + var k, v; + for (k in item_) + { + v = item_[k]; + save_item[ get_key_path(itemID, k) ] = v; + save_item[ get_itemID2Keys_path(itemID, k) ] = (v === null)? null : true; + } + return save_item; + }; + + instanceProto.create_remove_item = function (itemID, keys) + { + var remove_item = {}; + // remove itemID from list + remove_item[ get_itemID_path(itemID) ] = null; + // remove itemID-key + remove_item[ get_itemID2Keys_path(itemID, k) ] = null; + + // remove keys from filters + var k; + for(k in keys) + { + remove_item[ get_key_path(itemID, k) ] = null; + } + return remove_item; + }; + + instanceProto.save_item = function (itemID, item_, tag_) + { + var self = this; + var onComplete_handler = function(error) + { + if (!tag_) + return; + + var trig = (!error)? cr.plugins_.Rex_Firebase_ItemFilter.prototype.cnds.OnSaveComplete: + cr.plugins_.Rex_Firebase_ItemFilter.prototype.cnds.OnSaveError; + self.trig_tag = tag_; + self.exp_CurItemID = itemID; + self.runtime.trigger(trig, self); + self.trig_tag = null; + self.exp_CurItemID = ""; + }; + + + // multi-location update + var write_item = this.create_save_item(itemID, item_); + this.get_ref()["update"](write_item, onComplete_handler); + // multi-location update + }; + + instanceProto.remove_item = function (itemID, tag_) + { + var self = this; + + // try remove itemID + var on_read_keys = function (snapshot) + { + var keys = snapshot.val(); + if (keys == null) // itemID is not existed + { + onComplete_handler(true); + } + else // itemID is existed, get keys + { + var items = self.create_remove_item(itemID, keys); + self.get_ref()["update"](items, onComplete_handler); + + } + }; + // try remove itemID + + var onComplete_handler = function(error) + { + if (!tag_) + return; + + var trig = (!error)? cr.plugins_.Rex_Firebase_ItemFilter.prototype.cnds.OnRemoveComplete: + cr.plugins_.Rex_Firebase_ItemFilter.prototype.cnds.OnRemoveError; + self.trig_tag = tag_; + self.exp_CurItemID = itemID; + self.runtime.trigger(trig, self); + self.trig_tag = null; + self.exp_CurItemID = ""; + }; + + // read itemID-keys + this.get_itemID2Keys_ref(itemID)["once"]("value", on_read_keys); + }; + + instanceProto.get_Equal_codeString = function (key_, value_) + { + key_ = string_quote(key_); + value_ = string_quote(value_); + var code_string = 'filter.Query("Equal",'+key_+","+value_+")"; + return code_string; + }; + + instanceProto.get_GreaterEqual_codeString = function (key_, value_) + { + key_ = string_quote(key_); + value_ = string_quote(value_); + var code_string = 'filter.Query("GreaterEqual",'+key_+","+value_+")"; + return code_string; + }; + + instanceProto.get_LessEqual_codeString = function (key_, value_) + { + key_ = string_quote(key_); + value_ = string_quote(value_); + var code_string = 'filter.Query("LessEqual",'+key_+","+value_+")"; + return code_string; + }; + + instanceProto.get_InRange_codeString = function (key_, start_, end_) + { + key_ = string_quote(key_); + start_ = string_quote(start_); + end_ = string_quote(end_); + var code_string = 'filter.Query("InRange",'+key_+","+start_+","+end_+")"; + return code_string; + }; + + var ARGS_COPY = []; + instanceProto.get_OR_codeString = function () + { + array_copy(ARGS_COPY, arguments); + var code_string = 'filter.AddSETOP("OR",'+ARGS_COPY.join(",")+")"; + return code_string; + }; + + instanceProto.get_AND_codeString = function () + { + array_copy(ARGS_COPY, arguments); + var code_string = 'filter.AddSETOP("AND",'+ARGS_COPY.join(",")+")"; + return code_string; + }; + + instanceProto.get_SUB_codeString = function () + { + array_copy(ARGS_COPY, arguments); + var code_string = 'filter.AddSETOP("SUB",'+ARGS_COPY.join(",")+")"; + return code_string; + }; + + instanceProto.get_SUBVALUE_codeString = function () + { + array_copy(ARGS_COPY, arguments); + var code_string = 'filter.AddSETOP("SUB_VALUE",'+ARGS_COPY.join(",")+")"; + return code_string; + }; + + var retrieve_itemIDs = function (table_in, arr_out) + { + var itemID; + arr_out.length = 0; + for (itemID in table_in) + { + arr_out.push(itemID); + } + }; + + var string_quote = function(v) + { + var s; + if (typeof (v) == "string") + s = '"'+v+'"'; + else // number + s = v.toString(); + return s + }; + + var array_copy = function (arr_out, arr_in, start_index) + { + if (start_index == null) + start_index = 0 + + var i, cnt=arr_in.length; + arr_out.length = cnt - start_index; + for(i=start_index; i 0) + return; + + // all jobs done + var result_group = this.DoSetOperation(this.set_expression); + + if (on_complete != null) + on_complete(result_group); + }; + + FilterKlassProto.NewGroupUID = function() + { + var current_group_uid = this.current_groupUid.toString(); + this.groups[current_group_uid] = {}; + this.current_groupUid += 1; + return current_group_uid; + }; + + // picking cnditions + // export + FilterKlassProto["Query"] = function (query_typeName, key_, value0, value1) + { + // read handler + var current_group_uid = this.NewGroupUID(); + var read_result = this.groups[current_group_uid]; + + var self = this; + var read_item = function(childSnapshot) + { + var k = get_key(childSnapshot); + var v = childSnapshot["val"](); + read_result[k] = v; + }; + var on_read = function (snapshot) + { + snapshot["forEach"](read_item); + self.isDone_test(self.on_complete); + }; + + // create query + this.wait_events += 1; + var query = this.plugin.get_ref("filters")["child"](key_); + query = query["orderByValue"](); + query = this[query_typeName](query, value0, value1); + query["once"]("value", on_read); + + var code_string = '(filter.groups["'+current_group_uid+'"])'; + return code_string; + }; + // export + + FilterKlassProto["Equal"] = function (query, value_) + { + return query["equalTo"](value_); + }; + FilterKlassProto["GreaterEqual"] = function (query, value_) + { + return query["startAt"](value_); + }; + FilterKlassProto["LessEqual"] = function (query, value_) + { + return query["endAt"](value_); + }; + FilterKlassProto["InRange"] = function (query, value0, value1) + { + return query["startAt"](value0)["endAt"](value1); + }; + // picking cnditions + + // set operations + // export + var params = []; + FilterKlassProto["AddSETOP"] = function (operation_name) + { + var i,cnt=arguments.length; + for (i=1; i 0) + return; + + // all jobs done + var result_group = this.DoSetOperation(this.set_expression); + + if (on_complete != null) + on_complete(result_group); + }; + + FilterKlassProto.NewGroupUID = function() + { + var current_group_uid = this.current_groupUid.toString(); + this.groups[current_group_uid] = {}; + this.current_groupUid += 1; + return current_group_uid; + }; + + // picking cnditions + // export + FilterKlassProto["Query"] = function (query_typeName, key_, value0, value1) + { + // read handler + var current_group_uid = this.NewGroupUID(); + var read_result = this.groups[current_group_uid]; + + var self = this; + var read_item = function(childSnapshot) + { + var k = get_key(childSnapshot); + var v = childSnapshot["val"](); + read_result[k] = v; + }; + var on_read = function (snapshot) + { + snapshot["forEach"](read_item); + self.isDone_test(self.on_complete); + }; + + // create query + this.wait_events += 1; + var query = this.plugin.get_ref("filters")["child"](key_); + query = query["orderByValue"](); + query = this[query_typeName](query, value0, value1); + query["once"]("value", on_read); + + var code_string = '(filter.groups["'+current_group_uid+'"])'; + return code_string; + }; + // export + + FilterKlassProto["Equal"] = function (query, value_) + { + return query["equalTo"](value_); + }; + FilterKlassProto["GreaterEqual"] = function (query, value_) + { + return query["startAt"](value_); + }; + FilterKlassProto["LessEqual"] = function (query, value_) + { + return query["endAt"](value_); + }; + FilterKlassProto["InRange"] = function (query, value0, value1) + { + return query["startAt"](value0)["endAt"](value1); + }; + // picking cnditions + + // set operations + // export + var params = []; + FilterKlassProto["AddSETOP"] = function (operation_name) + { + var i,cnt=arguments.length; + for (i=1; i + # monitor item added and removed + : + # monitor key added and removed, and value changed +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_ItemMonitor = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_ItemMonitor.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + + this.query = null; + this.items = {}; + this.tag2items = {}; + if (!this.recycled) + { + this.callbackMap = new window.FirebaseCallbackMapKlass(); + } + else + { + this.callbackMap.Reset(); + } + + this.exp_LastItemID = ""; + this.exp_LastItemContent = null; + this.exp_LastPropertyName = ""; + this.exp_LastValue = null; + this.exp_PrevValue = null; + this.exp_CurItemID = ""; + this.exp_CurItemContent = null; + this.exp_CurKey = ""; + this.exp_CurValue = 0; + }; + + instanceProto.onDestroy = function () + { + this.StopMonitor(); + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + instanceProto.StartMonitor = function (query, tag, monitorKey) + { + this.StopMonitor(); + if (this.tag2items.hasOwnProperty(tag)) + return; + + this.tag2items[tag] = {}; + var tag2items = this.tag2items[tag]; + + var self = this; + var on_add = function (snapshot) + { + var itemID = get_key(snapshot); + // add itemID into tag2items, indexed by tag + tag2items[itemID] = true; + + // add item on monitor + var itemContent = snapshot["val"](); + self.items[itemID] = itemContent; + self.exp_LastItemID = itemID; + self.exp_LastItemContent = itemContent; + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnItemAdded, self); + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnItemListChanged, self); + self.start_monitor_item(snapshot, monitorKey); + }; + var on_remove = function (snapshot) + { + var itemID = get_key(snapshot); + // add itemID into tag2items, indexed by tag + delete tag2items[itemID]; + if (is_empty_table(self.tag2items[tag])) + delete self.tag2items[tag]; + + // remove item from monitor + delete self.items[itemID]; + self.stop_monitor_item(get_refPath(snapshot), monitorKey); + self.exp_LastItemID = itemID; + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnItemRemoved, self); + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnItemListChanged, self); + }; + this.callbackMap.Add(query, "child_added", "child_added#"+tag, on_add); + this.callbackMap.Add(query, "child_removed", "child_removed#"+tag, on_remove); + }; + + instanceProto.RemoveMonitorQuery = function (query, tag) + { + this.callbackMap.Remove(query, "child_added", "child_added#"+tag); + this.callbackMap.Remove(query, "child_removed", "child_removed#"+tag); + this.remove_tag2items(tag); + }; + + instanceProto.StopMonitor = function () + { + if (this.query == null) + return; + + for (var tag in this.tag2items) + { + this.RemoveMonitorQuery(this.query, tag); + } + + this.query = null; + }; + + + // read the item once then start monitor + instanceProto.start_monitor_item = function(snapshot, tag) + { + if (tag == null) + tag = ""; + + var ref = get_refPath(snapshot); + var k = get_key(snapshot); + var v = snapshot["val"](); + + // add item into items + this.items[k] = v; + var monitor_item = this.items[k]; + + // add callback + var self = this; + var on_prop_added = function (snapshot) + { + var ck = get_key(snapshot); + var cv = snapshot["val"](); + if (monitor_item[ck] === cv) + return; + + // run trigger + self.exp_LastItemID = k; + self.exp_LastPropertyName = ck; + self.exp_LastValue = cv; + monitor_item[ck] = cv; + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnPropertyAdded, self); + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnItemListChanged, self); + }; + + var on_value_changed = function (snapshot) + { + var ck = get_key(snapshot); + var cv = snapshot["val"](); + if (monitor_item[ck] === cv) + return; + + // run trigger + self.exp_LastItemID = k; + self.exp_LastPropertyName = ck; + self.exp_LastValue = cv; + + if (monitor_item[ck] == null) + self.exp_PrevValue = self.exp_LastValue; + else + self.exp_PrevValue = monitor_item[ck]; + + monitor_item[ck] = cv; + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnAnyValueChnaged, self); + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnValueChnaged, self); + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnItemListChanged, self); + }; + + var on_prop_removed = function (snapshot) + { + var ck = get_key(snapshot); + if (!monitor_item.hasOwnProperty(ck)) + return; + + // run trigger + self.exp_LastItemID = k; + self.exp_LastPropertyName = ck; + delete monitor_item[k]; + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnPropertyRemoved, self); + self.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnItemListChanged, self); + }; + + this.callbackMap.Add(ref, "child_added", "prop_added#"+tag, on_prop_added); + this.callbackMap.Add(ref, "child_removed", "prop_removed#"+tag, on_prop_removed); + this.callbackMap.Add(ref, "child_moved", "prop_added#"+tag, on_value_changed); + this.callbackMap.Add(ref, "child_changed", "prop_removed#"+tag, on_value_changed); + // add callback + }; + + instanceProto.stop_monitor_item = function(ref, tag) + { + this.callbackMap.Remove(ref, "child_added", "prop_added#"+tag); + this.callbackMap.Remove(ref, "child_removed", "prop_removed#"+tag); + this.callbackMap.Remove(ref, "child_moved", "prop_added#"+tag); + this.callbackMap.Remove(ref, "child_changed", "prop_removed#"+tag); + }; + + instanceProto.remove_tag2items = function (tag) + { + var tag2items = this.tag2items[tag]; + if (tag2items == null) + return; + + delete this.tag2items[tag]; + for(var itemID in tag2items) + { + delete this.items[itemID]; + this.stop_monitor_item(this.get_ref(itemID), tag); + + this.exp_LastItemID = itemID; + this.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnItemRemoved, this); + this.runtime.trigger(cr.plugins_.Rex_Firebase_ItemMonitor.prototype.cnds.OnItemListChanged, this); + } + }; + + instanceProto.ForEachItemID = function (itemIDList, items) + { + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var i, cnt=itemIDList.length; + for(i=0; i b)? 1: + (a == b)? 0: + (-1); + }; + var dec = function(a, b) + { + return (a < b)? 1: + (a == b)? 0: + (-1); + }; + + Cnds.prototype.ForEachItemID = function (order) + { + var itemIDList = Object.keys(this.items); + var sort_fn = (order == 0)? inc:dec; + itemIDList.sort(sort_fn); + return this.ForEachItemID(itemIDList, this.items); + }; + + Cnds.prototype.ForEachKey = function (itemID) + { + var item_props = this.items[itemID]; + if (item_props == null) + return false; + + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var k, o=item_props; + for(k in o) + { + if (solModifierAfterCnds) + { + this.runtime.pushCopySol(current_event.solModifiers); + } + + this.exp_CurKey = k; + this.exp_CurValue = o[k]; + current_event.retrigger(); + + if (solModifierAfterCnds) + { + this.runtime.popSol(current_event.solModifiers); + } + } + + return false; + }; + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetDomainRef = function (domain_ref, sub_domain_ref) + { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + this.load_items = {}; + }; + + Acts.prototype.StartMonitor = function () + { + if (this.query == null) + this.query = this.get_ref(); + + this.StartMonitor(this.query, "all"); + }; + + Acts.prototype.StopMonitor = function () + { + this.StopMonitor(); + }; + + var get_query = function (queryObjs) + { + if (queryObjs == null) + return null; + var query = queryObjs.getFirstPicked(); + if (query == null) + return null; + + return query.GetQuery(); + }; + Acts.prototype.SetQueryObject = function (queryObjs, type_, cbName) + { + this.StopMonitor(); + this.query = get_query(queryObjs); + }; + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.LastItemID = function (ret) + { + ret.set_string(this.exp_LastItemID); + }; + Exps.prototype.LastItemContent = function (ret, key_, default_value) + { + var val = getValueByKeyPath(this.exp_LastItemContent, key_); + val = din(val, default_value); + ret.set_any(val); + }; + Exps.prototype.At = function (ret, itemID, key_, default_value) + { + var val, props = this.items[itemID]; + if (props) + val = getValueByKeyPath(props, key_); + + val = din(val, default_value); + ret.set_any(val); + }; + + // ef_deprecated + Exps.prototype.LastItemContentPosX = function (ret) + { + var v = this.exp_LastItemContent; + if (v != null) + { + v = v["pos"]; + if (v != null) + v = v["x"]; + } + if ( v == null) + v = 0; + ret.set_float(v); + }; + // ef_deprecated + Exps.prototype.LastItemContentPosY = function (ret) + { + var v = this.exp_LastItemContent; + if (v != null) + { + v = v["pos"]; + if (v != null) + v = v["y"]; + } + if ( v == null) + v = 0; + ret.set_float(v); + }; + + Exps.prototype.LastPropertyName = function (ret) + { + ret.set_string(this.exp_LastPropertyName); + }; + Exps.prototype.LastValue = function (ret, subKey) + { + var val = getValueByKeyPath(this.exp_LastValue, subKey); + ret.set_any(din(val)); + }; + Exps.prototype.PrevValue = function (ret, subKey) + { + var val = getValueByKeyPath(this.exp_PrevValue, subKey); + ret.set_any(din(val)); + }; + + // ef_deprecated + Exps.prototype.LastValuePosX = function (ret) + { + var v = this.exp_LastValue; + if (v != null) + v = v["x"]; + if ( v == null) + v = 0; + ret.set_float(v); + }; + // ef_deprecated + Exps.prototype.LastValuePosY = function (ret) + { + var v = this.exp_LastValue; + if (v != null) + v = v["y"]; + if ( v == null) + v = 0; + ret.set_float(v); + }; + // ef_deprecated + Exps.prototype.PrevValuePosX = function (ret) + { + var v = this.exp_PrevValue; + if (v != null) + v = v["x"]; + if ( v == null) + v = 0; + ret.set_float(v); + }; + // ef_deprecated + Exps.prototype.PrevValuePosY = function (ret) + { + var v = this.exp_PrevValue; + if (v != null) + v = v["y"]; + if ( v == null) + v = 0; + ret.set_float(v); + }; + + Exps.prototype.CurItemID = function (ret) + { + ret.set_string(this.exp_CurItemID); + }; + Exps.prototype.CurKey = function (ret) + { + ret.set_string(this.exp_CurKey); + }; + + Exps.prototype.CurValue = function (ret, subKey) + { + var val = getValueByKeyPath(this.exp_CurValue, subKey); + ret.set_any(din(val)); + }; + Exps.prototype.CurItemContent = function (ret, key_, default_value) + { + var val = getValueByKeyPath(this.exp_CurItemContent, key_); + ret.set_any(din(val)); + }; +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/actions.js new file mode 100755 index 0000000..4b73b8d --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/actions.js @@ -0,0 +1,41 @@ +"use strict"; + var get_query = function (queryObjs) + { + if (queryObjs == null) + return null; + var query = queryObjs.GetFirstPicked(); + if (query == null) + return null; + + return query.GetSdkInstance().GetQuery(); + }; +{ + C3.Plugins.Rex_Firebase_ItemMonitor.Acts = + { + SetDomainRef(domain_ref, sub_domain_ref) + { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + this.load_items = {}; + }, + + StartMonitor() + { + if (this.query == null) + this.query = this.get_ref(); + + this.StartMonitor(this.query, "all"); + }, + + StopMonitor() + { + this.StopMonitor(); + }, + + + SetQueryObject(queryObjs, type_, cbName) + { + this.StopMonitor(); + this.query = get_query(queryObjs); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/conditions.js new file mode 100755 index 0000000..f3a9b11 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/conditions.js @@ -0,0 +1,96 @@ +"use strict"; + var inc = function(a, b) + { + return (a > b)? 1: + (a == b)? 0: + (-1); + }; + var dec = function(a, b) + { + return (a < b)? 1: + (a == b)? 0: + (-1); + }; +{ + C3.Plugins.Rex_Firebase_ItemMonitor.Cnds = + { + OnItemAdded() + { + return true; + }, + + OnItemRemoved() + { + return true; + }, + + OnValueChnaged(name) + { + return cr.equals_nocase(name, this.exp_LastPropertyName); + }, + + OnAnyValueChnaged() + { + return true; + }, + + OnPropertyAdded() + { + return true; + }, + + OnPropertyRemoved() + { + return true; + }, + + OnItemListChanged() + { + return true; + }, + + ForEachItemID(order) + { + var itemIDList = Object.keys(this.items); + var sort_fn = (order == 0)? inc:dec; + itemIDList.sort(sort_fn); + return this.ForEachItemID(itemIDList, this.items); + }, + + ForEachKey(itemID) + { + var item_props = this.items[itemID]; + if (item_props == null) + return false; + + var current_frame = runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = runtime.GetEventSheetManager().GetEventStack(); + var p = runtime.GetEventStack(); + var h = c.Push(current_event); + + var k, o=item_props; + for(k in o) + { + if (solModifierAfterCnds) + { + runtime.GetEventSheetManager().PushCopySol(solmod); + } + + this.exp_CurKey = k; + this.exp_CurValue = o[k]; + current_event.Retrigger(current_frame,h); + + if (solModifierAfterCnds) + { + runtime.GetEventSheetManager().PopSol(solmod); + } + } + p.Pop(); + + return false; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/expressions.js new file mode 100755 index 0000000..4171490 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/expressions.js @@ -0,0 +1,131 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_ItemMonitor.Exps = + { + LastItemID() + { + return (this.exp_LastItemID); + }, + LastItemContent(key_, default_value) + { + var val = getValueByKeyPath(this.exp_LastItemContent, key_); + val = din(val, default_value); + return (val); + }, + At(itemID, key_, default_value) + { + var val, props = this.items[itemID]; + if (props) + val = getValueByKeyPath(props, key_); + + val = din(val, default_value); + return (val); + }, + + // ef_deprecated + LastItemContentPosX() + { + var v = this.exp_LastItemContent; + if (v != null) + { + v = v["pos"]; + if (v != null) + v = v["x"]; + } + if ( v == null) + v = 0; + return (v); + }, + // ef_deprecated + LastItemContentPosY() + { + var v = this.exp_LastItemContent; + if (v != null) + { + v = v["pos"]; + if (v != null) + v = v["y"]; + } + if ( v == null) + v = 0; + return (v); + }, + + LastPropertyName() + { + return (this.exp_LastPropertyName); + }, + LastValue(subKey) + { + var val = getValueByKeyPath(this.exp_LastValue, subKey); + return (din(val)); + }, + PrevValue(subKey) + { + var val = getValueByKeyPath(this.exp_PrevValue, subKey); + return (din(val)); + }, + + // ef_deprecated + LastValuePosX() + { + var v = this.exp_LastValue; + if (v != null) + v = v["x"]; + if ( v == null) + v = 0; + return (v); + }, + // ef_deprecated + LastValuePosY() + { + var v = this.exp_LastValue; + if (v != null) + v = v["y"]; + if ( v == null) + v = 0; + return (v); + }, + // ef_deprecated + PrevValuePosX() + { + var v = this.exp_PrevValue; + if (v != null) + v = v["x"]; + if ( v == null) + v = 0; + return (v); + }, + // ef_deprecated + PrevValuePosY() + { + var v = this.exp_PrevValue; + if (v != null) + v = v["y"]; + if ( v == null) + v = 0; + return (v); + }, + + CurItemID() + { + return (this.exp_CurItemID); + }, + CurKey() + { + return (this.exp_CurKey); + }, + + CurValue(subKey) + { + var val = getValueByKeyPath(this.exp_CurValue, subKey); + return (din(val)); + }, + CurItemContent(key_, default_value) + { + var val = getValueByKeyPath(this.exp_CurItemContent, key_); + return (din(val)); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/instance.js new file mode 100755 index 0000000..51a098a --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemmonitor/source/c3runtime/instance.js @@ -0,0 +1,272 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_ItemMonitor.Instance = class Rex_Firebase_ItemMonitorInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + this.query = null; + this.items = {}; + this.tag2items = {}; + this.callbackMap = new window.FirebaseCallbackMapKlass(); + this.exp_LastItemID = ""; + this.exp_LastItemContent = null; + this.exp_LastPropertyName = ""; + this.exp_LastValue = null; + this.exp_PrevValue = null; + this.exp_CurItemID = ""; + this.exp_CurItemContent = null; + this.exp_CurKey = ""; + this.exp_CurValue = 0; + + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/" + properties[1] + "/"; + } + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + get_ref(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + } + + StartMonitor(query, tag, monitorKey) + { + this.StopMonitor(); + if (this.tag2items.hasOwnProperty(tag)) + return; + + this.tag2items[tag] = {}; + var tag2items = this.tag2items[tag]; + + var self = this; + var on_add = function (snapshot) + { + var itemID = get_key(snapshot); + // add itemID into tag2items, indexed by tag + tag2items[itemID] = true; + + // add item on monitor + var itemContent = snapshot["val"](); + self.items[itemID] = itemContent; + self.exp_LastItemID = itemID; + self.exp_LastItemContent = itemContent; + self.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnItemAdded); + self.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnItemListChanged); + self.start_monitor_item(snapshot, monitorKey); + }; + var on_remove = function (snapshot) + { + var itemID = get_key(snapshot); + // add itemID into tag2items, indexed by tag + delete tag2items[itemID]; + if (is_empty_table(self.tag2items[tag])) + delete self.tag2items[tag]; + + // remove item from monitor + delete self.items[itemID]; + self.stop_monitor_item(get_refPath(snapshot), monitorKey); + self.exp_LastItemID = itemID; + self.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnItemRemoved); + self.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnItemListChanged); + }; + this.callbackMap.Add(query, "child_added", "child_added#"+tag, on_add); + this.callbackMap.Add(query, "child_removed", "child_removed#"+tag, on_remove); + } + + RemoveMonitorQuery(query, tag) + { + this.callbackMap.Remove(query, "child_added", "child_added#"+tag); + this.callbackMap.Remove(query, "child_removed", "child_removed#"+tag); + this.remove_tag2items(tag); + } + + StopMonitor() + { + if (this.query == null) + return; + + for (var tag in this.tag2items) + { + this.RemoveMonitorQuery(this.query, tag); + } + + this.query = null; + } + + + // read the item once then start monitor + start_monitor_item(snapshot, tag) + { + if (tag == null) + tag = ""; + + var ref = get_refPath(snapshot); + var k = get_key(snapshot); + var v = snapshot["val"](); + + // add item into items + this.items[k] = v; + var monitor_item = this.items[k]; + + // add callback + var self = this; + var on_prop_added = function (snapshot) + { + var ck = get_key(snapshot); + var cv = snapshot["val"](); + if (monitor_item[ck] === cv) + return; + + // run trigger + self.exp_LastItemID = k; + self.exp_LastPropertyName = ck; + self.exp_LastValue = cv; + monitor_item[ck] = cv; + self.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnPropertyAdded); + self.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnItemListChanged); + }; + + var on_value_changed = function (snapshot) + { + var ck = get_key(snapshot); + var cv = snapshot["val"](); + if (monitor_item[ck] === cv) + return; + + // run trigger + self.exp_LastItemID = k; + self.exp_LastPropertyName = ck; + self.exp_LastValue = cv; + + if (monitor_item[ck] == null) + self.exp_PrevValue = self.exp_LastValue; + else + self.exp_PrevValue = monitor_item[ck]; + + monitor_item[ck] = cv; + self.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnAnyValueChnaged); + self.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnValueChnaged); + self.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnItemListChanged); + }; + + var on_prop_removed = function (snapshot) + { + var ck = get_key(snapshot); + if (!monitor_item.hasOwnProperty(ck)) + return; + + // run trigger + self.exp_LastItemID = k; + self.exp_LastPropertyName = ck; + delete monitor_item[k]; + self.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnPropertyRemoved); + self.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnItemListChanged); + }; + + this.callbackMap.Add(ref, "child_added", "prop_added#"+tag, on_prop_added); + this.callbackMap.Add(ref, "child_removed", "prop_removed#"+tag, on_prop_removed); + this.callbackMap.Add(ref, "child_moved", "prop_added#"+tag, on_value_changed); + this.callbackMap.Add(ref, "child_changed", "prop_removed#"+tag, on_value_changed); + // add callback + } + + stop_monitor_item(ref, tag) + { + this.callbackMap.Remove(ref, "child_added", "prop_added#"+tag); + this.callbackMap.Remove(ref, "child_removed", "prop_removed#"+tag); + this.callbackMap.Remove(ref, "child_moved", "prop_added#"+tag); + this.callbackMap.Remove(ref, "child_changed", "prop_removed#"+tag); + } + + remove_tag2items(tag) + { + var tag2items = this.tag2items[tag]; + if (tag2items == null) + return; + + delete this.tag2items[tag]; + for(var itemID in tag2items) + { + delete this.items[itemID]; + this.stop_monitor_item(this.get_ref(itemID), tag); + + this.exp_LastItemID = itemID; + this.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnItemRemoved); + this.Trigger(C3.Plugins.Rex_Firebase_ItemMonitor.Cnds.OnItemListChanged); + } + } + + ForEachItemID(itemIDList, items) + { + var current_frame = runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = runtime.GetEventSheetManager().GetEventStack(); + var p = runtime.GetEventStack(); + var h = c.Push(current_event); + + var i, cnt=itemIDList.length; + for(i=0; i\ + : +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_ItemTable = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_ItemTable.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + + this.save_item = {}; + if (!this.recycled) + { + this.disconnectRemove_absRefs = {}; + this.load_request_itemIDs = {}; + this.load_items = {}; + this.load_items_cnt = null; + } + else + { + clean_table( this.disconnectRemove_absRefs ); + clean_table( this.load_request_itemIDs ); + this.clean_load_items(); + } + + this.trig_tag = null; + + this.exp_CurItemID = ""; + this.exp_CurItemContent = null; + this.exp_CurKey = ""; + this.exp_CurValue = 0; + this.exp_LastItemID = ""; + this.exp_LastGeneratedKey = ""; + }; + + instanceProto.onDestroy = function () + { + this.CancelOnDisconnected(); + this.save_item = {}; + clean_table( this.disconnectRemove_absRefs ); + clean_table( this.load_request_itemIDs ); + this.clean_load_items(); + }; + + instanceProto.clean_load_items = function () + { + clean_table( this.load_items ); + this.load_items_cnt = null; + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + instanceProto.ForEachItemID = function (itemIDList, items) + { + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var i, cnt=itemIDList.length; + for(i=0; i b)? 1: + (a == b)? 0: + (-1); + }; + var dec = function(a, b) + { + return (a < b)? 1: + (a == b)? 0: + (-1); + }; + + Cnds.prototype.ForEachItemID = function (order) + { + var itemIDList = Object.keys(this.load_items); + var sort_fn = (order === 0)? inc:dec; + itemIDList.sort(sort_fn); + return this.ForEachItemID(itemIDList, this.load_items); + }; + + Cnds.prototype.ForEachKey = function (itemID) + { + var item_props = this.load_items[itemID]; + if (item_props == null) + return false; + + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var k, o=item_props; + for(k in o) + { + if (solModifierAfterCnds) + { + this.runtime.pushCopySol(current_event.solModifiers); + } + + this.exp_CurKey = k; + this.exp_CurValue = o[k]; + current_event.retrigger(); + + if (solModifierAfterCnds) + { + this.runtime.popSol(current_event.solModifiers); + } + } + + return false; + }; + + Cnds.prototype.OnCleanAllComplete = function () + { + return true; + }; + Cnds.prototype.OnCleanAllError = function () + { + return true; + }; + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + + Acts.prototype.SetDomainRef = function (domain_ref, sub_domain_ref) + { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + this.clean_load_items(); + }; + + Acts.prototype.SetValue = function (key_, value_) + { + this.save_item[key_] = dout(value_); + }; + + Acts.prototype.SetBooleanValue = function (key_, is_true) + { + this.save_item[key_] = (is_true == 1); + }; + + Acts.prototype.RemoveKey = function (key_) + { + this.save_item[key_] = null; + }; + + Acts.prototype.Save = function (itemID, set_mode, tag_) + { + this.Save(itemID, this.save_item, set_mode, tag_); + this.save_item = {}; + }; + + Acts.prototype.Push = function (tag_) + { + this.Save("", this.save_item, 1, tag_); + this.save_item = {}; + }; + + Acts.prototype.Remove = function (itemID, tag_) + { + this.Remove(itemID, tag_); + }; + + Acts.prototype.GenerateKey = function () + { + var ref = this.get_ref()["push"](); + this.exp_LastGeneratedKey = get_key(ref); + }; + + Acts.prototype.SetPosValue = function (x, y) + { + this.save_item["pos"] = {"x":x, "y":y}; + }; + + Acts.prototype.SetServerTimestampValue = function (key_) + { + this.save_item[key_] = serverTimeStamp(); + }; + + Acts.prototype.AddLoadRequestItemID = function (itemID) + { + if (itemID == "") + return; + + this.load_request_itemIDs[itemID] = true; + }; + + Acts.prototype.LoadItems = function (tag_) + { + this.clean_load_items(); + + var self = this; + // wait done + var wait_events = 0; + var isDone_handler = function() + { + wait_events -= 1; + if (wait_events == 0) + { + // all jobs done + self.trig_tag = tag_; + var trig = cr.plugins_.Rex_Firebase_ItemTable.prototype.cnds.OnLoadComplete; + self.runtime.trigger(trig, self); + self.trig_tag = null; + } + }; + // wait done + + // read handler + var on_read = function (snapshot) + { + var itemID = get_key(snapshot); + var content = snapshot["val"](); + self.load_items[itemID] = content; + isDone_handler(); + }; + + // read itemIDs + var itemID, item_ref; + for(itemID in this.load_request_itemIDs) + { + wait_events += 1; + item_ref = this.get_ref(itemID)["once"]("value", on_read); + delete this.load_request_itemIDs[itemID]; + } + }; + + Acts.prototype.LoadAllItems = function (tag_) + { + clean_table(this.load_items); + + var self = this; + // wait done + var wait_events = 0; + var isDone_handler = function() + { + wait_events -= 1; + if (wait_events == 0) + { + // all jobs done + self.trig_tag = tag_; + var trig = cr.plugins_.Rex_Firebase_ItemTable.prototype.cnds.OnLoadComplete; + self.runtime.trigger(trig, self); + self.trig_tag = null; + } + }; + // wait done + + // read handler + var read_item = function(childSnapshot) + { + var key = get_key(childSnapshot); + var childData = childSnapshot["val"](); + self.load_items[key] = childData; + }; + var on_read = function (snapshot) + { + snapshot["forEach"](read_item); + isDone_handler(); + }; + + // read all + wait_events += 1; + this.get_ref()["once"]("value", on_read); + }; + + Acts.prototype.CancelOnDisconnected = function () + { + this.CancelOnDisconnected(); + }; + + Acts.prototype.RemoveOnDisconnected = function (itemID) + { + if (itemID == "") + return; + + var ref = this.get_ref(itemID); + ref["onDisconnect"]()["remove"](); + this.disconnectRemove_absRefs[ref["toString"]()] = true; + }; + + Acts.prototype.CleanAll = function () + { + var self=this; + var onComplete = function(error) + { + var trig = (!error)? cr.plugins_.Rex_Firebase_ItemTable.prototype.cnds.OnCleanAllComplete: + cr.plugins_.Rex_Firebase_ItemTable.prototype.cnds.OnCleanAllError; + self.runtime.trigger(trig, self); + }; + var ref = this.get_ref(); + ref["remove"](onComplete); + }; + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.CurItemID = function (ret) + { + ret.set_string(this.exp_CurItemID); + }; + + Exps.prototype.LoadResultToJSON = function (ret) + { + ret.set_string(JSON.stringify(this.load_items)); + }; + + Exps.prototype.CurKey = function (ret) + { + ret.set_string(this.exp_CurKey); + }; + + Exps.prototype.CurValue = function (ret) + { + var v = this.exp_CurValue; + v = din(v); + ret.set_any(v); + }; + + Exps.prototype.At = function (ret, itemID, key_, default_value) + { + var v; + if (!this.load_items.hasOwnProperty(itemID)) + v = null; + else + v = this.load_items[itemID][key_]; + + v = din(v, default_value); + ret.set_any(v); + }; + + Exps.prototype.LastItemID = function (ret) + { + ret.set_string(this.exp_LastItemID); + }; + + Exps.prototype.CurItemContent = function (ret, key_, default_value) + { + var v; + if (key_ == null) + v = din(this.exp_CurItemContent); + else + v = din(this.exp_CurItemContent[key_], default_value); + + ret.set_any(v); + }; + + Exps.prototype.ItemsCount = function (ret) + { + if (this.load_items_cnt === null) + { + this.load_items_cnt = 0; + for (var k in this.load_items) + this.load_items_cnt += 1; + } + ret.set_int(this.load_items_cnt); + }; + + Exps.prototype.GenerateKey = function (ret) + { + var ref = this.get_ref()["push"](); + this.exp_LastGeneratedKey = get_key(ref); + ret.set_string(this.exp_LastGeneratedKey); + }; + + Exps.prototype.LastGeneratedKey = function (ret) + { + ret.set_string(this.exp_LastGeneratedKey); + }; + + Exps.prototype.Ref = function (ret, itemID_, key_) + { + var path = this.rootpath + getFullKey("", itemID_, key_); + ret.set_string(path); + }; +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/actions.js new file mode 100755 index 0000000..34e7e6a --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/actions.js @@ -0,0 +1,176 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_ItemTable.Acts = + { + + SetDomainRef(domain_ref, sub_domain_ref) + { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + this.clean_load_items(); + }, + + SetValue(key_, value_) + { + this.save_item[key_] = dout(value_); + }, + + SetBooleanValue(key_, is_true) + { + this.save_item[key_] = (is_true == 1); + }, + + RemoveKey(key_) + { + this.save_item[key_] = null; + }, + + Save(itemID, set_mode, tag_) + { + this.Save(itemID, this.save_item, set_mode, tag_); + this.save_item = {}; + }, + + Push(tag_) + { + this.Save("", this.save_item, 1, tag_); + this.save_item = {}; + }, + + Remove(itemID, tag_) + { + this.Remove(itemID, tag_); + }, + + GenerateKey() + { + var ref = this.get_ref()["push"](); + this.exp_LastGeneratedKey = get_key(ref); + }, + + SetPosValue(x, y) + { + this.save_item["pos"] = {"x":x, "y":y}; + }, + + SetServerTimestampValue(key_) + { + this.save_item[key_] = serverTimeStamp(); + }, + + AddLoadRequestItemID(itemID) + { + if (itemID == "") + return; + + this.load_request_itemIDs[itemID] = true; + }, + + LoadItems(tag_) + { + this.clean_load_items(); + + var self = this; + // wait done + var wait_events = 0; + var isDone_handler = function() + { + wait_events -= 1; + if (wait_events == 0) + { + // all jobs done + self.trig_tag = tag_; + var trig = C3.Plugins.Rex_Firebase_ItemTable.Cnds.OnLoadComplete; + self.Trigger(trig); + self.trig_tag = null; + } + }; + // wait done + + // read handler + var on_read = function (snapshot) + { + var itemID = get_key(snapshot); + var content = snapshot["val"](); + self.load_items[itemID] = content; + isDone_handler(); + }; + + // read itemIDs + var itemID, item_ref; + for(itemID in this.load_request_itemIDs) + { + wait_events += 1; + item_ref = this.get_ref(itemID)["once"]("value", on_read); + delete this.load_request_itemIDs[itemID]; + } + }, + + LoadAllItems(tag_) + { + clean_table(this.load_items); + + var self = this; + // wait done + var wait_events = 0; + var isDone_handler = function() + { + wait_events -= 1; + if (wait_events == 0) + { + // all jobs done + self.trig_tag = tag_; + var trig = C3.Plugins.Rex_Firebase_ItemTable.Cnds.OnLoadComplete; + self.Trigger(trig); + self.trig_tag = null; + } + }; + // wait done + + // read handler + var read_item = function(childSnapshot) + { + var key = get_key(childSnapshot); + var childData = childSnapshot["val"](); + self.load_items[key] = childData; + }; + var on_read = function (snapshot) + { + snapshot["forEach"](read_item); + isDone_handler(); + }; + + // read all + wait_events += 1; + this.get_ref()["once"]("value", on_read); + }, + + CancelOnDisconnected() + { + this.CancelOnDisconnected(); + }, + + RemoveOnDisconnected(itemID) + { + if (itemID == "") + return; + + var ref = this.get_ref(itemID); + ref["onDisconnect"]()["remove"](); + this.disconnectRemove_absRefs[ref["toString"]()] = true; + }, + + CleanAll() + { + var self=this; + var onComplete = function(error) + { + var trig = (!error)? C3.Plugins.Rex_Firebase_ItemTable.Cnds.OnCleanAllComplete: + C3.Plugins.Rex_Firebase_ItemTable.Cnds.OnCleanAllError; + self.Trigger(trig); + }; + var ref = this.get_ref(); + ref["remove"](onComplete); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/conditions.js new file mode 100755 index 0000000..c69d3c4 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/conditions.js @@ -0,0 +1,83 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_ItemTable.Cnds = + { + OnSaveComplete(tag_) + { + return C3.equalsNoCase(tag_, this.trig_tag); + }, + OnSaveError(tag_) + { + return C3.equalsNoCase(tag_, this.trig_tag); + }, + + OnRemoveComplete(tag_) + { + return C3.equalsNoCase(tag_, this.trig_tag); + }, + OnRemoveError(tag_) + { + return C3.equalsNoCase(tag_, this.trig_tag); + }, + + OnLoadComplete(tag_) + { + return C3.equalsNoCase(tag_, this.trig_tag); + }, + + + ForEachItemID(order) + { + var itemIDList = Object.keys(this.load_items); + var sort_fn = (order === 0)? inc:dec; + itemIDList.sort(sort_fn); + return this.ForEachItemID(itemIDList, this.load_items); + }, + + ForEachKey(itemID) + { + var item_props = this.load_items[itemID]; + if (item_props == null) + return false; + + var current_frame = this._runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = this._runtime.GetEventSheetManager().GetEventStack(); + var p = this._runtime.GetEventStack(); + var h = c.Push(current_event); + + var k, o=item_props; + for(k in o) + { + if (solModifierAfterCnds) + { + this._runtime.GetEventSheetManager().PushCopySol(solmod); + } + + this.exp_CurKey = k; + this.exp_CurValue = o[k]; + current_event.Retrigger(current_frame,h); + + if (solModifierAfterCnds) + { + this._runtime.GetEventSheetManager().PopSol(solmod); + } + } + p.Pop(); + + return false; + }, + + OnCleanAllComplete() + { + return true; + }, + OnCleanAllError() + { + return true; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/expressions.js new file mode 100755 index 0000000..ad49241 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/expressions.js @@ -0,0 +1,85 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_ItemTable.Exps = + { + CurItemID() + { + return (this.exp_CurItemID); + }, + + LoadResultToJSON() + { + return (JSON.stringify(this.load_items)); + }, + + CurKey() + { + return (this.exp_CurKey); + }, + + CurValue() + { + var v = this.exp_CurValue; + v = din(v); + return(v); + }, + + At(itemID, key_, default_value) + { + var v; + if (!this.load_items.hasOwnProperty(itemID)) + v = null; + else + v = this.load_items[itemID][key_]; + + v = din(v, default_value); + return(v); + }, + + LastItemID() + { + return (this.exp_LastItemID); + }, + + CurItemContent(key_, default_value) + { + var v; + if (key_ == null) + v = din(this.exp_CurItemContent); + else + v = din(this.exp_CurItemContent[key_], default_value); + + return(v); + }, + + ItemsCount() + { + if (this.load_items_cnt === null) + { + this.load_items_cnt = 0; + for (var k in this.load_items) + this.load_items_cnt += 1; + } + ret.set_int(this.load_items_cnt); + }, + + GenerateKey() + { + var ref = this.get_ref()["push"](); + this.exp_LastGeneratedKey = get_key(ref); + return (this.exp_LastGeneratedKey); + }, + + LastGeneratedKey() + { + return (this.exp_LastGeneratedKey); + }, + + Ref(itemID_, key_) + { + var path = this.rootpath + getFullKey("", itemID_, key_); + return (path); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/instance.js new file mode 100755 index 0000000..b00ebed --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/instance.js @@ -0,0 +1,181 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_ItemTable.Instance = class Rex_Firebase_ItemTableInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + + this.save_item = {}; + this.disconnectRemove_absRefs = {}; + this.load_request_itemIDs = {}; + this.load_items = {}; + this.load_items_cnt = null; + this.trig_tag = null; + this.exp_CurItemID = ""; + this.exp_CurItemContent = null; + this.exp_CurKey = ""; + this.exp_CurValue = 0; + this.exp_LastItemID = ""; + this.exp_LastGeneratedKey = ""; + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/" + properties[1] + "/"; + } + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + clean_load_items () + { + clean_table( this.load_items ); + this.load_items_cnt = null; + } + + + get_ref(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + } + + + ForEachItemID(itemIDList, items) + { + var current_frame = this._runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = this._runtime.GetEventSheetManager().GetEventStack(); + var p = this._runtime.GetEventStack(); + var h = c.Push(current_event); + + var i, cnt=itemIDList.length; + for(i=0; i b)? 1: + (a == b)? 0: + (-1); + }; + var dec = function(a, b) + { + return (a < b)? 1: + (a == b)? 0: + (-1); + }; + var getFullKey = function (prefix, itemID, key) + { + var k = prefix; + if (itemID != null) + k += "/" + itemID; + if (key != null) + { + key = key.replace(/\./g, "/"); + k += "/" + key; + } + + return k; + } + + var clean_table = function (o) + { + for (var k in o) + delete o[k]; + }; + + var is_empty_table = function (o) + { + for (var k in o) + return false; + + return true; + }; + + var din = function (d, default_value) + { + var o; + if (d === true) + o = 1; + else if (d === false) + o = 0; + else if (d == null) + { + if (default_value != null) + o = default_value; + else + o = 0; + } + else if (typeof(d) == "object") + o = JSON.stringify(d); + else + o = d; + return o; + }; + + var dout = function (d) + { + var o; + if (typeof(d) == "string") + { + try + { + o = JSON.parse(d) + } + catch(err) + { + o = d; + } + } + else + { + o = d; + } + return o; + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + +{ + C3.Plugins.Rex_Firebase_ItemTable = class Rex_Firebase_ItemTablePlugin extends C3.SDKPluginBase + { + constructor(opts) + { + super(opts); + } + + Release() + { + super.Release(); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/type.js new file mode 100755 index 0000000..70a975a --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/c3runtime/type.js @@ -0,0 +1,20 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_ItemTable.Type = class Rex_Firebase_ItemTableType extends C3.SDKTypeBase + { + constructor(objectClass) + { + super(objectClass); + } + + Release() + { + super.Release(); + } + + OnCreate() + { + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/icon.png new file mode 100755 index 0000000..cefd2c7 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/instance.js new file mode 100755 index 0000000..48ea206 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_ItemTable; + + PLUGIN_CLASS.Instance = class Rex_Firebase_ItemTableInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/lang/en-US.json new file mode 100755 index 0000000..408842f --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/lang/en-US.json @@ -0,0 +1,284 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Item table.", + "text": { + "plugins": { + "rex_firebase_itemtable": { + "name": "Item table", + "description": "Items table indexed by (itemID, key), supports writing a item or reading items back.", + "help-url": "http://c2rexplugins.weebly.com/rex_firebase_itemtable.html", + "properties": { + "domain": { + "name": "Domain", + "desc": "The root location of the Firebase data." + }, + "sub-domain": { + "name": "Sub domain", + "desc": "Sub domain for this function." + } + }, + "aceCategories": { + "domain": "Domain", + "prepare": "Prepare", + "save": "Save", + "remove": "Remove", + "ıtemıd": "ItemID", + "prepare_-_position": "Prepare - position", + "load": "Load", + "on_disconnected": "On disconnected", + "for_each": "For Each", + "load_items": "Load items", + "table": "Table", + "load_item": "Load item", + "reference": "Reference" + }, + "conditions": { + "onsavecomplete1": { + "list-name": "On save complete", + "display-text": "On save [i]{0}[/i] complete", + "description": "Triggered when save current item complete.", + "params": { + "tag0": { "name":"Tag", "desc":"A tag, to distinguish between different save requests."} + } + }, + "onsaveerror2": { + "list-name": "On save error", + "display-text": "On save [i]{0}[/i] error", + "description": "Triggered when save current item error.", + "params": { + "tag0": { "name":"Tag", "desc":"A tag, to distinguish between different save requests."} + } + }, + "onremovecomplete3": { + "list-name": "On remove complete", + "display-text": "On remove [i]{0}[/i] complete", + "description": "Triggered when remove current item complete.", + "params": { + "tag0": { "name":"Tag", "desc":"A tag, to distinguish between different save requests."} + } + }, + "onremoveerror4": { + "list-name": "On remove error", + "display-text": "On remove [i]{0}[/i] error", + "description": "Triggered when remove current item error.", + "params": { + "tag0": { "name":"Tag", "desc":"A tag, to distinguish between different save requests."} + } + }, + "onloadcomplete11": { + "list-name": "On load complete", + "display-text": "On load [i]{0}[/i] complete", + "description": "Triggered when load current item complete.", + "params": { + "tag0": { "name":"Tag", "desc":"A tag, to distinguish between different save requests."} + } + }, + "foreachıtemıd12": { + "list-name": "For each itemID", + "display-text": "For each itemID [i]{0}[/i]", + "description": "Repeat the event for each itemID of load result.", + "params": { + "order2": { "name":"Order", "desc":"Order of itemID.", "items":{"small to large":"Small to large","large to small":"Large to small"}} + } + }, + "foreachkey13": { + "list-name": "For each key", + "display-text": "For each key in item: [i]{0}[/i]", + "description": "Repeat the event for each key of a item of load result.", + "params": { + "ıd0": { "name":"ID", "desc":"ID of item."} + } + }, + "oncleanallcomplete31": { + "list-name": "On remove all complete", + "display-text": "On remove all complete", + "description": "Triggered when remove all items complete." + }, + "oncleanallerror32": { + "list-name": "On remove all error", + "display-text": "On remove all error", + "description": "Triggered when remove all items error." + } + }, + "actions": { + "setdomainref0": { + "list-name": "Set domain", + "display-text": "Set domain to [i]{0}[/i], sub domain to [i]{1}[/i]", + "description": "Set domain ref.", + "params": { + "domain0": { "name":"Domain", "desc":"The root location of the Firebase data."}, + "sub_domain1": { "name":"Sub domain", "desc":"Sub domain for this function."} + } + }, + "setvalue1": { + "list-name": "Set value", + "display-text": "Prepare- Set key [i]{0}[/i] to [i]{1}[/i] in current item", + "description": "Set value into current item.", + "params": { + "key0": { "name":"Key", "desc":"The name of the key."}, + "value1": { "name":"Value", "desc":"The value to set, could be number or (JSON) string."} + } + }, + "setbooleanvalue2": { + "list-name": "Set boolean value", + "display-text": "Prepare- Set key [i]{0}[/i] to [i]{1}[/i] in current item", + "description": "Set boolean value into current item.", + "params": { + "key0": { "name":"Key", "desc":"The name of the key."}, + "boolean3": { "name":"Boolean", "desc":"Boolean value.", "items":{"false":"False","true":"True"}} + } + }, + "removekey3": { + "list-name": "Remove key", + "display-text": "Prepare- Remove key [i]{0}[/i] in server", + "description": "Remove key in firebase server.", + "params": { + "key0": { "name":"Key", "desc":"The name of the key."} + } + }, + "save4": { + "list-name": "Save", + "display-text": "Save- [i]{1}[/i] current item at itemID: [i]{0}[/i] (tag [i]{2}[/i])", + "description": "Save current item into server. Push item if ID is equal to \"\".", + "params": { + "ıd0": { "name":"ID", "desc":"ID of item."}, + "set_mode3": { "name":"Set mode", "desc":"Update, or clean then set item values", "items":{"update":"Update","set":"Set"}}, + "tag4": { "name":"Tag", "desc":"A tag, to distinguish between different save requests."} + } + }, + "push5": { + "list-name": "Push", + "display-text": "Save- Push current item (tag [i]{0}[/i])", + "description": "Push current item into server. Get itemID by \"expression:LastItemID\".", + "params": { + "tag0": { "name":"Tag", "desc":"A tag, to distinguish between different save requests."} + } + }, + "remove6": { + "list-name": "Remove", + "display-text": "Remove- Remove itemID: [i]{0}[/i] (tag [i]{1}[/i])", + "description": "Remove item from server.", + "params": { + "ıd0": { "name":"ID", "desc":"ID of item."}, + "tag1": { "name":"Tag", "desc":"A tag, to distinguish between different save requests."} + } + }, + "generatekey7": { + "list-name": "Generate", + "display-text": "Generate a new itemID", + "description": "Generate a new itemID. Get it by \"Expression:LastGeneratedKey\". Or use \"Expression:GenerateKey\" directly." + }, + "setposvalue8": { + "list-name": "Set to position", + "display-text": "Prepare- Set key \"pos\" to ([i]{0}[/i], [i]{1}[/i])", + "description": "Set position value into current item.", + "params": { + "x0": { "name":"X", "desc":"The X position."}, + "y1": { "name":"Y", "desc":"The Y position."} + } + }, + "setservertimestampvalue9": { + "list-name": "Set to timestamp", + "display-text": "Prepare- Set key [i]{0}[/i] to server timestamp in current item", + "description": "Set server timestamp value into current item.", + "params": { + "key0": { "name":"Key", "desc":"The name of the key."} + } + }, + "addloadrequestıtemıd11": { + "list-name": "Add itemID", + "display-text": "Load- 1. Add load-request itemID: [i]{0}[/i]", + "description": "Add load-request itemID.", + "params": { + "ıd0": { "name":"ID", "desc":"ID of item."} + } + }, + "loadıtems12": { + "list-name": "Load", + "display-text": "Load- 2. Load items (tag [i]{0}[/i])", + "description": "Load items.", + "params": { + "tag0": { "name":"Tag", "desc":"A tag, to distinguish between different save requests."} + } + }, + "loadallıtems13": { + "list-name": "Load all", + "display-text": "Load- Load all items (tag [i]{0}[/i])", + "description": "Load all items.", + "params": { + "tag0": { "name":"Tag", "desc":"A tag, to distinguish between different save requests."} + } + }, + "cancelondisconnected21": { + "list-name": "Cancel disconnected handler", + "display-text": "Cancel all disconnected handlers", + "description": "Cancel all disconnected handlers." + }, + "removeondisconnected22": { + "list-name": "Auto remove", + "display-text": "Auto remove itemID: [i]{0}[/i] when disconnected", + "description": "Auto remov item when disconnected.", + "params": { + "ıd0": { "name":"ID", "desc":"ID of item."} + } + }, + "cleanall31": { + "list-name": "Remove all", + "display-text": "Remove all", + "description": "Remove all items." + } + }, + "expressions": { + "curıtemıd1": { + "description": "Get current itemID in a For Each loop, in last load result. Or in save/remove callback.", + "translated-name": "CurItemID" + }, + "loadresulttojson2": { + "description": "Get load reslt in JSON string.", + "translated-name": "LoadResultToJSON" + }, + "curkey3": { + "description": "Get current key in a For Each loop, in last load result.", + "translated-name": "CurKey" + }, + "curvalue4": { + "description": "Get current value in a For Each loop, in last load result.", + "translated-name": "CurValue" + }, + "at5": { + "description": "Get value by itemId and key in last load result. Add 3rd parameter for default value if this key is not existed.", + "translated-name": "At", + "params": { + "ıd0": { "name":"ID", "desc":"ID of item."}, + "key1": { "name":"Key", "desc":"The name of the key."} + } + }, + "lastıtemıd6": { + "description": "Get last itemID.", + "translated-name": "LastItemID" + }, + "curıtemcontent7": { + "description": "Get current content in JSON stringin in a For Each loop, in last load result. Add 2nd parameter for specific key, 3rd parameter for default value if this key is not existed.", + "translated-name": "CurItemContent" + }, + "ıtemscount8": { + "description": "Get loaded items count.", + "translated-name": "ItemsCount" + }, + "generatekey21": { + "description": "Generate new key from push action.", + "translated-name": "GenerateKey" + }, + "lastgeneratedkey22": { + "description": "Get last generate a key from push action.", + "translated-name": "LastGeneratedKey" + }, + "ref101": { + "description": "Get renerence in table, optional parameters are (itemID, key).", + "translated-name": "Ref" + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/plugin.js new file mode 100755 index 0000000..c871fd1 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/plugin.js @@ -0,0 +1,42 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase_ItemTable"; + const PLUGIN_VERSION = "0.1.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_ItemTable = class Rex_Firebase_ItemTable extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "domain", ""), + new SDK.PluginProperty("text", "sub-domain", "items") + ]); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/type.js new file mode 100755 index 0000000..963ff1c --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_itemtable/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_ItemTable; + + PLUGIN_CLASS.Type = class Rex_Firebase_ItemTableType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/dist/rex_firebase_leaderboard.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/dist/rex_firebase_leaderboard.c3addon new file mode 100644 index 0000000..be8d17d Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/dist/rex_firebase_leaderboard.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/aces.json new file mode 100755 index 0000000..83da68b --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/aces.json @@ -0,0 +1,372 @@ +{ + "domain": { + "conditions": [ + ], + "actions": [ + { + "c2id": 0, + "id": "setdomainref0", + "scriptName": "SetDomainRef", + "highlight": false, + "params": [ + {"id":"domain0", "type":"string", "initialValue":"\"\""}, + {"id":"ıd1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "send": { + "conditions": [ + { + "c2id": 1, + "id": "onpostcomplete1", + "scriptName": "OnPostComplete", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 2, + "id": "onposterror2", + "scriptName": "OnPostError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 1, + "id": "postscore1", + "scriptName": "PostScore", + "highlight": false, + "params": [ + {"id":"userıd0", "type":"string", "initialValue":"\"\""}, + {"id":"name1", "type":"string", "initialValue":"\"\""}, + {"id":"score2", "type":"any", "initialValue":"0"}, + {"id":"extra3", "type":"any", "initialValue":"\"\""}, + {"id":"post_condition8", "type":"combo", "items":["","if greater","if less","if not existed"]} + ] + }, + { + "c2id": 6, + "id": "addscore6", + "scriptName": "AddScore", + "highlight": false, + "params": [ + {"id":"userıd0", "type":"string", "initialValue":"\"\""}, + {"id":"name1", "type":"string", "initialValue":"\"\""}, + {"id":"add2", "type":"any", "initialValue":"0"}, + {"id":"extra3", "type":"any", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "update": { + "conditions": [ + { + "c2id": 3, + "id": "onupdate3", + "scriptName": "OnUpdate", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 2, + "id": "updateallranks2", + "scriptName": "UpdateAllRanks", + "highlight": false + }, + { + "c2id": 3, + "id": "updatetopranks3", + "scriptName": "UpdateTopRanks", + "highlight": false, + "params": [ + {"id":"count0", "type":"number", "initialValue":"10"} + ] + }, + { + "c2id": 5, + "id": "stopupdating5", + "scriptName": "StopUpdating", + "highlight": false + } + ], + "expressions": [ + ] + }, + "remove": { + "conditions": [ + ], + "actions": [ + { + "c2id": 4, + "id": "removepost4", + "scriptName": "RemovePost", + "highlight": false, + "params": [ + {"id":"userıd0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "score": { + "conditions": [ + ], + "actions": [ + { + "c2id": 22, + "id": "getscore22", + "scriptName": "GetScore", + "highlight": false, + "params": [ + {"id":"userıd0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "update_-_for_each": { + "conditions": [ + { + "c2id": 11, + "id": "foreachrank11", + "scriptName": "ForEachRank", + "isLooping": "true", + "isInvertible": "false", + "highlight": false + }, + { + "c2id": 12, + "id": "foreachrank12", + "scriptName": "ForEachRank", + "isLooping": "true", + "isInvertible": "false", + "highlight": false, + "params": [ + {"id":"start0", "type":"number", "initialValue":"0"}, + {"id":"end1", "type":"number", "initialValue":"2"} + ] + } + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 1, + "id": "curplayername1", + "expressionName": "CurPlayerName", + "scriptName": "CurPlayerName", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 2, + "id": "curplayerscore2", + "expressionName": "CurPlayerScore", + "scriptName": "CurPlayerScore", + "highlight": false, + "returnType": "any" + }, + { + "c2id": 3, + "id": "curplayerrank3", + "expressionName": "CurPlayerRank", + "scriptName": "CurPlayerRank", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 4, + "id": "curuserıd4", + "expressionName": "CurUserID", + "scriptName": "CurUserID", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 5, + "id": "curextradata5", + "expressionName": "CurExtraData", + "scriptName": "CurExtraData", + "highlight": false, + "returnType": "any" + } + ] + }, + "score_-_get": { + "conditions": [ + { + "c2id": 23, + "id": "ongetscore23", + "scriptName": "OnGetScore", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "post": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 11, + "id": "postplayername11", + "expressionName": "PostPlayerName", + "scriptName": "PostPlayerName", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 12, + "id": "postplayerscore12", + "expressionName": "PostPlayerScore", + "scriptName": "PostPlayerScore", + "highlight": false, + "returnType": "any" + }, + { + "c2id": 14, + "id": "postplayeruserıd14", + "expressionName": "PostPlayerUserID", + "scriptName": "PostPlayerUserID", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 15, + "id": "postextradata15", + "expressionName": "PostExtraData", + "scriptName": "PostExtraData", + "highlight": false, + "returnType": "any" + } + ] + }, + "rank": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 21, + "id": "rankcount21", + "expressionName": "RankCount", + "scriptName": "RankCount", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 22, + "id": "userıd2rank22", + "expressionName": "UserID2Rank", + "scriptName": "UserID2Rank", + "highlight": false, + "returnType": "number", + "params": [ + {"id":"userıd0", "type":"string", "initialValue":"\"\""} + ] + } + ] + }, + "rank_index": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 23, + "id": "rank2playername23", + "expressionName": "Rank2PlayerName", + "scriptName": "Rank2PlayerName", + "highlight": false, + "returnType": "string", + "params": [ + {"id":"rank0", "type":"number", "initialValue":"0"} + ] + }, + { + "c2id": 24, + "id": "rank2playerscore24", + "expressionName": "Rank2PlayerScore", + "scriptName": "Rank2PlayerScore", + "highlight": false, + "returnType": "any", + "params": [ + {"id":"rank0", "type":"number", "initialValue":"0"} + ] + }, + { + "c2id": 25, + "id": "rank2extradata25", + "expressionName": "Rank2ExtraData", + "scriptName": "Rank2ExtraData", + "highlight": false, + "returnType": "any", + "params": [ + {"id":"rank0", "type":"number", "initialValue":"0"} + ] + }, + { + "c2id": 26, + "id": "rank2playeruserıd26", + "expressionName": "Rank2PlayerUserID", + "scriptName": "Rank2PlayerUserID", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true, + "params": [ + {"id":"rank0", "type":"number", "initialValue":"0"} + ] + } + ] + }, + "request": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 52, + "id": "lastuserıd52", + "expressionName": "LastUserID", + "scriptName": "LastUserID", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 53, + "id": "lastscore53", + "expressionName": "LastScore", + "scriptName": "LastScore", + "highlight": false, + "returnType": "any" + }, + { + "c2id": 54, + "id": "lastplayername54", + "expressionName": "LastPlayerName", + "scriptName": "LastPlayerName", + "highlight": false, + "returnType": "any" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/addon.json new file mode 100755 index 0000000..432b817 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/addon.json @@ -0,0 +1,26 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Leader board", + "id": "Rex_Firebase_Leaderboard", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_leaderboard.html", + "documentation": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_leaderboard.html", + "description": "Leader board built on firebase.", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c2runtime/runtime.js new file mode 100755 index 0000000..7b69e75 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c2runtime/runtime.js @@ -0,0 +1,492 @@ +/* + + name - user name + score - score + extra - extra data like photo + updateAt - timestamp of last score updating +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_Leaderboard = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_Leaderboard.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + + this.ranking_order = this.properties[2]; + + this.ranks = this.create_ranks(this.properties[3]==1); + + this.exp_CurRankCol = null; + this.exp_CurPlayerRank = -1; + + this.exp_PostPlayerName = ""; + this.exp_PostPlayerScore = 0; + this.exp_PostPlayerUserID = ""; + this.exp_PostExtraData = ""; + + this.exp_LastUserID = ""; + this.exp_LastScore = 0; + this.exp_LastPlayerName = ""; + }; + + instanceProto.onDestroy = function () + { + this.ranks.StopUpdate(); + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + instanceProto.create_ranks = function(isAutoUpdate) + { + var ranks = new window.FirebaseItemListKlass(); + + ranks.updateMode = (isAutoUpdate)? ranks.AUTOCHILDUPDATE : ranks.MANUALUPDATE; + ranks.keyItemID = "userID"; + + var self = this; + var on_update = function() + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Leaderboard.prototype.cnds.OnUpdate, self); + }; + ranks.onItemsFetch = on_update; + ranks.onItemAdd = on_update; + ranks.onItemRemove = on_update; + ranks.onItemChange = on_update; + + var onGetIterItem = function(item, i) + { + self.exp_CurRankCol = item; + self.exp_CurPlayerRank = i; + }; + ranks.onGetIterItem = onGetIterItem; + + return ranks; + }; + + instanceProto.update_ranks = function (count) + { + var query = this.get_ref(); + if (count == -1) // update all + { + // no filter + } + else + { + query = query["orderByPriority"]()["limitToFirst"](count); + } + + this.ranks.StartUpdate(query); + }; + + var get_extraData = function (extra_data) + { + var save_extra_data; + if (extra_data == "") + { + save_extra_data = null; + } + else + { + try + { + save_extra_data = JSON.parse(extra_data) + } + catch(err) + { + save_extra_data = extra_data; + } + } + return save_extra_data; + } + instanceProto.post_score = function (userID, name, score, extra_data) + { + extra_data = get_extraData(extra_data); + + var self = this; + var onComplete = function(error) + { + self.onPostComplete.call(self, error, userID, name, score, extra_data); + }; + + var save_data = {"name":name, + "score":score, + "extra": extra_data, + "updateAt": serverTimeStamp() + }; + var priority = (this.ranking_order == 0)? score:-score; + var ref = this.get_ref(); + ref["child"](userID)["setWithPriority"](save_data, priority, onComplete); + }; + + instanceProto.onPostComplete = function(error, userID, name, score, extra_data) + { + this.exp_PostPlayerName = name; + this.exp_PostPlayerScore = score; + this.exp_PostPlayerUserID = userID; + this.exp_PostExtraData = extra_data; + var trig = (error)? cr.plugins_.Rex_Firebase_Leaderboard.prototype.cnds.OnPostError: + cr.plugins_.Rex_Firebase_Leaderboard.prototype.cnds.OnPostComplete; + this.runtime.trigger(trig, this); + }; + + ////////////////////////////////////// + // Conditions + function Cnds() {}; + pluginProto.cnds = new Cnds(); + + Cnds.prototype.OnPostComplete = function () + { + return true; + }; + Cnds.prototype.OnPostError = function () + { + return true; + }; + Cnds.prototype.OnUpdate = function () + { + return true; + }; + Cnds.prototype.ForEachRank = function (start, end) + { + return this.ranks.ForEachItem(this.runtime, start, end); + }; + + Cnds.prototype.OnGetScore = function () + { + return true; + }; + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetDomainRef = function (ref, ID_) + { + this.ranks.StopUpdate(); + this.rootpath = ref + "/" + ID_ + "/"; + }; + + Acts.prototype.PostScore = function (userID, name, score, extra_data, post_cond) + { + if (post_cond !== 0) + { + var self=this; + var onReadScore = function(snapshot) + { + var preScore = snapshot["val"](); + var doPosting; + if (post_cond === 1) + doPosting = (score > preScore); + else if (post_cond === 2) + doPosting = (score < preScore); + else if (post_cond === 3) + doPosting = (preScore == null) ; + + if (doPosting) + self.post_score(userID, name, score, extra_data); + else + { + self.onPostComplete.call(self, false, userID, name, preScore, extra_data); + } + }; + var ref = this.get_ref()["child"](userID)["child"]("score"); + ref["once"]("value", onReadScore) + } + else + { + this.post_score(userID, name, score, extra_data); + } + }; + + Acts.prototype.UpdateAllRanks = function () + { + this.update_ranks(-1); + }; + + Acts.prototype.UpdateTopRanks = function (count) + { + this.update_ranks(count); + }; + + Acts.prototype.RemovePost = function (userID) + { + var ref = this.get_ref(); + ref["child"](userID)["remove"](); + }; + + Acts.prototype.StopUpdating = function () + { + this.ranks.StopUpdate(); + }; + + Acts.prototype.AddScore = function (userID, name, scoreAddTo, extra_data) + { + extra_data = get_extraData(extra_data); + + var self = this; + var on_complete = function(error, committed, snapshot) + { + var val = snapshot["val"](); + self.onPostComplete.call(self, error, userID, name, val["score"], extra_data); + }; + + var on_transaction = function (currentValue) + { + var old_score = (currentValue == null)? 0: currentValue["score"]; + var new_score = old_score + scoreAddTo; + var save_data = {"name":name, + "score":new_score, + "extra": extra_data, + "updateAt": serverTimeStamp() + }; + var priority = (self.ranking_order == 0)? new_score:-new_score; + return { '.value': save_data, '.priority': priority }; + }; + var ref = this.get_ref(); + ref["child"](userID)["transaction"](on_transaction, on_complete); + }; + + Acts.prototype.GetScore = function (userID) + { + var self=this; + var onReadUserID = function(snapshot) + { + var userData = snapshot["val"](); + if (userData) + { + self.exp_LastUserID = userID; + self.exp_LastScore = userData["score"]; + self.exp_LastPlayerName = userData["name"]; + } + else + { + self.exp_LastUserID = ""; + self.exp_LastScore = 0; + self.exp_LastPlayerName = ""; + } + self.runtime.trigger(cr.plugins_.Rex_Firebase_Leaderboard.prototype.cnds.OnGetScore, self); + }; + var ref = this.get_ref()["child"](userID); + ref["once"]("value", onReadUserID); + }; + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.CurPlayerName = function (ret) + { + var name; + if (this.exp_CurRankCol != null) + name = this.exp_CurRankCol["name"]; + else + name = ""; + + ret.set_string(name); + }; + Exps.prototype.CurPlayerScore = function (ret) + { + var score; + if (this.exp_CurRankCol != null) + score = this.exp_CurRankCol["score"]; + else + score = 0; + + ret.set_any(score); + }; + Exps.prototype.CurPlayerRank = function (ret) + { + ret.set_int(this.exp_CurPlayerRank); + }; + Exps.prototype.CurUserID = function (ret) + { + var userID; + if (this.exp_CurRankCol != null) + userID = this.exp_CurRankCol["userID"]; + else + userID = ""; + + ret.set_string(this.exp_CurRankCol["userID"]); + }; + Exps.prototype.CurExtraData = function (ret) + { + var extra_data = this.exp_CurRankCol["extra"]; + if (extra_data == null) + { + extra_data = ""; + } + else if (typeof(extra_data) == "object") + { + extra_data = JSON.stringify(extra_data); + this.exp_CurRankCol["extra"] = extra_data; + } + + ret.set_any(extra_data); + }; + + + Exps.prototype.PostPlayerName = function (ret) + { + ret.set_string(this.exp_PostPlayerName); + }; + + Exps.prototype.PostPlayerScore = function (ret) + { + ret.set_any(this.exp_PostPlayerScore); + }; + Exps.prototype.PostPlayerUserID = function (ret) + { + ret.set_string(this.exp_PostPlayerUserID); + }; + + Exps.prototype.PostExtraData = function (ret) + { + ret.set_any(this.exp_PostExtraData); + }; + + Exps.prototype.RankCount = function (ret) + { + ret.set_int(this.ranks.GetItems().length); + }; + Exps.prototype.UserID2Rank = function (ret, userID) + { + var rank = this.ranks.GetItemIndexByID(userID); + if (rank == null) + rank = -1; + ret.set_int(rank); + }; + + Exps.prototype.Rank2PlayerName = function (ret, i) + { + var rank_info = this.ranks.GetItems()[i]; + var name = (!rank_info)? "":rank_info["name"]; + ret.set_string(name); + }; + Exps.prototype.Rank2PlayerScore = function (ret, i) + { + var rank_info = this.ranks.GetItems()[i]; + var score = (!rank_info)? "":rank_info["score"]; + ret.set_any(score); + }; + Exps.prototype.Rank2ExtraData = function (ret, i) + { + var rank_info = this.ranks.GetItems()[i]; + var extra_data = (!rank_info)? "":rank_info["extra"]; + ret.set_any(extra_data); + }; + Exps.prototype.Rank2PlayerUserID = function (ret, i) + { + var rank_info = this.ranks.GetItems()[i]; + var extra_data = (!rank_info)? "":rank_info["userID"]; + ret.set_any(extra_data); + }; + + Exps.prototype.LastUserID = function (ret) + { + ret.set_string(this.exp_LastUserID); + }; + Exps.prototype.LastScore = function (ret) + { + ret.set_any(this.exp_LastScore); + }; + Exps.prototype.LastPlayerName = function (ret) + { + ret.set_any(this.exp_LastPlayerName); + }; +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/actions.js new file mode 100755 index 0000000..79e6bd2 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/actions.js @@ -0,0 +1,116 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Leaderboard.Acts = + { + SetDomainRef(ref, ID_) + { + this.ranks.StopUpdate(); + this.rootpath = ref + "/" + ID_ + "/"; + }, + + PostScore(userID, name, score, extra_data, post_cond) + { + if (post_cond !== 0) + { + var self=this; + var onReadScore = function(snapshot) + { + var preScore = snapshot["val"](); + var doPosting; + if (post_cond === 1) + doPosting = (score > preScore); + else if (post_cond === 2) + doPosting = (score < preScore); + else if (post_cond === 3) + doPosting = (preScore == null) ; + + if (doPosting) + self.post_score(userID, name, score, extra_data); + else + { + self.onPostComplete.call(self, false, userID, name, preScore, extra_data); + } + }; + var ref = this.get_ref()["child"](userID)["child"]("score"); + ref["once"]("value", onReadScore) + } + else + { + this.post_score(userID, name, score, extra_data); + } + }, + + UpdateAllRanks() + { + this.update_ranks(-1); + }, + + UpdateTopRanks(count) + { + this.update_ranks(count); + }, + + RemovePost(userID) + { + var ref = this.get_ref(); + ref["child"](userID)["remove"](); + }, + + StopUpdating() + { + this.ranks.StopUpdate(); + }, + + AddScore(userID, name, scoreAddTo, extra_data) + { + extra_data = get_extraData(extra_data); + + var self = this; + var on_complete = function(error, committed, snapshot) + { + var val = snapshot["val"](); + self.onPostComplete.call(self, error, userID, name, val["score"], extra_data); + }; + + var on_transaction = function (currentValue) + { + var old_score = (currentValue == null)? 0: currentValue["score"]; + var new_score = old_score + scoreAddTo; + var save_data = {"name":name, + "score":new_score, + "extra": extra_data, + "updateAt": serverTimeStamp() + }; + var priority = (self.ranking_order == 0)? new_score:-new_score; + return { '.value': save_data, '.priority': priority }; + }; + var ref = this.get_ref(); + ref["child"](userID)["transaction"](on_transaction, on_complete); + }, + + GetScore(userID) + { + var self=this; + var onReadUserID = function(snapshot) + { + var userData = snapshot["val"](); + if (userData) + { + self.exp_LastUserID = userID; + self.exp_LastScore = userData["score"]; + self.exp_LastPlayerName = userData["name"]; + } + else + { + self.exp_LastUserID = ""; + self.exp_LastScore = 0; + self.exp_LastPlayerName = ""; + } + self.Trigger(C3.Plugins.Rex_Firebase_Leaderboard.Cnds.OnGetScore); + }; + var ref = this.get_ref()["child"](userID); + ref["once"]("value", onReadUserID); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/conditions.js new file mode 100755 index 0000000..bfa862d --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/conditions.js @@ -0,0 +1,28 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Leaderboard.Cnds = + { + OnPostComplete() + { + return true; + }, + OnPostError() + { + return true; + }, + OnUpdate() + { + return true; + }, + ForEachRank(start, end) + { + return this.ranks.ForEachItem(this._runtime, start, end); + }, + + OnGetScore() + { + return true; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/expressions.js new file mode 100755 index 0000000..a33f8f4 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/expressions.js @@ -0,0 +1,124 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Leaderboard.Exps = + { + CurPlayerName() + { + var name; + if (this.exp_CurRankCol != null) + name = this.exp_CurRankCol["name"]; + else + name = ""; + + return (name); + }, + CurPlayerScore() + { + var score; + if (this.exp_CurRankCol != null) + score = this.exp_CurRankCol["score"]; + else + score = 0; + + return (score); + }, + CurPlayerRank() + { + return (this.exp_CurPlayerRank); + }, + CurUserID() + { + var userID; + if (this.exp_CurRankCol != null) + userID = this.exp_CurRankCol["userID"]; + else + userID = ""; + + return (this.exp_CurRankCol["userID"]); + }, + CurExtraData() + { + var extra_data = this.exp_CurRankCol["extra"]; + if (extra_data == null) + { + extra_data = ""; + } + else if (typeof(extra_data) == "object") + { + extra_data = JSON.stringify(extra_data); + this.exp_CurRankCol["extra"] = extra_data; + } + + return (extra_data); + }, + PostPlayerName() + { + return (this.exp_PostPlayerName); + }, + + PostPlayerScore() + { + return (this.exp_PostPlayerScore); + }, + PostPlayerUserID() + { + return (this.exp_PostPlayerUserID); + }, + + PostExtraData() + { + return (this.exp_PostExtraData); + }, + + RankCount() + { + return (this.ranks.GetItems().length); + }, + UserID2Rank(userID) + { + var rank = this.ranks.GetItemIndexByID(userID); + if (rank == null) + rank = -1; + return (rank); + }, + + Rank2PlayerName(i) + { + var rank_info = this.ranks.GetItems()[i]; + var name = (!rank_info)? "":rank_info["name"]; + return (name); + }, + Rank2PlayerScore(i) + { + var rank_info = this.ranks.GetItems()[i]; + var score = (!rank_info)? "":rank_info["score"]; + return (score); + }, + Rank2ExtraData(i) + { + var rank_info = this.ranks.GetItems()[i]; + var extra_data = (!rank_info)? "":rank_info["extra"]; + return (extra_data); + }, + Rank2PlayerUserID(i) + { + var rank_info = this.ranks.GetItems()[i]; + var extra_data = (!rank_info)? "":rank_info["userID"]; + return (extra_data); + }, + + LastUserID() + { + return (this.exp_LastUserID); + }, + LastScore() + { + return (this.exp_LastScore); + }, + LastPlayerName() + { + return (this.exp_LastPlayerName); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/instance.js new file mode 100755 index 0000000..3d126b4 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/instance.js @@ -0,0 +1,152 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Leaderboard.Instance = class Rex_Firebase_LeaderboardInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + + + + + this.exp_CurRankCol = null; + this.exp_CurPlayerRank = -1; + + this.exp_PostPlayerName = ""; + this.exp_PostPlayerScore = 0; + this.exp_PostPlayerUserID = ""; + this.exp_PostExtraData = ""; + + this.exp_LastUserID = ""; + this.exp_LastScore = 0; + this.exp_LastPlayerName = ""; + + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/" + properties[1] + "/"; + this.ranking_order = properties[2]; + this.ranks = this.create_ranks(properties[3]==1); + } + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + + get_ref(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + } + + create_ranks(isAutoUpdate) + { + var ranks = new window.FirebaseItemListKlass(); + + ranks.updateMode = (isAutoUpdate)? ranks.AUTOCHILDUPDATE : ranks.MANUALUPDATE; + ranks.keyItemID = "userID"; + + var self = this; + var on_update = function() + { + self.Trigger(C3.Plugins.Rex_Firebase_Leaderboard.Cnds.OnUpdate); + }; + ranks.onItemsFetch = on_update; + ranks.onItemAdd = on_update; + ranks.onItemRemove = on_update; + ranks.onItemChange = on_update; + + var onGetIterItem = function(item, i) + { + self.exp_CurRankCol = item; + self.exp_CurPlayerRank = i; + }; + ranks.onGetIterItem = onGetIterItem; + + return ranks; + } + + update_ranks(count) + { + var query = this.get_ref(); + if (count == -1) // update all + { + // no filter + } + else + { + query = query["orderByPriority"]()["limitToFirst"](count); + } + + this.ranks.StartUpdate(query); + } + + + post_score(userID, name, score, extra_data) + { + extra_data = get_extraData(extra_data); + + var self = this; + var onComplete = function(error) + { + self.onPostComplete.call(self, error, userID, name, score, extra_data); + }; + + var save_data = {"name":name, + "score":score, + "extra": extra_data, + "updateAt": serverTimeStamp() + }; + var priority = (this.ranking_order == 0)? score:-score; + var ref = this.get_ref(); + ref["child"](userID)["setWithPriority"](save_data, priority, onComplete); + } + + onPostComplete(error, userID, name, score, extra_data) + { + this.exp_PostPlayerName = name; + this.exp_PostPlayerScore = score; + this.exp_PostPlayerUserID = userID; + this.exp_PostExtraData = extra_data; + var trig = (error)? C3.Plugins.Rex_Firebase_Leaderboard.Cnds.OnPostError: + C3.Plugins.Rex_Firebase_Leaderboard.Cnds.OnPostComplete; + this.Trigger(trig); + } + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/plugin.js new file mode 100755 index 0000000..ad9d175 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/plugin.js @@ -0,0 +1,71 @@ +"use strict"; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + var get_extraData = function (extra_data) + { + var save_extra_data; + if (extra_data == "") + { + save_extra_data = null; + } + else + { + try + { + save_extra_data = JSON.parse(extra_data) + } + catch(err) + { + save_extra_data = extra_data; + } + } + return save_extra_data; + } + +{ + C3.Plugins.Rex_Firebase_Leaderboard = class Rex_Firebase_LeaderboardPlugin extends C3.SDKPluginBase + { + constructor(opts) + { + super(opts); + } + + Release() + { + super.Release(); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/type.js new file mode 100755 index 0000000..d2062f9 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/c3runtime/type.js @@ -0,0 +1,20 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Leaderboard.Type = class Rex_Firebase_LeaderboardType extends C3.SDKTypeBase + { + constructor(objectClass) + { + super(objectClass); + } + + Release() + { + super.Release(); + } + + OnCreate() + { + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/icon.png new file mode 100755 index 0000000..1cc04d5 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/instance.js new file mode 100755 index 0000000..559d2c6 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Leaderboard; + + PLUGIN_CLASS.Instance = class Rex_Firebase_LeaderboardInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/lang/en-US.json new file mode 100755 index 0000000..02561c5 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/lang/en-US.json @@ -0,0 +1,245 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Leader board.", + "text": { + "plugins": { + "rex_firebase_leaderboard": { + "name": "Leader board", + "description": "Leader board built on firebase.", + "help-url": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_leaderboard.html", + "properties": { + "domain": { + "name": "Domain", + "desc": "The root location of the Firebase data." + }, + "ıd": { + "name": "ID", + "desc": "ID of leader board, i.e. \"Sub domain\"." + }, + "order": { + "name": "Order", + "desc": "Ranking order.", + "items": { + "small to large":"Small to large", + "large to small":"Large to small" + } + }, + "update": { + "name": "Update", + "desc": "Manual update or auto update.", + "items": { + "manual":"Manual", + "auto":"Auto" + } + } + }, + "aceCategories": { + "domain": "Domain", + "send": "Send", + "update": "Update", + "remove": "Remove", + "score": "Score", + "update_-_for_each": "Update - for each", + "score_-_get": "Score - get", + "post": "Post", + "rank": "Rank", + "rank_index": "Rank index", + "request": "Request" + }, + "conditions": { + "onpostcomplete1": { + "list-name": "On post complete", + "display-text": "On post complete", + "description": "Triggered when post complete." + }, + "onposterror2": { + "list-name": "On post error", + "display-text": "On post error", + "description": "Triggered when post error." + }, + "onupdate3": { + "list-name": "On update", + "display-text": "On update ranks", + "description": "Triggered when ranks updated." + }, + "foreachrank11": { + "list-name": "For each rank", + "display-text": "For each rank", + "description": "Repeat the event for each rank." + }, + "foreachrank12": { + "list-name": "For each rank in a range", + "display-text": "For each rank from [i]{0}[/i] to [i]{1}[/i]", + "description": "Repeat the event for each rank in a range.", + "params": { + "start0": { "name":"Start", "desc":"Start from rank index (0-based)."}, + "end1": { "name":"End", "desc":"End to rank index (0-based). This value should larger than Start."} + } + }, + "ongetscore23": { + "list-name": "On get score", + "display-text": "On get score", + "description": "Triggered when get score." + } + }, + "actions": { + "setdomainref0": { + "list-name": "Set domain", + "display-text": "Set domain to [i]{0}[/i], ID to [i]{1}[/i]", + "description": "Set domain ref.", + "params": { + "domain0": { "name":"Domain", "desc":"The root location of the Firebase data."}, + "ıd1": { "name":"ID", "desc":"ID of leader board, i.e. \"Sub domain\"."} + } + }, + "postscore1": { + "list-name": "Post score", + "display-text": "Post (User ID: [i]{0}[/i]) [i]{1}[/i]: [i]{2}[/i], extra data to [i]{3}[/i] [i]{4}[/i]", + "description": "Post score by user ID.", + "params": { + "userıd0": { "name":"UserID", "desc":"UserID from authentication."}, + "name1": { "name":"Name", "desc":"Player name."}, + "score2": { "name":"Score", "desc":"Player Score"}, + "extra3": { "name":"Extra", "desc":"Extra data, could be number or (JSON) string."}, + "post_condition8": { "name":"Post condition", "desc":"Post if score is greater or less then saved score.", "items":{"":"","if greater":"if greater","if less":"if less","if not existed":"if not existed"}} + } + }, + "updateallranks2": { + "list-name": "Update all", + "display-text": "Update all ranks", + "description": "Update all ranks." + }, + "updatetopranks3": { + "list-name": "Update top", + "display-text": "Update top [i]{0}[/i] ranks", + "description": "Update top ranks.", + "params": { + "count0": { "name":"Count", "desc":"The count of top ranks."} + } + }, + "removepost4": { + "list-name": "Remove post", + "display-text": "Remove post by User ID: [i]{0}[/i]", + "description": "Remove post by User ID.", + "params": { + "userıd0": { "name":"UserID", "desc":"UserID from authentication."} + } + }, + "stopupdating5": { + "list-name": "Stop updating", + "display-text": "Stop updating", + "description": "Stop updating ranks." + }, + "addscore6": { + "list-name": "Add to score", + "display-text": "Add [i]{2}[/i] to (User ID: [i]{0}[/i]) [i]{1}[/i] 's score, extra data to [i]{3}[/i]", + "description": "Add score by user ID.", + "params": { + "userıd0": { "name":"UserID", "desc":"UserID from authentication."}, + "name1": { "name":"Name", "desc":"(Optional) Player name."}, + "add2": { "name":"Add", "desc":"Add score"}, + "extra3": { "name":"Extra", "desc":"(Optional) Extra data, could be number or (JSON) string."} + } + }, + "getscore22": { + "list-name": "Get score", + "display-text": "Get score of User ID: [i]{0}[/i]", + "description": "Get score.", + "params": { + "userıd0": { "name":"UserID", "desc":"UserID from authentication."} + } + } + }, + "expressions": { + "curplayername1": { + "description": "Get the current player name in a For Each loop.", + "translated-name": "CurPlayerName" + }, + "curplayerscore2": { + "description": "Get the current player score in a For Each loop.", + "translated-name": "CurPlayerScore" + }, + "curplayerrank3": { + "description": "Get the current player rank (0-based) in a For Each loop.", + "translated-name": "CurPlayerRank" + }, + "curuserıd4": { + "description": "Get the current user id in a For Each loop.", + "translated-name": "CurUserID" + }, + "curextradata5": { + "description": "Get the current extra data in a For Each loop.", + "translated-name": "CurExtraData" + }, + "postplayername11": { + "description": "The post player name. Uses under \"condition:On post complete\".", + "translated-name": "PostPlayerName" + }, + "postplayerscore12": { + "description": "Get posted current player score under \"condition:On post complete\".", + "translated-name": "PostPlayerScore" + }, + "postplayeruserıd14": { + "description": "Get posted current user id under \"condition:On post complete\".", + "translated-name": "PostPlayerUserID" + }, + "postextradata15": { + "description": "Get posted current extra data under \"condition:On post complete\".", + "translated-name": "PostExtraData" + }, + "rankcount21": { + "description": "Get total rank count.", + "translated-name": "RankCount" + }, + "userıd2rank22": { + "description": "Get rank by user ID. Return (-1) if not found.", + "translated-name": "UserID2Rank", + "params": { + "userıd0": { "name":"UserID", "desc":"UserID from authentication."} + } + }, + "rank2playername23": { + "description": "Get player name by rank index.", + "translated-name": "Rank2PlayerName", + "params": { + "rank0": { "name":"Rank", "desc":"Rank index (0-based)."} + } + }, + "rank2playerscore24": { + "description": "Get player score by rank index.", + "translated-name": "Rank2PlayerScore", + "params": { + "rank0": { "name":"Rank", "desc":"Rank index (0-based)."} + } + }, + "rank2extradata25": { + "description": "Get extra data by rank index.", + "translated-name": "Rank2ExtraData", + "params": { + "rank0": { "name":"Rank", "desc":"Rank index (0-based)."} + } + }, + "rank2playeruserıd26": { + "description": "Get userID by rank index. Add default value at 2nd parameter.", + "translated-name": "Rank2PlayerUserID", + "params": { + "rank0": { "name":"Rank", "desc":"Rank index (0-based)."} + } + }, + "lastuserıd52": { + "description": "Get requested userID. Return \"\" if invalided.", + "translated-name": "LastUserID" + }, + "lastscore53": { + "description": "Get requested score. Return 0 if invalided.", + "translated-name": "LastScore" + }, + "lastplayername54": { + "description": "Get requested score. Return \"\" if invalided.", + "translated-name": "LastPlayerName" + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/plugin.js new file mode 100755 index 0000000..4f0371e --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/plugin.js @@ -0,0 +1,44 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase_Leaderboard"; + const PLUGIN_VERSION = "0.1.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Leaderboard = class Rex_Firebase_Leaderboard extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "domain", ""), + new SDK.PluginProperty("text", "ıd", "Leaderboard"), + new SDK.PluginProperty("combo", "order", {initialValue:"large to small", items:["small to large","large to small"]}), + new SDK.PluginProperty("combo", "update", {initialValue:"manual", items:["manual","auto"]}) + ]); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/type.js new file mode 100755 index 0000000..e9754be --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_leaderboard/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Leaderboard; + + PLUGIN_CLASS.Type = class Rex_Firebase_LeaderboardType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/dist/rex_firebase_message.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/dist/rex_firebase_message.c3addon new file mode 100644 index 0000000..fd6b973 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/dist/rex_firebase_message.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/source/aces.json new file mode 100755 index 0000000..a1ad952 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/source/aces.json @@ -0,0 +1,109 @@ +{ + "user_info": { + "conditions": [ + ], + "actions": [ + { + "c2id": 1, + "id": "setuserınfo1", + "scriptName": "SetUserInfo", + "highlight": false, + "params": [ + {"id":"sender_ıd0", "type":"string", "initialValue":"\"\""}, + {"id":"sender_name1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "update": { + "conditions": [ + ], + "actions": [ + { + "c2id": 11, + "id": "startupdate11", + "scriptName": "StartUpdate", + "highlight": false, + "params": [ + {"id":"receiver_ıd0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 12, + "id": "stopupdate12", + "scriptName": "StopUpdate", + "highlight": false + } + ], + "expressions": [ + ] + }, + "message": { + "conditions": [ + { + "c2id": 1, + "id": "onnewmessage1", + "scriptName": "OnNewMessage", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 21, + "id": "send21", + "scriptName": "Send", + "highlight": false, + "params": [ + {"id":"receiver_userıd0", "type":"string", "initialValue":"\"\""}, + {"id":"title1", "type":"string", "initialValue":"\"\""}, + {"id":"content2", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + { + "c2id": 1, + "id": "lastsenderıd1", + "expressionName": "LastSenderID", + "scriptName": "LastSenderID", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 2, + "id": "lastsendername2", + "expressionName": "LastSenderName", + "scriptName": "LastSenderName", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 3, + "id": "lasttitle3", + "expressionName": "LastTitle", + "scriptName": "LastTitle", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 4, + "id": "lastcontent4", + "expressionName": "LastContent", + "scriptName": "LastContent", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 5, + "id": "lastmessageıd5", + "expressionName": "LastMessageID", + "scriptName": "LastMessageID", + "highlight": false, + "returnType": "string" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/source/addon.json new file mode 100755 index 0000000..a9fae8d --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/source/addon.json @@ -0,0 +1,27 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Message", + "id": "Rex_Firebase_message", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_message.html", + "documentation": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_message.html", + "description": "Send/receive messages.", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "firebase.js", + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/source/c2runtime/runtime.js new file mode 100755 index 0000000..16a429a --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_message/source/c2runtime/runtime.js @@ -0,0 +1,305 @@ +/* +headers\ + + senderID - userID of sender + senderName - name of sender + receiverID - userID of receiver + title - title (header) of message + sentAt - timestamp +bodies\ + - content (body) of message, string or json object in string + +*/ + + +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_message = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_message.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + jsfile_load("firebase.js"); + }; + + var jsfile_load = function(file_name) + { + var scripts=document.getElementsByTagName("script"); + var exist=false; + for(var i=0;ib?e+="000":256>b?e+="00":4096>b&&(e+="0");return Ea[a]=e+b.toString(16)}),'"')};function Ga(){return Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^la()).toString(36)};var Ha;a:{var Ia=aa.navigator;if(Ia){var Ja=Ia.userAgent;if(Ja){Ha=Ja;break a}}Ha=""};function Ka(){this.Va=-1};function La(){this.Va=-1;this.Va=64;this.N=[];this.me=[];this.Wf=[];this.Ld=[];this.Ld[0]=128;for(var a=1;ae;e++)d[e]=b.charCodeAt(c)<<24|b.charCodeAt(c+1)<<16|b.charCodeAt(c+2)<<8|b.charCodeAt(c+3),c+=4;else for(e=0;16>e;e++)d[e]=b[c]<<24|b[c+1]<<16|b[c+2]<<8|b[c+3],c+=4;for(e=16;80>e;e++){var f=d[e-3]^d[e-8]^d[e-14]^d[e-16];d[e]=(f<<1|f>>>31)&4294967295}b=a.N[0];c=a.N[1];for(var h=a.N[2],k=a.N[3],l=a.N[4],m,e=0;80>e;e++)40>e?20>e?(f=k^c&(h^k),m=1518500249):(f=c^h^k,m=1859775393):60>e?(f=c&h|k&(c|h),m=2400959708):(f=c^h^k,m=3395469782),f=(b<< +5|b>>>27)+f+l+m+d[e]&4294967295,l=k,k=h,h=(c<<30|c>>>2)&4294967295,c=b,b=f;a.N[0]=a.N[0]+b&4294967295;a.N[1]=a.N[1]+c&4294967295;a.N[2]=a.N[2]+h&4294967295;a.N[3]=a.N[3]+k&4294967295;a.N[4]=a.N[4]+l&4294967295} +La.prototype.update=function(a,b){if(null!=a){n(b)||(b=a.length);for(var c=b-this.Va,d=0,e=this.me,f=this.ac;dc?Math.max(0,a.length+c):c;if(p(a))return p(b)&&1==b.length?a.indexOf(b,c):-1;for(;cc?null:p(a)?a.charAt(c):a[c]}function Ua(a,b,c){for(var d=a.length,e=p(a)?a.split(""):a,f=0;f=arguments.length?u.slice.call(a,b):u.slice.call(a,b,c)} +function Xa(a,b){a.sort(b||Ya)}function Ya(a,b){return a>b?1:aparseFloat(a))?String(b):a})();var cb=null,db=null,eb=null;function fb(a,b){if(!fa(a))throw Error("encodeByteArray takes an array as a parameter");gb();for(var c=b?db:cb,d=[],e=0;e>2,f=(f&3)<<4|k>>4,k=(k&15)<<2|m>>6,m=m&63;l||(m=64,h||(k=64));d.push(c[t],c[f],c[k],c[m])}return d.join("")} +function gb(){if(!cb){cb={};db={};eb={};for(var a=0;65>a;a++)cb[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a),db[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.".charAt(a),eb[db[a]]=a,62<=a&&(eb["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a)]=a)}};var hb=hb||"2.3.2";function v(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function w(a,b){if(Object.prototype.hasOwnProperty.call(a,b))return a[b]}function ib(a,b){for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b(c,a[c])}function jb(a){var b={};ib(a,function(a,d){b[a]=d});return b};function kb(a){var b=[];ib(a,function(a,d){ea(d)?Oa(d,function(d){b.push(encodeURIComponent(a)+"="+encodeURIComponent(d))}):b.push(encodeURIComponent(a)+"="+encodeURIComponent(d))});return b.length?"&"+b.join("&"):""}function lb(a){var b={};a=a.replace(/^\?/,"").split("&");Oa(a,function(a){a&&(a=a.split("="),b[a[0]]=a[1])});return b};function x(a,b,c,d){var e;dc&&(e=0===c?"none":"no more than "+c);if(e)throw Error(a+" failed: Was called with "+d+(1===d?" argument.":" arguments.")+" Expects "+e+".");}function y(a,b,c){var d="";switch(b){case 1:d=c?"first":"First";break;case 2:d=c?"second":"Second";break;case 3:d=c?"third":"Third";break;case 4:d=c?"fourth":"Fourth";break;default:throw Error("errorPrefix called with argumentNumber > 4. Need to update it?");}return a=a+" failed: "+(d+" argument ")} +function A(a,b,c,d){if((!d||n(c))&&!ha(c))throw Error(y(a,b,d)+"must be a valid function.");}function mb(a,b,c){if(n(c)&&(!ia(c)||null===c))throw Error(y(a,b,!0)+"must be a valid context object.");};function nb(a){return"undefined"!==typeof JSON&&n(JSON.parse)?JSON.parse(a):Aa(a)}function B(a){if("undefined"!==typeof JSON&&n(JSON.stringify))a=JSON.stringify(a);else{var b=[];Ca(new Ba,a,b);a=b.join("")}return a};function ob(){this.Wd=C}ob.prototype.j=function(a){return this.Wd.Q(a)};ob.prototype.toString=function(){return this.Wd.toString()};function pb(){}pb.prototype.qf=function(){return null};pb.prototype.ye=function(){return null};var qb=new pb;function rb(a,b,c){this.Tf=a;this.Ka=b;this.Kd=c}rb.prototype.qf=function(a){var b=this.Ka.O;if(sb(b,a))return b.j().R(a);b=null!=this.Kd?new tb(this.Kd,!0,!1):this.Ka.w();return this.Tf.xc(a,b)};rb.prototype.ye=function(a,b,c){var d=null!=this.Kd?this.Kd:ub(this.Ka);a=this.Tf.ne(d,b,1,c,a);return 0===a.length?null:a[0]};function vb(){this.tb=[]}function wb(a,b){for(var c=null,d=0;db?c=c.left:0c?d=d.left:0e)a=this.Fe?a.left:a.right;else if(0===e){this.Pa.push(a);break}else this.Pa.push(a),a=this.Fe?a.right:a.left} +function J(a){if(0===a.Pa.length)return null;var b=a.Pa.pop(),c;c=a.Ud?a.Ud(b.key,b.value):{key:b.key,value:b.value};if(a.Fe)for(b=b.left;!b.e();)a.Pa.push(b),b=b.right;else for(b=b.right;!b.e();)a.Pa.push(b),b=b.left;return c}function ec(a){if(0===a.Pa.length)return null;var b;b=a.Pa;b=b[b.length-1];return a.Ud?a.Ud(b.key,b.value):{key:b.key,value:b.value}}function fc(a,b,c,d,e){this.key=a;this.value=b;this.color=null!=c?c:!0;this.left=null!=d?d:bc;this.right=null!=e?e:bc}g=fc.prototype; +g.Y=function(a,b,c,d,e){return new fc(null!=a?a:this.key,null!=b?b:this.value,null!=c?c:this.color,null!=d?d:this.left,null!=e?e:this.right)};g.count=function(){return this.left.count()+1+this.right.count()};g.e=function(){return!1};g.ia=function(a){return this.left.ia(a)||a(this.key,this.value)||this.right.ia(a)};function gc(a){return a.left.e()?a:gc(a.left)}g.Sc=function(){return gc(this).key};g.fc=function(){return this.right.e()?this.key:this.right.fc()}; +g.Oa=function(a,b,c){var d,e;e=this;d=c(a,e.key);e=0>d?e.Y(null,null,null,e.left.Oa(a,b,c),null):0===d?e.Y(null,b,null,null,null):e.Y(null,null,null,null,e.right.Oa(a,b,c));return hc(e)};function ic(a){if(a.left.e())return bc;a.left.fa()||a.left.left.fa()||(a=jc(a));a=a.Y(null,null,null,ic(a.left),null);return hc(a)} +g.remove=function(a,b){var c,d;c=this;if(0>b(a,c.key))c.left.e()||c.left.fa()||c.left.left.fa()||(c=jc(c)),c=c.Y(null,null,null,c.left.remove(a,b),null);else{c.left.fa()&&(c=kc(c));c.right.e()||c.right.fa()||c.right.left.fa()||(c=lc(c),c.left.left.fa()&&(c=kc(c),c=lc(c)));if(0===b(a,c.key)){if(c.right.e())return bc;d=gc(c.right);c=c.Y(d.key,d.value,null,null,ic(c.right))}c=c.Y(null,null,null,null,c.right.remove(a,b))}return hc(c)};g.fa=function(){return this.color}; +function hc(a){a.right.fa()&&!a.left.fa()&&(a=mc(a));a.left.fa()&&a.left.left.fa()&&(a=kc(a));a.left.fa()&&a.right.fa()&&(a=lc(a));return a}function jc(a){a=lc(a);a.right.left.fa()&&(a=a.Y(null,null,null,null,kc(a.right)),a=mc(a),a=lc(a));return a}function mc(a){return a.right.Y(null,null,a.color,a.Y(null,null,!0,null,a.right.left),null)}function kc(a){return a.left.Y(null,null,a.color,null,a.Y(null,null,!0,a.left.right,null))} +function lc(a){return a.Y(null,null,!a.color,a.left.Y(null,null,!a.left.color,null,null),a.right.Y(null,null,!a.right.color,null,null))}function nc(){}g=nc.prototype;g.Y=function(){return this};g.Oa=function(a,b){return new fc(a,b,null)};g.remove=function(){return this};g.count=function(){return 0};g.e=function(){return!0};g.ia=function(){return!1};g.Sc=function(){return null};g.fc=function(){return null};g.fa=function(){return!1};var bc=new nc;function oc(a,b){return a&&"object"===typeof a?(K(".sv"in a,"Unexpected leaf node or priority contents"),b[a[".sv"]]):a}function pc(a,b){var c=new qc;rc(a,new L(""),function(a,e){c.nc(a,sc(e,b))});return c}function sc(a,b){var c=a.C().I(),c=oc(c,b),d;if(a.K()){var e=oc(a.Ca(),b);return e!==a.Ca()||c!==a.C().I()?new tc(e,M(c)):a}d=a;c!==a.C().I()&&(d=d.ga(new tc(c)));a.P(N,function(a,c){var e=sc(c,b);e!==c&&(d=d.U(a,e))});return d};function uc(){this.wc={}}uc.prototype.set=function(a,b){null==b?delete this.wc[a]:this.wc[a]=b};uc.prototype.get=function(a){return v(this.wc,a)?this.wc[a]:null};uc.prototype.remove=function(a){delete this.wc[a]};uc.prototype.wf=!0;function vc(a){this.Fc=a;this.Pd="firebase:"}g=vc.prototype;g.set=function(a,b){null==b?this.Fc.removeItem(this.Pd+a):this.Fc.setItem(this.Pd+a,B(b))};g.get=function(a){a=this.Fc.getItem(this.Pd+a);return null==a?null:nb(a)};g.remove=function(a){this.Fc.removeItem(this.Pd+a)};g.wf=!1;g.toString=function(){return this.Fc.toString()};function wc(a){try{if("undefined"!==typeof window&&"undefined"!==typeof window[a]){var b=window[a];b.setItem("firebase:sentinel","cache");b.removeItem("firebase:sentinel");return new vc(b)}}catch(c){}return new uc}var xc=wc("localStorage"),yc=wc("sessionStorage");function zc(a,b,c,d,e){this.host=a.toLowerCase();this.domain=this.host.substr(this.host.indexOf(".")+1);this.kb=b;this.hc=c;this.Wg=d;this.Od=e||"";this.Ya=xc.get("host:"+a)||this.host}function Ac(a,b){b!==a.Ya&&(a.Ya=b,"s-"===a.Ya.substr(0,2)&&xc.set("host:"+a.host,a.Ya))} +function Bc(a,b,c){K("string"===typeof b,"typeof type must == string");K("object"===typeof c,"typeof params must == object");if(b===Cc)b=(a.kb?"wss://":"ws://")+a.Ya+"/.ws?";else if(b===Dc)b=(a.kb?"https://":"http://")+a.Ya+"/.lp?";else throw Error("Unknown connection type: "+b);a.host!==a.Ya&&(c.ns=a.hc);var d=[];r(c,function(a,b){d.push(b+"="+a)});return b+d.join("&")}zc.prototype.toString=function(){var a=(this.kb?"https://":"http://")+this.host;this.Od&&(a+="<"+this.Od+">");return a};var Ec=function(){var a=1;return function(){return a++}}();function K(a,b){if(!a)throw Fc(b);}function Fc(a){return Error("Firebase ("+hb+") INTERNAL ASSERT FAILED: "+a)} +function Gc(a){try{var b;if("undefined"!==typeof atob)b=atob(a);else{gb();for(var c=eb,d=[],e=0;e>4);64!=k&&(d.push(h<<4&240|k>>2),64!=l&&d.push(k<<6&192|l))}if(8192>d.length)b=String.fromCharCode.apply(null,d);else{a="";for(c=0;ca.ac?a.update(a.Ld,56-a.ac):a.update(a.Ld,a.Va-(a.ac-56));for(var d=a.Va-1;56<=d;d--)a.me[d]=c&255,c/=256;Ma(a,a.me);for(d=c=0;5>d;d++)for(var e=24;0<=e;e-=8)b[c]=a.N[d]>>e&255,++c;return fb(b)} +function Jc(a){for(var b="",c=0;ca?c.push(a.substring(d,a.length)):c.push(a.substring(d,d+b));return c}function Wc(a,b){if(ea(a))for(var c=0;ca,a=Math.abs(a),a>=Math.pow(2,-1022)?(d=Math.min(Math.floor(Math.log(a)/Math.LN2),1023),c=d+1023,d=Math.round(a*Math.pow(2,52-d)-Math.pow(2,52))):(c=0,d=Math.round(a/Math.pow(2,-1074))));e=[];for(a=52;a;--a)e.push(d%2?1:0),d=Math.floor(d/2);for(a=11;a;--a)e.push(c%2?1:0),c=Math.floor(c/2);e.push(b?1:0);e.reverse();b=e.join("");c="";for(a=0;64>a;a+=8)d=parseInt(b.substr(a,8),2).toString(16),1===d.length&& +(d="0"+d),c+=d;return c.toLowerCase()}var Yc=/^-?\d{1,10}$/;function Sc(a){return Yc.test(a)&&(a=Number(a),-2147483648<=a&&2147483647>=a)?a:null}function Db(a){try{a()}catch(b){setTimeout(function(){O("Exception was thrown by user callback.",b.stack||"");throw b;},Math.floor(0))}}function P(a,b){if(ha(a)){var c=Array.prototype.slice.call(arguments,1).slice();Db(function(){a.apply(null,c)})}};function Ic(a){for(var b=[],c=0,d=0;d=e&&(e-=55296,d++,K(de?b[c++]=e:(2048>e?b[c++]=e>>6|192:(65536>e?b[c++]=e>>12|224:(b[c++]=e>>18|240,b[c++]=e>>12&63|128),b[c++]=e>>6&63|128),b[c++]=e&63|128)}return b}function Zc(a){for(var b=0,c=0;cd?b++:2048>d?b+=2:55296<=d&&56319>=d?(b+=4,c++):b+=3}return b};function $c(a){var b={},c={},d={},e="";try{var f=a.split("."),b=nb(Gc(f[0])||""),c=nb(Gc(f[1])||""),e=f[2],d=c.d||{};delete c.d}catch(h){}return{Zg:b,Bc:c,data:d,Qg:e}}function ad(a){a=$c(a).Bc;return"object"===typeof a&&a.hasOwnProperty("iat")?w(a,"iat"):null}function bd(a){a=$c(a);var b=a.Bc;return!!a.Qg&&!!b&&"object"===typeof b&&b.hasOwnProperty("iat")};function cd(a){this.W=a;this.g=a.n.g}function dd(a,b,c,d){var e=[],f=[];Oa(b,function(b){"child_changed"===b.type&&a.g.Ad(b.Ke,b.Ja)&&f.push(new D("child_moved",b.Ja,b.Wa))});ed(a,e,"child_removed",b,d,c);ed(a,e,"child_added",b,d,c);ed(a,e,"child_moved",f,d,c);ed(a,e,"child_changed",b,d,c);ed(a,e,Fb,b,d,c);return e}function ed(a,b,c,d,e,f){d=Pa(d,function(a){return a.type===c});Xa(d,q(a.hg,a));Oa(d,function(c){var d=fd(a,c,f);Oa(e,function(e){e.Kf(c.type)&&b.push(e.createEvent(d,a.W))})})} +function fd(a,b,c){"value"!==b.type&&"child_removed"!==b.type&&(b.Qd=c.rf(b.Wa,b.Ja,a.g));return b}cd.prototype.hg=function(a,b){if(null==a.Wa||null==b.Wa)throw Fc("Should only compare child_ events.");return this.g.compare(new F(a.Wa,a.Ja),new F(b.Wa,b.Ja))};function gd(){this.bb={}} +function hd(a,b){var c=b.type,d=b.Wa;K("child_added"==c||"child_changed"==c||"child_removed"==c,"Only child changes supported for tracking");K(".priority"!==d,"Only non-priority child changes can be tracked.");var e=w(a.bb,d);if(e){var f=e.type;if("child_added"==c&&"child_removed"==f)a.bb[d]=new D("child_changed",b.Ja,d,e.Ja);else if("child_removed"==c&&"child_added"==f)delete a.bb[d];else if("child_removed"==c&&"child_changed"==f)a.bb[d]=new D("child_removed",e.Ke,d);else if("child_changed"==c&& +"child_added"==f)a.bb[d]=new D("child_added",b.Ja,d);else if("child_changed"==c&&"child_changed"==f)a.bb[d]=new D("child_changed",b.Ja,d,e.Ke);else throw Fc("Illegal combination of changes: "+b+" occurred after "+e);}else a.bb[d]=b};function id(a,b,c){this.Rb=a;this.pb=b;this.rb=c||null}g=id.prototype;g.Kf=function(a){return"value"===a};g.createEvent=function(a,b){var c=b.n.g;return new Gb("value",this,new Q(a.Ja,b.Ib(),c))};g.Vb=function(a){var b=this.rb;if("cancel"===a.ze()){K(this.pb,"Raising a cancel event on a listener with no cancel callback");var c=this.pb;return function(){c.call(b,a.error)}}var d=this.Rb;return function(){d.call(b,a.Zd)}};g.gf=function(a,b){return this.pb?new Hb(this,a,b):null}; +g.matches=function(a){return a instanceof id?a.Rb&&this.Rb?a.Rb===this.Rb&&a.rb===this.rb:!0:!1};g.tf=function(){return null!==this.Rb};function jd(a,b,c){this.ha=a;this.pb=b;this.rb=c}g=jd.prototype;g.Kf=function(a){a="children_added"===a?"child_added":a;return("children_removed"===a?"child_removed":a)in this.ha};g.gf=function(a,b){return this.pb?new Hb(this,a,b):null}; +g.createEvent=function(a,b){K(null!=a.Wa,"Child events should have a childName.");var c=b.Ib().u(a.Wa);return new Gb(a.type,this,new Q(a.Ja,c,b.n.g),a.Qd)};g.Vb=function(a){var b=this.rb;if("cancel"===a.ze()){K(this.pb,"Raising a cancel event on a listener with no cancel callback");var c=this.pb;return function(){c.call(b,a.error)}}var d=this.ha[a.ud];return function(){d.call(b,a.Zd,a.Qd)}}; +g.matches=function(a){if(a instanceof jd){if(!this.ha||!a.ha)return!0;if(this.rb===a.rb){var b=pa(a.ha);if(b===pa(this.ha)){if(1===b){var b=qa(a.ha),c=qa(this.ha);return c===b&&(!a.ha[b]||!this.ha[c]||a.ha[b]===this.ha[c])}return oa(this.ha,function(b,c){return a.ha[c]===b})}}}return!1};g.tf=function(){return null!==this.ha};function kd(a){this.g=a}g=kd.prototype;g.G=function(a,b,c,d,e,f){K(a.Jc(this.g),"A node must be indexed if only a child is updated");e=a.R(b);if(e.Q(d).ca(c.Q(d))&&e.e()==c.e())return a;null!=f&&(c.e()?a.Da(b)?hd(f,new D("child_removed",e,b)):K(a.K(),"A child remove without an old child only makes sense on a leaf node"):e.e()?hd(f,new D("child_added",c,b)):hd(f,new D("child_changed",c,b,e)));return a.K()&&c.e()?a:a.U(b,c).lb(this.g)}; +g.xa=function(a,b,c){null!=c&&(a.K()||a.P(N,function(a,e){b.Da(a)||hd(c,new D("child_removed",e,a))}),b.K()||b.P(N,function(b,e){if(a.Da(b)){var f=a.R(b);f.ca(e)||hd(c,new D("child_changed",e,b,f))}else hd(c,new D("child_added",e,b))}));return b.lb(this.g)};g.ga=function(a,b){return a.e()?C:a.ga(b)};g.Na=function(){return!1};g.Wb=function(){return this};function ld(a){this.Be=new kd(a.g);this.g=a.g;var b;a.ma?(b=md(a),b=a.g.Pc(nd(a),b)):b=a.g.Tc();this.ed=b;a.pa?(b=od(a),a=a.g.Pc(pd(a),b)):a=a.g.Qc();this.Gc=a}g=ld.prototype;g.matches=function(a){return 0>=this.g.compare(this.ed,a)&&0>=this.g.compare(a,this.Gc)};g.G=function(a,b,c,d,e,f){this.matches(new F(b,c))||(c=C);return this.Be.G(a,b,c,d,e,f)}; +g.xa=function(a,b,c){b.K()&&(b=C);var d=b.lb(this.g),d=d.ga(C),e=this;b.P(N,function(a,b){e.matches(new F(a,b))||(d=d.U(a,C))});return this.Be.xa(a,d,c)};g.ga=function(a){return a};g.Na=function(){return!0};g.Wb=function(){return this.Be};function qd(a){this.sa=new ld(a);this.g=a.g;K(a.ja,"Only valid if limit has been set");this.ka=a.ka;this.Jb=!rd(a)}g=qd.prototype;g.G=function(a,b,c,d,e,f){this.sa.matches(new F(b,c))||(c=C);return a.R(b).ca(c)?a:a.Db()=this.g.compare(this.sa.ed,f):0>=this.g.compare(f,this.sa.Gc))d=d.U(f.name,f.S),e++;else break}}else{d=b.lb(this.g);d=d.ga(C);var k,l,m;if(this.Jb){b=d.sf(this.g);k=this.sa.Gc;l=this.sa.ed;var t=td(this.g);m=function(a,b){return t(b,a)}}else b=d.Xb(this.g),k=this.sa.ed, +l=this.sa.Gc,m=td(this.g);for(var e=0,z=!1;0=m(k,f)&&(z=!0),(h=z&&e=m(f,l))?e++:d=d.U(f.name,C)}return this.sa.Wb().xa(a,d,c)};g.ga=function(a){return a};g.Na=function(){return!0};g.Wb=function(){return this.sa.Wb()}; +function sd(a,b,c,d,e,f){var h;if(a.Jb){var k=td(a.g);h=function(a,b){return k(b,a)}}else h=td(a.g);K(b.Db()==a.ka,"");var l=new F(c,d),m=a.Jb?ud(b,a.g):vd(b,a.g),t=a.sa.matches(l);if(b.Da(c)){for(var z=b.R(c),m=e.ye(a.g,m,a.Jb);null!=m&&(m.name==c||b.Da(m.name));)m=e.ye(a.g,m,a.Jb);e=null==m?1:h(m,l);if(t&&!d.e()&&0<=e)return null!=f&&hd(f,new D("child_changed",d,c,z)),b.U(c,d);null!=f&&hd(f,new D("child_removed",z,c));b=b.U(c,C);return null!=m&&a.sa.matches(m)?(null!=f&&hd(f,new D("child_added", +m.S,m.name)),b.U(m.name,m.S)):b}return d.e()?b:t&&0<=h(m,l)?(null!=f&&(hd(f,new D("child_removed",m.S,m.name)),hd(f,new D("child_added",d,c))),b.U(c,d).U(m.name,C)):b};function wd(a,b){this.je=a;this.fg=b}function xd(a){this.V=a} +xd.prototype.ab=function(a,b,c,d){var e=new gd,f;if(b.type===Yb)b.source.we?c=yd(this,a,b.path,b.Ga,c,d,e):(K(b.source.pf,"Unknown source."),f=b.source.af||Jb(a.w())&&!b.path.e(),c=Ad(this,a,b.path,b.Ga,c,d,f,e));else if(b.type===Bd)b.source.we?c=Cd(this,a,b.path,b.children,c,d,e):(K(b.source.pf,"Unknown source."),f=b.source.af||Jb(a.w()),c=Dd(this,a,b.path,b.children,c,d,f,e));else if(b.type===Ed)if(b.Vd)if(b=b.path,null!=c.tc(b))c=a;else{f=new rb(c,a,d);d=a.O.j();if(b.e()||".priority"===E(b))Ib(a.w())? +b=c.za(ub(a)):(b=a.w().j(),K(b instanceof R,"serverChildren would be complete if leaf node"),b=c.yc(b)),b=this.V.xa(d,b,e);else{var h=E(b),k=c.xc(h,a.w());null==k&&sb(a.w(),h)&&(k=d.R(h));b=null!=k?this.V.G(d,h,k,H(b),f,e):a.O.j().Da(h)?this.V.G(d,h,C,H(b),f,e):d;b.e()&&Ib(a.w())&&(d=c.za(ub(a)),d.K()&&(b=this.V.xa(b,d,e)))}d=Ib(a.w())||null!=c.tc(G);c=Fd(a,b,d,this.V.Na())}else c=Gd(this,a,b.path,b.Qb,c,d,e);else if(b.type===$b)d=b.path,b=a.w(),f=b.j(),h=b.ea||d.e(),c=Hd(this,new Id(a.O,new tb(f, +h,b.Ub)),d,c,qb,e);else throw Fc("Unknown operation type: "+b.type);e=ra(e.bb);d=c;b=d.O;b.ea&&(f=b.j().K()||b.j().e(),h=Jd(a),(0b.compare(d,a);)J(c),d=ec(c);return c};g.sf=function(a){return this.$b(a.Qc(),a)};g.$b=function(a,b){var c=qe(this,b);if(c)return c.$b(a,function(a){return a});for(var c=this.m.$b(a.name,Tb),d=ec(c);null!=d&&0f.status){try{b=nb(f.responseText)}catch(c){O("Failed to parse JSON response for "+e+": "+f.responseText)}d(null,b)}else 401!==f.status&&404!== +f.status&&O("Got unsuccessful REST response for "+e+" Status: "+f.status),d(f.status);d=null}};f.open("GET",e,!0);f.send()};function De(a){K(ea(a)&&0f;f++)b[f]=Math.floor(64*Math.random());for(f=0;12>f;f++)c+="-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(b[f]);K(20===c.length,"nextPushId: Length should be 20."); +return c}}();function Ge(){De.call(this,["online"]);this.kc=!0;if("undefined"!==typeof window&&"undefined"!==typeof window.addEventListener){var a=this;window.addEventListener("online",function(){a.kc||(a.kc=!0,a.fe("online",!0))},!1);window.addEventListener("offline",function(){a.kc&&(a.kc=!1,a.fe("online",!1))},!1)}}ma(Ge,De);Ge.prototype.Ae=function(a){K("online"===a,"Unknown event type: "+a);return[this.kc]};ca(Ge);function He(){De.call(this,["visible"]);var a,b;"undefined"!==typeof document&&"undefined"!==typeof document.addEventListener&&("undefined"!==typeof document.hidden?(b="visibilitychange",a="hidden"):"undefined"!==typeof document.mozHidden?(b="mozvisibilitychange",a="mozHidden"):"undefined"!==typeof document.msHidden?(b="msvisibilitychange",a="msHidden"):"undefined"!==typeof document.webkitHidden&&(b="webkitvisibilitychange",a="webkitHidden"));this.Ob=!0;if(b){var c=this;document.addEventListener(b, +function(){var b=!document[a];b!==c.Ob&&(c.Ob=b,c.fe("visible",b))},!1)}}ma(He,De);He.prototype.Ae=function(a){K("visible"===a,"Unknown event type: "+a);return[this.Ob]};ca(He);function L(a,b){if(1==arguments.length){this.o=a.split("/");for(var c=0,d=0;d=a.o.length?null:a.o[a.Z]}function Kd(a){return a.o.length-a.Z}function H(a){var b=a.Z;b=this.o.length)return null;for(var a=[],b=this.Z;b=this.o.length};g.ca=function(a){if(Kd(this)!==Kd(a))return!1;for(var b=this.Z,c=a.Z;b<=this.o.length;b++,c++)if(this.o[b]!==a.o[c])return!1;return!0}; +g.contains=function(a){var b=this.Z,c=a.Z;if(Kd(this)>Kd(a))return!1;for(;b=b&&nf(h,c.path)?d=!1:c.path.contains(h.path)&&(e=!0));f--}if(d){if(e)this.T=of(this.na,pf,G),this.Mc=0f.Mc,"Stacking an older write on top of newer ones");n(h)||(h=!0);f.na.push({path:b,Ga:c,kd:d,visible:h});h&&(f.T=ef(f.T,b,c));f.Mc=d;return e?xf(a,new Xb($e,b,c)):[]}function yf(a,b,c,d){var e=a.ib;K(d>e.Mc,"Stacking an older merge on top of newer ones");e.na.push({path:b,children:c,kd:d,visible:!0});e.T=ff(e.T,b,c);e.Mc=d;c=Oe(c);return xf(a,new ze($e,b,c))} +function zf(a,b,c){c=c||!1;var d=mf(a.ib,b);if(a.ib.Rd(b)){var e=Pd;null!=d.Ga?e=e.set(G,!0):ib(d.children,function(a,b){e=e.set(new L(a),b)});return xf(a,new Ze(d.path,e,c))}return[]}function Af(a,b,c){c=Oe(c);return xf(a,new ze(bf,b,c))}function Bf(a,b,c,d){d=Cf(a,d);if(null!=d){var e=Df(d);d=e.path;e=e.Hb;b=T(d,b);c=new Xb(new af(!1,!0,e,!0),b,c);return Ef(a,d,c)}return[]} +function Ff(a,b,c,d){if(d=Cf(a,d)){var e=Df(d);d=e.path;e=e.Hb;b=T(d,b);c=Oe(c);c=new ze(new af(!1,!0,e,!0),b,c);return Ef(a,d,c)}return[]} +vf.prototype.Pb=function(a,b){var c=a.path,d=null,e=!1;Ve(this.ta,c,function(a,b){var f=T(a,c);d=d||b.fb(f);e=e||null!=sf(b)});var f=this.ta.get(c);f?(e=e||null!=sf(f),d=d||f.fb(G)):(f=new rf,this.ta=this.ta.set(c,f));var h;null!=d?h=!0:(h=!1,d=C,Ye(this.ta.subtree(c),function(a,b){var c=b.fb(G);c&&(d=d.U(a,c))}));var k=null!=uf(f,a);if(!k&&!S(a.n)){var l=Gf(a);K(!(l in this.mc),"View does not exist, but we have a tag");var m=Hf++;this.mc[l]=m;this.$e["_"+m]=l}h=f.Pb(a,b,new qf(c,this.ib),d,h);k|| +e||(f=uf(f,a),h=h.concat(If(this,a,f)));return h}; +vf.prototype.jb=function(a,b,c){var d=a.path,e=this.ta.get(d),f=[];if(e&&("default"===a.va()||null!=uf(e,a))){f=e.jb(a,b,c);e.e()&&(this.ta=this.ta.remove(d));e=f.Kg;f=f.mg;b=-1!==Ua(e,function(a){return S(a.n)});var h=Te(this.ta,d,function(a,b){return null!=sf(b)});if(b&&!h&&(d=this.ta.subtree(d),!d.e()))for(var d=Jf(d),k=0;k10485760/3&&10485760=a}else if(-1=a;return!1};function Bg(){var a=window.opener.frames,b;for(b=a.length-1;0<=b;b--)try{if(a[b].location.protocol===window.location.protocol&&a[b].location.host===window.location.host&&"__winchan_relay_frame"===a[b].name)return a[b]}catch(c){}return null}function Cg(a,b,c){a.attachEvent?a.attachEvent("on"+b,c):a.addEventListener&&a.addEventListener(b,c,!1)}function Dg(a,b,c){a.detachEvent?a.detachEvent("on"+b,c):a.removeEventListener&&a.removeEventListener(b,c,!1)} +function Eg(a){/^https?:\/\//.test(a)||(a=window.location.href);var b=/^(https?:\/\/[\-_a-zA-Z\.0-9:]+)/.exec(a);return b?b[1]:a}function Fg(a){var b="";try{a=a.replace("#","");var c=lb(a);c&&v(c,"__firebase_request_key")&&(b=w(c,"__firebase_request_key"))}catch(d){}return b}function Gg(){var a=Pc(sg);return a.scheme+"://"+a.host+"/v2"}function Hg(a){return Gg()+"/"+a+"/auth/channel"};function Ig(a){var b=this;this.Ac=a;this.ce="*";Ag(8)?this.Rc=this.zd=Bg():(this.Rc=window.opener,this.zd=window);if(!b.Rc)throw"Unable to find relay frame";Cg(this.zd,"message",q(this.jc,this));Cg(this.zd,"message",q(this.Bf,this));try{Jg(this,{a:"ready"})}catch(c){Cg(this.Rc,"load",function(){Jg(b,{a:"ready"})})}Cg(window,"unload",q(this.Bg,this))}function Jg(a,b){b=B(b);Ag(8)?a.Rc.doPost(b,a.ce):a.Rc.postMessage(b,a.ce)} +Ig.prototype.jc=function(a){var b=this,c;try{c=nb(a.data)}catch(d){}c&&"request"===c.a&&(Dg(window,"message",this.jc),this.ce=a.origin,this.Ac&&setTimeout(function(){b.Ac(b.ce,c.d,function(a,c){b.dg=!c;b.Ac=void 0;Jg(b,{a:"response",d:a,forceKeepWindowOpen:c})})},0))};Ig.prototype.Bg=function(){try{Dg(this.zd,"message",this.Bf)}catch(a){}this.Ac&&(Jg(this,{a:"error",d:"unknown closed window"}),this.Ac=void 0);try{window.close()}catch(b){}};Ig.prototype.Bf=function(a){if(this.dg&&"die"===a.data)try{window.close()}catch(b){}};function Kg(a){this.pc=Ga()+Ga()+Ga();this.Ef=a}Kg.prototype.open=function(a,b){yc.set("redirect_request_id",this.pc);yc.set("redirect_request_id",this.pc);b.requestId=this.pc;b.redirectTo=b.redirectTo||window.location.href;a+=(/\?/.test(a)?"":"?")+kb(b);window.location=a};Kg.isAvailable=function(){return!zg()&&!yg()};Kg.prototype.Cc=function(){return"redirect"};var Lg={NETWORK_ERROR:"Unable to contact the Firebase server.",SERVER_ERROR:"An unknown server error occurred.",TRANSPORT_UNAVAILABLE:"There are no login transports available for the requested method.",REQUEST_INTERRUPTED:"The browser redirected the page before the login request could complete.",USER_CANCELLED:"The user cancelled authentication."};function Mg(a){var b=Error(w(Lg,a),a);b.code=a;return b};function Ng(a){var b;(b=!a.window_features)||(b=xg(),b=-1!==b.indexOf("Fennec/")||-1!==b.indexOf("Firefox/")&&-1!==b.indexOf("Android"));b&&(a.window_features=void 0);a.window_name||(a.window_name="_blank");this.options=a} +Ng.prototype.open=function(a,b,c){function d(a){h&&(document.body.removeChild(h),h=void 0);t&&(t=clearInterval(t));Dg(window,"message",e);Dg(window,"unload",d);if(m&&!a)try{m.close()}catch(b){k.postMessage("die",l)}m=k=void 0}function e(a){if(a.origin===l)try{var b=nb(a.data);"ready"===b.a?k.postMessage(z,l):"error"===b.a?(d(!1),c&&(c(b.d),c=null)):"response"===b.a&&(d(b.forceKeepWindowOpen),c&&(c(null,b.d),c=null))}catch(e){}}var f=Ag(8),h,k;if(!this.options.relay_url)return c(Error("invalid arguments: origin of url and relay_url must match")); +var l=Eg(a);if(l!==Eg(this.options.relay_url))c&&setTimeout(function(){c(Error("invalid arguments: origin of url and relay_url must match"))},0);else{f&&(h=document.createElement("iframe"),h.setAttribute("src",this.options.relay_url),h.style.display="none",h.setAttribute("name","__winchan_relay_frame"),document.body.appendChild(h),k=h.contentWindow);a+=(/\?/.test(a)?"":"?")+kb(b);var m=window.open(a,this.options.window_name,this.options.window_features);k||(k=m);var t=setInterval(function(){m&&m.closed&& +(d(!1),c&&(c(Mg("USER_CANCELLED")),c=null))},500),z=B({a:"request",d:b});Cg(window,"unload",d);Cg(window,"message",e)}}; +Ng.isAvailable=function(){var a;if(a="postMessage"in window&&!zg())(a=yg()||"undefined"!==typeof navigator&&(!!xg().match(/Windows Phone/)||!!window.Windows&&/^ms-appx:/.test(location.href)))||(a=xg(),a="undefined"!==typeof navigator&&"undefined"!==typeof window&&!!(a.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i)||a.match(/CriOS/)||a.match(/Twitter for iPhone/)||a.match(/FBAN\/FBIOS/)||window.navigator.standalone)),a=!a;return a&&!xg().match(/PhantomJS/)};Ng.prototype.Cc=function(){return"popup"};function Og(a){a.method||(a.method="GET");a.headers||(a.headers={});a.headers.content_type||(a.headers.content_type="application/json");a.headers.content_type=a.headers.content_type.toLowerCase();this.options=a} +Og.prototype.open=function(a,b,c){function d(){c&&(c(Mg("REQUEST_INTERRUPTED")),c=null)}var e=new XMLHttpRequest,f=this.options.method.toUpperCase(),h;Cg(window,"beforeunload",d);e.onreadystatechange=function(){if(c&&4===e.readyState){var a;if(200<=e.status&&300>e.status){try{a=nb(e.responseText)}catch(b){}c(null,a)}else 500<=e.status&&600>e.status?c(Mg("SERVER_ERROR")):c(Mg("NETWORK_ERROR"));c=null;Dg(window,"beforeunload",d)}};if("GET"===f)a+=(/\?/.test(a)?"":"?")+kb(b),h=null;else{var k=this.options.headers.content_type; +"application/json"===k&&(h=B(b));"application/x-www-form-urlencoded"===k&&(h=kb(b))}e.open(f,a,!0);a={"X-Requested-With":"XMLHttpRequest",Accept:"application/json;text/plain"};za(a,this.options.headers);for(var l in a)e.setRequestHeader(l,a[l]);e.send(h)};Og.isAvailable=function(){var a;if(a=!!window.XMLHttpRequest)a=xg(),a=!(a.match(/MSIE/)||a.match(/Trident/))||Ag(10);return a};Og.prototype.Cc=function(){return"json"};function Pg(a){this.pc=Ga()+Ga()+Ga();this.Ef=a} +Pg.prototype.open=function(a,b,c){function d(){c&&(c(Mg("USER_CANCELLED")),c=null)}var e=this,f=Pc(sg),h;b.requestId=this.pc;b.redirectTo=f.scheme+"://"+f.host+"/blank/page.html";a+=/\?/.test(a)?"":"?";a+=kb(b);(h=window.open(a,"_blank","location=no"))&&ha(h.addEventListener)?(h.addEventListener("loadstart",function(a){var b;if(b=a&&a.url)a:{try{var m=document.createElement("a");m.href=a.url;b=m.host===f.host&&"/blank/page.html"===m.pathname;break a}catch(t){}b=!1}b&&(a=Fg(a.url),h.removeEventListener("exit", +d),h.close(),a=new tg(null,null,{requestId:e.pc,requestKey:a}),e.Ef.requestWithCredential("/auth/session",a,c),c=null)}),h.addEventListener("exit",d)):c(Mg("TRANSPORT_UNAVAILABLE"))};Pg.isAvailable=function(){return yg()};Pg.prototype.Cc=function(){return"redirect"};function Qg(a){a.callback_parameter||(a.callback_parameter="callback");this.options=a;window.__firebase_auth_jsonp=window.__firebase_auth_jsonp||{}} +Qg.prototype.open=function(a,b,c){function d(){c&&(c(Mg("REQUEST_INTERRUPTED")),c=null)}function e(){setTimeout(function(){window.__firebase_auth_jsonp[f]=void 0;wa(window.__firebase_auth_jsonp)&&(window.__firebase_auth_jsonp=void 0);try{var a=document.getElementById(f);a&&a.parentNode.removeChild(a)}catch(b){}},1);Dg(window,"beforeunload",d)}var f="fn"+(new Date).getTime()+Math.floor(99999*Math.random());b[this.options.callback_parameter]="__firebase_auth_jsonp."+f;a+=(/\?/.test(a)?"":"?")+kb(b); +Cg(window,"beforeunload",d);window.__firebase_auth_jsonp[f]=function(a){c&&(c(null,a),c=null);e()};Rg(f,a,c)}; +function Rg(a,b,c){setTimeout(function(){try{var d=document.createElement("script");d.type="text/javascript";d.id=a;d.async=!0;d.src=b;d.onerror=function(){var b=document.getElementById(a);null!==b&&b.parentNode.removeChild(b);c&&c(Mg("NETWORK_ERROR"))};var e=document.getElementsByTagName("head");(e&&0!=e.length?e[0]:document.documentElement).appendChild(d)}catch(f){c&&c(Mg("NETWORK_ERROR"))}},0)}Qg.isAvailable=function(){return"undefined"!==typeof document&&null!=document.createElement}; +Qg.prototype.Cc=function(){return"json"};function Sg(a,b,c,d){De.call(this,["auth_status"]);this.F=a;this.df=b;this.Vg=c;this.Le=d;this.sc=new wg(a,[xc,yc]);this.mb=null;this.Se=!1;Tg(this)}ma(Sg,De);g=Sg.prototype;g.xe=function(){return this.mb||null};function Tg(a){yc.get("redirect_request_id")&&Ug(a);var b=a.sc.get();b&&b.token?(Vg(a,b),a.df(b.token,function(c,d){Wg(a,c,d,!1,b.token,b)},function(b,d){Xg(a,"resumeSession()",b,d)})):Vg(a,null)} +function Yg(a,b,c,d,e,f){"firebaseio-demo.com"===a.F.domain&&O("Firebase authentication is not supported on demo Firebases (*.firebaseio-demo.com). To secure your Firebase, create a production Firebase at https://www.firebase.com.");a.df(b,function(f,k){Wg(a,f,k,!0,b,c,d||{},e)},function(b,c){Xg(a,"auth()",b,c,f)})}function Zg(a,b){a.sc.clear();Vg(a,null);a.Vg(function(a,d){if("ok"===a)P(b,null);else{var e=(a||"error").toUpperCase(),f=e;d&&(f+=": "+d);f=Error(f);f.code=e;P(b,f)}})} +function Wg(a,b,c,d,e,f,h,k){"ok"===b?(d&&(b=c.auth,f.auth=b,f.expires=c.expires,f.token=bd(e)?e:"",c=null,b&&v(b,"uid")?c=w(b,"uid"):v(f,"uid")&&(c=w(f,"uid")),f.uid=c,c="custom",b&&v(b,"provider")?c=w(b,"provider"):v(f,"provider")&&(c=w(f,"provider")),f.provider=c,a.sc.clear(),bd(e)&&(h=h||{},c=xc,"sessionOnly"===h.remember&&(c=yc),"none"!==h.remember&&a.sc.set(f,c)),Vg(a,f)),P(k,null,f)):(a.sc.clear(),Vg(a,null),f=a=(b||"error").toUpperCase(),c&&(f+=": "+c),f=Error(f),f.code=a,P(k,f))} +function Xg(a,b,c,d,e){O(b+" was canceled: "+d);a.sc.clear();Vg(a,null);a=Error(d);a.code=c.toUpperCase();P(e,a)}function $g(a,b,c,d,e){ah(a);c=new tg(d||{},{},c||{});bh(a,[Og,Qg],"/auth/"+b,c,e)} +function ch(a,b,c,d){ah(a);var e=[Ng,Pg];c=vg(c);"anonymous"===b||"password"===b?setTimeout(function(){P(d,Mg("TRANSPORT_UNAVAILABLE"))},0):(c.ee.window_features="menubar=yes,modal=yes,alwaysRaised=yeslocation=yes,resizable=yes,scrollbars=yes,status=yes,height=625,width=625,top="+("object"===typeof screen?.5*(screen.height-625):0)+",left="+("object"===typeof screen?.5*(screen.width-625):0),c.ee.relay_url=Hg(a.F.hc),c.ee.requestWithCredential=q(a.qc,a),bh(a,e,"/auth/"+b,c,d))} +function Ug(a){var b=yc.get("redirect_request_id");if(b){var c=yc.get("redirect_client_options");yc.remove("redirect_request_id");yc.remove("redirect_client_options");var d=[Og,Qg],b={requestId:b,requestKey:Fg(document.location.hash)},c=new tg(c,{},b);a.Se=!0;try{document.location.hash=document.location.hash.replace(/&__firebase_request_key=([a-zA-z0-9]*)/,"")}catch(e){}bh(a,d,"/auth/session",c,function(){this.Se=!1}.bind(a))}} +g.se=function(a,b){ah(this);var c=vg(a);c.$a._method="POST";this.qc("/users",c,function(a,c){a?P(b,a):P(b,a,c)})};g.Te=function(a,b){var c=this;ah(this);var d="/users/"+encodeURIComponent(a.email),e=vg(a);e.$a._method="DELETE";this.qc(d,e,function(a,d){!a&&d&&d.uid&&c.mb&&c.mb.uid&&c.mb.uid===d.uid&&Zg(c);P(b,a)})};g.pe=function(a,b){ah(this);var c="/users/"+encodeURIComponent(a.email)+"/password",d=vg(a);d.$a._method="PUT";d.$a.password=a.newPassword;this.qc(c,d,function(a){P(b,a)})}; +g.oe=function(a,b){ah(this);var c="/users/"+encodeURIComponent(a.oldEmail)+"/email",d=vg(a);d.$a._method="PUT";d.$a.email=a.newEmail;d.$a.password=a.password;this.qc(c,d,function(a){P(b,a)})};g.Ve=function(a,b){ah(this);var c="/users/"+encodeURIComponent(a.email)+"/password",d=vg(a);d.$a._method="POST";this.qc(c,d,function(a){P(b,a)})};g.qc=function(a,b,c){dh(this,[Og,Qg],a,b,c)}; +function bh(a,b,c,d,e){dh(a,b,c,d,function(b,c){!b&&c&&c.token&&c.uid?Yg(a,c.token,c,d.od,function(a,b){a?P(e,a):P(e,null,b)}):P(e,b||Mg("UNKNOWN_ERROR"))})} +function dh(a,b,c,d,e){b=Pa(b,function(a){return"function"===typeof a.isAvailable&&a.isAvailable()});0===b.length?setTimeout(function(){P(e,Mg("TRANSPORT_UNAVAILABLE"))},0):(b=new (b.shift())(d.ee),d=jb(d.$a),d.v="js-"+hb,d.transport=b.Cc(),d.suppress_status_codes=!0,a=Gg()+"/"+a.F.hc+c,b.open(a,d,function(a,b){if(a)P(e,a);else if(b&&b.error){var c=Error(b.error.message);c.code=b.error.code;c.details=b.error.details;P(e,c)}else P(e,null,b)}))} +function Vg(a,b){var c=null!==a.mb||null!==b;a.mb=b;c&&a.fe("auth_status",b);a.Le(null!==b)}g.Ae=function(a){K("auth_status"===a,'initial event must be of type "auth_status"');return this.Se?null:[this.mb]};function ah(a){var b=a.F;if("firebaseio.com"!==b.domain&&"firebaseio-demo.com"!==b.domain&&"auth.firebase.com"===sg)throw Error("This custom Firebase server ('"+a.F.domain+"') does not support delegated login.");};var Cc="websocket",Dc="long_polling";function eh(a){this.jc=a;this.Nd=[];this.Sb=0;this.qe=-1;this.Fb=null}function fh(a,b,c){a.qe=b;a.Fb=c;a.qedocument.domain="'+document.domain+'";\x3c/script>');a=""+a+"";try{this.Ea.eb.open(),this.Ea.eb.write(a),this.Ea.eb.close()}catch(f){Cb("frame writing exception"),f.stack&&Cb(f.stack),Cb(f)}} +kh.prototype.close=function(){this.le=!1;if(this.Ea){this.Ea.eb.body.innerHTML="";var a=this;setTimeout(function(){null!==a.Ea&&(document.body.removeChild(a.Ea),a.Ea=null)},Math.floor(0))}var b=this.hb;b&&(this.hb=null,b())}; +function nh(a){if(a.le&&a.Xd&&a.Pe.count()<(0=a.ad[0].kf.length+30+c.length){var e=a.ad.shift(),c=c+"&seg"+d+"="+e.Mg+"&ts"+d+"="+e.Ug+"&d"+d+"="+e.kf;d++}else break;oh(a,b+c,a.te);return!0}return!1}function oh(a,b,c){function d(){a.Pe.remove(c);nh(a)}a.Pe.add(c,1);var e=setTimeout(d,Math.floor(25E3));mh(a,b,function(){clearTimeout(e);d()})} +function mh(a,b,c){setTimeout(function(){try{if(a.Xd){var d=a.Ea.eb.createElement("script");d.type="text/javascript";d.async=!0;d.src=b;d.onload=d.onreadystatechange=function(){var a=d.readyState;a&&"loaded"!==a&&"complete"!==a||(d.onload=d.onreadystatechange=null,d.parentNode&&d.parentNode.removeChild(d),c())};d.onerror=function(){Cb("Long-poll script failed to load: "+b);a.Xd=!1;a.close()};a.Ea.eb.body.appendChild(d)}}catch(e){}},Math.floor(1))};var ph=null;"undefined"!==typeof MozWebSocket?ph=MozWebSocket:"undefined"!==typeof WebSocket&&(ph=WebSocket);function qh(a,b,c,d){this.re=a;this.f=Mc(this.re);this.frames=this.Kc=null;this.nb=this.ob=this.bf=0;this.Ua=Rb(b);a={v:"5"};"undefined"!==typeof location&&location.href&&-1!==location.href.indexOf("firebaseio.com")&&(a.r="f");c&&(a.s=c);d&&(a.ls=d);this.ef=Bc(b,Cc,a)}var rh; +qh.prototype.open=function(a,b){this.hb=b;this.zg=a;this.f("Websocket connecting to "+this.ef);this.Hc=!1;xc.set("previous_websocket_failure",!0);try{this.ua=new ph(this.ef)}catch(c){this.f("Error instantiating WebSocket.");var d=c.message||c.data;d&&this.f(d);this.gb();return}var e=this;this.ua.onopen=function(){e.f("Websocket connected.");e.Hc=!0};this.ua.onclose=function(){e.f("Websocket connection was disconnected.");e.ua=null;e.gb()};this.ua.onmessage=function(a){if(null!==e.ua)if(a=a.data,e.nb+= +a.length,Ob(e.Ua,"bytes_received",a.length),sh(e),null!==e.frames)th(e,a);else{a:{K(null===e.frames,"We already have a frame buffer");if(6>=a.length){var b=Number(a);if(!isNaN(b)){e.bf=b;e.frames=[];a=null;break a}}e.bf=1;e.frames=[]}null!==a&&th(e,a)}};this.ua.onerror=function(a){e.f("WebSocket error. Closing connection.");(a=a.message||a.data)&&e.f(a);e.gb()}};qh.prototype.start=function(){}; +qh.isAvailable=function(){var a=!1;if("undefined"!==typeof navigator&&navigator.userAgent){var b=navigator.userAgent.match(/Android ([0-9]{0,}\.[0-9]{0,})/);b&&1parseFloat(b[1])&&(a=!0)}return!a&&null!==ph&&!rh};qh.responsesRequiredToBeHealthy=2;qh.healthyTimeout=3E4;g=qh.prototype;g.Ed=function(){xc.remove("previous_websocket_failure")};function th(a,b){a.frames.push(b);if(a.frames.length==a.bf){var c=a.frames.join("");a.frames=null;c=nb(c);a.zg(c)}} +g.send=function(a){sh(this);a=B(a);this.ob+=a.length;Ob(this.Ua,"bytes_sent",a.length);a=Vc(a,16384);1=a.Mf?(a.f("Secondary connection is healthy."),a.Ab=!0,a.D.Ed(),a.D.start(),a.f("sending client ack on secondary"),a.D.send({t:"c",d:{t:"a",d:{}}}),a.f("Ending transmission on primary"),a.J.send({t:"c",d:{t:"n",d:{}}}),a.hd=a.D,Eh(a)):(a.f("sending ping on secondary."),a.D.send({t:"c",d:{t:"p",d:{}}}))}yh.prototype.Id=function(a){Gh(this);this.jc(a)};function Gh(a){a.Ab||(a.Re--,0>=a.Re&&(a.f("Primary connection is healthy."),a.Ab=!0,a.J.Ed()))} +function Dh(a,b){a.D=new b("c:"+a.id+":"+a.ff++,a.F,a.Nf);a.Mf=b.responsesRequiredToBeHealthy||0;a.D.open(Ah(a,a.D),Bh(a,a.D));setTimeout(function(){a.D&&(a.f("Timed out trying to upgrade."),a.D.close())},Math.floor(6E4))}function Ch(a,b,c){a.f("Realtime connection established.");a.J=b;a.Ta=1;a.Wc&&(a.Wc(c,a.Nf),a.Wc=null);0===a.Re?(a.f("Primary connection is healthy."),a.Ab=!0):setTimeout(function(){Hh(a)},Math.floor(5E3))} +function Hh(a){a.Ab||1!==a.Ta||(a.f("sending ping on primary."),Jh(a,{t:"c",d:{t:"p",d:{}}}))}function Jh(a,b){if(1!==a.Ta)throw"Connection is not connected";a.hd.send(b)}yh.prototype.close=function(){2!==this.Ta&&(this.f("Closing realtime connection."),this.Ta=2,Fh(this),this.la&&(this.la(),this.la=null))};function Fh(a){a.f("Shutting down all connections");a.J&&(a.J.close(),a.J=null);a.D&&(a.D.close(),a.D=null);a.yd&&(clearTimeout(a.yd),a.yd=null)};function Kh(a,b,c,d){this.id=Lh++;this.f=Mc("p:"+this.id+":");this.xf=this.Ee=!1;this.$={};this.qa=[];this.Yc=0;this.Vc=[];this.oa=!1;this.Za=1E3;this.Fd=3E5;this.Gb=b;this.Uc=c;this.Oe=d;this.F=a;this.sb=this.Aa=this.Ia=this.Bb=this.We=null;this.Ob=!1;this.Td={};this.Lg=0;this.nf=!0;this.Lc=this.Ge=null;Mh(this,0);He.ub().Eb("visible",this.Cg,this);-1===a.host.indexOf("fblocal")&&Ge.ub().Eb("online",this.Ag,this)}var Lh=0,Nh=0;g=Kh.prototype; +g.Fa=function(a,b,c){var d=++this.Lg;a={r:d,a:a,b:b};this.f(B(a));K(this.oa,"sendRequest call when we're not connected not allowed.");this.Ia.Fa(a);c&&(this.Td[d]=c)};g.yf=function(a,b,c,d){var e=a.va(),f=a.path.toString();this.f("Listen called for "+f+" "+e);this.$[f]=this.$[f]||{};K(fe(a.n)||!S(a.n),"listen() called for non-default but complete query");K(!this.$[f][e],"listen() called twice for same path/queryId.");a={H:d,xd:b,Ig:a,tag:c};this.$[f][e]=a;this.oa&&Oh(this,a)}; +function Oh(a,b){var c=b.Ig,d=c.path.toString(),e=c.va();a.f("Listen on "+d+" for "+e);var f={p:d};b.tag&&(f.q=ee(c.n),f.t=b.tag);f.h=b.xd();a.Fa("q",f,function(f){var k=f.d,l=f.s;if(k&&"object"===typeof k&&v(k,"w")){var m=w(k,"w");ea(m)&&0<=Na(m,"no_index")&&O("Using an unspecified index. Consider adding "+('".indexOn": "'+c.n.g.toString()+'"')+" at "+c.path.toString()+" to your security rules for better performance")}(a.$[d]&&a.$[d][e])===b&&(a.f("listen response",f),"ok"!==l&&Ph(a,d,e),b.H&&b.H(l, +k))})}g.M=function(a,b,c){this.Aa={ig:a,of:!1,zc:b,md:c};this.f("Authenticating using credential: "+a);Qh(this);(b=40==a.length)||(a=$c(a).Bc,b="object"===typeof a&&!0===w(a,"admin"));b&&(this.f("Admin auth credential detected. Reducing max reconnect time."),this.Fd=3E4)};g.ge=function(a){delete this.Aa;this.oa&&this.Fa("unauth",{},function(b){a(b.s,b.d)})}; +function Qh(a){var b=a.Aa;a.oa&&b&&a.Fa("auth",{cred:b.ig},function(c){var d=c.s;c=c.d||"error";"ok"!==d&&a.Aa===b&&delete a.Aa;b.of?"ok"!==d&&b.md&&b.md(d,c):(b.of=!0,b.zc&&b.zc(d,c))})}g.Rf=function(a,b){var c=a.path.toString(),d=a.va();this.f("Unlisten called for "+c+" "+d);K(fe(a.n)||!S(a.n),"unlisten() called for non-default but complete query");if(Ph(this,c,d)&&this.oa){var e=ee(a.n);this.f("Unlisten on "+c+" for "+d);c={p:c};b&&(c.q=e,c.t=b);this.Fa("n",c)}}; +g.Me=function(a,b,c){this.oa?Rh(this,"o",a,b,c):this.Vc.push({$c:a,action:"o",data:b,H:c})};g.Cf=function(a,b,c){this.oa?Rh(this,"om",a,b,c):this.Vc.push({$c:a,action:"om",data:b,H:c})};g.Jd=function(a,b){this.oa?Rh(this,"oc",a,null,b):this.Vc.push({$c:a,action:"oc",data:null,H:b})};function Rh(a,b,c,d,e){c={p:c,d:d};a.f("onDisconnect "+b,c);a.Fa(b,c,function(a){e&&setTimeout(function(){e(a.s,a.d)},Math.floor(0))})}g.put=function(a,b,c,d){Sh(this,"p",a,b,c,d)}; +g.zf=function(a,b,c,d){Sh(this,"m",a,b,c,d)};function Sh(a,b,c,d,e,f){d={p:c,d:d};n(f)&&(d.h=f);a.qa.push({action:b,Jf:d,H:e});a.Yc++;b=a.qa.length-1;a.oa?Th(a,b):a.f("Buffering put: "+c)}function Th(a,b){var c=a.qa[b].action,d=a.qa[b].Jf,e=a.qa[b].H;a.qa[b].Jg=a.oa;a.Fa(c,d,function(d){a.f(c+" response",d);delete a.qa[b];a.Yc--;0===a.Yc&&(a.qa=[]);e&&e(d.s,d.d)})} +g.Ue=function(a){this.oa&&(a={c:a},this.f("reportStats",a),this.Fa("s",a,function(a){"ok"!==a.s&&this.f("reportStats","Error sending stats: "+a.d)}))}; +g.Id=function(a){if("r"in a){this.f("from server: "+B(a));var b=a.r,c=this.Td[b];c&&(delete this.Td[b],c(a.b))}else{if("error"in a)throw"A server-side error has occurred: "+a.error;"a"in a&&(b=a.a,c=a.b,this.f("handleServerMessage",b,c),"d"===b?this.Gb(c.p,c.d,!1,c.t):"m"===b?this.Gb(c.p,c.d,!0,c.t):"c"===b?Uh(this,c.p,c.q):"ac"===b?(a=c.s,b=c.d,c=this.Aa,delete this.Aa,c&&c.md&&c.md(a,b)):"sd"===b?this.We?this.We(c):"msg"in c&&"undefined"!==typeof console&&console.log("FIREBASE: "+c.msg.replace("\n", +"\nFIREBASE: ")):Nc("Unrecognized action received from server: "+B(b)+"\nAre you using the latest client?"))}};g.Wc=function(a,b){this.f("connection ready");this.oa=!0;this.Lc=(new Date).getTime();this.Oe({serverTimeOffset:a-(new Date).getTime()});this.Bb=b;if(this.nf){var c={};c["sdk.js."+hb.replace(/\./g,"-")]=1;yg()&&(c["framework.cordova"]=1);this.Ue(c)}Vh(this);this.nf=!1;this.Uc(!0)}; +function Mh(a,b){K(!a.Ia,"Scheduling a connect when we're already connected/ing?");a.sb&&clearTimeout(a.sb);a.sb=setTimeout(function(){a.sb=null;Wh(a)},Math.floor(b))}g.Cg=function(a){a&&!this.Ob&&this.Za===this.Fd&&(this.f("Window became visible. Reducing delay."),this.Za=1E3,this.Ia||Mh(this,0));this.Ob=a};g.Ag=function(a){a?(this.f("Browser went online."),this.Za=1E3,this.Ia||Mh(this,0)):(this.f("Browser went offline. Killing connection."),this.Ia&&this.Ia.close())}; +g.Df=function(){this.f("data client disconnected");this.oa=!1;this.Ia=null;for(var a=0;a=a)throw Error("Query.limit: First argument must be a positive integer.");if(this.n.ja)throw Error("Query.limit: Limit was already set (by another call to limit, limitToFirst, orlimitToLast.");var b=this.n.He(a);ti(b);return new Y(this.k,this.path,b,this.lc)}; +g.Ie=function(a){x("Query.limitToFirst",1,1,arguments.length);if(!ga(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limitToFirst: First argument must be a positive integer.");if(this.n.ja)throw Error("Query.limitToFirst: Limit was already set (by another call to limit, limitToFirst, or limitToLast).");return new Y(this.k,this.path,this.n.Ie(a),this.lc)}; +g.Je=function(a){x("Query.limitToLast",1,1,arguments.length);if(!ga(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limitToLast: First argument must be a positive integer.");if(this.n.ja)throw Error("Query.limitToLast: Limit was already set (by another call to limit, limitToFirst, or limitToLast).");return new Y(this.k,this.path,this.n.Je(a),this.lc)}; +g.Eg=function(a){x("Query.orderByChild",1,1,arguments.length);if("$key"===a)throw Error('Query.orderByChild: "$key" is invalid. Use Query.orderByKey() instead.');if("$priority"===a)throw Error('Query.orderByChild: "$priority" is invalid. Use Query.orderByPriority() instead.');if("$value"===a)throw Error('Query.orderByChild: "$value" is invalid. Use Query.orderByValue() instead.');ig("Query.orderByChild",a);ui(this,"Query.orderByChild");var b=new L(a);if(b.e())throw Error("Query.orderByChild: cannot pass in empty path. Use Query.orderByValue() instead."); +b=new Ud(b);b=de(this.n,b);si(b);return new Y(this.k,this.path,b,!0)};g.Fg=function(){x("Query.orderByKey",0,0,arguments.length);ui(this,"Query.orderByKey");var a=de(this.n,Qd);si(a);return new Y(this.k,this.path,a,!0)};g.Gg=function(){x("Query.orderByPriority",0,0,arguments.length);ui(this,"Query.orderByPriority");var a=de(this.n,N);si(a);return new Y(this.k,this.path,a,!0)}; +g.Hg=function(){x("Query.orderByValue",0,0,arguments.length);ui(this,"Query.orderByValue");var a=de(this.n,$d);si(a);return new Y(this.k,this.path,a,!0)};g.$d=function(a,b){x("Query.startAt",0,2,arguments.length);bg("Query.startAt",a,this.path,!0);hg("Query.startAt",b);var c=this.n.$d(a,b);ti(c);si(c);if(this.n.ma)throw Error("Query.startAt: Starting point was already set (by another call to startAt or equalTo).");n(a)||(b=a=null);return new Y(this.k,this.path,c,this.lc)}; +g.td=function(a,b){x("Query.endAt",0,2,arguments.length);bg("Query.endAt",a,this.path,!0);hg("Query.endAt",b);var c=this.n.td(a,b);ti(c);si(c);if(this.n.pa)throw Error("Query.endAt: Ending point was already set (by another call to endAt or equalTo).");return new Y(this.k,this.path,c,this.lc)}; +g.kg=function(a,b){x("Query.equalTo",1,2,arguments.length);bg("Query.equalTo",a,this.path,!1);hg("Query.equalTo",b);if(this.n.ma)throw Error("Query.equalTo: Starting point was already set (by another call to endAt or equalTo).");if(this.n.pa)throw Error("Query.equalTo: Ending point was already set (by another call to endAt or equalTo).");return this.$d(a,b).td(a,b)}; +g.toString=function(){x("Query.toString",0,0,arguments.length);for(var a=this.path,b="",c=a.Z;c.firebaseio.com instead");c&&"undefined"!=c||Oc("Cannot parse Firebase url. Please use https://.firebaseio.com");d.kb||"undefined"!==typeof window&&window.location&&window.location.protocol&&-1!==window.location.protocol.indexOf("https:")&&O("Insecure Firebase access from a secure page. Please use https in calls to new Firebase()."); +c=new zc(d.host,d.kb,c,"ws"===d.scheme||"wss"===d.scheme);d=new L(d.$c);e=d.toString();var f;!(f=!p(c.host)||0===c.host.length||!$f(c.hc))&&(f=0!==e.length)&&(e&&(e=e.replace(/^\/*\.info(\/|$)/,"/")),f=!(p(e)&&0!==e.length&&!Yf.test(e)));if(f)throw Error(y("new Firebase",1,!1)+'must be a valid firebase URL and the path can\'t contain ".", "#", "$", "[", or "]".');if(b)if(b instanceof W)e=b;else if(p(b))e=W.ub(),c.Od=b;else throw Error("Expected a valid Firebase.Context for second argument to new Firebase()"); +else e=W.ub();f=c.toString();var h=w(e.oc,f);h||(h=new Yh(c,e.Sf),e.oc[f]=h);c=h}Y.call(this,c,d,be,!1)}ma(U,Y);var wi=U,xi=["Firebase"],yi=aa;xi[0]in yi||!yi.execScript||yi.execScript("var "+xi[0]);for(var zi;xi.length&&(zi=xi.shift());)!xi.length&&n(wi)?yi[zi]=wi:yi=yi[zi]?yi[zi]:yi[zi]={};U.goOffline=function(){x("Firebase.goOffline",0,0,arguments.length);W.ub().yb()};U.goOnline=function(){x("Firebase.goOnline",0,0,arguments.length);W.ub().rc()}; +function Lc(a,b){K(!b||!0===a||!1===a,"Can't turn on custom loggers persistently.");!0===a?("undefined"!==typeof console&&("function"===typeof console.log?Bb=q(console.log,console):"object"===typeof console.log&&(Bb=function(a){console.log(a)})),b&&yc.set("logging_enabled",!0)):a?Bb=a:(Bb=null,yc.remove("logging_enabled"))}U.enableLogging=Lc;U.ServerValue={TIMESTAMP:{".sv":"timestamp"}};U.SDK_VERSION=hb;U.INTERNAL=V;U.Context=W;U.TEST_ACCESS=Z; +U.prototype.name=function(){O("Firebase.name() being deprecated. Please use Firebase.key() instead.");x("Firebase.name",0,0,arguments.length);return this.key()};U.prototype.name=U.prototype.name;U.prototype.key=function(){x("Firebase.key",0,0,arguments.length);return this.path.e()?null:Ld(this.path)};U.prototype.key=U.prototype.key; +U.prototype.u=function(a){x("Firebase.child",1,1,arguments.length);if(ga(a))a=String(a);else if(!(a instanceof L))if(null===E(this.path)){var b=a;b&&(b=b.replace(/^\/*\.info(\/|$)/,"/"));ig("Firebase.child",b)}else ig("Firebase.child",a);return new U(this.k,this.path.u(a))};U.prototype.child=U.prototype.u;U.prototype.parent=function(){x("Firebase.parent",0,0,arguments.length);var a=this.path.parent();return null===a?null:new U(this.k,a)};U.prototype.parent=U.prototype.parent; +U.prototype.root=function(){x("Firebase.ref",0,0,arguments.length);for(var a=this;null!==a.parent();)a=a.parent();return a};U.prototype.root=U.prototype.root;U.prototype.set=function(a,b){x("Firebase.set",1,2,arguments.length);jg("Firebase.set",this.path);bg("Firebase.set",a,this.path,!1);A("Firebase.set",2,b,!0);this.k.Kb(this.path,a,null,b||null)};U.prototype.set=U.prototype.set; +U.prototype.update=function(a,b){x("Firebase.update",1,2,arguments.length);jg("Firebase.update",this.path);if(ea(a)){for(var c={},d=0;d + filter - close/open + "|" + public/private/... + name - The display name of the room. + + +# header of room, write by owner of room. Each room has unique roomID. +# read it when joining the room +room-metadata/ + + name - The display name of the room. + + # monitor filter to catch room open/close event + filter - close/open + "|" + public/private/... + + # moderators of this room + moderators/ + - userName + + # join permission + permission - null("anyone")/("black-list")/("white-list") + black-list/ + - userName + white-list/ + - userName + # ignore room if user can not join + + maxPeers - The maximum number of peers that can join this room. + # limit the amount of users + + extra/ + +# body of room data. Each room has unique roomID. +rooms/ + + alive - true or null + + # users in this room. + users/ + + ID - The id of the user. + # monitor ID == null for "user kicked-out" + name - The name of the user. + + <"channel-"+channel_name> - custom channel + + + + + +# write by each user, user could join to many rooms. +user-metadata\ + + user/ + ID - The id of the user. + name - The display name of the user. + room/ + ID - The id of the room + name - The display name of the room. + +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_Rooms = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_Rooms.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + var ROOMOPEN = "open"; + var ROOMCLOSED = "closed"; + var LIFE_TEMPORARY = 0; + var LIFE_PERSISTED = 1; + var JOINPERMINNSION = [null /*"anyone"*/, "black-list", "white-list"]; + var DOORSTATES = [ROOMCLOSED, ROOMOPEN]; + var LEAVEDELAY = 10; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + //this.messageType = this.properties[2]; + this.LockedByAction = false; + this.triggeredRoomName = ""; + this.triggeredRoomID = ""; + this.triggeredUserName = ""; + this.triggeredUserID = ""; + this.exp_CurRoom = null; + this.exp_CurUser = null; + this.exp_LoopIndex = 0; + + // room + this.room = new RoomMgrKlass(this); + this.room.doorAutoControl = (this.properties[2] === 1); + // room list + this.roomsList = new RoomsListKlass(this); + // user list + this.usersList = this.room.usersList; + + //window["Firebase"]["enableLogging"](true); + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + instanceProto.get_room_ref = function(roomID) + { + var ref = this.get_ref("rooms"); + if (roomID) + ref = ref["child"](roomID); + return ref; + }; + + instanceProto.get_roomUser_ref = function(roomID, joinAt) + { + var ref = this.get_room_ref(roomID)["child"]("users"); + if (joinAt != null) + ref = ref["child"](joinAt); + return ref; + }; + + instanceProto.get_roomAliveFlag_ref = function(roomID) + { + return this.get_room_ref(roomID)["child"]("alive"); + }; + + instanceProto.get_roomfilter_ref = function(roomID) + { + var ref = this.get_ref("room-filter"); + if (roomID != null) + ref = ref["child"](roomID); + return ref; + }; + instanceProto.get_roommetadata_ref = function(roomID) + { + var ref = this.get_ref("room-metadata"); + if (roomID != null) + ref = ref["child"](roomID); + return ref; + }; + + + instanceProto.get_usermetadata_ref = function(userID) + { + return this.get_ref("user-metadata")["child"](userID); + }; + + var getFilter = function(state, type_) + { + var val = state+"|"+type_; + return val; + }; + + var parseFilter = function(filter) + { + var arr = filter.split("|"); + var state = arr[0]; + var type = arr[1]; + return [state, type]; + } + + var get_roomState = function (filter) + { + return filter.split("|")[0]; + }; + + instanceProto.run_room_trigger = function(trig, roomName, roomID) + { + // trigger next tick + var self=this; + setTimeout(function() + { + self.triggeredRoomName = roomName; + self.triggeredRoomID = roomID; + self.runtime.trigger(trig, self); + }, 0); + }; + instanceProto.run_userlist_trigger = function(trig, userName, userID) + { + // trigger next tick + var self=this; + setTimeout(function() + { + self.triggeredUserName = userName; + self.triggeredUserID = userID; + self.runtime.trigger(trig, self); + }, 0); + }; + + ////////////////////////////////////// + // Conditions + function Cnds() {}; + pluginProto.cnds = new Cnds(); + + Cnds.prototype.OnCreateRoom = function () + { + return true; + }; + + Cnds.prototype.OnCreateRoomError = function () + { + return true; + }; + + Cnds.prototype.OnJoinRoom = function () + { + return true; + }; + + Cnds.prototype.OnJoinRoomError = function () + { + return true; + }; + + Cnds.prototype.OnLeftRoom = function () + { + return true; + }; + + Cnds.prototype.OnKicked = function () + { + return true; + }; + + Cnds.prototype.OnOpened = function () + { + return true; + }; + + Cnds.prototype.OnClosed = function () + { + return true; + }; + + Cnds.prototype.IsInRoom = function () + { + return this.room.IsInRoom(); + }; + + Cnds.prototype.OnUpdateRoomsList = function () + { + return true; + }; + + Cnds.prototype.ForEachRoom = function (start, end) + { + return this.roomsList.ForEachRoom(start, end); + }; + + Cnds.prototype.OnUpdateUsersList = function () + { + return true; + }; + + Cnds.prototype.ForEachUser = function (start, end) + { + return this.usersList.ForEachUser(start, end); + }; + + Cnds.prototype.OnUserJoin = function () + { + return true; + }; + + Cnds.prototype.OnUserLeft = function () + { + return true; + }; + + Cnds.prototype.IsFirstUser = function () + { + return this.usersList.isFirstUser(); + }; + + Cnds.prototype.IsFull = function () + { + return this.usersList.IsFull(); + }; + + Cnds.prototype.OnBecomeFirstUser = function () + { + return true; + }; + + Cnds.prototype.ForEachUserInPermissionList = function (listType) + { + var listName = (listType === 1)? "black-list" : "white-list"; + var permissionList = (this.room.metadata)? this.room.metadata[listName] : null; + if (permissionList == null) + return false; + + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var userID, user; + this.exp_CurUser = {}; + this.exp_LoopIndex = -1; + for(userID in permissionList) + { + if (solModifierAfterCnds) + { + this.runtime.pushCopySol(current_event.solModifiers); + } + + this.exp_CurUser["ID"] = userID + this.exp_CurUser["name"] = permissionList[userID]; + this.exp_LoopIndex ++; + current_event.retrigger(); + + + if (solModifierAfterCnds) + { + this.runtime.popSol(current_event.solModifiers); + } + } + + this.exp_CurUser = null; + return false; + }; + + Cnds.prototype.IsLocked = function () + { + return this.LockedByAction; + }; + + Cnds.prototype.OnGetUsersList = function () + { + return true; + }; + + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetUserInfo = function (userID, name) + { + if (userID == "") + { + console.error("rex_firebase_rooms: UserID should not be empty string."); + return; + } + this.room.SetUser(userID, name); + }; + + Acts.prototype.CreateRoom = function (roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin) + { + this.LockedByAction = true; + var self = this; + var on_end = function () + { + self.LockedByAction = false; + } + + // push a new room if roomID == "" + doorState = DOORSTATES[doorState]; + createThenJoin = (createThenJoin === 1); + if (createThenJoin) + { + + var on_create = function (error) + { + if ((roomID !== "") && error) + { + self.room.TryJoinRoom(roomID, on_end); + } + }; + + var on_left = function (error) + { + if (error) + { + on_end(); + return; + } + + setTimeout(function() + { + self.room.TryCreateRoom(roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, on_create); + }, LEAVEDELAY); + } + + if (this.room.IsInRoom()) + { + this.room.LeaveRoom(on_left); + } + else + this.room.TryCreateRoom(roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, on_create); + + } + else // create room only + { + this.room.TryCreateRoom(roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, on_end); + } + }; + + Acts.prototype.SwitchDoor = function (doorState) + { + doorState = DOORSTATES[doorState]; + this.room.SwitchDoor(doorState); + }; + + Acts.prototype.JoinRoom = function (roomID, leftThenJoin) + { + this.LockedByAction = true; + var self = this; + var on_end = function () + { + self.LockedByAction = false; + }; + + var try_join = function (error) + { + if (error || (roomID === "")) + { + on_end(); + self.run_room_trigger(cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnJoinRoomError, "", ""); + return; + } + + setTimeout(function() + { + self.room.TryJoinRoom(roomID, on_end); + }, LEAVEDELAY); + } + + if (leftThenJoin===0) + try_join(); + else + this.room.LeaveRoom(try_join); + }; + + Acts.prototype.LeaveRoom = function () + { + this.LockedByAction = true; + var self = this; + var on_end = function () + { + self.LockedByAction = false; + }; + + this.room.LeaveRoom(on_end); + }; + + //Acts.prototype.RemoveRoom = function (roomID, permission) + //{ + // if (roomID == "") + // return; + // + // this.room.RemoveRoom(roomID, permission); + //}; + + Acts.prototype.KickUser = function (userID) + { + this.room.KickUser(userID); + }; + + + Acts.prototype.UpdateOpenRoomsList = function (roomType) + { + this.roomsList.UpdateOpenRoomsList(roomType); + }; + + Acts.prototype.StopUpdatingOpenRoomsList = function () + { + this.roomsList.StopUpdatingOpenRoomsList(); + }; + + + Acts.prototype.PermissionListAdd = function (userID, name, listType) + { + var listName = (listType === 1)? "black-list" : "white-list"; + this.room.SetPermissionList(listName, userID, name); + }; + Acts.prototype.PermissionListRemove = function (userID, listType) + { + var listName = (listType === 1)? "black-list" : "white-list"; + this.room.SetPermissionList(listName, userID, null); + }; + + Acts.prototype.RequestMetadata = function () + { + this.room.RequestMetadata(); + }; + + Acts.prototype.RequestUserMetadata = function (userID) + { + + }; + + Acts.prototype.JoinRandomRoom = function (leftThenJoin, retry) + { + var roomID = ""; + + this.LockedByAction = true; + var self = this; + var on_end = function (failed) + { + self.LockedByAction = false; + + if (failed) + { + self.run_room_trigger(cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnJoinRoomError, "", ""); + } + else + { + var roomName = self.room.roomName; + var roomID = self.room.roomID; + self.run_room_trigger(cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnJoinRoom, roomName, roomID); + } + }; + + // step 3. join room success, or retry + var on_join = function (error) + { + if (error) + main(); + else + on_end(); + }; + // step 3. join room success, or retry + + // step 2. try join room, left then join + var try_join = function (error) + { + if (error || (roomID === "")) + { + on_end(true); + return; + } + + setTimeout(function() + { + self.room.TryJoinRoom(roomID, on_join, true); // ignore trigger + }, LEAVEDELAY); + } + // step 2. try join room, left then join + + // step 1. try join a random room + var main = function () + { + if (retry < 0) + { + on_end(true); + return; + } + + retry -= 1; + var rooms = self.roomsList.GetRooms(); + var idx = Math.floor( Math.random() * rooms.length ); + var room = rooms[idx]; + roomID = (room)? room["roomID"]:""; + + if (leftThenJoin===0) + try_join(); + else + self.room.LeaveRoom(try_join); + } + // step 1. try join a random room + + main(); + }; + + Acts.prototype.GetUsersList = function (roomID) + { + var on_read = function (snapshot) + { + var val = snapshot["val"](); + } + + var usersList_ref = this.get_roomUser_ref(roomID); + usersList_ref["once"]("value", on_read); + }; + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.UserName = function (ret) + { + ret.set_string(this.room.userName); + }; + + Exps.prototype.UserID = function (ret) + { + ret.set_string(this.room.userID); + }; + + Exps.prototype.MyUserName = Exps.prototype.UserName; + Exps.prototype.MyUserID = Exps.prototype.UserID; + + Exps.prototype.RoomName = function (ret) + { + ret.set_string(this.room.roomName); + }; + + Exps.prototype.RoomID = function (ret) + { + ret.set_string(this.room.roomID); + }; + + Exps.prototype.TriggeredRoomName = function (ret) + { + ret.set_string(this.triggeredRoomName); + }; + + Exps.prototype.TriggeredRoomID = function (ret) + { + ret.set_string(this.triggeredRoomID); + }; + + Exps.prototype.CurRoomName = function (ret) + { + var room = this.exp_CurRoom; + var name = (room)? room["name"]:""; + ret.set_string(name); + }; + + Exps.prototype.CurRoomID = function (ret) + { + var room = this.exp_CurRoom; + var ID = (room)? room["roomID"]:""; + ret.set_string(ID); + }; + + Exps.prototype.CurCreatorName = function (ret) + { + var room = this.exp_CurRoom; + var name; + if (room) + { + var user = room["moderators"]; + for(var ID in user) + { + name = user[ID]; + break; + } + } + if (name == null) + name = ""; + ret.set_string(name); + }; + + Exps.prototype.CurCreatorID = function (ret) + { + var room = this.exp_CurRoom; + var ID; + if (room) + { + var user = room["moderators"]; + for(ID in user) + { + break; + } + } + if (ID == null) + ID = ""; + ret.set_string(ID); + }; + + Exps.prototype.Index2RoomName = function (ret, index) + { + var room = this.roomsList.GetRooms()[index]; + var name = (room)? room["name"]:""; + ret.set_string(name); + }; + + Exps.prototype.Index2RoomID = function (ret, index) + { + var room = this.roomsList.GetRooms()[index]; + var ID = (room)? room["roomID"]:""; + ret.set_string(ID); + }; + + Exps.prototype.RoomsCount = function (ret, index) + { + ret.set_int(this.roomsList.GetRooms().length); + }; + + Exps.prototype.CurUserName = function (ret) + { + var user = this.exp_CurUser; + var name = (user)? user["name"]:""; + ret.set_string(name); + }; + + Exps.prototype.CurUserID = function (ret) + { + var user = this.exp_CurUser; + var ID = (user)? user["ID"]:""; + ret.set_string(ID); + }; + + Exps.prototype.Index2UserName = function (ret, index) + { + var user = this.usersList.usersList.GetItems()[index]; + var name = (user)? user["name"]:""; + ret.set_string(name); + }; + + Exps.prototype.Index2UserID = function (ret, index) + { + var user = this.usersList.usersList.GetItems()[index]; + var ID = (user)? user["ID"]:""; + ret.set_string(ID); + }; + + Exps.prototype.TriggeredUserName = function (ret) + { + ret.set_string(this.triggeredUserName); + }; + + Exps.prototype.TriggeredUserID = function (ret) + { + ret.set_string(this.triggeredUserID); + }; + + Exps.prototype.UsersCount = function (ret) + { + ret.set_int(this.usersList.usersList.GetItems().length); + }; + + Exps.prototype.CurRoomMaxPeers = function (ret) + { + var room = this.exp_CurRoom; + var maxPeers = (room)? (room["maxPeers"] || 0) : 0; + ret.set_int(maxPeers); + }; + + Exps.prototype.Index2RoomMaxPeers = function (ret, index) + { + var room = this.roomsList.GetRooms()[index]; + var maxPeers = (room)? (room["maxPeers"] || 0) : 0; + ret.set_int(maxPeers); + }; + + Exps.prototype.WhiteListToJSON = function (ret) + { + var permissionList; + + if (this.room.metadata) + permissionList = this.room.metadata["white-list"]; + if (permissionList == null) + permissionList = {} + + ret.set_string(JSON.stringify(permissionList)); + }; + + Exps.prototype.BlackListToJSON = function (ret) + { + var permissionList; + + if (this.room.metadata) + permissionList = this.room.metadata["black-list"]; + if (permissionList == null) + permissionList = {} + + ret.set_string(JSON.stringify(permissionList)); + }; + + Exps.prototype.ChannelRef = function (ret, name, roomID) + { + if (roomID == null) + roomID = this.room.roomID; + + var path = this.rootpath + "/rooms/" + roomID +"/"; + if (name != null) + path += "channel-"+name + "/"; + ret.set_string(path); + }; + + Exps.prototype.LoopIndex = function (ret) + { + ret.set_int(this.exp_LoopIndex); + }; + + + + // -------- + + var RoomMgrKlass = function (plugin) + { + this.plugin = plugin; + this.doorAutoControl = true; + this.isRemoveRoomWhenLeft = false; + this.manualLeave = false; + + this.userID = ""; + this.userName = ""; + // key of room ref + this.roomID = ""; + this.roomName = ""; + this.roomType = ""; + this.maxPeers = 0; + this.metadata = null; + + // state + this.doorState = null; + this.isFullSave = false; + this.is_creater = false; + // key of user ref + this.joinAt = ""; + + // monitor ref + this.monitor_ref = []; + + // users list + this.usersList = new UsersListKlass(this); + + // user metadata + //this.user_metadata = new UserMetadataKlass(this); + }; + + var RoomMgrKlassProto = RoomMgrKlass.prototype; + + // export + RoomMgrKlassProto.SetUser = function (userID, name) + { + this.userID = userID; + this.userName = name; + + //this.user_metadata.Init(); + }; + + RoomMgrKlassProto.IsInRoom = function() + { + return (this.roomID !== ""); + }; + + RoomMgrKlassProto.TryCreateRoom = function (roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, + onComplete, ignoreTrigger) + { + // does not support + //if ((roomID !== "") && (lifePeriod === LIFE_TEMPORARY)) + //{ + // return; + //} + + if (this.IsInRoom()) + { + if (onComplete) + onComplete(true); + + return; + } + + var self = this; + + // on complete + var on_create_room_complete = function(error, metadata) + { + if (error) + { + on_create_room_error(); + return; + } + + // end of create room + + if (createThenJoin) + { + self.roomID = roomID; + self.roomName = roomName; + self.roomType = roomType; + self.maxPeers = maxPeers; + } + + if (!ignoreTrigger) + { + var trig = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnCreateRoom; + self.plugin.run_room_trigger(trig, roomName, roomID); + } + // create successful + self.onJoinRoom(roomID, metadata, onComplete, ignoreTrigger); + + if (onComplete) + onComplete(); + }; + + + // on error + var on_create_room_error = function() + { + if (!ignoreTrigger) + { + // create failed + var trig = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnCreateRoomError; + self.plugin.run_room_trigger(trig, roomName, roomID); + } + + if (onComplete) + onComplete(true); + }; + + // try allocate a room + if (roomID == "") + { + roomID = get_key( this.plugin.get_room_ref()["push"]() ); + this.createRoom(roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, + on_create_room_complete); + } + else // roomID !== "" + { + var self=this; + var on_write_userID = function(current_value) + { + if (current_value === null) + return true; + else + return; // Abort the transaction + }; + var on_write_userID_complete = function(error, committed, snapshot) + { + if (error || !committed) + { + // create failed + on_create_room_error(); + } + else + { + self.createRoom(roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, + on_create_room_complete); + } + }; + // try create room + var ref = this.plugin.get_roomAliveFlag_ref(roomID); + ref["transaction"](on_write_userID, on_write_userID_complete); + } + }; + + RoomMgrKlassProto.SwitchDoor = function (doorState) + { + if (!this.IsInRoom()) + return; + + this.SetDoorState(doorState); + }; + + RoomMgrKlassProto.isRoomOpened = function (metadata) + { + if (metadata == null) + return false; + + var state = get_roomState(metadata["filter"]); + if (state === ROOMCLOSED) + return false; + + var IamModerators = metadata["moderators"].hasOwnProperty(this.userID); + if (IamModerators) + return true; + + var permission = metadata["permission"]; + if (permission === "black-list") + { + var blackList = metadata["black-list"]; + if (blackList && blackList.hasOwnProperty(this.userID)) + return false; + else + return true; + } + else if (permission === "white-list") + { + var whiteList = metadata["white-list"]; + if (whiteList && whiteList.hasOwnProperty(this.userID)) + return true; + else + return true; + } + else // permission === "anyone" + return true; + } + + RoomMgrKlassProto.TryJoinRoom = function (roomID, onComplete, ignoreTrigger) + { + if (this.IsInRoom()) + { + if (onComplete) + onComplete(true); + + return; + } + + var self = this; + var on_join_complete = function(metadata) + { + self.onJoinRoom(roomID, metadata, onComplete, ignoreTrigger); + }; + var on_join_errror = function() + { + if (!ignoreTrigger) + { + var trig = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnJoinRoomError; + self.plugin.run_room_trigger(trig, "", roomID); + } + + if (onComplete) + onComplete(true); + }; + + // step 3: check user count + var check_user_count = function (metadata) + { + var on_read = function (snapshot) + { + var isInList = false; + snapshot["forEach"](function (childSnapshot) + { + var userID = childSnapshot["val"]()["ID"]; + isInList = (userID === self.userID); + if (isInList) + return true; + }); + if (isInList) + { + on_join_complete(metadata); + } + else + { + self.removeUsersList(roomID, on_join_errror); + } + } + + // read user list after exits this callback + setTimeout(function() + { + var usersList_ref = self.plugin.get_roomUser_ref(roomID); + usersList_ref["limitToFirst"](metadata["maxPeers"])["once"]("value", on_read); + }, 0); + }; + // step 3: check user count + + // step 2: add to user list + var try_join = function (metadata) + { + var on_write = function (error) + { + if (error) + { + on_join_errror(); + return; + } + + if (metadata["maxPeers"]) + check_user_count(metadata); + else + on_join_complete(metadata); + } + + self.addUsersList(roomID, on_write); + }; + // step 2: add to user list + + // step 1: check room-metadata (room header) + var check_door = function () + { + var on_read = function (snapshot) + { + var metadata = snapshot["val"](); + if (!self.isRoomOpened(metadata)) + { + on_join_errror(); + return; + } + try_join(metadata); + }; + var roommetadata_ref = self.plugin.get_roommetadata_ref(roomID); + roommetadata_ref["once"]("value", on_read); + }; + // step 1: check metadata + + check_door(); + this.pendCommand = "JOIN"; + }; + + RoomMgrKlassProto.KickUser = function (userID, onComplete) + { + var user = this.usersList.GetUser(userID); + if (user == null) + { + if (onComplete) + onComplete(true); + + return; + } + + var user_ref = this.plugin.get_roomUser_ref(this.roomID, user["joinAt"]); + user_ref["remove"](onComplete); + }; + + RoomMgrKlassProto.LeaveRoom = function (onComplete, ignoreTrigger) + { + if (!this.IsInRoom()) + { + if (onComplete) + onComplete(true); + + return; + } + + this.manualLeave = true; + var self=this; + var on_left = function(error) + { + self.pendCommand = null; + if (!error) + { + self.isRemoveRoomWhenLeft = false; + self.is_creater = false; + } + + if (onComplete) + onComplete(error); + }; + + if (this.isRemoveRoomWhenLeft) + { + // remove room, include user list + this.removeRoom(this.roomID, on_left); + } + else + { + // remove from user list only + this.removeUsersList(this.roomID, on_left); + } + }; + + RoomMgrKlassProto.SetPermissionList = function (listName, userID, value) + { + if (!this.IsInRoom()) + return; + + var data = {}; + data["permission"] = listName; + + if (userID !== "") + data[listName + "/" + userID] = value; + + var metadata_ref = this.plugin.get_roommetadata_ref(this.roomID); + metadata_ref["update"](data); + }; + + RoomMgrKlassProto.RequestMetadata = function () + { + if (!this.IsInRoom()) + return; + + var self=this; + var on_read = function (snapshot) + { + self.metadata = snapshot["val"](); + + } + + var metadata_ref = this.plugin.get_roommetadata_ref(this.roomID); + metadata_ref["once"]("value", on_read); + }; + // export + + RoomMgrKlassProto.addUsersList = function(roomID, onComplete) + { + var usersList_ref = this.plugin.get_roomUser_ref(roomID); + var user_ref = usersList_ref["push"](); + user_ref["onDisconnect"]()["remove"](); + this.joinAt = get_key( user_ref ); + var userData = { + "ID": this.userID, + "name": this.userName, + }; + + // write to user list if onComplete + if (onComplete) + user_ref["set"](userData, onComplete); + + // prepare return data + var data = {}; + data[this.joinAt] = userData; + return data; + }; + + // normal case + RoomMgrKlassProto.removeUsersList = function (roomID, onComplete) + { + if (roomID == null) + roomID = this.roomID; + + var user_ref = this.plugin.get_roomUser_ref(roomID, this.joinAt); + var on_remove = function (error) + { + if (!error) + { + user_ref["onDisconnect"]()["cancel"](); + } + if (onComplete) + onComplete(error); + } + user_ref["remove"](on_remove); + }; + + RoomMgrKlassProto.monitorMyStateOn = function () + { + var self = this; + // monitor user kicked + var id_ref = this.plugin.get_roomUser_ref(this.roomID, this.joinAt)["child"]("ID"); + var on_value_changed = function (snapshot) + { + var ID = snapshot["val"](); + if (ID != null) + return; + + self.onLeftRoom(); + }; + this.monitor_ref.push(id_ref["toString"]()); + id_ref["on"]("value", on_value_changed); + + // monitor filter (door state) + var filter_ref = this.plugin.get_roommetadata_ref(this.roomID)["child"]("filter"); + var on_value_changed = function (snapshot) + { + var filter = snapshot["val"](); + if (filter == null) + return; + + var state = get_roomState(filter); + if (self.doorState !== state) + { + var cnds = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds; + var trig = (state === ROOMOPEN)? cnds.OnOpened : cnds.OnClosed; + self.plugin.run_room_trigger(trig, self.roomName, self.roomID); + self.doorState = state; + } + } + this.monitor_ref.push(filter_ref["toString"]()); + filter_ref["on"]("value", on_value_changed); + }; + + RoomMgrKlassProto.monitorMyStateOff = function () + { + var i, cnt=this.monitor_ref.length; + for (i=0; i 0) + metadata["maxPeers"] = maxPeers; + + // set room data + var roomdata = { + "alive": true, + }; + + if (createThenJoin) + { + roomdata["users"] = {}; + var userData = this.addUsersList(roomID, false); + for (var k in userData) + roomdata["users"][k] = userData[k]; + } + var data = {}; + data["room-filter/"+roomID] = roomfilter; + data["room-metadata/"+roomID] = metadata; + data["rooms/"+roomID] = roomdata; + + var onComplete = function(error) + { + if (onComplete_) + onComplete_(error, metadata); + } + var root_ref = this.plugin.get_ref(); + root_ref["update"](data, onComplete); + this.is_creater = true; + + }; + + RoomMgrKlassProto.removeRoom = function (roomID, onComplete) + { + var self=this; + var on_remove = function(error) + { + if (!error) + { + // cancel disconnect handler after remove room writting + var roomfilter_ref = self.plugin.get_roomfilter_ref(roomID); + var metadata_ref = self.plugin.get_roommetadata_ref(roomID); + var room_ref = self.plugin.get_room_ref(roomID); + roomfilter_ref["onDisconnect"]()["cancel"](); + metadata_ref["onDisconnect"]()["cancel"](); + room_ref["onDisconnect"]()["cancel"](); + + if (roomID === self.roomID) + { + var user_ref = self.plugin.get_roomUser_ref(roomID, self.joinAt); + user_ref["onDisconnect"]()["cancel"](); + self.joinAt = ""; + } + } + if (onComplete) + onComplete(error); + }; + + var data = {}; + data["room-filter/"+roomID] = null; + data["room-metadata/"+ roomID] = null; + data["rooms/"+ roomID] = null; + var root_ref = this.plugin.get_ref(); + root_ref["update"](data, on_remove); + }; + + RoomMgrKlassProto.onJoinRoom = function (roomID, metadata, onComplete, ignoreTrigger) + { + this.metadata = metadata; + var filterProps = parseFilter(metadata["filter"]); // state,type + this.roomID = roomID; + this.roomName = metadata["name"]; + this.roomType = filterProps[1]; + this.maxPeers = metadata["maxPeers"] || 0; + this.doorState = null; + + this.monitorMyStateOn(); + + // users list + var self=this; + this.usersList.onInitialize = function () + { + if (!ignoreTrigger) + { + var trig = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnJoinRoom; + self.plugin.run_room_trigger(trig, self.roomName, roomID); + } + + // call onComplete while users list has initialized + if (onComplete) + onComplete(); + self.usersList.onInitialize = null; + } + this.usersList.StartUpdate(roomID, this.maxPeers); + //this.user_metadata.Update(); + + }; + + RoomMgrKlassProto.onLeftRoom = function () + { + var roomID = this.roomID; + var roomName = this.roomName; + this.roomID = ""; + this.roomName = ""; + this.doorState = null; + this.isFullSave = false; + + this.monitorMyStateOff(); + this.usersList.StopUpdate(); + this.usersList.Clean(); + // roomID had been cleaned + + // clean user metadata + //this.user_metadata.Update(); + + var trig = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnLeftRoom; + this.plugin.run_room_trigger(trig, roomName, roomID); + + if (!this.manualLeave) + { + var trig = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnKicked; + this.plugin.run_room_trigger(trig, roomName, roomID); + } + + this.manualLeave = false; + }; + + RoomMgrKlassProto.SetDoorState = function (doorState, onComplete) + { + var filter = getFilter(doorState, this.roomType); + var data = {}; + data["room-filter/"+this.roomID+"/filter"] = filter; + data["room-metadata/"+this.roomID+"/filter"] = filter; + var root_ref = this.plugin.get_ref(); + root_ref["update"](data, onComplete); + }; + + + RoomMgrKlassProto.onUsersListUpdated = function (usersList) + { + // delay execute + var self=this; + setTimeout(function () + { + var nowIsFull = self.usersList.IsFull(); + if (self.doorAutoControl && self.usersList.isFirstUser()) + { + if (self.isFullSave !== nowIsFull) + { + var doorState = (nowIsFull)? ROOMCLOSED : ROOMOPEN; + self.SetDoorState( doorState ); + } + } + self.isFullSave = nowIsFull; + }, 0); + }; + + var clean_table = function (o) + { + var k; + for (k in o) + delete o[k]; + }; + + + // -------- + var RoomsListKlass = function (plugin) + { + this.plugin = plugin; + this.myRoom = plugin.room; + this.rooms_list = new window.FirebaseItemListKlass(); + + this.rooms_list.keyItemID = "roomID"; + }; + + var RoomsListKlassProto = RoomsListKlass.prototype; + + RoomsListKlassProto.UpdateOpenRoomsList = function (roomType) + { + var self = this; + var on_roomList_update = function (room) + { + var trig = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnUpdateRoomsList; + self.plugin.run_room_trigger(trig, room["name"], room["roomID"]); + }; + + this.rooms_list.onItemAdd = on_roomList_update; + this.rooms_list.onItemRemove = on_roomList_update; + this.rooms_list.onItemChange = on_roomList_update; + + // prepare filter ref + var filter_ref = this.plugin.get_roomfilter_ref(); + var query = filter_ref["orderByChild"]("filter"); + if (roomType != "") + query = query["equalTo"](getFilter(ROOMOPEN, roomType)); + else + query = query["startAt"](ROOMOPEN)["endAt"](ROOMOPEN+"~"); + + this.rooms_list.StartUpdate(query); + }; + + RoomsListKlassProto.StopUpdatingOpenRoomsList = function() + { + this.rooms_list.StopUpdate(); + }; + + RoomsListKlassProto.ForEachRoom = function (start, end) + { + var self = this; + var onGetIterItem = function(item, i) + { + self.plugin.exp_CurRoom = item; + self.plugin.exp_LoopIndex = i; + }; + this.rooms_list.onGetIterItem = onGetIterItem; + this.rooms_list.ForEachItem(this.plugin.runtime, start, end); + this.plugin.exp_CurRoom = null; + this.plugin.exp_LoopIndex = 0; + return false; + }; + + RoomsListKlassProto.GetRooms = function() + { + return this.rooms_list.GetItems(); + }; + + var UsersListKlass = function (room) + { + // overwrite these values + this.onInitialize = null; + // overwrite these values + + this.plugin = room.plugin; + this.myRoom = room; + this.usersList = new window.FirebaseItemListKlass(); + this.userID2joinAt = {}; + this.room = room; + this.roomID = ""; + this.limit = 0; + this.isFirstUserSave = false; + + this.usersList.keyItemID = "joinAt"; + }; + + var UsersListKlassProto = UsersListKlass.prototype; + + UsersListKlassProto.StartUpdate = function (roomID, limit) + { + if (limit == null) + limit = 0; + + this.StopUpdate(); + + this.roomID = roomID; + this.limit = limit; + + var self = this; + var on_usersList_update = function (item) + { + var trig = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnUpdateUsersList; + self.plugin.run_userlist_trigger(trig, item["name"], item["ID"]); + + var isFirstUser = self.isFirstUser(); + if (isFirstUser && !self.isFirstUserSave) + { + var trig = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnBecomeFirstUser; + self.plugin.run_userlist_trigger(trig, self.room.userName, self.room.userID); + } + self.isFirstUserSave = isFirstUser; + }; + var on_user_join = function (item) + { + self.userID2joinAt[ item["ID"] ] = item["joinAt"]; + + if (item["ID"] === self.room.userID) + { + if (self.onInitialize) + self.onInitialize(self.usersList.GetItems()); + } + var trig = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnUserJoin; + self.plugin.run_userlist_trigger(trig, item["name"], item["ID"]); + on_usersList_update(item); + self.myRoom.onUsersListUpdated(self.usersList.GetItems()); + }; + var on_user_left = function (item) + { + if (self.userID2joinAt.hasOwnProperty( item["ID"] )) + delete self.userID2joinAt[ item["ID"] ]; + + var trig = cr.plugins_.Rex_Firebase_Rooms.prototype.cnds.OnUserLeft; + self.plugin.run_userlist_trigger(trig, item["name"], item["ID"]); + on_usersList_update(item); + self.myRoom.onUsersListUpdated(self.usersList.GetItems()); + }; + + var query = this.plugin.get_roomUser_ref(this.roomID); + if (limit > 0) + query = query["limitToFirst"](limit); + + this.usersList.onItemAdd = on_user_join; + this.usersList.onItemRemove = on_user_left; + this.usersList.onItemChange = on_usersList_update; + this.usersList.StartUpdate(query); + }; + + UsersListKlassProto.StopUpdate = function() + { + this.usersList.StopUpdate(); + this.roomID = ""; + this.limit = 0; + }; + + UsersListKlassProto.ForEachUser = function (start, end) + { + var self = this; + var onGetIterItem = function(item, i) + { + self.plugin.exp_CurUser = item; + self.plugin.exp_LoopIndex = i; + }; + this.usersList.onGetIterItem = onGetIterItem; + this.usersList.ForEachItem(this.plugin.runtime, start, end); + this.plugin.exp_CurUser = null; + this.plugin.exp_LoopIndex = 0; + return false; + }; + + UsersListKlassProto.Clean = function () + { + this.usersList.Clean(); + }; + + UsersListKlassProto.IsFull = function () + { + if (this.limit === 0) + return false; + + return (this.usersList.GetItems().length >= this.limit); + }; + UsersListKlassProto.isFirstUser = function (userID) + { + if (userID == null) + userID = this.room.userID; + + var user = this.usersList.GetItems()[0]; + if (!user) + return false; + + return (user["ID"] === userID); + }; + UsersListKlassProto.GetUser = function (userID) + { + if (!this.userID2joinAt.hasOwnProperty(userID)) + return null; + + var joinAt = this.userID2joinAt[userID]; + return this.usersList.GetItemByID(joinAt); + }; + + var UserMetadataKlass = function (room) + { + this.room = room; + this.plugin = room.plugin; + this.ref = null; + }; + + var UserMetadataKlassProto = UserMetadataKlass.prototype; + + UserMetadataKlassProto.Init = function () + { + if (this.ref) + this.ref["onDisconnect"]()["cancel"](); + + this.ref = this.plugin.get_usermetadata_ref(this.room.userID); + this.ref["onDisconnect"]()["remove"](); + this.Update(); + }; + + UserMetadataKlassProto.Update = function () + { + var metadata = { + "name": this.room.userName, + "roomID": this.room.roomID, + "roomName": this.room.roomName, + }; + this.ref["set"](metadata); + }; + +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/actions.js new file mode 100755 index 0000000..6f851f4 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/actions.js @@ -0,0 +1,238 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Rooms.Acts = + { + SetUserInfo(userID, name) + { + if (userID == "") + { + console.error("rex_firebase_rooms: UserID should not be empty string."); + return; + } + this.room.SetUser(userID, name); + }, + + CreateRoom(roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin) + { + this.LockedByAction = true; + var self = this; + var on_end = function () + { + self.LockedByAction = false; + } + + // push a new room if roomID == "" + doorState = DOORSTATES[doorState]; + createThenJoin = (createThenJoin === 1); + if (createThenJoin) + { + + var on_create = function (error) + { + if ((roomID !== "") && error) + { + self.room.TryJoinRoom(roomID, on_end); + } + }; + + var on_left = function (error) + { + if (error) + { + on_end(); + return; + } + + setTimeout(function() + { + self.room.TryCreateRoom(roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, on_create); + }, LEAVEDELAY); + } + + if (this.room.IsInRoom()) + { + this.room.LeaveRoom(on_left); + } + else + this.room.TryCreateRoom(roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, on_create); + + } + else // create room only + { + this.room.TryCreateRoom(roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, on_end); + } + }, + + SwitchDoor(doorState) + { + doorState = DOORSTATES[doorState]; + this.room.SwitchDoor(doorState); + }, + + JoinRoom(roomID, leftThenJoin) + { + this.LockedByAction = true; + var self = this; + var on_end = function () + { + self.LockedByAction = false; + }; + + var try_join = function (error) + { + if (error || (roomID === "")) + { + on_end(); + self.run_room_trigger(C3.Plugins.Rex_Firebase_Rooms.Cnds.OnJoinRoomError, "", ""); + return; + } + + setTimeout(function() + { + self.room.TryJoinRoom(roomID, on_end); + }, LEAVEDELAY); + } + + if (leftThenJoin===0) + try_join(); + else + this.room.LeaveRoom(try_join); + }, + + LeaveRoom() + { + this.LockedByAction = true; + var self = this; + var on_end = function () + { + self.LockedByAction = false; + }; + + this.room.LeaveRoom(on_end); + }, + + + KickUser(userID) + { + this.room.KickUser(userID); + }, + + + UpdateOpenRoomsList(roomType) + { + this.roomsList.UpdateOpenRoomsList(roomType); + }, + + StopUpdatingOpenRoomsList() + { + this.roomsList.StopUpdatingOpenRoomsList(); + }, + + + PermissionListAdd(userID, name, listType) + { + var listName = (listType === 1)? "black-list" : "white-list"; + this.room.SetPermissionList(listName, userID, name); + }, + PermissionListRemove(userID, listType) + { + var listName = (listType === 1)? "black-list" : "white-list"; + this.room.SetPermissionList(listName, userID, null); + }, + + RequestMetadata() + { + this.room.RequestMetadata(); + }, + + RequestUserMetadata(userID) + { + + }, + + JoinRandomRoom(leftThenJoin, retry) + { + var roomID = ""; + + this.LockedByAction = true; + var self = this; + var on_end = function (failed) + { + self.LockedByAction = false; + + if (failed) + { + self.run_room_trigger(C3.Plugins.Rex_Firebase_Rooms.Cnds.OnJoinRoomError, "", ""); + } + else + { + var roomName = self.room.roomName; + var roomID = self.room.roomID; + self.run_room_trigger(C3.Plugins.Rex_Firebase_Rooms.Cnds.OnJoinRoom, roomName, roomID); + } + }; + + // step 3. join room success, or retry + var on_join = function (error) + { + if (error) + main(); + else + on_end(); + }; + // step 3. join room success, or retry + + // step 2. try join room, left then join + var try_join = function (error) + { + if (error || (roomID === "")) + { + on_end(true); + return; + } + + setTimeout(function() + { + self.room.TryJoinRoom(roomID, on_join, true); // ignore trigger + }, LEAVEDELAY); + } + // step 2. try join room, left then join + + // step 1. try join a random room + var main = function () + { + if (retry < 0) + { + on_end(true); + return; + } + + retry -= 1; + var rooms = self.roomsList.GetRooms(); + var idx = Math.floor( Math.random() * rooms.length ); + var room = rooms[idx]; + roomID = (room)? room["roomID"]:""; + + if (leftThenJoin===0) + try_join(); + else + self.room.LeaveRoom(try_join); + } + // step 1. try join a random room + + main(); + }, + + GetUsersList(roomID) + { + var on_read = function (snapshot) + { + var val = snapshot["val"](); + } + + var usersList_ref = this.get_roomUser_ref(roomID); + usersList_ref["once"]("value", on_read); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/conditions.js new file mode 100755 index 0000000..ef0c97f --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/conditions.js @@ -0,0 +1,150 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Rooms.Cnds = + { + + OnCreateRoom() + { + return true; + }, + + OnCreateRoomError() + { + return true; + }, + + OnJoinRoom() + { + return true; + }, + + OnJoinRoomError() + { + return true; + }, + + OnLeftRoom() + { + return true; + }, + + OnKicked() + { + return true; + }, + + OnOpened() + { + return true; + }, + + OnClosed() + { + return true; + }, + + IsInRoom() + { + return this.room.IsInRoom(); + }, + + OnUpdateRoomsList() + { + return true; + }, + + ForEachRoom(start, end) + { + return this.roomsList.ForEachRoom(start, end); + }, + + OnUpdateUsersList() + { + return true; + }, + + ForEachUser(start, end) + { + return this.usersList.ForEachUser(start, end); + }, + + OnUserJoin() + { + return true; + }, + + OnUserLeft() + { + return true; + }, + + IsFirstUser() + { + return this.usersList.isFirstUser(); + }, + + IsFull() + { + return this.usersList.IsFull(); + }, + + OnBecomeFirstUser() + { + return true; + }, + + ForEachUserInPermissionList(listType) + { + var listName = (listType === 1)? "black-list" : "white-list"; + var permissionList = (this.room.metadata)? this.room.metadata[listName] : null; + if (permissionList == null) + return false; + + + var current_frame = this._runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = this._runtime.GetEventSheetManager().GetEventStack(); + var p = this._runtime.GetEventStack(); + var h = c.Push(current_event); + + var userID, user; + this.exp_CurUser = {}; + this.exp_LoopIndex = -1; + for(userID in permissionList) + { + if (solModifierAfterCnds) + { + this._runtime.GetEventSheetManager().PushCopySol(solmod); + } + + this.exp_CurUser["ID"] = userID + this.exp_CurUser["name"] = permissionList[userID]; + this.exp_LoopIndex ++; + current_event.Retrigger(current_frame,h); + + + if (solModifierAfterCnds) + { + this._runtime.GetEventSheetManager().PopSol(solmod); + } + } + p.Pop(); + + this.exp_CurUser = null; + return false; + }, + + IsLocked() + { + return this.LockedByAction; + }, + + OnGetUsersList() + { + return true; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/expressions.js new file mode 100755 index 0000000..b4a38a4 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/expressions.js @@ -0,0 +1,213 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Rooms.Exps = + { + + UserName() + { + return (this.room.userName); + }, + + UserID() + { + return (this.room.userID); + }, + + MyUserName() + { + return this.UserName; + }, + MyUserID() + { + return this.UserID; + }, + + RoomName() + { + return (this.room.roomName); + }, + + RoomID() + { + return (this.room.roomID); + }, + + TriggeredRoomName() + { + return (this.triggeredRoomName); + }, + + TriggeredRoomID() + { + return (this.triggeredRoomID); + }, + + CurRoomName() + { + var room = this.exp_CurRoom; + var name = (room)? room["name"]:""; + return (name); + }, + + CurRoomID() + { + var room = this.exp_CurRoom; + var ID = (room)? room["roomID"]:""; + return (ID); + }, + + CurCreatorName() + { + var room = this.exp_CurRoom; + var name; + if (room) + { + var user = room["moderators"]; + for(var ID in user) + { + name = user[ID]; + break; + } + } + if (name == null) + name = ""; + return (name); + }, + + CurCreatorID() + { + var room = this.exp_CurRoom; + var ID; + if (room) + { + var user = room["moderators"]; + for(ID in user) + { + break; + } + } + if (ID == null) + ID = ""; + return (ID); + }, + + Index2RoomName( index) + { + var room = this.roomsList.GetRooms()[index]; + var name = (room)? room["name"]:""; + return (name); + }, + + Index2RoomID( index) + { + var room = this.roomsList.GetRooms()[index]; + var ID = (room)? room["roomID"]:""; + return (ID); + }, + + RoomsCount( index) + { + return (this.roomsList.GetRooms().length); + }, + + CurUserName() + { + var user = this.exp_CurUser; + var name = (user)? user["name"]:""; + return (name); + }, + + CurUserID() + { + var user = this.exp_CurUser; + var ID = (user)? user["ID"]:""; + return (ID); + }, + + Index2UserName( index) + { + var user = this.usersList.usersList.GetItems()[index]; + var name = (user)? user["name"]:""; + return (name); + }, + + Index2UserID( index) + { + var user = this.usersList.usersList.GetItems()[index]; + var ID = (user)? user["ID"]:""; + return (ID); + }, + + TriggeredUserName() + { + return (this.triggeredUserName); + }, + + TriggeredUserID() + { + return (this.triggeredUserID); + }, + + UsersCount() + { + return (this.usersList.usersList.GetItems().length); + }, + + CurRoomMaxPeers() + { + var room = this.exp_CurRoom; + var maxPeers = (room)? (room["maxPeers"] || 0) : 0; + return (maxPeers); + }, + + Index2RoomMaxPeers( index) + { + var room = this.roomsList.GetRooms()[index]; + var maxPeers = (room)? (room["maxPeers"] || 0) : 0; + return (maxPeers); + }, + + WhiteListToJSON() + { + var permissionList; + + if (this.room.metadata) + permissionList = this.room.metadata["white-list"]; + if (permissionList == null) + permissionList = {} + + return (JSON.stringify(permissionList)); + }, + + BlackListToJSON() + { + var permissionList; + + if (this.room.metadata) + permissionList = this.room.metadata["black-list"]; + if (permissionList == null) + permissionList = {} + + return (JSON.stringify(permissionList)); + }, + + ChannelRef( name, roomID) + { + if (roomID == null) + roomID = this.room.roomID; + + var path = this.rootpath + "/rooms/" + roomID +"/"; + if (name != null) + path += "channel-"+name + "/"; + return (path); + }, + + LoopIndex() + { + return (this.exp_LoopIndex); + } + + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/instance.js new file mode 100755 index 0000000..ba358f5 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/instance.js @@ -0,0 +1,146 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Rooms.Instance = class Rex_Firebase_RoomsInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + // room + this.room = new RoomMgrKlass(this); + + // room list + this.roomsList = new RoomsListKlass(this); + // user list + this.usersList = this.room.usersList; + + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/" + properties[1] + "/"; + this.room.doorAutoControl = (properties[2] === 1); + } + this.LockedByAction = false; + this.triggeredRoomName = ""; + this.triggeredRoomID = ""; + this.triggeredUserName = ""; + this.triggeredUserID = ""; + this.exp_CurRoom = null; + this.exp_CurUser = null; + this.exp_LoopIndex = 0; + + + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + get_ref(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + } + + + + get_room_ref(roomID) + { + var ref = this.get_ref("rooms"); + if (roomID) + ref = ref["child"](roomID); + return ref; + } + + get_roomUser_ref(roomID, joinAt) + { + var ref = this.get_room_ref(roomID)["child"]("users"); + if (joinAt != null) + ref = ref["child"](joinAt); + return ref; + } + + get_roomAliveFlag_ref(roomID) + { + return this.get_room_ref(roomID)["child"]("alive"); + } + + get_roomfilter_ref(roomID) + { + var ref = this.get_ref("room-filter"); + if (roomID != null) + ref = ref["child"](roomID); + return ref; + } + get_roommetadata_ref(roomID) + { + var ref = this.get_ref("room-metadata"); + if (roomID != null) + ref = ref["child"](roomID); + return ref; + } + + + get_usermetadata_ref(userID) + { + return this.get_ref("user-metadata")["child"](userID); + } + + + run_room_trigger(trig, roomName, roomID) + { + // trigger next tick + var self=this; + setTimeout(function() + { + self.triggeredRoomName = roomName; + self.triggeredRoomID = roomID; + self.Trigger(trig); + }, 0); + } + run_userlist_trigger(trig, userName, userID) + { + // trigger next tick + var self=this; + setTimeout(function() + { + self.triggeredUserName = userName; + self.triggeredUserID = userID; + self.Trigger(trig); + }, 0); + } + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/plugin.js new file mode 100755 index 0000000..6c68258 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/plugin.js @@ -0,0 +1,964 @@ +"use strict"; + var ROOMOPEN = "open"; + var ROOMCLOSED = "closed"; + var LIFE_TEMPORARY = 0; + var LIFE_PERSISTED = 1; + var JOINPERMINNSION = [null /*"anyone"*/, "black-list", "white-list"]; + var DOORSTATES = [ROOMCLOSED, ROOMOPEN]; + var LEAVEDELAY = 10; + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + var getFilter = function(state, type_) + { + var val = state+"|"+type_; + return val; + }; + + var parseFilter = function(filter) + { + var arr = filter.split("|"); + var state = arr[0]; + var type = arr[1]; + return [state, type]; + } + + var get_roomState = function (filter) + { + return filter.split("|")[0]; + }; + + + // -------- + + var RoomMgrKlass = function (plugin) + { + this.plugin = plugin; + this.doorAutoControl = true; + this.isRemoveRoomWhenLeft = false; + this.manualLeave = false; + + this.userID = ""; + this.userName = ""; + // key of room ref + this.roomID = ""; + this.roomName = ""; + this.roomType = ""; + this.maxPeers = 0; + this.metadata = null; + + // state + this.doorState = null; + this.isFullSave = false; + this.is_creater = false; + // key of user ref + this.joinAt = ""; + + // monitor ref + this.monitor_ref = []; + + // users list + this.usersList = new UsersListKlass(this); + + // user metadata + //this.user_metadata = new UserMetadataKlass(this); + }; + + var RoomMgrKlassProto = RoomMgrKlass.prototype; + + // export + RoomMgrKlassProto.SetUser = function (userID, name) + { + this.userID = userID; + this.userName = name; + + //this.user_metadata.Init(); + }; + + RoomMgrKlassProto.IsInRoom = function() + { + return (this.roomID !== ""); + }; + + RoomMgrKlassProto.TryCreateRoom = function (roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, + onComplete, ignoreTrigger) + { + // does not support + //if ((roomID !== "") && (lifePeriod === LIFE_TEMPORARY)) + //{ + // return; + //} + + if (this.IsInRoom()) + { + if (onComplete) + onComplete(true); + + return; + } + + var self = this; + + // on complete + var on_create_room_complete = function(error, metadata) + { + if (error) + { + on_create_room_error(); + return; + } + + // end of create room + + if (createThenJoin) + { + self.roomID = roomID; + self.roomName = roomName; + self.roomType = roomType; + self.maxPeers = maxPeers; + } + + if (!ignoreTrigger) + { + var trig = C3.Plugins.Rex_Firebase_Rooms.Cnds.OnCreateRoom; + self.plugin.run_room_trigger(trig, roomName, roomID); + } + // create successful + self.onJoinRoom(roomID, metadata, onComplete, ignoreTrigger); + + if (onComplete) + onComplete(); + }; + + + // on error + var on_create_room_error = function() + { + if (!ignoreTrigger) + { + // create failed + var trig = C3.Plugins.Rex_Firebase_Rooms.Cnds.OnCreateRoomError; + self.plugin.run_room_trigger(trig, roomName, roomID); + } + + if (onComplete) + onComplete(true); + }; + + // try allocate a room + if (roomID == "") + { + roomID = get_key( this.plugin.get_room_ref()["push"]() ); + this.createRoom(roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, + on_create_room_complete); + } + else // roomID !== "" + { + var self=this; + var on_write_userID = function(current_value) + { + if (current_value === null) + return true; + else + return; // Abort the transaction + }; + var on_write_userID_complete = function(error, committed, snapshot) + { + if (error || !committed) + { + // create failed + on_create_room_error(); + } + else + { + self.createRoom(roomName, roomType, maxPeers, lifePeriod, doorState, roomID, createThenJoin, + on_create_room_complete); + } + }; + // try create room + var ref = this.plugin.get_roomAliveFlag_ref(roomID); + ref["transaction"](on_write_userID, on_write_userID_complete); + } + }; + + RoomMgrKlassProto.SwitchDoor = function (doorState) + { + if (!this.IsInRoom()) + return; + + this.SetDoorState(doorState); + }; + + RoomMgrKlassProto.isRoomOpened = function (metadata) + { + if (metadata == null) + return false; + + var state = get_roomState(metadata["filter"]); + if (state === ROOMCLOSED) + return false; + + var IamModerators = metadata["moderators"].hasOwnProperty(this.userID); + if (IamModerators) + return true; + + var permission = metadata["permission"]; + if (permission === "black-list") + { + var blackList = metadata["black-list"]; + if (blackList && blackList.hasOwnProperty(this.userID)) + return false; + else + return true; + } + else if (permission === "white-list") + { + var whiteList = metadata["white-list"]; + if (whiteList && whiteList.hasOwnProperty(this.userID)) + return true; + else + return true; + } + else // permission === "anyone" + return true; + } + + RoomMgrKlassProto.TryJoinRoom = function (roomID, onComplete, ignoreTrigger) + { + if (this.IsInRoom()) + { + if (onComplete) + onComplete(true); + + return; + } + + var self = this; + var on_join_complete = function(metadata) + { + self.onJoinRoom(roomID, metadata, onComplete, ignoreTrigger); + }; + var on_join_errror = function() + { + if (!ignoreTrigger) + { + var trig = C3.Plugins.Rex_Firebase_Rooms.Cnds.OnJoinRoomError; + self.plugin.run_room_trigger(trig, "", roomID); + } + + if (onComplete) + onComplete(true); + }; + + // step 3: check user count + var check_user_count = function (metadata) + { + var on_read = function (snapshot) + { + var isInList = false; + snapshot["forEach"](function (childSnapshot) + { + var userID = childSnapshot["val"]()["ID"]; + isInList = (userID === self.userID); + if (isInList) + return true; + }); + if (isInList) + { + on_join_complete(metadata); + } + else + { + self.removeUsersList(roomID, on_join_errror); + } + } + + // read user list after exits this callback + setTimeout(function() + { + var usersList_ref = self.plugin.get_roomUser_ref(roomID); + usersList_ref["limitToFirst"](metadata["maxPeers"])["once"]("value", on_read); + }, 0); + }; + // step 3: check user count + + // step 2: add to user list + var try_join = function (metadata) + { + var on_write = function (error) + { + if (error) + { + on_join_errror(); + return; + } + + if (metadata["maxPeers"]) + check_user_count(metadata); + else + on_join_complete(metadata); + } + + self.addUsersList(roomID, on_write); + }; + // step 2: add to user list + + // step 1: check room-metadata (room header) + var check_door = function () + { + var on_read = function (snapshot) + { + var metadata = snapshot["val"](); + if (!self.isRoomOpened(metadata)) + { + on_join_errror(); + return; + } + try_join(metadata); + }; + var roommetadata_ref = self.plugin.get_roommetadata_ref(roomID); + roommetadata_ref["once"]("value", on_read); + }; + // step 1: check metadata + + check_door(); + this.pendCommand = "JOIN"; + }; + + RoomMgrKlassProto.KickUser = function (userID, onComplete) + { + var user = this.usersList.GetUser(userID); + if (user == null) + { + if (onComplete) + onComplete(true); + + return; + } + + var user_ref = this.plugin.get_roomUser_ref(this.roomID, user["joinAt"]); + user_ref["remove"](onComplete); + }; + + RoomMgrKlassProto.LeaveRoom = function (onComplete, ignoreTrigger) + { + if (!this.IsInRoom()) + { + if (onComplete) + onComplete(true); + + return; + } + + this.manualLeave = true; + var self=this; + var on_left = function(error) + { + self.pendCommand = null; + if (!error) + { + self.isRemoveRoomWhenLeft = false; + self.is_creater = false; + } + + if (onComplete) + onComplete(error); + }; + + if (this.isRemoveRoomWhenLeft) + { + // remove room, include user list + this.removeRoom(this.roomID, on_left); + } + else + { + // remove from user list only + this.removeUsersList(this.roomID, on_left); + } + }; + + RoomMgrKlassProto.SetPermissionList = function (listName, userID, value) + { + if (!this.IsInRoom()) + return; + + var data = {}; + data["permission"] = listName; + + if (userID !== "") + data[listName + "/" + userID] = value; + + var metadata_ref = this.plugin.get_roommetadata_ref(this.roomID); + metadata_ref["update"](data); + }; + + RoomMgrKlassProto.RequestMetadata = function () + { + if (!this.IsInRoom()) + return; + + var self=this; + var on_read = function (snapshot) + { + self.metadata = snapshot["val"](); + + } + + var metadata_ref = this.plugin.get_roommetadata_ref(this.roomID); + metadata_ref["once"]("value", on_read); + }; + // export + + RoomMgrKlassProto.addUsersList = function(roomID, onComplete) + { + var usersList_ref = this.plugin.get_roomUser_ref(roomID); + var user_ref = usersList_ref["push"](); + user_ref["onDisconnect"]()["remove"](); + this.joinAt = get_key( user_ref ); + var userData = { + "ID": this.userID, + "name": this.userName, + }; + + // write to user list if onComplete + if (onComplete) + user_ref["set"](userData, onComplete); + + // prepare return data + var data = {}; + data[this.joinAt] = userData; + return data; + }; + + // normal case + RoomMgrKlassProto.removeUsersList = function (roomID, onComplete) + { + if (roomID == null) + roomID = this.roomID; + + var user_ref = this.plugin.get_roomUser_ref(roomID, this.joinAt); + var on_remove = function (error) + { + if (!error) + { + user_ref["onDisconnect"]()["cancel"](); + } + if (onComplete) + onComplete(error); + } + user_ref["remove"](on_remove); + }; + + RoomMgrKlassProto.monitorMyStateOn = function () + { + var self = this; + // monitor user kicked + var id_ref = this.plugin.get_roomUser_ref(this.roomID, this.joinAt)["child"]("ID"); + var on_value_changed = function (snapshot) + { + var ID = snapshot["val"](); + if (ID != null) + return; + + self.onLeftRoom(); + }; + this.monitor_ref.push(id_ref["toString"]()); + id_ref["on"]("value", on_value_changed); + + // monitor filter (door state) + var filter_ref = this.plugin.get_roommetadata_ref(this.roomID)["child"]("filter"); + var on_value_changed = function (snapshot) + { + var filter = snapshot["val"](); + if (filter == null) + return; + + var state = get_roomState(filter); + if (self.doorState !== state) + { + var cnds = C3.Plugins.Rex_Firebase_Rooms.Cnds; + var trig = (state === ROOMOPEN)? cnds.OnOpened : cnds.OnClosed; + self.plugin.run_room_trigger(trig, self.roomName, self.roomID); + self.doorState = state; + } + } + this.monitor_ref.push(filter_ref["toString"]()); + filter_ref["on"]("value", on_value_changed); + }; + + RoomMgrKlassProto.monitorMyStateOff = function () + { + var i, cnt=this.monitor_ref.length; + for (i=0; i 0) + metadata["maxPeers"] = maxPeers; + + // set room data + var roomdata = { + "alive": true, + }; + + if (createThenJoin) + { + roomdata["users"] = {}; + var userData = this.addUsersList(roomID, false); + for (var k in userData) + roomdata["users"][k] = userData[k]; + } + var data = {}; + data["room-filter/"+roomID] = roomfilter; + data["room-metadata/"+roomID] = metadata; + data["rooms/"+roomID] = roomdata; + + var onComplete = function(error) + { + if (onComplete_) + onComplete_(error, metadata); + } + var root_ref = this.plugin.get_ref(); + root_ref["update"](data, onComplete); + this.is_creater = true; + + }; + + RoomMgrKlassProto.removeRoom = function (roomID, onComplete) + { + var self=this; + var on_remove = function(error) + { + if (!error) + { + // cancel disconnect handler after remove room writting + var roomfilter_ref = self.plugin.get_roomfilter_ref(roomID); + var metadata_ref = self.plugin.get_roommetadata_ref(roomID); + var room_ref = self.plugin.get_room_ref(roomID); + roomfilter_ref["onDisconnect"]()["cancel"](); + metadata_ref["onDisconnect"]()["cancel"](); + room_ref["onDisconnect"]()["cancel"](); + + if (roomID === self.roomID) + { + var user_ref = self.plugin.get_roomUser_ref(roomID, self.joinAt); + user_ref["onDisconnect"]()["cancel"](); + self.joinAt = ""; + } + } + if (onComplete) + onComplete(error); + }; + + var data = {}; + data["room-filter/"+roomID] = null; + data["room-metadata/"+ roomID] = null; + data["rooms/"+ roomID] = null; + var root_ref = this.plugin.get_ref(); + root_ref["update"](data, on_remove); + }; + + RoomMgrKlassProto.onJoinRoom = function (roomID, metadata, onComplete, ignoreTrigger) + { + this.metadata = metadata; + var filterProps = parseFilter(metadata["filter"]); // state,type + this.roomID = roomID; + this.roomName = metadata["name"]; + this.roomType = filterProps[1]; + this.maxPeers = metadata["maxPeers"] || 0; + this.doorState = null; + + this.monitorMyStateOn(); + + // users list + var self=this; + this.usersList.onInitialize = function () + { + if (!ignoreTrigger) + { + var trig = C3.Plugins.Rex_Firebase_Rooms.Cnds.OnJoinRoom; + self.plugin.run_room_trigger(trig, self.roomName, roomID); + } + + // call onComplete while users list has initialized + if (onComplete) + onComplete(); + self.usersList.onInitialize = null; + } + this.usersList.StartUpdate(roomID, this.maxPeers); + //this.user_metadata.Update(); + + }; + + RoomMgrKlassProto.onLeftRoom = function () + { + var roomID = this.roomID; + var roomName = this.roomName; + this.roomID = ""; + this.roomName = ""; + this.doorState = null; + this.isFullSave = false; + + this.monitorMyStateOff(); + this.usersList.StopUpdate(); + this.usersList.Clean(); + // roomID had been cleaned + + // clean user metadata + //this.user_metadata.Update(); + + var trig = C3.Plugins.Rex_Firebase_Rooms.Cnds.OnLeftRoom; + this.plugin.run_room_trigger(trig, roomName, roomID); + + if (!this.manualLeave) + { + var trig = C3.Plugins.Rex_Firebase_Rooms.Cnds.OnKicked; + this.plugin.run_room_trigger(trig, roomName, roomID); + } + + this.manualLeave = false; + }; + + RoomMgrKlassProto.SetDoorState = function (doorState, onComplete) + { + var filter = getFilter(doorState, this.roomType); + var data = {}; + data["room-filter/"+this.roomID+"/filter"] = filter; + data["room-metadata/"+this.roomID+"/filter"] = filter; + var root_ref = this.plugin.get_ref(); + root_ref["update"](data, onComplete); + }; + + + RoomMgrKlassProto.onUsersListUpdated = function (usersList) + { + // delay execute + var self=this; + setTimeout(function () + { + var nowIsFull = self.usersList.IsFull(); + if (self.doorAutoControl && self.usersList.isFirstUser()) + { + if (self.isFullSave !== nowIsFull) + { + var doorState = (nowIsFull)? ROOMCLOSED : ROOMOPEN; + self.SetDoorState( doorState ); + } + } + self.isFullSave = nowIsFull; + }, 0); + }; + + var clean_table = function (o) + { + var k; + for (k in o) + delete o[k]; + }; + + + // -------- + var RoomsListKlass = function (plugin) + { + this.plugin = plugin; + this.myRoom = plugin.room; + this.rooms_list = new window.FirebaseItemListKlass(); + + this.rooms_list.keyItemID = "roomID"; + }; + + var RoomsListKlassProto = RoomsListKlass.prototype; + + RoomsListKlassProto.UpdateOpenRoomsList = function (roomType) + { + var self = this; + var on_roomList_update = function (room) + { + var trig = C3.Plugins.Rex_Firebase_Rooms.Cnds.OnUpdateRoomsList; + self.plugin.run_room_trigger(trig, room["name"], room["roomID"]); + }; + + this.rooms_list.onItemAdd = on_roomList_update; + this.rooms_list.onItemRemove = on_roomList_update; + this.rooms_list.onItemChange = on_roomList_update; + + // prepare filter ref + var filter_ref = this.plugin.get_roomfilter_ref(); + var query = filter_ref["orderByChild"]("filter"); + if (roomType != "") + query = query["equalTo"](getFilter(ROOMOPEN, roomType)); + else + query = query["startAt"](ROOMOPEN)["endAt"](ROOMOPEN+"~"); + + this.rooms_list.StartUpdate(query); + }; + + RoomsListKlassProto.StopUpdatingOpenRoomsList = function() + { + this.rooms_list.StopUpdate(); + }; + + RoomsListKlassProto.ForEachRoom = function (start, end) + { + var self = this; + var onGetIterItem = function(item, i) + { + self.plugin.exp_CurRoom = item; + self.plugin.exp_LoopIndex = i; + }; + this.rooms_list.onGetIterItem = onGetIterItem; + this.rooms_list.ForEachItem(this.plugin._runtime, start, end); + this.plugin.exp_CurRoom = null; + this.plugin.exp_LoopIndex = 0; + return false; + }; + + RoomsListKlassProto.GetRooms = function() + { + return this.rooms_list.GetItems(); + }; + + var UsersListKlass = function (room) + { + // overwrite these values + this.onInitialize = null; + // overwrite these values + + this.plugin = room.plugin; + this.myRoom = room; + this.usersList = new window.FirebaseItemListKlass(); + this.userID2joinAt = {}; + this.room = room; + this.roomID = ""; + this.limit = 0; + this.isFirstUserSave = false; + + this.usersList.keyItemID = "joinAt"; + }; + + var UsersListKlassProto = UsersListKlass.prototype; + + UsersListKlassProto.StartUpdate = function (roomID, limit) + { + if (limit == null) + limit = 0; + + this.StopUpdate(); + + this.roomID = roomID; + this.limit = limit; + + var self = this; + var on_usersList_update = function (item) + { + var trig = C3.Plugins.Rex_Firebase_Rooms.Cnds.OnUpdateUsersList; + self.plugin.run_userlist_trigger(trig, item["name"], item["ID"]); + + var isFirstUser = self.isFirstUser(); + if (isFirstUser && !self.isFirstUserSave) + { + var trig = C3.Plugins.Rex_Firebase_Rooms.Cnds.OnBecomeFirstUser; + self.plugin.run_userlist_trigger(trig, self.room.userName, self.room.userID); + } + self.isFirstUserSave = isFirstUser; + }; + var on_user_join = function (item) + { + self.userID2joinAt[ item["ID"] ] = item["joinAt"]; + + if (item["ID"] === self.room.userID) + { + if (self.onInitialize) + self.onInitialize(self.usersList.GetItems()); + } + var trig = C3.Plugins.Rex_Firebase_Rooms.Cnds.OnUserJoin; + self.plugin.run_userlist_trigger(trig, item["name"], item["ID"]); + on_usersList_update(item); + self.myRoom.onUsersListUpdated(self.usersList.GetItems()); + }; + var on_user_left = function (item) + { + if (self.userID2joinAt.hasOwnProperty( item["ID"] )) + delete self.userID2joinAt[ item["ID"] ]; + + var trig = C3.Plugins.Rex_Firebase_Rooms.Cnds.OnUserLeft; + self.plugin.run_userlist_trigger(trig, item["name"], item["ID"]); + on_usersList_update(item); + self.myRoom.onUsersListUpdated(self.usersList.GetItems()); + }; + + var query = this.plugin.get_roomUser_ref(this.roomID); + if (limit > 0) + query = query["limitToFirst"](limit); + + this.usersList.onItemAdd = on_user_join; + this.usersList.onItemRemove = on_user_left; + this.usersList.onItemChange = on_usersList_update; + this.usersList.StartUpdate(query); + }; + + UsersListKlassProto.StopUpdate = function() + { + this.usersList.StopUpdate(); + this.roomID = ""; + this.limit = 0; + }; + + UsersListKlassProto.ForEachUser = function (start, end) + { + var self = this; + var onGetIterItem = function(item, i) + { + self.plugin.exp_CurUser = item; + self.plugin.exp_LoopIndex = i; + }; + this.usersList.onGetIterItem = onGetIterItem; + this.usersList.ForEachItem(this.plugin._runtime, start, end); + this.plugin.exp_CurUser = null; + this.plugin.exp_LoopIndex = 0; + return false; + }; + + UsersListKlassProto.Clean = function () + { + this.usersList.Clean(); + }; + + UsersListKlassProto.IsFull = function () + { + if (this.limit === 0) + return false; + + return (this.usersList.GetItems().length >= this.limit); + }; + UsersListKlassProto.isFirstUser = function (userID) + { + if (userID == null) + userID = this.room.userID; + + var user = this.usersList.GetItems()[0]; + if (!user) + return false; + + return (user["ID"] === userID); + }; + UsersListKlassProto.GetUser = function (userID) + { + if (!this.userID2joinAt.hasOwnProperty(userID)) + return null; + + var joinAt = this.userID2joinAt[userID]; + return this.usersList.GetItemByID(joinAt); + }; + + var UserMetadataKlass = function (room) + { + this.room = room; + this.plugin = room.plugin; + this.ref = null; + }; + + var UserMetadataKlassProto = UserMetadataKlass.prototype; + + UserMetadataKlassProto.Init = function () + { + if (this.ref) + this.ref["onDisconnect"]()["cancel"](); + + this.ref = this.plugin.get_usermetadata_ref(this.room.userID); + this.ref["onDisconnect"]()["remove"](); + this.Update(); + }; + + UserMetadataKlassProto.Update = function () + { + var metadata = { + "name": this.room.userName, + "roomID": this.room.roomID, + "roomName": this.room.roomName, + }; + this.ref["set"](metadata); + }; + +{ + C3.Plugins.Rex_Firebase_Rooms = class Rex_Firebase_RoomsPlugin extends C3.SDKPluginBase + { + constructor(opts) + { + super(opts); + } + + Release() + { + super.Release(); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/type.js new file mode 100755 index 0000000..3238f04 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/c3runtime/type.js @@ -0,0 +1,20 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Rooms.Type = class Rex_Firebase_RoomsType extends C3.SDKTypeBase + { + constructor(objectClass) + { + super(objectClass); + } + + Release() + { + super.Release(); + } + + OnCreate() + { + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/icon.png new file mode 100755 index 0000000..86eb069 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/instance.js new file mode 100755 index 0000000..f58ef13 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Rooms; + + PLUGIN_CLASS.Instance = class Rex_Firebase_RoomsInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/lang/en-US.json new file mode 100755 index 0000000..4d918b0 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/lang/en-US.json @@ -0,0 +1,435 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Rooms.", + "text": { + "plugins": { + "rex_firebase_rooms": { + "name": "Rooms", + "description": "Rooms management.", + "help-url": "http://c2rexplugins.weebly.com/rex_firebase_rooms.html", + "properties": { + "domain": { + "name": "Domain", + "desc": "The root location of the Firebase data." + }, + "sub-domain": { + "name": "Sub domain", + "desc": "Sub domain for this function." + }, + "door-control": { + "name": "Door control", + "desc": "Set \"Auto\" to close or open door when room is full or not.", + "items": { + "manual":"Manual", + "auto":"Auto" + } + } + }, + "aceCategories": { + "0._my_info": "0. My info", + "room": "Room", + "door_state": "Door state", + "room_list": "Room list", + "permission_list": "Permission list", + "room_-_metadata": "Room - metadata", + "user_list": "User list", + "create_room": "Create room", + "join_room": "Join room", + "leave_room": "Leave room", + "rooms_list": "Rooms list", + "users_list": "Users list", + "action": "Action", + "my": "My", + "triggered": "Triggered", + "rooms_list_-_for_each": "Rooms list - for each", + "rooms_list_-_index": "Rooms list - index", + "users_list_-_for_each": "Users list - for each", + "users_list_-_index": "Users list - index", + "custom_channel": "Custom channel", + "for_each_-_index": "For each - index" + }, + "conditions": { + "oncreateroom11": { + "list-name": "On create", + "display-text": "On create room", + "description": "Triggered when room created." + }, + "oncreateroomerror12": { + "list-name": "On create error", + "display-text": "On create room error", + "description": "Triggered when room created error." + }, + "onjoinroom13": { + "list-name": "On join", + "display-text": "On join room", + "description": "Triggered when join room." + }, + "onjoinroomerror14": { + "list-name": "On join error", + "display-text": "On join room error", + "description": "Triggered when join room error." + }, + "onleftroom15": { + "list-name": "On left", + "display-text": "On left room", + "description": "Triggered when left room or room removed" + }, + "onkicked16": { + "list-name": "On kicked", + "display-text": "On kicked out from room", + "description": "Triggered when user kicked out or room removed." + }, + "onopened17": { + "list-name": "On opened", + "display-text": "On opened", + "description": "Triggered when room is opened." + }, + "onclosed18": { + "list-name": "On closed", + "display-text": "On closed", + "description": "Triggered when room is closed." + }, + "ısınroom19": { + "list-name": "In room", + "display-text": "Is in a room", + "description": "Return true if current user is in a room." + }, + "onupdateroomslist21": { + "list-name": "On update", + "display-text": "On update rooms list", + "description": "Triggered when rooms list updated." + }, + "foreachroom22": { + "list-name": "For each room", + "display-text": "For each room", + "description": "Repeat the event for each room in rooms list." + }, + "foreachroom23": { + "list-name": "For each room in a range", + "display-text": "For each room from [i]{0}[/i] to [i]{1}[/i]", + "description": "Repeat the event for each room in a range.", + "params": { + "start0": { "name":"Start", "desc":"Start from index (0-based)."}, + "end1": { "name":"End", "desc":"End to index (0-based). This value should larger than Start."} + } + }, + "onupdateuserslist31": { + "list-name": "On update", + "display-text": "On update user list", + "description": "Triggered when user list updated." + }, + "foreachuser32": { + "list-name": "For each user", + "display-text": "For each user", + "description": "Repeat the event for each user in users list." + }, + "foreachuser33": { + "list-name": "For each user in a range", + "display-text": "For each user from [i]{0}[/i] to [i]{1}[/i]", + "description": "Repeat the event for each user in a range.", + "params": { + "start0": { "name":"Start", "desc":"Start from index (0-based)."}, + "end1": { "name":"End", "desc":"End to index (0-based). This value should larger than Start."} + } + }, + "onuserjoin35": { + "list-name": "On user joined", + "display-text": "On user joined", + "description": "Triggered when user joined." + }, + "onuserleft36": { + "list-name": "On user left", + "display-text": "On user left", + "description": "Triggered when user left." + }, + "ısfirstuser37": { + "list-name": "I am first user", + "display-text": "I am first user", + "description": "Return true if client is the first user of current room." + }, + "ısfull38": { + "list-name": "Is full", + "display-text": "Room is full", + "description": "Return true if room is full of users." + }, + "onbecomefirstuser39": { + "list-name": "On become first user", + "display-text": "On become first user", + "description": "Triggered when became first user of current room." + }, + "foreachuserınpermissionlist51": { + "list-name": "For each user", + "display-text": "For each user in [i]{0}[/i]", + "description": "Repeat the event for each user in permission list.", + "params": { + "list2": { "name":"List", "desc":"List type.", "items":{"white - list":"white - list","black - lisk":"black - lisk"}} + } + }, + "ıslocked100": { + "list-name": "Locked", + "display-text": "Is locked", + "description": "Return true if plugin is locked which could not run any action." + }, + "ongetuserslist111": { + "list-name": "On get users list", + "display-text": "On get users list", + "description": "Triggered when get users list." + } + }, + "actions": { + "setuserınfo1": { + "list-name": "Set my info", + "display-text": "Set user name to [i]{1}[/i], user ID to [i]{0}[/i]", + "description": "Set user info.", + "params": { + "userıd0": { "name":"UserID", "desc":"UserID from authentication."}, + "name1": { "name":"Name", "desc":"User name."} + } + }, + "createroom11": { + "list-name": "Create", + "display-text": "{6} [i]{3}[/i] [i]{1}[/i] room: [i]{0}[/i], ID: [i]{5}[/i], with max peers to [i]{2}[/i], door state to [i]{4}[/i]", + "description": "Create then join this room.", + "params": { + "name0": { "name":"Name", "desc":"Room name."}, + "type1": { "name":"Type", "desc":"Room type. \"public\", \"private\", or others."}, + "max_peers2": { "name":"Max peers", "desc":"The maximum number of peers that can join this room. Leave 0 for unlimited."}, + "life_period5": { "name":"Life period", "desc":"Life period of this room.", "items":{"temporary":"Temporary","persisted":"Persisted"}}, + "door_state8": { "name":"Door state", "desc":"Door state of this room.", "items":{"closed":"Closed","open":"Open"}}, + "room_ıd9": { "name":"Room ID", "desc":"Room ID. Leave \"\" to use timestamp form server."}, + "create_action12": { "name":"Create action", "desc":"Create action.", "items":{"create":"Create","leave current room, then create or join":"Leave current room, then create or join"}} + } + }, + "switchdoor12": { + "list-name": "Open", + "display-text": "[i]{0}[/i] current room", + "description": "Open or close current room.", + "params": { + "door_state2": { "name":"Door state", "desc":"Door state of this room.", "items":{"close":"Close","open":"Open"}} + } + }, + "createroom13": { + "list-name": "Create (#)", + "display-text": "{7} [i]{3}[/i] [i]{1}[/i] room: [i]{0}[/i], ID: [i]{6}[/i], with max peers to [i]{2}[/i], door state to [i]{4}[/i], Join permission to [i]{5}[/i]", + "description": "Create then join this room.", + "params": { + "name0": { "name":"Name", "desc":"Room name."}, + "type1": { "name":"Type", "desc":"Room type. \"public\", \"private\", or others."}, + "max_peers2": { "name":"Max peers", "desc":"The maximum number of peers that can join this room. Leave 0 for unlimited."}, + "life_period3": { "name":"Life period", "desc":"0=Temporary, 1=Persisted."}, + "door_state4": { "name":"Door state", "desc":"0=Closed, 1=Open."}, + "oin_permission5": { "name":"oin permission", "desc":"0=Anyone, 1=Black list, 2=White list."}, + "room_ıd6": { "name":"Room ID", "desc":"Room ID. Leave \"\" to use timestamp form server."}, + "create_action9": { "name":"Create action", "desc":"Create action.", "items":{"create":"Create","create then join":"Create then join"}} + } + }, + "joinroom15": { + "list-name": "Join", + "display-text": "{1} room ID: [i]{0}[/i]", + "description": "Join room.", + "params": { + "room_ıd0": { "name":"Room ID", "desc":"Room ID."}, + "join_action3": { "name":"Join action", "desc":"Join action.", "items":{"join":"Join","leave current room then join":"Leave current room then join"}} + } + }, + "leaveroom16": { + "list-name": "Leave", + "display-text": "Leave current room", + "description": "Leave current room." + }, + "kickuser19": { + "list-name": "Kick user", + "display-text": "Kick user ID: [i]{0}[/i]", + "description": "Kick user.", + "params": { + "userıd0": { "name":"UserID", "desc":"UserID from authentication."} + } + }, + "updateopenroomslist21": { + "list-name": "Update", + "display-text": "Start updating [i]{0}[/i] rooms list", + "description": "Update opened rooms list.", + "params": { + "type0": { "name":"Type", "desc":"Room type. \"public\", \"private\", or others. Leave \"\" to get all \"open\" rooms for all types."} + } + }, + "stopupdatingopenroomslist22": { + "list-name": "Stop updating", + "display-text": "Stop updating rooms list", + "description": "Stop updating opened rooms list." + }, + "permissionlistadd51": { + "list-name": "Add", + "display-text": "Add user [i]{1}[/i], ID: [i]{0}[/i] to [i]{2}[/i]", + "description": "Add user to permission list.", + "params": { + "userıd0": { "name":"UserID", "desc":"UserID from authentication."}, + "name1": { "name":"Name", "desc":"Player name."}, + "list4": { "name":"List", "desc":"List type.", "items":{"white - list":"white - list","black - lisk":"black - lisk"}} + } + }, + "permissionlistremove52": { + "list-name": "Remove", + "display-text": "Remove user ID: [i]{0}[/i] from [i]{1}[/i]", + "description": "Remove user from permission list.", + "params": { + "userıd0": { "name":"UserID", "desc":"UserID from authentication."}, + "list3": { "name":"List", "desc":"List type.", "items":{"white - list":"white - list","black - lisk":"black - lisk"}} + } + }, + "requestmetadata61": { + "list-name": "Get metadata", + "display-text": "Get metadata", + "description": "Get metadata included white list and black list." + }, + "joinrandomroom101": { + "list-name": "Join random", + "display-text": "[i]{0}[/i] random room with retry [i]{1}[/i] times", + "description": "Join random room from current rooms list.", + "params": { + "join_action2": { "name":"Join action", "desc":"Join action.", "items":{"join":"Join","leave current room then join":"Leave current room then join"}}, + "retry3": { "name":"Retry", "desc":"Retry count to get default value."} + } + }, + "getuserslist111": { + "list-name": "Get users list of room", + "display-text": "Get users list of room ID: [i]{0}[/i]", + "description": "Get users list of room.", + "params": { + "room_ıd0": { "name":"Room ID", "desc":"Room ID."} + } + } + }, + "expressions": { + "username1": { + "description": "Get my user name.", + "translated-name": "UserName" + }, + "userıd2": { + "description": "Get my user ID.", + "translated-name": "UserID" + }, + "myusername3": { + "description": "Get my user name.", + "translated-name": "MyUserName" + }, + "myuserıd4": { + "description": "Get my user ID.", + "translated-name": "MyUserID" + }, + "roomname11": { + "description": "Get current room name.", + "translated-name": "RoomName" + }, + "roomıd12": { + "description": "Get current room ID.", + "translated-name": "RoomID" + }, + "triggeredroomname13": { + "description": "Get triggered room name.", + "translated-name": "TriggeredRoomName" + }, + "triggeredroomıd14": { + "description": "Get triggered room ID.", + "translated-name": "TriggeredRoomID" + }, + "curroomname21": { + "description": "Get the current room name in a For Each loop.", + "translated-name": "CurRoomName" + }, + "curroomıd22": { + "description": "Get the current room ID in a For Each loop.", + "translated-name": "CurRoomID" + }, + "curcreatorname23": { + "description": "Get the current creater name in a For Each loop.", + "translated-name": "CurCreatorName" + }, + "curcreatorıd24": { + "description": "Get the current creater ID in a For Each loop.", + "translated-name": "CurCreatorID" + }, + "ındex2roomname25": { + "description": "Get room name by room index.", + "translated-name": "Index2RoomName", + "params": { + "ındex0": { "name":"Index", "desc":"Room index."} + } + }, + "ındex2roomıd26": { + "description": "Get room ID by room index.", + "translated-name": "Index2RoomID", + "params": { + "ındex0": { "name":"Index", "desc":"Room index."} + } + }, + "roomscount27": { + "description": "Get amount of opened rooms.", + "translated-name": "RoomsCount" + }, + "curusername31": { + "description": "Get the current user name in a For Each loop.", + "translated-name": "CurUserName" + }, + "curuserıd32": { + "description": "Get the current user ID in a For Each loop.", + "translated-name": "CurUserID" + }, + "ındex2username33": { + "description": "Get user name by user index.", + "translated-name": "Index2UserName", + "params": { + "ındex0": { "name":"Index", "desc":"User index."} + } + }, + "ındex2userıd34": { + "description": "Get user ID by user index.", + "translated-name": "Index2UserID", + "params": { + "ındex0": { "name":"Index", "desc":"User index."} + } + }, + "triggeredusername35": { + "description": "Get triggered user name.", + "translated-name": "TriggeredUserName" + }, + "triggereduserıd36": { + "description": "Get triggered user ID.", + "translated-name": "TriggeredUserID" + }, + "userscount37": { + "description": "Get amount of users in users list.", + "translated-name": "UsersCount" + }, + "curroommaxpeers41": { + "description": "Get max peers of current room in a For Each loop.", + "translated-name": "CurRoomMaxPeers" + }, + "ındex2roommaxpeers42": { + "description": "Get room name by room index.", + "translated-name": "Index2RoomMaxPeers", + "params": { + "ındex0": { "name":"Index", "desc":"Room index."} + } + }, + "whitelisttojson51": { + "description": "Get white list in JSON string.", + "translated-name": "WhiteListToJSON" + }, + "blacklisttojson52": { + "description": "Get black list in JSON string.", + "translated-name": "BlackListToJSON" + }, + "channelref81": { + "description": "Get custom channel absolute reference. Add 2nd parameter for roomID.", + "translated-name": "ChannelRef" + }, + "loopındex100": { + "description": "Get loop index in for each loop.", + "translated-name": "LoopIndex" + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/plugin.js new file mode 100755 index 0000000..43fd065 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/plugin.js @@ -0,0 +1,43 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase_Rooms"; + const PLUGIN_VERSION = "0.1.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Rooms = class Rex_Firebase_Rooms extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "domain", ""), + new SDK.PluginProperty("text", "sub-domain", "Rooms"), + new SDK.PluginProperty("combo", "door-control", {initialValue:"manual", items:["manual","auto"]}) + ]); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/type.js new file mode 100755 index 0000000..b589277 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_rooms/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Rooms; + + PLUGIN_CLASS.Type = class Rex_Firebase_RoomsType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/dist/rex_firebase_savedata.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/dist/rex_firebase_savedata.c3addon new file mode 100644 index 0000000..1802390 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/dist/rex_firebase_savedata.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/aces.json new file mode 100755 index 0000000..22c657d --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/aces.json @@ -0,0 +1,433 @@ +{ + "0._setup": { + "conditions": [ + ], + "actions": [ + { + "c2id": 1, + "id": "setowner1", + "scriptName": "SetOwner", + "highlight": false, + "params": [ + {"id":"user_ıd0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "prepare": { + "conditions": [ + ], + "actions": [ + { + "c2id": 2, + "id": "setvalue2", + "scriptName": "SetValue", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""}, + {"id":"value1", "type":"any", "initialValue":"0"}, + {"id":"slot4", "type":"combo", "items":["header","body"]} + ] + }, + { + "c2id": 4, + "id": "setbooleanvalue4", + "scriptName": "SetBooleanValue", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""}, + {"id":"boolean3", "type":"combo", "items":["false","true"]}, + {"id":"slot6", "type":"combo", "items":["header","body"]} + ] + }, + { + "c2id": 5, + "id": "setcurrentservertimestamp5", + "scriptName": "SetCurrentServerTimestamp", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""}, + {"id":"slot3", "type":"combo", "items":["header","body"]} + ] + }, + { + "c2id": 6, + "id": "removekey6", + "scriptName": "RemoveKey", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""}, + {"id":"slot3", "type":"combo", "items":["header","body"]} + ] + }, + { + "c2id": 7, + "id": "setjson7", + "scriptName": "SetJSON", + "highlight": false, + "params": [ + {"id":"key0", "type":"any", "initialValue":"\"\""}, + {"id":"json1", "type":"string", "initialValue":"\"\""}, + {"id":"slot4", "type":"combo", "items":["header","body"]} + ] + } + ], + "expressions": [ + ] + }, + "save": { + "conditions": [ + { + "c2id": 1, + "id": "onsave1", + "scriptName": "OnSave", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 2, + "id": "onsaveerror2", + "scriptName": "OnSaveError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 3, + "id": "save3", + "scriptName": "Save", + "highlight": false, + "params": [ + {"id":"name0", "type":"any", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "load": { + "conditions": [ + ], + "actions": [ + { + "c2id": 11, + "id": "getallheaders11", + "scriptName": "GetAllHeaders", + "highlight": false + }, + { + "c2id": 12, + "id": "getslotbody12", + "scriptName": "GetSlotBody", + "highlight": false, + "params": [ + {"id":"name0", "type":"any", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "clean": { + "conditions": [ + { + "c2id": 21, + "id": "onclean21", + "scriptName": "OnClean", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 22, + "id": "oncleanerror22", + "scriptName": "OnCleanError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 21, + "id": "cleanslot21", + "scriptName": "CleanSlot", + "highlight": false + }, + { + "c2id": 22, + "id": "cleanslot22", + "scriptName": "CleanSlot", + "highlight": false, + "params": [ + {"id":"name0", "type":"any", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "load_-_header": { + "conditions": [ + { + "c2id": 11, + "id": "ongetallheaders11", + "scriptName": "OnGetAllHeaders", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 12, + "id": "foreachheader12", + "scriptName": "ForEachHeader", + "isLooping": "true", + "isInvertible": "false", + "highlight": false + }, + { + "c2id": 31, + "id": "ongetallheaderserror31", + "scriptName": "OnGetAllHeadersError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "load_-_body": { + "conditions": [ + { + "c2id": 13, + "id": "ongetbody13", + "scriptName": "OnGetBody", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 14, + "id": "ongetunusedbody14", + "scriptName": "OnGetUnusedBody", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 32, + "id": "ongetbodyerror32", + "scriptName": "OnGetBodyError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "header": { + "conditions": [ + { + "c2id": 15, + "id": "allslotareempty15", + "scriptName": "AllSlotAreEmpty", + "highlight": false + }, + { + "c2id": 16, + "id": "ısoccupied16", + "scriptName": "IsOccupied", + "highlight": false, + "params": [ + {"id":"name0", "type":"any", "initialValue":"\"\""} + ] + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "header_-_for_each": { + "conditions": [ + { + "c2id": 17, + "id": "foreachkeyınheader17", + "scriptName": "ForEachKeyInHeader", + "isLooping": "true", + "isInvertible": "false", + "highlight": false, + "params": [ + {"id":"name0", "type":"any", "initialValue":"\"\""} + ] + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "body_-_for_each": { + "conditions": [ + { + "c2id": 18, + "id": "foreachkeyınbody18", + "scriptName": "ForEachKeyInBody", + "isLooping": "true", + "isInvertible": "false", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + ] + }, + "body": { + "conditions": [ + { + "c2id": 19, + "id": "bodyısınvalid19", + "scriptName": "BodyIsInvalid", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 3, + "id": "bodyvalue3", + "expressionName": "BodyValue", + "scriptName": "BodyValue", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + }, + { + "c2id": 9, + "id": "lastslotname9", + "expressionName": "LastSlotName", + "scriptName": "LastSlotName", + "highlight": false, + "returnType": "any" + } + ] + }, + "for_each_header": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 1, + "id": "curslotname1", + "expressionName": "CurSlotName", + "scriptName": "CurSlotName", + "highlight": false, + "returnType": "any" + }, + { + "c2id": 2, + "id": "curheadervalue2", + "expressionName": "CurHeaderValue", + "scriptName": "CurHeaderValue", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + } + ] + }, + "json": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 4, + "id": "headerstojson4", + "expressionName": "HeadersToJSON", + "scriptName": "HeadersToJSON", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 5, + "id": "bodytojson5", + "expressionName": "BodyToJSON", + "scriptName": "BodyToJSON", + "highlight": false, + "returnType": "string" + } + ] + }, + "headers": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 6, + "id": "headervalue6", + "expressionName": "HeaderValue", + "scriptName": "HeaderValue", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + } + ] + }, + "for_each_key": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 7, + "id": "curkey7", + "expressionName": "CurKey", + "scriptName": "CurKey", + "highlight": false, + "returnType": "any" + }, + { + "c2id": 8, + "id": "curvalue8", + "expressionName": "CurValue", + "scriptName": "CurValue", + "highlight": false, + "returnType": "any" + } + ] + }, + "error": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 21, + "id": "lasterrorcode21", + "expressionName": "LastErrorCode", + "scriptName": "LastErrorCode", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 22, + "id": "lasterrormessage22", + "expressionName": "LastErrorMessage", + "scriptName": "LastErrorMessage", + "highlight": false, + "returnType": "string" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/addon.json new file mode 100755 index 0000000..bb05b94 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/addon.json @@ -0,0 +1,26 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Save slot", + "id": "Rex_Firebase_SaveSlot", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_saveslot.html", + "documentation": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_saveslot.html", + "description": "Private save slots.", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c2runtime/runtime.js new file mode 100755 index 0000000..c05ea33 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c2runtime/runtime.js @@ -0,0 +1,673 @@ +/* + + headers\ + + - value + + bodies\ + + - value + +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_SaveSlot = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_SaveSlot.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + + this.ownerID = ""; + + this.error = null; + this.save_header = {}; + this.save_body = {}; + this.save_item = {}; + + this.load_headers = null; + this.load_body = null; + this.exp_LastSlotName = null; + + this.exp_CurSlotName = ""; + this.exp_CurHeader = {}; + this.exp_CurKey = ""; + this.exp_CurValue = 0; + }; + + instanceProto.onDestroy = function () + { + this.save_header = {}; + this.save_body = {}; + this.save_item = {}; + + this.load_headers = null; + this.load_body = null; + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + var is_empty = function (o) + { + for (var k in o) + { + if (o[k] !== null) + return false; + } + return true; + }; + + + var get_path = function (slot_name, is_body, key) + { + key = key.replace(re_ALLDOT, "/"); + var p = (is_body)? "bodies":"headers"; + p += "/" + slot_name + "/" + key; + return p; + }; + + instanceProto.updateCacheData = function (slot_name, save_header, save_body) + { + if (this.load_headers == null) + this.load_headers = {}; + if (!this.load_headers.hasOwnProperty(slot_name)) + this.load_headers[slot_name] = {}; + + var load_header = this.load_headers[slot_name]; + for(var n in save_header) + { + n = setItemValue(n, save_header[n], load_header); + } + + if (slot_name === this.exp_LastSlotName) + { + if (this.load_body == null) + this.load_body = {}; + for (var n in save_body) + { + setItemValue(n, save_body[n], this.load_body); + } + } + }; + + var setItemValue = function(keys, value, root) + { + if (typeof (keys) === "string") + keys = keys.split("."); + + var lastKey = keys.pop(); + var entry = getEntry(keys, root); + entry[lastKey] = value; + }; + + var getEntry = function(keys, root) + { + var entry = root; + if ((keys === "") || (keys.length === 0)) + { + //entry = root; + } + else + { + if (typeof (keys) === "string") + keys = keys.split("."); + + var i, cnt=keys.length, key; + for (i=0; i< cnt; i++) + { + key = keys[i]; + if ( (entry[key] == null) || (typeof(entry[key]) !== "object") ) + entry[key] = {}; + + entry = entry[key]; + } + } + + return entry; + }; + + /**BEGIN-PREVIEWONLY**/ + // slightly modified neet simple function from Pumbaa80 + // http://stackoverflow.com/questions/4810841/how-can-i-pretty-print-json-using-javascript#answer-7220510 + function syntaxHighlight(json) { + json = json.replace(/&/g, '&').replace(//g, '>'); // basic html escaping + return json + .replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { + var cls = 'red'; + if (/^"/.test(match)) { + if (/:$/.test(match)) { + cls = 'blue'; + } else { + cls = 'green'; + } + } else if (/true|false/.test(match)) { + cls = 'Sienna'; + } else if (/null/.test(match)) { + cls = 'gray'; + } + return '' + match + ''; + }) + .replace(/\t/g,"  ") // to keep indentation in html + .replace(/\n/g,"
"); // to keep line break in html + }; + var color_JSON = function (o) + { + var val = syntaxHighlight(JSON.stringify(o)); + return ""+val+""; + }; + + instanceProto.getDebuggerValues = function (propsections) + { + var prop = [ + {"name": "OwnerID", "value": this.ownerID, "readonly":true}, + {"name": "Slot name", "value": this.exp_LastSlotName || "", "readonly":true} + ]; + + + if (this.exp_LastSlotName && this.load_headers && + this.load_headers.hasOwnProperty(this.exp_LastSlotName)) + { + var header = this.load_headers[this.exp_LastSlotName]; + for (var n in header) + { + prop.push({"name": "Header-" + n, + "value": color_JSON(header[n]), + "html": true, + "readonly":true}); + } + } + + if (this.load_body) + { + for (var n in this.load_body) + { + prop.push({"name": "Body-" + n, + "value": color_JSON(this.load_body[n]), + "html": true, + "readonly":true}); + } + } + + propsections.push({ + "title": this.type.name, + "properties": prop + }); + }; + + instanceProto.onDebugValueEdited = function (header, name, value) + { + }; + /**END-PREVIEWONLY**/ + ////////////////////////////////////// + // Conditions + function Cnds() {}; + pluginProto.cnds = new Cnds(); + + Cnds.prototype.OnSave = function () + { + return true; + }; + Cnds.prototype.OnSaveError = function () + { + return true; + }; + + Cnds.prototype.OnGetAllHeaders = function () + { + return true; + }; + Cnds.prototype.ForEachHeader = function (slot_name) + { + if (this.load_headers == null) + return false; + + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var k, o=this.exp_CurHeader; + + for(k in this.load_headers) + { + if (solModifierAfterCnds) + { + this.runtime.pushCopySol(current_event.solModifiers); + } + + this.exp_CurSlotName = k; + this.exp_CurHeader = this.load_headers[k]; + current_event.retrigger(); + + if (solModifierAfterCnds) + { + this.runtime.popSol(current_event.solModifiers); + } + } + + this.exp_CurSlotName = ""; + this.exp_CurHeader = o; + return false; + }; + + Cnds.prototype.OnGetBody = function () + { + return true; + }; + + Cnds.prototype.OnGetUnusedBody = function () + { + return true; + }; + + Cnds.prototype.AllSlotAreEmpty = function () + { + if (this.load_headers == null) + return true; + + return is_empty(this.load_headers); + }; + + Cnds.prototype.IsOccupied = function (slot_name) + { + if (this.load_headers == null) + return false; + + return this.load_headers.hasOwnProperty(slot_name); + }; + + Cnds.prototype.ForEachKeyInHeader = function (slot_name) + { + if (!this.load_headers || !this.load_headers[slot_name]) + return false; + + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + var k, header = this.load_headers[slot_name]; + for(k in header) + { + if (solModifierAfterCnds) + { + this.runtime.pushCopySol(current_event.solModifiers); + } + + this.exp_CurKey = k; + this.exp_CurValue = header[this.exp_CurKey]; + current_event.retrigger(); + + if (solModifierAfterCnds) + { + this.runtime.popSol(current_event.solModifiers); + } + } + + return false; + }; + + Cnds.prototype.ForEachKeyInBody = function () + { + if (!this.load_body) + return false; + + var current_frame = this.runtime.getCurrentEventStack(); + var current_event = current_frame.current_event; + var solModifierAfterCnds = current_frame.isModifierAfterCnds(); + + for(var k in this.load_body) + { + if (solModifierAfterCnds) + { + this.runtime.pushCopySol(current_event.solModifiers); + } + + this.exp_CurKey = k; + this.exp_CurValue = this.load_body[this.exp_CurKey]; + current_event.retrigger(); + + if (solModifierAfterCnds) + { + this.runtime.popSol(current_event.solModifiers); + } + } + + return false; + }; + + Cnds.prototype.BodyIsInvalid = function () + { + return (this.load_body == null); + }; + + Cnds.prototype.OnClean = function () + { + return true; + }; + + Cnds.prototype.OnCleanError = function () + { + return true; + }; + + Cnds.prototype.OnGetAllHeadersError = function () + { + return true; + }; + + Cnds.prototype.OnGetBodyError = function () + { + return true; + }; + + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetOwner = function (id) + { + this.ownerID = id; + this.exp_LastSlotName = null; + this.load_body = null; + this.load_headers = null; + }; + + var re_ALLDOT = new RegExp(/\./, 'g'); + Acts.prototype.SetValue = function (k, v, is_body) + { + var table = (is_body==1)? this.save_body:this.save_header; + k = k.replace(re_ALLDOT, "/"); + table[k] = v; + }; + + Acts.prototype.Save = function (slot_name) + { + var self = this; + var on_complete = function(error) + { + self.error = error; + var trig = (!error)? cr.plugins_.Rex_Firebase_SaveSlot.prototype.cnds.OnSave: + cr.plugins_.Rex_Firebase_SaveSlot.prototype.cnds.OnSaveError; + self.runtime.trigger(trig, self); + }; + + if (is_empty(this.save_header)) + this.save_header["is-used"] = true; + + var k; + for (k in this.save_header) + this.save_item[ get_path(slot_name, false, k) ] = this.save_header[k]; + + for (k in this.save_body) + this.save_item[ get_path(slot_name, true, k) ] = this.save_body[k]; + + var ref = this.get_ref(this.ownerID); + ref["update"](this.save_item, on_complete); + + this.updateCacheData(slot_name, this.save_header, this.save_body); + this.save_header = {}; + this.save_body = {}; + this.save_item = {}; + }; + + Acts.prototype.SetBooleanValue = function (k, b, is_body) + { + var table = (is_body==1)? this.save_body:this.save_header; + table[k] = (b==1); + }; + + Acts.prototype.SetJSON = function (k, v, is_body) + { + var table = (is_body==1)? this.save_body:this.save_header; + table[k] = JSON.parse(v); + }; + + Acts.prototype.RemoveKey = function (k, is_body) + { + var table = (is_body==1)? this.save_body:this.save_header; + table[k] = null; + }; + + Acts.prototype.SetBooleanValue = function (k, b, is_body) + { + var table = (is_body==1)? this.save_body:this.save_header; + table[k] = (b==1); + }; + + Acts.prototype.GetAllHeaders = function () + { + var ref = this.get_ref(this.ownerID)["child"]("headers"); + + var self = this; + var on_read = function (snapshot) + { + self.error = null; + self.load_headers = snapshot.val(); + self.runtime.trigger(cr.plugins_.Rex_Firebase_SaveSlot.prototype.cnds.OnGetAllHeaders, self); + }; + var on_read_failure = function(error) + { + self.error = error; + self.runtime.trigger(cr.plugins_.Rex_Firebase_SaveSlot.prototype.cnds.OnGetAllHeadersError, self); + }; + + ref["once"]("value", on_read, on_read_failure); + }; + + Acts.prototype.GetSlotBody = function (slot_name) + { + var ref = this.get_ref(this.ownerID)["child"]("bodies")["child"](slot_name); + + var self = this; + var on_read = function (snapshot) + { + self.exp_LastSlotName = slot_name; + self.load_body = snapshot.val(); + self.error = null; + var trig = (self.load_body!=null)? cr.plugins_.Rex_Firebase_SaveSlot.prototype.cnds.OnGetBody: + cr.plugins_.Rex_Firebase_SaveSlot.prototype.cnds.OnGetUnusedBody; + self.runtime.trigger(trig, self); + }; + var on_read_failure = function(error) + { + self.error = error; + self.exp_LastSlotName = slot_name; + self.load_body = null; + self.runtime.trigger(cr.plugins_.Rex_Firebase_SaveSlot.prototype.cnds.OnGetBodyError, self); + }; + + ref["once"]("value", on_read, on_read_failure); + }; + + Acts.prototype.CleanSlot = function (slot_name) + { + var self = this; + var on_complete = function(error) + { + self.error = error; + var trig = (!error)? cr.plugins_.Rex_Firebase_SaveSlot.prototype.cnds.OnClean: + cr.plugins_.Rex_Firebase_SaveSlot.prototype.cnds.OnCleanError; + self.runtime.trigger(trig, self); + }; + + var ref = this.get_ref(this.ownerID); + var save_item = {}; + slot_name = (slot_name)? ("/"+slot_name) : ""; + save_item["headers" + slot_name] = null; + save_item["bodies" + slot_name] = null; + ref["update"](save_item, on_complete); + }; + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.CurSlotName = function (ret) + { + ret.set_string(this.exp_CurSlotName); + }; + + Exps.prototype.CurHeaderValue = function (ret, key, default_value) + { + ret.set_any( window.FirebaseGetValueByKeyPath(this.exp_CurHeader, key, default_value) ); + }; + + Exps.prototype.BodyValue = function (ret, key, default_value) + { + ret.set_any( window.FirebaseGetValueByKeyPath(this.load_body, key, default_value) ); + }; + + Exps.prototype.HeadersToJSON = function (ret) + { + ret.set_string(JSON.stringify(this.load_headers || {})); + }; + + Exps.prototype.BodyToJSON = function (ret) + { + ret.set_string(JSON.stringify(this.load_body || {})); + }; + + Exps.prototype.HeaderValue = function (ret, slot_name, key, default_value) + { + var val = this.load_headers; + if (slot_name) + val = val[slot_name]; + + ret.set_any( window.FirebaseGetValueByKeyPath(val, key, default_value) ); + }; + + Exps.prototype.CurHeaderValue = function (ret, key, default_value) + { + ret.set_any( window.FirebaseGetValueByKeyPath(this.exp_CurHeader, key, default_value) ); + }; + + Exps.prototype.CurKey = function (ret) + { + ret.set_any(this.exp_CurKey); + }; + + Exps.prototype.CurValue = function (ret, subKey, default_value) + { + ret.set_any( window.FirebaseGetValueByKeyPath(this.exp_CurValue, subKey, default_value) ); + }; + + Exps.prototype.LastSlotName = function (ret) + { + ret.set_any( this.exp_LastSlotName || "" ); + }; + + Exps.prototype.LastErrorCode = function (ret) + { + var code; + if (this.error) + code = this.error["code"]; + ret.set_string(code || ""); + }; + + Exps.prototype.LastErrorMessage = function (ret) + { + var s; + if (this.error) + s = this.error["serverResponse"]; + ret.set_string(s || ""); + }; +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/actions.js new file mode 100755 index 0000000..3532f37 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/actions.js @@ -0,0 +1,140 @@ +"use strict"; +var re_ALLDOT = new RegExp(/\./, 'g'); +{ + C3.Plugins.Rex_Firebase_SaveSlot.Acts = + { + SetOwner(id) + { + this.ownerID = id; + this.exp_LastSlotName = null; + this.load_body = null; + this.load_headers = null; + }, + + + SetValue(k, v, is_body) + { + var table = (is_body==1)? this.save_body:this.save_header; + k = k.replace(re_ALLDOT, "/"); + table[k] = v; + }, + + Save(slot_name) + { + var self = this; + var on_complete = function(error) + { + self.error = error; + var trig = (!error)? C3.Plugins.Rex_Firebase_SaveSlot.Cnds.OnSave: + C3.Plugins.Rex_Firebase_SaveSlot.Cnds.OnSaveError; + self.Trigger(trig); + }; + + if (is_empty(this.save_header)) + this.save_header["is-used"] = true; + + var k; + for (k in this.save_header) + this.save_item[ get_path(slot_name, false, k) ] = this.save_header[k]; + + for (k in this.save_body) + this.save_item[ get_path(slot_name, true, k) ] = this.save_body[k]; + + var ref = this.get_ref(this.ownerID); + ref["update"](this.save_item, on_complete); + + this.updateCacheData(slot_name, this.save_header, this.save_body); + this.save_header = {}; + this.save_body = {}; + this.save_item = {}; + }, + + SetBooleanValue(k, b, is_body) + { + var table = (is_body==1)? this.save_body:this.save_header; + table[k] = (b==1); + }, + + SetJSON(k, v, is_body) + { + var table = (is_body==1)? this.save_body:this.save_header; + table[k] = JSON.parse(v); + }, + + RemoveKey(k, is_body) + { + var table = (is_body==1)? this.save_body:this.save_header; + table[k] = null; + }, + + SetBooleanValue(k, b, is_body) + { + var table = (is_body==1)? this.save_body:this.save_header; + table[k] = (b==1); + }, + + GetAllHeaders() + { + var ref = this.get_ref(this.ownerID)["child"]("headers"); + + var self = this; + var on_read = function(snapshot) + { + self.error = null; + self.load_headers = snapshot.val(); + self.Trigger(C3.Plugins.Rex_Firebase_SaveSlot.Cnds.OnGetAllHeaders, self); + }; + var on_read_failure = function(error) + { + self.error = error; + self.Trigger(C3.Plugins.Rex_Firebase_SaveSlot.Cnds.OnGetAllHeadersError, self); + }; + + ref["once"]("value", on_read, on_read_failure); + }, + + GetSlotBody(slot_name) + { + var ref = this.get_ref(this.ownerID)["child"]("bodies")["child"](slot_name); + + var self = this; + var on_read = function (snapshot) + { + self.exp_LastSlotName = slot_name; + self.load_body = snapshot.val(); + self.error = null; + var trig = (self.load_body!=null)? C3.Plugins.Rex_Firebase_SaveSlot.Cnds.OnGetBody: + C3.Plugins.Rex_Firebase_SaveSlot.Cnds.OnGetUnusedBody; + self.Trigger(trig, self); + }; + var on_read_failure = function(error) + { + self.error = error; + self.exp_LastSlotName = slot_name; + self.load_body = null; + self.Trigger(C3.Plugins.Rex_Firebase_SaveSlot.Cnds.OnGetBodyError, self); + }; + + ref["once"]("value", on_read, on_read_failure); + }, + + CleanSlot(slot_name) + { + var self = this; + var on_complete = function(error) + { + self.error = error; + var trig = (!error)? C3.Plugins.Rex_Firebase_SaveSlot.Cnds.OnClean: + C3.Plugins.Rex_Firebase_SaveSlot.Cnds.OnCleanError; + self.Trigger(trig, self); + }; + + var ref = this.get_ref(this.ownerID); + var save_item = {}; + slot_name = (slot_name)? ("/"+slot_name) : ""; + save_item["headers" + slot_name] = null; + save_item["bodies" + slot_name] = null; + ref["update"](save_item, on_complete); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/conditions.js new file mode 100755 index 0000000..cafbed3 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/conditions.js @@ -0,0 +1,176 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SaveSlot.Cnds = + { + OnSave() + { + return true; + }, + OnSaveError() + { + return true; + }, + + OnGetAllHeaders() + { + return true; + }, + ForEachHeader(slot_name) + { + if (this.load_headers == null) + return false; + var current_frame = this._runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = this._runtime.GetEventSheetManager().GetEventStack(); + var p = this._runtime.GetEventStack(); + var h = c.Push(current_event); + + var k, o=this.exp_CurHeader; + for(k in this.load_headers) + { + if (solModifierAfterCnds) + { + this._runtime.GetEventSheetManager().PushCopySol(solmod); + } + + this.exp_CurSlotName = k; + this.exp_CurHeader = this.load_headers[k]; + current_event.Retrigger(current_frame,h); + + if (solModifierAfterCnds) + { + this._runtime.GetEventSheetManager().PopSol(solmod); + } + } + p.Pop(); + + this.exp_CurSlotName = ""; + this.exp_CurHeader = o; + return false; + }, + + OnGetBody() + { + return true; + }, + + OnGetUnusedBody() + { + return true; + }, + + AllSlotAreEmpty() + { + if (this.load_headers == null) + return true; + + return is_empty(this.load_headers); + }, + + IsOccupied(slot_name) + { + if (this.load_headers == null) + return false; + + return this.load_headers.hasOwnProperty(slot_name); + }, + + ForEachKeyInHeader(slot_name) + { + if (!this.load_headers || !this.load_headers[slot_name]) + return false; + + var current_frame = this._runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = this._runtime.GetEventSheetManager().GetEventStack(); + var p = this._runtime.GetEventStack(); + var h = c.Push(current_event); + + var k, header = this.load_headers[slot_name]; + for(k in header) + { + if (solModifierAfterCnds) + { + this._runtime.GetEventSheetManager().PushCopySol(solmod); + } + + this.exp_CurKey = k; + this.exp_CurValue = header[this.exp_CurKey]; + current_event.Retrigger(current_frame,h); + + if (solModifierAfterCnds) + { + this._runtime.GetEventSheetManager().PopSol(solmod); + } + } + p.Pop(); + + return false; + }, + + ForEachKeyInBody() + { + if (!this.load_body) + return false; + + var current_frame = this._runtime.GetEventSheetManager().GetCurrentEventStackFrame(); + var current_event = current_frame.GetCurrentEvent(); + var solmod = current_event.GetSolModifiers(); + var solModifierAfterCnds = current_frame.IsSolModifierAfterCnds(); + var c = this._runtime.GetEventSheetManager().GetEventStack(); + var p = this._runtime.GetEventStack(); + var h = c.Push(current_event); + + for(var k in this.load_body) + { + if (solModifierAfterCnds) + { + this._runtime.GetEventSheetManager().PushCopySol(solmod); + } + + this.exp_CurKey = k; + this.exp_CurValue = this.load_body[this.exp_CurKey]; + current_event.Retrigger(current_frame,h); + + if (solModifierAfterCnds) + { + this._runtime.GetEventSheetManager().PopSol(solmod); + } + } + p.Pop(); + + return false; + }, + + BodyIsInvalid() + { + return (this.load_body == null); + }, + + OnClean() + { + return true; + }, + + OnCleanError() + { + return true; + }, + + OnGetAllHeadersError() + { + return true; + }, + + OnGetBodyError() + { + return true; + } + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/expressions.js new file mode 100755 index 0000000..d826f62 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/expressions.js @@ -0,0 +1,76 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SaveSlot.Exps = + { + CurSlotName() + { + return (this.exp_CurSlotName); + }, + + CurHeaderValue(key, default_value) + { + return( window.FirebaseGetValueByKeyPath(this.exp_CurHeader, key, default_value) ); + }, + + BodyValue(key, default_value) + { + return( window.FirebaseGetValueByKeyPath(this.load_body, key, default_value) ); + }, + + HeadersToJSON() + { + return (JSON.stringify(this.load_headers || {})); + }, + + BodyToJSON() + { + return (JSON.stringify(this.load_body || {})); + }, + + HeaderValue(slot_name, key, default_value) + { + var val = this.load_headers; + if (slot_name) + val = val[slot_name]; + + return( window.FirebaseGetValueByKeyPath(val, key, default_value) ); + }, + + CurHeaderValue(key, default_value) + { + return( window.FirebaseGetValueByKeyPath(this.exp_CurHeader, key, default_value) ); + }, + + CurKey() + { + return(this.exp_CurKey); + }, + + CurValue(subKey, default_value) + { + return( window.FirebaseGetValueByKeyPath(this.exp_CurValue, subKey, default_value) ); + }, + + LastSlotName() + { + return( this.exp_LastSlotName || "" ); + }, + + LastErrorCode() + { + var code; + if (this.error) + code = this.error["code"]; + return (code || ""); + }, + + LastErrorMessage() + { + var s; + if (this.error) + s = this.error["serverResponse"]; + return (s || ""); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/instance.js new file mode 100755 index 0000000..18aa470 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/instance.js @@ -0,0 +1,97 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SaveSlot.Instance = class Rex_Firebase_SaveSlotInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + this.ownerID = ""; + + this.error = null; + this.save_header = {}; + this.save_body = {}; + this.save_item = {}; + + this.load_headers = null; + this.load_body = null; + this.exp_LastSlotName = null; + + this.exp_CurSlotName = ""; + this.exp_CurHeader = {}; + this.exp_CurKey = ""; + this.exp_CurValue = 0; + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/" + properties[1] + "/"; + } + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + get_ref(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + } + + updateCacheData(slot_name, save_header, save_body) + { + if (this.load_headers == null) + this.load_headers = {}; + if (!this.load_headers.hasOwnProperty(slot_name)) + this.load_headers[slot_name] = {}; + + var load_header = this.load_headers[slot_name]; + for(var n in save_header) + { + n = setItemValue(n, save_header[n], load_header); + } + + if (slot_name === this.exp_LastSlotName) + { + if (this.load_body == null) + this.load_body = {}; + for (var n in save_body) + { + setItemValue(n, save_body[n], this.load_body); + } + } + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/plugin.js new file mode 100755 index 0000000..bd895c1 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/plugin.js @@ -0,0 +1,109 @@ +"use strict"; + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + var is_empty = function (o) + { + for (var k in o) + { + if (o[k] !== null) + return false; + } + return true; + }; + + + var get_path = function (slot_name, is_body, key) + { + key = key.replace(re_ALLDOT, "/"); + var p = (is_body)? "bodies":"headers"; + p += "/" + slot_name + "/" + key; + return p; + }; + + var setItemValue = function(keys, value, root) + { + if (typeof (keys) === "string") + keys = keys.split("."); + + var lastKey = keys.pop(); + var entry = getEntry(keys, root); + entry[lastKey] = value; + }; + + var getEntry = function(keys, root) + { + var entry = root; + if ((keys === "") || (keys.length === 0)) + { + //entry = root; + } + else + { + if (typeof (keys) === "string") + keys = keys.split("."); + + var i, cnt=keys.length, key; + for (i=0; i< cnt; i++) + { + key = keys[i]; + if ( (entry[key] == null) || (typeof(entry[key]) !== "object") ) + entry[key] = {}; + + entry = entry[key]; + } + } + + return entry; + }; + +{ + C3.Plugins.Rex_Firebase_SaveSlot = class Rex_Firebase_SaveSlotPlugin extends C3.SDKPluginBase + { + constructor(opts) + { + super(opts); + } + + Release() + { + super.Release(); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/type.js new file mode 100755 index 0000000..42ec167 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/c3runtime/type.js @@ -0,0 +1,20 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SaveSlot.Type = class Rex_Firebase_SaveSlotType extends C3.SDKTypeBase + { + constructor(objectClass) + { + super(objectClass); + } + + Release() + { + super.Release(); + } + + OnCreate() + { + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/icon.png new file mode 100755 index 0000000..1e44c43 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/instance.js new file mode 100755 index 0000000..f9158be --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_SaveSlot; + + PLUGIN_CLASS.Instance = class Rex_Firebase_SaveSlotInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/lang/en-US.json new file mode 100755 index 0000000..ce784be --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/lang/en-US.json @@ -0,0 +1,262 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Save slot.", + "text": { + "plugins": { + "rex_firebase_saveslot": { + "name": "Save slot", + "description": "Private save slots.", + "help-url": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_saveslot.html", + "properties": { + "domain": { + "name": "Domain", + "desc": "The root location of the Firebase data." + }, + "sub-domain": { + "name": "Sub domain", + "desc": "Sub domain of this function." + } + }, + "aceCategories": { + "0._setup": "0. Setup", + "prepare": "Prepare", + "save": "Save", + "load": "Load", + "clean": "Clean", + "load_-_header": "Load - header", + "load_-_body": "Load - body", + "header": "Header", + "header_-_for_each": "Header - for each", + "body_-_for_each": "Body - for each", + "body": "Body", + "for_each_header": "For each header", + "json": "JSON", + "headers": "Headers", + "for_each_key": "For each key", + "error": "Error" + }, + "conditions": { + "onsave1": { + "list-name": "On save", + "display-text": "On save", + "description": "Triggered when save complete." + }, + "onsaveerror2": { + "list-name": "On save error", + "display-text": "On save error", + "description": "Triggered when save error." + }, + "ongetallheaders11": { + "list-name": "On get headers", + "display-text": "On get all headers", + "description": "Triggered when get all slot headers from server." + }, + "foreachheader12": { + "list-name": "For each header", + "display-text": "For each header", + "description": "Repeat the event for each slot header." + }, + "ongetbody13": { + "list-name": "On get body", + "display-text": "On get body", + "description": "Triggered when get slot body complete from server complete." + }, + "ongetunusedbody14": { + "list-name": "On get unused body", + "display-text": "On get unused body", + "description": "Triggered when get unused body." + }, + "allslotareempty15": { + "list-name": "All slots are empty", + "display-text": "All slots are empty", + "description": "All slots are unused. Call it after load headers from server." + }, + "ısoccupied16": { + "list-name": "Slot is occupied", + "display-text": "Slot [i]{0}[/i] is occupied", + "description": "Slot is occupied. Call it after load headers from server.", + "params": { + "name0": { "name":"Name", "desc":"The slot name."} + } + }, + "foreachkeyınheader17": { + "list-name": "For each key", + "display-text": "For each key in header [i]{0}[/i]", + "description": "Repeat the event for each key in a header.", + "params": { + "name0": { "name":"Name", "desc":"The slot name."} + } + }, + "foreachkeyınbody18": { + "list-name": "For each key", + "display-text": "For each key in body", + "description": "Repeat the event for each key in body." + }, + "bodyısınvalid19": { + "list-name": "Invalid body", + "display-text": "Body is invalid", + "description": "Current loaded body is invalid." + }, + "onclean21": { + "list-name": "On clean", + "display-text": "On clean", + "description": "Triggered when clean slots complete on server complete." + }, + "oncleanerror22": { + "list-name": "On clean error", + "display-text": "On clean error", + "description": "Triggered when clean slots error on server error." + }, + "ongetallheaderserror31": { + "list-name": "On get headers error", + "display-text": "On get all headers error", + "description": "Triggered when get all slot headers error." + }, + "ongetbodyerror32": { + "list-name": "On get body error", + "display-text": "On get body error", + "description": "Triggered when get slot body error." + } + }, + "actions": { + "setowner1": { + "list-name": "Set owner", + "display-text": "Set user ID of slot owner to [i]{0}[/i]", + "description": "Set user ID of slot owner.", + "params": { + "user_ıd0": { "name":"User ID", "desc":"User ID from authentication."} + } + }, + "setvalue2": { + "list-name": "Set value", + "display-text": "Prepare- Set key [i]{0}[/i] to [i]{1}[/i] in slot [i]{2}[/i]", + "description": "Sets value into slot.", + "params": { + "key0": { "name":"Key", "desc":"The name of the key."}, + "value1": { "name":"Value", "desc":"The value to set"}, + "slot4": { "name":"Slot", "desc":"Header or body.", "items":{"header":"Header","body":"Body"}} + } + }, + "save3": { + "list-name": "Save", + "display-text": "Save- Save slot with name [i]{0}[/i]", + "description": "Save slot into server.", + "params": { + "name0": { "name":"Name", "desc":"The slot name."} + } + }, + "setbooleanvalue4": { + "list-name": "Set boolean value", + "display-text": "Prepare- Set key [i]{0}[/i] to [i]{1}[/i] in slot [i]{2}[/i]", + "description": "Sets boolean value into slot.", + "params": { + "key0": { "name":"Key", "desc":"The name of the key."}, + "boolean3": { "name":"Boolean", "desc":"Boolean value.", "items":{"false":"False","true":"True"}}, + "slot6": { "name":"Slot", "desc":"Header or body.", "items":{"header":"Header","body":"Body"}} + } + }, + "setcurrentservertimestamp5": { + "list-name": "Set to current server timestamp", + "display-text": "Prepare- Set key [i]{0}[/i] to current server timestamp in slot [i][/i] {1}", + "description": "Sets current server timestamp into slot.", + "params": { + "key0": { "name":"Key", "desc":"The name of the key."}, + "slot3": { "name":"Slot", "desc":"Header or body.", "items":{"header":"Header","body":"Body"}} + } + }, + "removekey6": { + "list-name": "Remove key", + "display-text": "Prepare- Remove key [i]{0}[/i] in slot [i][/i] {1}", + "description": "Remove from slot.", + "params": { + "key0": { "name":"Key", "desc":"The name of the key."}, + "slot3": { "name":"Slot", "desc":"Header or body.", "items":{"header":"Header","body":"Body"}} + } + }, + "setjson7": { + "list-name": "Set JSON", + "display-text": "Prepare- Set key [i]{0}[/i] to [i]{1}[/i] in slot [i]{2}[/i]", + "description": "Sets JSON into slot.", + "params": { + "key0": { "name":"Key", "desc":"The name of the key."}, + "json1": { "name":"JSON", "desc":"The JSON to set"}, + "slot4": { "name":"Slot", "desc":"Header or body.", "items":{"header":"Header","body":"Body"}} + } + }, + "getallheaders11": { + "list-name": "Get all headers", + "display-text": "Get all slot headers", + "description": "Get all slot headers from server." + }, + "getslotbody12": { + "list-name": "Get body", + "display-text": "Get slot body with name [i]{0}[/i]", + "description": "Get slot body from server.", + "params": { + "name0": { "name":"Name", "desc":"The slot name."} + } + }, + "cleanslot21": { + "list-name": "Clean all slots", + "display-text": "Clean all slots on server", + "description": "Clean all slots on server." + }, + "cleanslot22": { + "list-name": "Clean slot", + "display-text": "Clean slot with name [i]{0}[/i]", + "description": "Clean slot on server.", + "params": { + "name0": { "name":"Name", "desc":"The slot name."} + } + } + }, + "expressions": { + "curslotname1": { + "description": "Get current slot name in a For Each loop.", + "translated-name": "CurSlotName" + }, + "curheadervalue2": { + "description": "Get current header value by key in a For Each loop. Add default value at 2nd parameter if read data is null.", + "translated-name": "CurHeaderValue" + }, + "bodyvalue3": { + "description": "Get body value by key. Add key at 1st parameter, add default value at 2nd parameter if read data is null", + "translated-name": "BodyValue" + }, + "headerstojson4": { + "description": "Get all headers in JSON string.", + "translated-name": "HeadersToJSON" + }, + "bodytojson5": { + "description": "Get all body values in JSON string.", + "translated-name": "BodyToJSON" + }, + "headervalue6": { + "description": "Get header value by slot name and key. Add default value at 3rd parameter if read data is null.", + "translated-name": "HeaderValue" + }, + "curkey7": { + "description": "Get current key in a For Each loop.", + "translated-name": "CurKey" + }, + "curvalue8": { + "description": "Get current value in a For Each loop.", + "translated-name": "CurValue" + }, + "lastslotname9": { + "description": "Get last loaded slot name.", + "translated-name": "LastSlotName" + }, + "lasterrorcode21": { + "description": "Error code.", + "translated-name": "LastErrorCode" + }, + "lasterrormessage22": { + "description": "Error message (error.serverResponse) .", + "translated-name": "LastErrorMessage" + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/plugin.js new file mode 100755 index 0000000..3f6fc55 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/plugin.js @@ -0,0 +1,42 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase_SaveSlot"; + const PLUGIN_VERSION = "0.1.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_SaveSlot = class Rex_Firebase_SaveSlot extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "domain", ""), + new SDK.PluginProperty("text", "sub-domain", "SaveSlot") + ]); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/type.js new file mode 100755 index 0000000..8467058 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_savedata/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_SaveSlot; + + PLUGIN_CLASS.Type = class Rex_Firebase_SaveSlotType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/dist/rex_firebase_simplemessage.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/dist/rex_firebase_simplemessage.c3addon new file mode 100644 index 0000000..8dc9f82 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/dist/rex_firebase_simplemessage.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/aces.json new file mode 100755 index 0000000..0424b49 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/aces.json @@ -0,0 +1,119 @@ +{ + "domain": { + "conditions": [ + ], + "actions": [ + { + "c2id": 0, + "id": "setdomainref0", + "scriptName": "SetDomainRef", + "highlight": false, + "params": [ + {"id":"domain0", "type":"string", "initialValue":"\"\""}, + {"id":"sub_domain1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "user_info": { + "conditions": [ + ], + "actions": [ + { + "c2id": 1, + "id": "setuserınfo1", + "scriptName": "SetUserInfo", + "highlight": false, + "params": [ + {"id":"sender_ıd0", "type":"string", "initialValue":"\"\""}, + {"id":"sender_name1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "update": { + "conditions": [ + ], + "actions": [ + { + "c2id": 11, + "id": "startupdate11", + "scriptName": "StartUpdate", + "highlight": false, + "params": [ + {"id":"receiver_ıd0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 12, + "id": "stopupdate12", + "scriptName": "StopUpdate", + "highlight": false + } + ], + "expressions": [ + ] + }, + "message": { + "conditions": [ + { + "c2id": 1, + "id": "onreceivedmessage1", + "scriptName": "OnReceivedMessage", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 21, + "id": "sendmessage21", + "scriptName": "SendMessage", + "highlight": false, + "params": [ + {"id":"send_to_ıd0", "type":"string", "initialValue":"\"\""}, + {"id":"message1", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 22, + "id": "cleanmessagebox22", + "scriptName": "CleanMessageBox", + "highlight": false, + "params": [ + {"id":"send_to_ıd0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + { + "c2id": 1, + "id": "lastsenderıd1", + "expressionName": "LastSenderID", + "scriptName": "LastSenderID", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 2, + "id": "lastsendername2", + "expressionName": "LastSenderName", + "scriptName": "LastSenderName", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 3, + "id": "lastmessage3", + "expressionName": "LastMessage", + "scriptName": "LastMessage", + "highlight": false, + "returnType": "string" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/addon.json new file mode 100755 index 0000000..d7cdde6 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/addon.json @@ -0,0 +1,26 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Simple message", + "id": "Rex_Firebase_SimpleMessage", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "http://c2rexplugins.weebly.com/rex_firebase_simplemessage.html", + "documentation": "http://c2rexplugins.weebly.com/rex_firebase_simplemessage.html", + "description": "Send message to ID.", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c2runtime/runtime.js new file mode 100755 index 0000000..f2691b5 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c2runtime/runtime.js @@ -0,0 +1,490 @@ +/* + + message - message + senderID - ID of sender, assume that each senders has an unique ID + senderName - name of sender + stamp - toggle between true and false + +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_SimpleMessage = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_SimpleMessage.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + var OFFLMSG_DISCARD = 0; + var OFFLMSG_PEND = 1; + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + + this.userID = ""; + this.userName = ""; + + // check outPort changing + this.lastReceiverID = null; + + var message_type = this.properties[2]; + this.offline_mode = this.properties[3]; + + if (!this.recycled) + { + var messageKlass = (this.offline_mode == OFFLMSG_DISCARD)? + window.FirebaseSimpleMessageKlass: window.FirebaseStackMessageKlass; + this.inBox = this.create_inBox(messageKlass, message_type); + this.outPort = new messageKlass(message_type); + } + this.exp_LastMessage = null; + }; + + instanceProto.onDestroy = function () + { + this.inBox.StopUpdate(); + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + // 2.x , 3.x + + + instanceProto.create_inBox = function (messageKlass, message_type) + { + var self = this; + var on_received = function(d) + { + self.exp_LastMessage = d; + var trig = cr.plugins_.Rex_Firebase_SimpleMessage.prototype.cnds.OnReceivedMessage; + self.runtime.trigger(trig, self); + }; + + var simple_message = new messageKlass(message_type); + simple_message.onReceived = on_received; + + return simple_message; + }; + + instanceProto.send_message = function (receiverID, message) + { + if ((receiverID == null) || (receiverID == "")) + return; + + // re-build outPort + if (this.lastReceiverID != receiverID) + { + var ref = this.get_ref(receiverID); + this.outPort.SetRef(ref); + } + + if (message == null) + { + // clean message + this.outPort.Send(); + } + else + { + this.outPort.Send(message, this.userID, this.userName); + } + + }; + + ////////////////////////////////////// + // Conditions + function Cnds() {}; + pluginProto.cnds = new Cnds(); + + Cnds.prototype.OnReceivedMessage = function () + { + return true; + }; + + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetDomainRef = function (domain_ref, sub_domain_ref) + { + this.inBox.StopUpdate(); + + // clean previous outPort + if (this.offline_mode == OFFLMSG_DISCARD) + { + this.send_message(this.lastReceiverID, null); + } + this.lastReceiverID = null; // re-build outPort in next send_message + + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + }; + + Acts.prototype.SetUserInfo = function (userID, userName) + { + this.userID = userID; + this.userName = userName; + }; + Acts.prototype.StartUpdate = function (receiverID) + { + if (receiverID == "") + return; + + var ref = this.get_ref(receiverID); + this.inBox.StartUpdate(ref); + }; + + Acts.prototype.StopUpdate = function () + { + this.inBox.StopUpdate(); + }; + + Acts.prototype.SendMessage = function (receiverID, message) + { + if (receiverID == "") + return; + + this.send_message(receiverID, message); + this.lastReceiverID = receiverID; + }; + + Acts.prototype.CleanMessageBox = function (receiverID) + { + if (receiverID == "") + return; + + this.send_message(receiverID, null); + }; + + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.LastSenderID = function (ret) + { + var senderID = null; + if (this.exp_LastMessage != null) + senderID = this.exp_LastMessage["senderID"]; + if (senderID == null) + senderID = ""; + + ret.set_string(senderID); + }; + + Exps.prototype.LastSenderName = function (ret) + { + var senderName = null; + if (this.exp_LastMessage != null) + senderName = this.exp_LastMessage["senderName"]; + if (senderName == null) + senderName = ""; + + ret.set_string(senderName); + }; + + Exps.prototype.LastMessage = function (ret) + { + var message = null; + if (this.exp_LastMessage != null) + message = this.exp_LastMessage["message"]; + if (message == null) + message = ""; + + ret.set_string(message); + }; + +}()); + +(function () +{ + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + // 2.x , 3.x + + if (window.FirebaseStackMessageKlass != null) + return; + + var MESSAGE_STRING = 0; + var MESSAGE_JSON = 1; + var StackMessageKlass = function (messageType) + { + // export + this.onReceived = null + // export + + this.messageType = messageType; + + // internal + this.ref = null; + this.on_read = null; + }; + + var StackMessageKlassProto = StackMessageKlass.prototype; + + StackMessageKlassProto.SetRef = function (ref) + { + var is_reading = (this.on_read != null); + this.StopUpdate(); + this.ref = ref; + if (is_reading) + this.StartUpdate(); + }; + + StackMessageKlassProto.Send = function (message, senderID, senderName) + { + if (this.ref == null) + return; + + + // clean message + if ((message == null) && (senderID == null) && (senderName == null)) + { + // do nothing + return; + } + + if (this.messageType == MESSAGE_JSON) + message = JSON.parse(message); + + var d = { + "message": message, + "senderID": senderID, + "senderName": senderName, + }; + this.ref["push"](d); + }; + + StackMessageKlassProto.StartUpdate = function (ref) + { + this.StopUpdate(); + if (ref != null) + this.ref = ref; + + var self = this; + var on_update = function (snapshot) + { + var d = snapshot["val"](); + if (self.skip_first) + { + self.skip_first = false; + return; + } + if (d == null) + return; + + + if (self.messageType == MESSAGE_JSON) + d["message"] = JSON.stringify(d["message"]); + + if (self.onReceived) + self.onReceived(d); + + // remove this child + get_refPath(snapshot)["remove"](); + }; + + this.ref["limitToFirst"](1)["on"]("child_added", on_update); + this.on_read = on_update; + }; + + StackMessageKlassProto.StopUpdate = function () + { + if (this.on_read == null) + return; + + this.ref["off"]("child_added", this.on_read); + this.on_read = null; + }; + + window.FirebaseStackMessageKlass = StackMessageKlass; +}()); + +(function () +{ + if (window.FirebaseSimpleMessageKlass != null) + return; + + var MESSAGE_STRING = 0; + var MESSAGE_JSON = 1; + var SimpleMessageKlass = function (messageType) + { + // export + this.onReceived = null + // export + + this.messageType = messageType; + + // internal + this.skip_first = true; + this.stamp = false; + this.ref = null; + this.on_read = null; + }; + + var SimpleMessageKlassProto = SimpleMessageKlass.prototype; + + SimpleMessageKlassProto.SetRef = function (ref) + { + var is_reading = (this.on_read != null); + this.StopUpdate(); + this.ref = ref; + if (is_reading) + this.StartUpdate(); + }; + + SimpleMessageKlassProto.Send = function (message, senderID, senderName) + { + if (this.ref == null) + return; + + + // clean message + if ((message == null) && (senderID == null) && (senderName == null)) + { + this.ref["remove"](); + return; + } + + if (this.messageType == MESSAGE_JSON) + message = JSON.parse(message); + + var d = { + "message": message, + "senderID": senderID, + "senderName": senderName, + "stamp" : this.stamp, + }; + this.skip_first = false; + this.ref["set"](d); + this.stamp = !this.stamp; + }; + + SimpleMessageKlassProto.StartUpdate = function (ref) + { + this.StopUpdate(); + if (ref != null) + this.ref = ref; + + this.skip_first = true; // skip previous message + + var self = this; + var on_update = function (snapshot) + { + var d = snapshot["val"](); + if (self.skip_first) + { + self.skip_first = false; + return; + } + if (d == null) + return; + + + if (self.messageType == MESSAGE_JSON) + d["message"] = JSON.stringify(d["message"]); + + if (self.onReceived) + self.onReceived(d); + }; + + this.ref["on"]("value", on_update); + this.on_read = on_update; + this.ref["onDisconnect"]()["remove"](); + }; + + SimpleMessageKlassProto.StopUpdate = function () + { + if (this.on_read == null) + return; + + this.ref["off"]("value", this.on_read); + this.on_read = null; + + this.ref["remove"](); + this.ref["onDisconnect"]()["cancel"](); + }; + + window.FirebaseSimpleMessageKlass = SimpleMessageKlass; +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/actions.js new file mode 100755 index 0000000..a2ca258 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/actions.js @@ -0,0 +1,56 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SimpleMessage.Acts = + { + SetDomainRef(domain_ref, sub_domain_ref) + { + this.inBox.StopUpdate(); + + // clean previous outPort + if (this.offline_mode == OFFLMSG_DISCARD) + { + this.send_message(this.lastReceiverID, null); + } + this.lastReceiverID = null; // re-build outPort in next send_message + + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + }, + + SetUserInfo(userID, userName) + { + this.userID = userID; + this.userName = userName; + }, + StartUpdate(receiverID) + { + if (receiverID == "") + return; + + var ref = this.get_ref(receiverID); + this.inBox.StartUpdate(ref); + }, + + StopUpdate() + { + this.inBox.StopUpdate(); + }, + + SendMessage(receiverID, message) + { + if (receiverID == "") + return; + + this.send_message(receiverID, message); + this.lastReceiverID = receiverID; + }, + + CleanMessageBox(receiverID) + { + if (receiverID == "") + return; + + this.send_message(receiverID, null); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/conditions.js new file mode 100755 index 0000000..1aefb90 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/conditions.js @@ -0,0 +1,11 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SimpleMessage.Cnds = + { + OnReceivedMessage() + { + return true; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/expressions.js new file mode 100755 index 0000000..61b334f --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/expressions.js @@ -0,0 +1,40 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SimpleMessage.Exps = + { + + LastSenderID() + { + var senderID = null; + if (this.exp_LastMessage != null) + senderID = this.exp_LastMessage["senderID"]; + if (senderID == null) + senderID = ""; + + return (senderID); + }, + + LastSenderName() + { + var senderName = null; + if (this.exp_LastMessage != null) + senderName = this.exp_LastMessage["senderName"]; + if (senderName == null) + senderName = ""; + + return (senderName); + }, + + LastMessage() + { + var message = null; + if (this.exp_LastMessage != null) + message = this.exp_LastMessage["message"]; + if (message == null) + message = ""; + + return (message); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/instance.js new file mode 100755 index 0000000..5dce3e3 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/instance.js @@ -0,0 +1,113 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SimpleMessage.Instance = class Rex_Firebase_SimpleMessageInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + this.userID = ""; + this.userName = ""; + + // check outPort changing + this.lastReceiverID = null; + + + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/" + properties[1] + "/"; + var message_type = properties[2]; + this.offline_mode = properties[3]; + } + var messageKlass = (this.offline_mode == OFFLMSG_DISCARD)? window.FirebaseSimpleMessageKlass: window.FirebaseStackMessageKlass; + this.inBox = this.create_inBox(messageKlass, message_type); + this.outPort = new messageKlass(message_type); + + this.exp_LastMessage = null; + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + get_ref(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + } + + + create_inBox(messageKlass, message_type) + { + var self = this; + var on_received = function(d) + { + self.exp_LastMessage = d; + var trig = C3.Plugins.Rex_Firebase_SimpleMessage.Cnds.OnReceivedMessage; + self.Trigger(trig); + }; + + var simple_message = new messageKlass(message_type); + simple_message.onReceived = on_received; + + return simple_message; + } + + send_message(receiverID, message) + { + if ((receiverID == null) || (receiverID == "")) + return; + + // re-build outPort + if (this.lastReceiverID != receiverID) + { + var ref = this.get_ref(receiverID); + this.outPort.SetRef(ref); + } + + if (message == null) + { + // clean message + this.outPort.Send(); + } + else + { + this.outPort.Send(message, this.userID, this.userName); + } + + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/plugin.js new file mode 100755 index 0000000..f2842eb --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/plugin.js @@ -0,0 +1,256 @@ +"use strict"; +var OFFLMSG_DISCARD = 0; +var OFFLMSG_PEND = 1; + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + // 2.x , 3.x + +(function () +{ + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + // 2.x , 3.x + + if (window.FirebaseStackMessageKlass != null) + return; + + var MESSAGE_STRING = 0; + var MESSAGE_JSON = 1; + var StackMessageKlass = function (messageType) + { + // export + this.onReceived = null + // export + + this.messageType = messageType; + + // internal + this.ref = null; + this.on_read = null; + }; + + var StackMessageKlassProto = StackMessageKlass.prototype; + + StackMessageKlassProto.SetRef = function (ref) + { + var is_reading = (this.on_read != null); + this.StopUpdate(); + this.ref = ref; + if (is_reading) + this.StartUpdate(); + }; + + StackMessageKlassProto.Send = function (message, senderID, senderName) + { + if (this.ref == null) + return; + + + // clean message + if ((message == null) && (senderID == null) && (senderName == null)) + { + // do nothing + return; + } + + if (this.messageType == MESSAGE_JSON) + message = JSON.parse(message); + + var d = { + "message": message, + "senderID": senderID, + "senderName": senderName, + }; + this.ref["push"](d); + }; + + StackMessageKlassProto.StartUpdate = function (ref) + { + this.StopUpdate(); + if (ref != null) + this.ref = ref; + + var self = this; + var on_update = function (snapshot) + { + var d = snapshot["val"](); + if (self.skip_first) + { + self.skip_first = false; + return; + } + if (d == null) + return; + + + if (self.messageType == MESSAGE_JSON) + d["message"] = JSON.stringify(d["message"]); + + if (self.onReceived) + self.onReceived(d); + + // remove this child + get_refPath(snapshot)["remove"](); + }; + + this.ref["limitToFirst"](1)["on"]("child_added", on_update); + this.on_read = on_update; + }; + + StackMessageKlassProto.StopUpdate = function () + { + if (this.on_read == null) + return; + + this.ref["off"]("child_added", this.on_read); + this.on_read = null; + }; + + window.FirebaseStackMessageKlass = StackMessageKlass; +}()); + +(function () +{ + if (window.FirebaseSimpleMessageKlass != null) + return; + + var MESSAGE_STRING = 0; + var MESSAGE_JSON = 1; + var SimpleMessageKlass = function (messageType) + { + // export + this.onReceived = null + // export + + this.messageType = messageType; + + // internal + this.skip_first = true; + this.stamp = false; + this.ref = null; + this.on_read = null; + }; + + var SimpleMessageKlassProto = SimpleMessageKlass.prototype; + + SimpleMessageKlassProto.SetRef = function (ref) + { + var is_reading = (this.on_read != null); + this.StopUpdate(); + this.ref = ref; + if (is_reading) + this.StartUpdate(); + }; + + SimpleMessageKlassProto.Send = function (message, senderID, senderName) + { + if (this.ref == null) + return; + + + // clean message + if ((message == null) && (senderID == null) && (senderName == null)) + { + this.ref["remove"](); + return; + } + + if (this.messageType == MESSAGE_JSON) + message = JSON.parse(message); + + var d = { + "message": message, + "senderID": senderID, + "senderName": senderName, + "stamp" : this.stamp, + }; + this.skip_first = false; + this.ref["set"](d); + this.stamp = !this.stamp; + }; + + SimpleMessageKlassProto.StartUpdate = function (ref) + { + this.StopUpdate(); + if (ref != null) + this.ref = ref; + + this.skip_first = true; // skip previous message + + var self = this; + var on_update = function (snapshot) + { + var d = snapshot["val"](); + if (self.skip_first) + { + self.skip_first = false; + return; + } + if (d == null) + return; + + + if (self.messageType == MESSAGE_JSON) + d["message"] = JSON.stringify(d["message"]); + + if (self.onReceived) + self.onReceived(d); + }; + + this.ref["on"]("value", on_update); + this.on_read = on_update; + this.ref["onDisconnect"]()["remove"](); + }; + + SimpleMessageKlassProto.StopUpdate = function () + { + if (this.on_read == null) + return; + + this.ref["off"]("value", this.on_read); + this.on_read = null; + + this.ref["remove"](); + this.ref["onDisconnect"]()["cancel"](); + }; + + window.FirebaseSimpleMessageKlass = SimpleMessageKlass; +}()); +{ + C3.Plugins.Rex_Firebase_SimpleMessage = class Rex_Firebase_SimpleMessagePlugin extends C3.SDKPluginBase + { + constructor(opts) + { + super(opts); + } + + Release() + { + super.Release(); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/type.js new file mode 100755 index 0000000..060d00d --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/c3runtime/type.js @@ -0,0 +1,20 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SimpleMessage.Type = class Rex_Firebase_SimpleMessageType extends C3.SDKTypeBase + { + constructor(objectClass) + { + super(objectClass); + } + + Release() + { + super.Release(); + } + + OnCreate() + { + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/icon.png new file mode 100755 index 0000000..cde0e6d Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/instance.js new file mode 100755 index 0000000..b689665 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_SimpleMessage; + + PLUGIN_CLASS.Instance = class Rex_Firebase_SimpleMessageInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/lang/en-US.json new file mode 100755 index 0000000..52acd44 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/lang/en-US.json @@ -0,0 +1,116 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Simple message.", + "text": { + "plugins": { + "rex_firebase_simplemessage": { + "name": "Simple message", + "description": "Send message to ID.", + "help-url": "http://c2rexplugins.weebly.com/rex_firebase_simplemessage.html", + "properties": { + "domain": { + "name": "Domain", + "desc": "The root location of the Firebase data." + }, + "sub-domain": { + "name": "Sub domain", + "desc": "Sub domain for this function." + }, + "message-type": { + "name": "Message type", + "desc": "Sent message type, string or JSON object in string.", + "items": { + "string":"String", + "json string":"JSON string" + } + }, + "offline-message": { + "name": "Offline message", + "desc": "Discard or pend offline message. Pend mode is only used for single receiver.", + "items": { + "discard":"Discard", + "pend":"Pend" + } + } + }, + "aceCategories": { + "domain": "Domain", + "user_info": "User info", + "update": "Update", + "message": "Message" + }, + "conditions": { + "onreceivedmessage1": { + "list-name": "On receive", + "display-text": "On receive message", + "description": "Triggered when received message." + } + }, + "actions": { + "setdomainref0": { + "list-name": "Set domain", + "display-text": "Set domain to [i]{0}[/i], sub domain to [i]{1}[/i]", + "description": "Set domain ref.", + "params": { + "domain0": { "name":"Domain", "desc":"The root location of the Firebase data."}, + "sub_domain1": { "name":"Sub domain", "desc":"Sub domain for this function."} + } + }, + "setuserınfo1": { + "list-name": "Set user", + "display-text": "Set sender name to [i]{1}[/i], sender ID to [i]{0}[/i]", + "description": "Set user info.", + "params": { + "sender_ıd0": { "name":"Sender ID", "desc":"Sender ID."}, + "sender_name1": { "name":"Sender name", "desc":"Sender name."} + } + }, + "startupdate11": { + "list-name": "Start", + "display-text": "Start receiving on channel ID [i]{0}[/i]", + "description": "Start receiving.", + "params": { + "receiver_ıd0": { "name":"Receiver ID", "desc":"ID of receiver."} + } + }, + "stopupdate12": { + "list-name": "Stop", + "display-text": "Stop receiving", + "description": "Stop receiving." + }, + "sendmessage21": { + "list-name": "Send", + "display-text": "Send message: [i]{1}[/i] to ID: [i]{0}[/i]", + "description": "Send message.", + "params": { + "send_to_ıd0": { "name":"Send to ID", "desc":"Send to ID."}, + "message1": { "name":"Message", "desc":"Message. String or JSON string for object."} + } + }, + "cleanmessagebox22": { + "list-name": "Clean", + "display-text": "Clean message box of ID: [i]{0}[/i]", + "description": "Clean message box.", + "params": { + "send_to_ıd0": { "name":"Send to ID", "desc":"Send to ID."} + } + } + }, + "expressions": { + "lastsenderıd1": { + "description": "Get sender ID of last message.", + "translated-name": "LastSenderID" + }, + "lastsendername2": { + "description": "Get sender name of last message.", + "translated-name": "LastSenderName" + }, + "lastmessage3": { + "description": "Get last message.", + "translated-name": "LastMessage" + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/plugin.js new file mode 100755 index 0000000..65e66c7 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/plugin.js @@ -0,0 +1,44 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase_SimpleMessage"; + const PLUGIN_VERSION = "0.1.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_SimpleMessage = class Rex_Firebase_SimpleMessage extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "domain", ""), + new SDK.PluginProperty("text", "sub-domain", "private message"), + new SDK.PluginProperty("combo", "message-type", {initialValue:"string", items:["string","json string"]}), + new SDK.PluginProperty("combo", "offline-message", {initialValue:"discard", items:["discard","pend"]}) + ]); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/type.js new file mode 100755 index 0000000..30ea064 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_simplemessage/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_SimpleMessage; + + PLUGIN_CLASS.Type = class Rex_Firebase_SimpleMessageType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/dist/rex_firebase_singleLogin.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/dist/rex_firebase_singleLogin.c3addon new file mode 100644 index 0000000..b9d13bc Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/dist/rex_firebase_singleLogin.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/aces.json new file mode 100755 index 0000000..701dfee --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/aces.json @@ -0,0 +1,144 @@ +{ + "domain": { + "conditions": [ + ], + "actions": [ + { + "c2id": 0, + "id": "setdomainref0", + "scriptName": "SetDomainRef", + "highlight": false, + "params": [ + {"id":"domain0", "type":"string", "initialValue":"\"\""}, + {"id":"sub_domain1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "login": { + "conditions": [ + { + "c2id": 1, + "id": "onloginsuccess1", + "scriptName": "OnLoginSuccess", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 2, + "id": "onloginerror2", + "scriptName": "OnLoginError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 1, + "id": "login1", + "scriptName": "Login", + "highlight": false, + "params": [ + {"id":"userıd0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "general": { + "conditions": [ + ], + "actions": [ + { + "c2id": 2, + "id": "loggingout2", + "scriptName": "LoggingOut", + "highlight": false + } + ], + "expressions": [ + ] + }, + "kick": { + "conditions": [ + ], + "actions": [ + { + "c2id": 21, + "id": "kickbyındex21", + "scriptName": "KickByIndex", + "highlight": false, + "params": [ + {"id":"ındex0", "type":"number", "initialValue":"0"} + ] + } + ], + "expressions": [ + ] + }, + "multiple_login": { + "conditions": [ + { + "c2id": 3, + "id": "onkicked3", + "scriptName": "OnKicked", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 4, + "id": "onloginlistchanged4", + "scriptName": "OnLoginListChanged", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 1, + "id": "logincount1", + "expressionName": "LoginCount", + "scriptName": "LoginCount", + "highlight": false, + "returnType": "number" + } + ] + }, + "multiple_login_-_for_each": { + "conditions": [ + { + "c2id": 11, + "id": "foreachlogin11", + "scriptName": "ForEachLogin", + "isLooping": "true", + "isInvertible": "false", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 11, + "id": "curloginındex11", + "expressionName": "CurLoginIndex", + "scriptName": "CurLoginIndex", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 12, + "id": "curlogintimestamp12", + "expressionName": "CurLoginTimestamp", + "scriptName": "CurLoginTimestamp", + "highlight": false, + "returnType": "number" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/addon.json new file mode 100755 index 0000000..3abaf54 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/addon.json @@ -0,0 +1,26 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Single login", + "id": "Rex_Firebase_SingleLogin", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_singlelogin.html", + "documentation": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_singlelogin.html", + "description": "Test if user account had been logined on one client only.", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "c2runtime/runtime.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c2runtime/runtime.js new file mode 100755 index 0000000..79168fc --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c2runtime/runtime.js @@ -0,0 +1,334 @@ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_SingleLogin = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_SingleLogin.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + this.myUserID = null; + this.myLoginID = null; + this.loginList = null; + this.kickMode = this.properties[2]; + this.tryLogin = false; + this.exp_CurLoginItem = null; + this.exp_CurLoginItemIdx = -1; + }; + + instanceProto.onDestroy = function () + { + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + + instanceProto.create_loginList = function() + { + var loginList = new window.FirebaseItemListKlass(); + + loginList.updateMode = loginList.AUTOALLUPDATE; + loginList.keyItemID = "loginID"; + + var self = this; + var snapshot2Item = function (snapshot) + { + var item = {}; + item[loginList.keyItemID] = get_key(snapshot); + item["timestamp"] = snapshot["val"](); + return item; + }; + loginList.snapshot2Item = snapshot2Item; + + var on_update = function() + { + var myIndex = loginList.GetItemIndexByID(self.myLoginID); + if (myIndex != null) + { + var loggingOut = false; + if (self.kickMode === 1) // Kick previous + { + var lastIndex = loginList.GetItems().length - 1; + loggingOut = (myIndex !== lastIndex); + } + else if (self.kickMode === 2) // Kick current + { + loggingOut = (myIndex !== 0); + } + + if (self.tryLogin) + { + self.tryLogin = false; + if (!loggingOut) + self.runtime.trigger(cr.plugins_.Rex_Firebase_SingleLogin.prototype.cnds.OnLoginSuccess, self); + } + + if (loggingOut) + { + self.loggingOut(); + self.runtime.trigger(cr.plugins_.Rex_Firebase_SingleLogin.prototype.cnds.OnKicked, self); + } + + self.runtime.trigger(cr.plugins_.Rex_Firebase_SingleLogin.prototype.cnds.OnLoginListChanged, self); + } + else // kicked from other machine + { + self.tryLogin = false; + self.loggingOut(); + self.runtime.trigger(cr.plugins_.Rex_Firebase_SingleLogin.prototype.cnds.OnKicked, self); + self.runtime.trigger(cr.plugins_.Rex_Firebase_SingleLogin.prototype.cnds.OnLoginListChanged, self); + } + }; + loginList.onItemsFetch = on_update; + + var onGetIterItem = function(item, i) + { + self.exp_CurLoginItem = item; + self.exp_CurLoginItemIdx = i; + }; + loginList.onGetIterItem = onGetIterItem; + + return loginList; + }; + + instanceProto.login = function (userID) + { + var userRef = this.get_ref(userID); + var loginRef = userRef["push"](); + + var self = this; + var on_write = function (error) + { + if (error) + { + loginRef["onDisconnect"]()["cancel"](); + self.myUserID = null; + self.myLoginID = null; + self.runtime.trigger(cr.plugins_.Rex_Firebase_SingleLogin.prototype.cnds.OnLoginError, self); + } + else + { + self.tryLogin = true; + self.myUserID = userID; + self.myLoginID = get_key(loginRef); + if (self.loginList === null) + self.loginList = self.create_loginList(); + var query = userRef["orderByKey"](); + + setTimeout(function() + { + self.loginList.StartUpdate(query); + }, 0); + } + }; + + loginRef["onDisconnect"]()["remove"](); + var ts = serverTimeStamp(); + loginRef["set"](ts, on_write); + }; + + instanceProto.loggingOut = function () + { + if (this.myUserID === null) + return; + + this.loginList.StopUpdate(); + this.loginList.Clean(); + + var loginRef = this.get_ref(this.myUserID)["child"](this.myLoginID); + loginRef["remove"](); + loginRef["onDisconnect"]()["cancel"](); + }; + ////////////////////////////////////// + // Conditions + function Cnds() {}; + pluginProto.cnds = new Cnds(); + + Cnds.prototype.OnLoginSuccess = function () + { + return true; + }; + + Cnds.prototype.OnLoginError = function () + { + return true; + }; + + Cnds.prototype.OnKicked = function () + { + return true; + }; + + Cnds.prototype.OnLoginListChanged = function () + { + return true; + }; + + Cnds.prototype.ForEachLogin = function () + { + if (this.loginList === null) + return false; + + return this.loginList.ForEachItem(this.runtime); + }; + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetDomainRef = function (domain_ref, sub_domain_ref) + { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + }; + + Acts.prototype.Login = function (userID) + { + this.login(userID); + }; + + Acts.prototype.LoggingOut = function () + { + this.loggingOut(); + }; + + Acts.prototype.KickByIndex = function (index) + { + if (this.loginList === null) + return false; + + var item = this.loginList.GetItems()[index]; + if (!item) + return; + + var loginID = item[this.loginList.keyItemID]; + var loginRef = this.get_ref(this.myUserID)["child"](loginID); + loginRef["remove"](); + }; + + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.LoginCount = function (ret) + { + var cnt = (this.loginList === null)? 0: this.loginList.GetItems().length; + ret.set_int(cnt); + }; + + Exps.prototype.CurLoginIndex = function (ret) + { + ret.set_int(this.exp_CurLoginItemIdx); + }; + + Exps.prototype.CurLoginTimestamp = function (ret) + { + var ts; + if (this.exp_CurLoginItem != null) + ts = get_timestamp(this.exp_CurLoginItem["timestamp"]); + else + ts = 0; + + ret.set_int(ts); + }; + + +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/actions.js new file mode 100755 index 0000000..b2da1ee --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/actions.js @@ -0,0 +1,35 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SingleLogin.Acts = + { + SetDomainRef(domain_ref, sub_domain_ref) + { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + }, + + Login(userID) + { + this.login(userID); + }, + + LoggingOut() + { + this.loggingOut(); + }, + + KickByIndex(index) + { + if (this.loginList === null) + return false; + + var item = this.loginList.GetItems()[index]; + if (!item) + return; + + var loginID = item[this.loginList.keyItemID]; + var loginRef = this.get_ref(this.myUserID)["child"](loginID); + loginRef["remove"](); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/conditions.js new file mode 100755 index 0000000..cc9fd6d --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/conditions.js @@ -0,0 +1,34 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SingleLogin.Cnds = + { + OnLoginSuccess () + { + return true; + }, + + OnLoginError () + { + return true; + }, + + OnKicked () + { + return true; + }, + + OnLoginListChanged () + { + return true; + }, + + ForEachLogin () + { + if (this.loginList === null) + return false; + + return this.loginList.ForEachItem(this._runtime); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/expressions.js new file mode 100755 index 0000000..a828f3f --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/expressions.js @@ -0,0 +1,28 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SingleLogin.Exps = + { + LoginCount() + { + var cnt = (this.loginList === null)? 0: this.loginList.GetItems().length; + return (cnt); + }, + + CurLoginIndex() + { + return (this.exp_CurLoginItemIdx); + }, + + CurLoginTimestamp() + { + var ts; + if (this.exp_CurLoginItem != null) + ts = get_timestamp(this.exp_CurLoginItem["timestamp"]); + else + ts = 0; + + return (ts); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/instance.js new file mode 100755 index 0000000..abbe383 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/instance.js @@ -0,0 +1,183 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SingleLogin.Instance = class Rex_Firebase_SingleLoginInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + + this.myUserID = null; + this.myLoginID = null; + this.loginList = null; + + this.tryLogin = false; + this.exp_CurLoginItem = null; + this.exp_CurLoginItemIdx = -1; + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/" + properties[1] + "/"; + this.kickMode = properties[2]; + } + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + get_ref (k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + } + create_loginList () + { + var loginList = new window.FirebaseItemListKlass(); + + loginList.updateMode = loginList.AUTOALLUPDATE; + loginList.keyItemID = "loginID"; + + var self = this; + var snapshot2Item = function (snapshot) + { + var item = {}; + item[loginList.keyItemID] = get_key(snapshot); + item["timestamp"] = snapshot["val"](); + return item; + }; + loginList.snapshot2Item = snapshot2Item; + + var on_update = function() + { + var myIndex = loginList.GetItemIndexByID(self.myLoginID); + if (myIndex != null) + { + var loggingOut = false; + if (self.kickMode === 1) // Kick previous + { + var lastIndex = loginList.GetItems().length - 1; + loggingOut = (myIndex !== lastIndex); + } + else if (self.kickMode === 2) // Kick current + { + loggingOut = (myIndex !== 0); + } + + if (self.tryLogin) + { + self.tryLogin = false; + if (!loggingOut) + self.Trigger(C3.Plugins.Rex_Firebase_SingleLogin.Cnds.OnLoginSuccess); + } + + if (loggingOut) + { + self.loggingOut(); + self.Trigger(C3.Plugins.Rex_Firebase_SingleLogin.Cnds.OnKicked); + } + + self.Trigger(C3.Plugins.Rex_Firebase_SingleLogin.Cnds.OnLoginListChanged); + } + else // kicked from other machine + { + self.tryLogin = false; + self.loggingOut(); + self.Trigger(C3.Plugins.Rex_Firebase_SingleLogin.Cnds.OnKicked); + self.Trigger(C3.Plugins.Rex_Firebase_SingleLogin.Cnds.OnLoginListChanged); + } + }; + loginList.onItemsFetch = on_update; + + var onGetIterItem = function(item, i) + { + self.exp_CurLoginItem = item; + self.exp_CurLoginItemIdx = i; + }; + loginList.onGetIterItem = onGetIterItem; + + return loginList; + } + + login (userID) + { + var userRef = this.get_ref(userID); + var loginRef = userRef["push"](); + + var self = this; + var on_write = function (error) + { + if (error) + { + loginRef["onDisconnect"]()["cancel"](); + self.myUserID = null; + self.myLoginID = null; + self.Trigger(C3.Plugins.Rex_Firebase_SingleLogin.Cnds.OnLoginError); + } + else + { + self.tryLogin = true; + self.myUserID = userID; + self.myLoginID = get_key(loginRef); + if (self.loginList === null) + self.loginList = self.create_loginList(); + var query = userRef["orderByKey"](); + + setTimeout(function() + { + self.loginList.StartUpdate(query); + }, 0); + } + }; + + loginRef["onDisconnect"]()["remove"](); + var ts = serverTimeStamp(); + loginRef["set"](ts, on_write); + } + + loggingOut () + { + if (this.myUserID === null) + return; + + this.loginList.StopUpdate(); + this.loginList.Clean(); + + var loginRef = this.get_ref(this.myUserID)["child"](this.myLoginID); + loginRef["remove"](); + loginRef["onDisconnect"]()["cancel"](); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/plugin.js new file mode 100755 index 0000000..f1b8ab6 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/plugin.js @@ -0,0 +1,54 @@ +"use strict"; + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_refPath = function (obj) + { + return (!isFirebase3x())? obj["ref"]() : obj["ref"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; +{ + C3.Plugins.Rex_Firebase_SingleLogin = class Rex_Firebase_SingleLoginPlugin extends C3.SDKPluginBase + { + constructor(opts) + { + super(opts); + } + + Release() + { + super.Release(); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/type.js new file mode 100755 index 0000000..fedf8a7 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/c3runtime/type.js @@ -0,0 +1,20 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_SingleLogin.Type = class Rex_Firebase_SingleLoginType extends C3.SDKTypeBase + { + constructor(objectClass) + { + super(objectClass); + } + + Release() + { + super.Release(); + } + + OnCreate() + { + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/icon.png new file mode 100755 index 0000000..f9041dd Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/instance.js new file mode 100755 index 0000000..a83fd0c --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_SingleLogin; + + PLUGIN_CLASS.Instance = class Rex_Firebase_SingleLoginInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/lang/en-US.json new file mode 100755 index 0000000..0dd6f91 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/lang/en-US.json @@ -0,0 +1,113 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Single login.", + "text": { + "plugins": { + "rex_firebase_singlelogin": { + "name": "Single login", + "description": "Test if user account had been logined on one client only.", + "help-url": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_singlelogin.html", + "properties": { + "domain": { + "name": "Domain", + "desc": "The root location of the Firebase data." + }, + "sub-domain": { + "name": "Sub domain", + "desc": "Sub domain for this function." + }, + "kick-mode": { + "name": "Kick mode", + "desc": "Choose the kicking action while multiple login.", + "items": { + "do nothing":"Do nothing", + "kick previous":"Kick previous", + "kick current":"Kick current" + } + } + }, + "aceCategories": { + "domain": "Domain", + "login": "Login", + "general": "General", + "kick": "Kick", + "multiple_login": "Multiple login", + "multiple_login_-_for_each": "Multiple login - for each" + }, + "conditions": { + "onloginsuccess1": { + "list-name": "On success", + "display-text": "On login success", + "description": "Triggered when single login success." + }, + "onloginerror2": { + "list-name": "On error", + "display-text": "On login error", + "description": "Triggered when single login error." + }, + "onkicked3": { + "list-name": "On kicked", + "display-text": "On kicked", + "description": "Triggered when kicked by multiple login." + }, + "onloginlistchanged4": { + "list-name": "On login list changed", + "display-text": "On login list changed", + "description": "Triggered when login list changed." + }, + "foreachlogin11": { + "list-name": "For each login", + "display-text": "For each login", + "description": "Repeat the event for each login." + } + }, + "actions": { + "setdomainref0": { + "list-name": "Set domain", + "display-text": "Set domain to [i]{0}[/i], sub domain to [i]{1}[/i]", + "description": "Set domain ref.", + "params": { + "domain0": { "name":"Domain", "desc":"The root location of the Firebase data."}, + "sub_domain1": { "name":"Sub domain", "desc":"Sub domain for this function."} + } + }, + "login1": { + "list-name": "Login", + "display-text": "Login with user ID: [i]{0}[/i]", + "description": "Login.", + "params": { + "userıd0": { "name":"UserID", "desc":"User ID."} + } + }, + "loggingout2": { + "list-name": "Logging out", + "display-text": "Logging out", + "description": "Logging out." + }, + "kickbyındex21": { + "list-name": "Kick by index", + "display-text": "Kick login by index to [i]{0}[/i]", + "description": "Kick login by index.", + "params": { + "ındex0": { "name":"Index", "desc":"Index in login list."} + } + } + }, + "expressions": { + "logincount1": { + "description": "Get the current login cout.", + "translated-name": "LoginCount" + }, + "curloginındex11": { + "description": "Get the current login index in a For Each loop.", + "translated-name": "CurLoginIndex" + }, + "curlogintimestamp12": { + "description": "Get the current login timestamp in a For Each loop.", + "translated-name": "CurLoginTimestamp" + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/plugin.js new file mode 100755 index 0000000..5fdbbfb --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/plugin.js @@ -0,0 +1,43 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase_SingleLogin"; + const PLUGIN_VERSION = "0.1.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_SingleLogin = class Rex_Firebase_SingleLogin extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "domain", ""), + new SDK.PluginProperty("text", "sub-domain", "Single-login"), + new SDK.PluginProperty("combo", "kick-mode", {initialValue:"kick previous", items:["do nothing","kick previous","kick current"]}) + ]); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/type.js new file mode 100755 index 0000000..d4f911e --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_singleLogin/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_SingleLogin; + + PLUGIN_CLASS.Type = class Rex_Firebase_SingleLoginType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/dist/rex_firebase_storage.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/dist/rex_firebase_storage.c3addon new file mode 100644 index 0000000..dd88229 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/dist/rex_firebase_storage.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/firebase_cors_error.txt b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/firebase_cors_error.txt new file mode 100644 index 0000000..27de44f --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/firebase_cors_error.txt @@ -0,0 +1 @@ +https://stackoverflow.com/questions/37760695/firebase-storage-and-access-control-allow-origin/37765371#37765371 \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/aces.json new file mode 100755 index 0000000..8c1ba83 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/aces.json @@ -0,0 +1,374 @@ +{ + "domain": { + "conditions": [ + ], + "actions": [ + { + "c2id": 0, + "id": "setsubdomainref0", + "scriptName": "SetSubDomainRef", + "highlight": false, + "params": [ + {"id":"sub_domain0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "upload": { + "conditions": [ + { + "c2id": 1, + "id": "onuploadcompleted1", + "scriptName": "OnUploadCompleted", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 2, + "id": "onuploaderror2", + "scriptName": "OnUploadError", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 3, + "id": "onuploadcanceled3", + "scriptName": "OnUploadCanceled", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 4, + "id": "onpaused4", + "scriptName": "OnPaused", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 5, + "id": "onresmue5", + "scriptName": "OnResmue", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 6, + "id": "ısuploading6", + "scriptName": "IsUploading", + "highlight": false + }, + { + "c2id": 7, + "id": "onprogress7", + "scriptName": "OnProgress", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 8, + "id": "onstart8", + "scriptName": "OnStart", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 1, + "id": "uploadfromfilechooser1", + "scriptName": "UploadFromFileChooser", + "highlight": false, + "params": [ + {"id":"file_chooser0", "type":"object"}, + {"id":"dataref1", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 5, + "id": "uploadfromsprite5", + "scriptName": "UploadFromSprite", + "highlight": false, + "params": [ + {"id":"sprite0", "type":"object"}, + {"id":"dataref1", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 6, + "id": "uploaddataurı6", + "scriptName": "UploadDataURI", + "highlight": false, + "params": [ + {"id":"data_urı0", "type":"string", "initialValue":"\"\""}, + {"id":"dataref1", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 7, + "id": "uploadstring7", + "scriptName": "UploadString", + "highlight": false, + "params": [ + {"id":"content0", "type":"string", "initialValue":"\"\""}, + {"id":"dataref1", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 8, + "id": "uploadobjecturl8", + "scriptName": "UploadObjectURL", + "highlight": false, + "params": [ + {"id":"objecturl0", "type":"string", "initialValue":"\"\""}, + {"id":"content_type1", "type":"string", "initialValue":"\"\""}, + {"id":"dataref2", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + { + "c2id": 1, + "id": "lastdownloadurl1", + "expressionName": "LastDownloadURL", + "scriptName": "LastDownloadURL", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 2, + "id": "progress2", + "expressionName": "Progress", + "scriptName": "Progress", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 3, + "id": "transferredbytes3", + "expressionName": "TransferredBytes", + "scriptName": "TransferredBytes", + "highlight": false, + "returnType": "number" + }, + { + "c2id": 4, + "id": "totalbytes4", + "expressionName": "TotalBytes", + "scriptName": "TotalBytes", + "highlight": false, + "returnType": "number" + } + ] + }, + "upload_task": { + "conditions": [ + ], + "actions": [ + { + "c2id": 2, + "id": "canceluploading2", + "scriptName": "CancelUploading", + "highlight": false + }, + { + "c2id": 3, + "id": "pauseuploading3", + "scriptName": "PauseUploading", + "highlight": false + }, + { + "c2id": 4, + "id": "resumeuploading4", + "scriptName": "ResumeUploading", + "highlight": false + } + ], + "expressions": [ + ] + }, + "download": { + "conditions": [ + { + "c2id": 11, + "id": "ongetdownloadurl11", + "scriptName": "OnGetDownloadURL", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 12, + "id": "ongetdownloadurlerror12", + "scriptName": "OnGetDownloadURLError", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 13, + "id": "filedoesntexist13", + "scriptName": "FileDoesntExist", + "highlight": false + } + ], + "actions": [ + { + "c2id": 11, + "id": "getdownloadurl11", + "scriptName": "GetDownloadURL", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "delete": { + "conditions": [ + { + "c2id": 21, + "id": "ondeletecompleted21", + "scriptName": "OnDeleteCompleted", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 22, + "id": "ondeleteerror22", + "scriptName": "OnDeleteError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 21, + "id": "deleteaturl21", + "scriptName": "DeleteAtURL", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "metadata": { + "conditions": [ + { + "c2id": 71, + "id": "ongetmetadata71", + "scriptName": "OnGetMetadata", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 72, + "id": "ongetmetadataerror72", + "scriptName": "OnGetMetadataError", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 73, + "id": "onupdatemetadata73", + "scriptName": "OnUpdateMetadata", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 74, + "id": "onupdatemetadataerror74", + "scriptName": "OnUpdateMetadataError", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + { + "c2id": 71, + "id": "getmetadata71", + "scriptName": "GetMetadata", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 72, + "id": "updatemetadata72", + "scriptName": "UpdateMetadata", + "highlight": false, + "params": [ + {"id":"dataref0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 73, + "id": "metadatasetvalue73", + "scriptName": "MetadataSetValue", + "highlight": false, + "params": [ + {"id":"key0", "type":"string", "initialValue":"\"\""}, + {"id":"value1", "type":"any", "initialValue":"\"\""} + ] + }, + { + "c2id": 74, + "id": "metadataloadjson74", + "scriptName": "MetadataLoadJSON", + "highlight": false, + "params": [ + {"id":"json_string0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 75, + "id": "metadataremovekey75", + "scriptName": "MetadataRemoveKey", + "highlight": false, + "params": [ + {"id":"key0", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + { + "c2id": 71, + "id": "lastmetadata71", + "expressionName": "LastMetadata", + "scriptName": "LastMetadata", + "highlight": false, + "returnType": "any", + "isVariadicParameters": true + } + ] + }, + "error": { + "conditions": [ + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 21, + "id": "lasterrorcode21", + "expressionName": "LastErrorCode", + "scriptName": "LastErrorCode", + "highlight": false, + "returnType": "string" + }, + { + "c2id": 22, + "id": "lasterrormessage22", + "expressionName": "LastErrorMessage", + "scriptName": "LastErrorMessage", + "highlight": false, + "returnType": "string" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/addon.json new file mode 100755 index 0000000..2c28d98 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/addon.json @@ -0,0 +1,32 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Storage", + "id": "Rex_Firebase_Storage", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_storage.html", + "documentation": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_storage.html", + "description": "File storage in firebase serivice (v3.x only).", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "c2runtime/runtime.js", + "c3runtime/plugin.js", + "c3runtime/type.js", + "c3runtime/instance.js", + "c3runtime/conditions.js", + "c3runtime/actions.js", + "c3runtime/expressions.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c2runtime/runtime.js new file mode 100755 index 0000000..7cfadf8 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c2runtime/runtime.js @@ -0,0 +1,685 @@ +/* +- counter value +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_Storage = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_Storage.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/"; + + this.uploadTask = null; + this.metadata = {}; + + this.snapshot = null; + this.isUploading = false; + this.error = null; + + this.exp_LastDownloadURL = ""; + this.exp_LastMetadata = null + }; + + instanceProto.onDestroy = function () + { + }; + + instanceProto.get_storage_ref = function(k) + { + if (k == null) + k = ""; + var path = this.rootpath + k + "/"; + return window["Firebase"]["storage"]()["ref"](path); + }; + + instanceProto.upload = function(file, path, metadata) + { + if (this.uploadTask) + this.uploadTask["cancel"](); + + var self=this; + this.isUploading = null; + this.snapshot = null; + this.error = null; + this.exp_LastDownloadURL = ""; + + var onComplete = function () + { + self.isUploading = false; + self.snapshot = self.uploadTask["snapshot"]; + self.exp_LastDownloadURL = self.snapshot["downloadURL"]; + self.exp_LastMetadata = self.snapshot["metadata"]; + self.runtime.trigger(cr.plugins_.Rex_Firebase_Storage.prototype.cnds.OnUploadCompleted, self); + }; + var onError = function (error) + { + self.isUploading = false; + self.error = error; + switch (error["code"]) + { + case 'storage/unauthorized': + self.runtime.trigger(cr.plugins_.Rex_Firebase_Storage.prototype.cnds.OnUploadError, self); + break; + + case 'storage/canceled': + self.runtime.trigger(cr.plugins_.Rex_Firebase_Storage.prototype.cnds.OnUploadCanceled, self); + break; + + case 'storage/unknown': + self.runtime.trigger(cr.plugins_.Rex_Firebase_Storage.prototype.cnds.OnUploadError, self); + break; + + default: + self.runtime.trigger(cr.plugins_.Rex_Firebase_Storage.prototype.cnds.OnUploadError, self); + break; + } + }; + var onStateChanged = function (snapshot) + { + self.snapshot = self.uploadTask["snapshot"]; + var isRunning = (snapshot["state"] === 'running'); + if (isRunning && (self.isUploading === null)) + self.runtime.trigger(cr.plugins_.Rex_Firebase_Storage.prototype.cnds.OnStart, self); + else if (isRunning && !self.isUploading) + self.runtime.trigger(cr.plugins_.Rex_Firebase_Storage.prototype.cnds.OnResmue, self); + else if (!isRunning && self.isUploading) + self.runtime.trigger(cr.plugins_.Rex_Firebase_Storage.prototype.cnds.OnPaused, self); + + self.isUploading = isRunning; + + self.runtime.trigger(cr.plugins_.Rex_Firebase_Storage.prototype.cnds.OnProgress, self); + }; + + this.exp_LastMetadata = metadata; + this.uploadTask = this.get_storage_ref(path)["put"](file, metadata); + this.uploadTask["on"]('state_changed', onStateChanged, onError, onComplete); + }; + + + instanceProto.doRequest = function ( url_, callback ) + { + var oReq; + + // Windows Phone 8 can't AJAX local files using the standards-based API, but + // can if we use the old-school ActiveXObject. So use ActiveX on WP8 only. + if (this.runtime.isWindowsPhone8) + oReq = new ActiveXObject("Microsoft.XMLHTTP"); + else + oReq = new XMLHttpRequest(); + + oReq.open("GET", url_, true); + oReq.responseType = "arraybuffer"; + + oReq.onload = function (oEvent) + { + callback(oReq.response); + }; + + oReq.send(null); + }; + + var parseMetadata = function(metadata, defaultContentType) + { + if ((metadata.indexOf("{") !== -1) && (metadata.indexOf("}") !== -1)) + { + metadata = JSON.parse(metadata); + } + else if (metadata !== "") + { + metadata = {"contentType": metadata}; + } + else + metadata = {}; + + if (!metadata.hasOwnProperty("contentType") && defaultContentType) + metadata["contentType"] = defaultContentType; + + return metadata; + }; + + var setValue = function(keys, value, root) + { + if (typeof (keys) === "string") + keys = keys.split("."); + + var lastKey = keys.pop(); + var entry = getEntry(keys, root); + entry[lastKey] = value; + }; + + var getEntry = function(keys, root) + { + var entry = root; + if ((keys === "") || (keys.length === 0)) + { + //entry = root; + } + else + { + if (typeof (keys) === "string") + keys = keys.split("."); + + var i, cnt=keys.length, key; + for (i=0; i< cnt; i++) + { + key = keys[i]; + if ( (entry[key] == null) || (typeof(entry[key]) !== "object") ) + entry[key] = {}; + + entry = entry[key]; + } + } + + return entry; + }; + + var getItemValue = function (item, k, default_value) + { + var v; + if (item == null) + v = null; + else if ( (k == null) || (k === "") ) + v = item; + else if ((typeof(k) === "number") || (k.indexOf(".") == -1)) + v = item[k]; + else + { + var kList = k.split("."); + v = item; + var i,cnt=kList.length; + for(i=0; i { + b["toBlob"](onGetBlob); + }); + } + + // canvas + /* + else if (inst.canvas) + { + canvas = inst.canvas; + } + + + // canvas["toBlob"](onGetBlob); */ + }, + + + + UploadDataURI(dataURI, storagePath) + { + var self = this; + var blob = dataURI["startsWith"]('blob'); + if (blob == true){ + var xhr = new XMLHttpRequest(); + xhr.open("GET", dataURI); + xhr.responseType = "blob"; + function analyze_data(blob) + { + var myReader = new FileReader(); + myReader.readAsDataURL(blob) + + myReader.addEventListener("loadend", function(e) + { + var buffer = e.srcElement.result; + var base64_link = buffer; + var obj = dataURItoBlob(base64_link); + var blob = obj[0]; + var contentType = obj[1]; + + if (!self.metadata.hasOwnProperty("contentType")) + self.metadata["contentType"] = contentType; + + self.upload(blob, storagePath, self.metadata); + self.metadata = {}; + }); + } + + xhr.onload = function() + { + analyze_data(xhr.response); + } + xhr.send(); + } + }, + + UploadString(s, storagePath) + { + var type = "text/plain"; + var blob = new Blob([s], {"type": type}); + + if (!this.metadata.hasOwnProperty("contentType")) + this.metadata["contentType"] = type; + + this.upload(blob, storagePath, this.metadata); + this.metadata = {}; + }, + + UploadObjectURL(objectURL, contentType, storagePath) + { + var self=this; + var callback = function (blob) + { + if (contentType !== "") + self.metadata["contentType"] = contentType; + + self.upload(blob, storagePath, self.metadata); + self.metadata = {}; + } + this.doRequest(objectURL, callback); + }, + + GetDownloadURL(storagePath) + { + var self=this; + var ref = this.get_storage_ref(storagePath); + + this.error = null; + this.exp_LastDownloadURL = ""; + var onComplete = function (url) + { + self.exp_LastDownloadURL = url; + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnGetDownloadURL); + }; + var onError = function (error) + { + self.error = error; + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnGetDownloadURLError); + } + ref["getDownloadURL"]()["then"](onComplete)["catch"](onError); + }, + + DeleteAtURL(storagePath) + { + var self=this; + var ref = this.get_storage_ref(storagePath); + + this.error = null; + var onComplete = function () + { + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnDeleteCompleted); + }; + var onError = function (error) + { + self.error = error; + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnDeleteError); + } + ref["delete"]()["then"](onComplete)["catch"](onError); + }, + + GetMetadata(storagePath) + { + var self=this; + var ref = this.get_storage_ref(storagePath); + + this.error = null; + this.exp_LastMetadata = null; + var onComplete = function (metadata) + { + self.exp_LastMetadata = metadata; + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnGetMetadata); + }; + var onError = function (error) + { + self.error = error; + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnGetMetadataError); + } + ref["getMetadata"]()["then"](onComplete)["catch"](onError); + }, + + UpdateMetadata(storagePath) + { + var self=this; + var ref = this.get_storage_ref(storagePath); + + this.error = null; + this.exp_LastMetadata = null; + var onComplete = function (metadata) + { + self.exp_LastMetadata = metadata; + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnUpdateMetadata); + }; + var onError = function (error) + { + self.error = error; + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnUpdateMetadataError); + } + ref["updateMetadata"](this.metadata)["then"](onComplete)["catch"](onError); + this.metadata = {}; + }, + + MetadataSetValue(k, v) + { + setValue(k, v, this.metadata); + this.metadata + }, + + MetadataLoadJSON(s) + { + this.metadata = JSON.parse(s); + }, + + MetadataRemoveKey(k) + { + setValue(k, null, this.metadata); + this.metadata + } + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/conditions.js new file mode 100755 index 0000000..6e49039 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/conditions.js @@ -0,0 +1,91 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Storage.Cnds = + { + OnUploadCompleted() + { + return true; + }, + + OnUploadError() + { + return true; + }, + + OnUploadCanceled() + { + return true; + }, + + OnPaused() + { + return true; + }, + + OnResmue() + { + return true; + }, + + IsUploading() + { + return this.isUploading; + }, + + OnProgress() + { + return true; + }, + + OnStart() + { + return true; + }, + + OnGetDownloadURL() + { + return true; + }, + + OnGetDownloadURLError() + { + return true; + }, + + FileDoesntExist() + { + return (this.error && (this.error === 'storage/object_not_found')); + }, + + OnDeleteCompleted() + { + return true; + }, + + OnDeleteError() + { + return true; + }, + + OnGetMetadata() + { + return true; + }, + + OnGetMetadataError() + { + return true; + }, + + OnUpdateMetadata() + { + return true; + }, + + OnUpdateMetadataError() + { + return true; + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/expressions.js new file mode 100755 index 0000000..80fc305 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/expressions.js @@ -0,0 +1,59 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Storage.Exps = + { + LastDownloadURL() + { + return (this.exp_LastDownloadURL); + }, + + Progress() + { + var p; + if (this.snapshot) + p = this.snapshot["bytesTransferred"] / this.snapshot["totalBytes"]; + + return (p || 0); + }, + + TransferredBytes() + { + var b; + if (this.snapshot) + b = this.snapshot["bytesTransferred"]; + + return (b || 0); + }, + + TotalBytes() + { + var b; + if (this.snapshot) + b = this.snapshot["totalBytes"]; + + return (b || 0); + }, + + LastErrorCode() + { + var code; + if (this.error) + code = this.error["code"]; + return (code || ""); + }, + + LastErrorMessage() + { + var s; + if (this.error) + s = this.error["serverResponse"]; + return (s || ""); + }, + + LastMetadata(ret, k, default_value) + { + return(getItemValue(this.exp_LastMetadata, k, default_value) ); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/instance.js new file mode 100755 index 0000000..a175311 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/instance.js @@ -0,0 +1,137 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Storage.Instance = class Rex_Firebase_StorageInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + + + this.uploadTask = null; + this.metadata = {}; + this.snapshot = null; + this.isUploading = false; + this.error = null; + this.exp_LastDownloadURL = ""; + this.exp_LastMetadata = null + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/"; + } + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + get_storage_ref(k) + { + if (k == null) + k = ""; + var path = this.rootpath + k + "/"; + return window["Firebase"]["storage"]()["ref"](path); + } + + upload(file, path, metadata) + { + if (this.uploadTask) + this.uploadTask["cancel"](); + + var self=this; + this.isUploading = null; + this.snapshot = null; + this.error = null; + this.exp_LastDownloadURL = ""; + + var onComplete = function () + { + self.isUploading = false; + self.snapshot = self.uploadTask["snapshot"]; + self.exp_LastDownloadURL = self.snapshot["downloadURL"]; + self.exp_LastMetadata = self.snapshot["metadata"]; + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnUploadCompleted); + }; + var onError = function (error) + { + self.isUploading = false; + self.error = error; + switch (error["code"]) + { + case 'storage/unauthorized': + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnUploadError); + break; + + case 'storage/canceled': + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnUploadCanceled); + break; + + case 'storage/unknown': + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnUploadError); + break; + + default: + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnUploadError); + break; + } + }; + var onStateChanged = function (snapshot) + { + self.snapshot = self.uploadTask["snapshot"]; + var isRunning = (snapshot["state"] === 'running'); + if (isRunning && (self.isUploading === null)) + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnStart); + else if (isRunning && !self.isUploading) + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnResmue); + else if (!isRunning && self.isUploading) + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnPaused); + + self.isUploading = isRunning; + + self.Trigger(C3.Plugins.Rex_Firebase_Storage.Cnds.OnProgress); + }; + + this.exp_LastMetadata = metadata; + this.uploadTask = this.get_storage_ref(path)["put"](file, metadata); + this.uploadTask["on"]('state_changed', onStateChanged, onError, onComplete); + } + + + doRequest( url_, callback ) + { + var oReq; + + // Windows Phone 8 can't AJAX local files using the standards-based API, but + // can if we use the old-school ActiveXObject. So use ActiveX on WP8 only. + /*if (this.runtime.isWindowsPhone8) + oReq = new ActiveXObject("Microsoft.XMLHTTP"); + else*/ + oReq = new XMLHttpRequest(); + + oReq.open("GET", url_, true); + oReq.responseType = "arraybuffer"; + + oReq.onload = function (oEvent) + { + callback(oReq.response); + }; + + oReq.send(null); + } + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/plugin.js new file mode 100755 index 0000000..f7d0d8f --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_storage/source/c3runtime/plugin.js @@ -0,0 +1,157 @@ +"use strict"; + var parseMetadata = function(metadata, defaultContentType) + { + if ((metadata.indexOf("{") !== -1) && (metadata.indexOf("}") !== -1)) + { + metadata = JSON.parse(metadata); + } + else if (metadata !== "") + { + metadata = {"contentType": metadata}; + } + else + metadata = {}; + + if (!metadata.hasOwnProperty("contentType") && defaultContentType) + metadata["contentType"] = defaultContentType; + + return metadata; + }; + + var setValue = function(keys, value, root) + { + if (typeof (keys) === "string") + keys = keys.split("."); + + var lastKey = keys.pop(); + var entry = getEntry(keys, root); + entry[lastKey] = value; + }; + + var getEntry = function(keys, root) + { + var entry = root; + if ((keys === "") || (keys.length === 0)) + { + //entry = root; + } + else + { + if (typeof (keys) === "string") + keys = keys.split("."); + + var i, cnt=keys.length, key; + for (i=0; i< cnt; i++) + { + key = keys[i]; + if ( (entry[key] == null) || (typeof(entry[key]) !== "object") ) + entry[key] = {}; + + entry = entry[key]; + } + } + + return entry; + }; + + var getItemValue = function (item, k, default_value) + { + var v; + if (item == null) + v = null; + else if ( (k == null) || (k === "") ) + v = item; + else if ((typeof(k) === "number") || (k.indexOf(".") == -1)) + v = item[k]; + else + { + var kList = k.split("."); + v = item; + var i,cnt=kList.length; + for(i=0; i + +out\ + + +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_SyncQueue = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var input_text = ""; + var pluginProto = cr.plugins_.Rex_Firebase_SyncQueue.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + jsfile_load("firebase.js"); + }; + + var jsfile_load = function(file_name) + { + var scripts=document.getElementsByTagName("script"); + var exist=false; + for(var i=0;ib?e+="000":256>b?e+="00":4096>b&&(e+="0");return ra[a]=e+b.toString(16)}),'"')};function ta(a){return"undefined"!==typeof JSON&&m(JSON.parse)?JSON.parse(a):na(a)}function r(a){if("undefined"!==typeof JSON&&m(JSON.stringify))a=JSON.stringify(a);else{var b=[];pa(new oa,a,b);a=b.join("")}return a};function s(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function t(a,b){if(Object.prototype.hasOwnProperty.call(a,b))return a[b]}function ua(a,b){for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b(c,a[c])}function va(a){var b={};ua(a,function(a,d){b[a]=d});return b};function wa(a){this.uc=a;this.Ed="firebase:"}h=wa.prototype;h.set=function(a,b){null==b?this.uc.removeItem(this.Ed+a):this.uc.setItem(this.Ed+a,r(b))};h.get=function(a){a=this.uc.getItem(this.Ed+a);return null==a?null:ta(a)};h.remove=function(a){this.uc.removeItem(this.Ed+a)};h.lf=!1;h.toString=function(){return this.uc.toString()};function xa(){this.oc={}}xa.prototype.set=function(a,b){null==b?delete this.oc[a]:this.oc[a]=b};xa.prototype.get=function(a){return s(this.oc,a)?this.oc[a]:null};xa.prototype.remove=function(a){delete this.oc[a]};xa.prototype.lf=!0;function ya(a){try{if("undefined"!==typeof window&&"undefined"!==typeof window[a]){var b=window[a];b.setItem("firebase:sentinel","cache");b.removeItem("firebase:sentinel");return new wa(b)}}catch(c){}return new xa}var za=ya("localStorage"),v=ya("sessionStorage");function Aa(a,b,c,d,e){this.host=a.toLowerCase();this.domain=this.host.substr(this.host.indexOf(".")+1);this.Ab=b;this.tb=c;this.Dg=d;this.Dd=e||"";this.Ma=za.get("host:"+a)||this.host}function Ba(a,b){b!==a.Ma&&(a.Ma=b,"s-"===a.Ma.substr(0,2)&&za.set("host:"+a.host,a.Ma))}Aa.prototype.toString=function(){var a=(this.Ab?"https://":"http://")+this.host;this.Dd&&(a+="<"+this.Dd+">");return a};function Ca(){this.Sa=-1};function Da(){this.Sa=-1;this.Sa=64;this.R=[];this.be=[];this.Ef=[];this.Ad=[];this.Ad[0]=128;for(var a=1;ae;e++)d[e]=b.charCodeAt(c)<<24|b.charCodeAt(c+1)<<16|b.charCodeAt(c+2)<<8|b.charCodeAt(c+3),c+=4;else for(e=0;16>e;e++)d[e]=b[c]<<24|b[c+1]<<16|b[c+2]<<8|b[c+3],c+=4;for(e=16;80>e;e++){var f=d[e-3]^d[e-8]^d[e-14]^d[e-16];d[e]=(f<<1|f>>>31)&4294967295}b=a.R[0];c=a.R[1];for(var g=a.R[2],k=a.R[3],l=a.R[4],n,e=0;80>e;e++)40>e?20>e?(f=k^c&(g^k),n=1518500249):(f=c^g^k,n=1859775393):60>e?(f=c&g|k&(c|g),n=2400959708):(f=c^g^k,n=3395469782),f=(b<< +5|b>>>27)+f+l+n+d[e]&4294967295,l=k,k=g,g=(c<<30|c>>>2)&4294967295,c=b,b=f;a.R[0]=a.R[0]+b&4294967295;a.R[1]=a.R[1]+c&4294967295;a.R[2]=a.R[2]+g&4294967295;a.R[3]=a.R[3]+k&4294967295;a.R[4]=a.R[4]+l&4294967295} +Da.prototype.update=function(a,b){m(b)||(b=a.length);for(var c=b-this.Sa,d=0,e=this.be,f=this.Sb;dc?Math.max(0,a.length+c):c;if(p(a))return p(b)&&1==b.length?a.indexOf(b,c):-1;for(;cc?null:p(a)?a.charAt(c):a[c]}function Na(a,b,c){for(var d=a.length,e=p(a)?a.split(""):a,f=0;f=arguments.length?w.slice.call(a,b):w.slice.call(a,b,c)}function Qa(a,b){a.sort(b||Ra)}function Ra(a,b){return a>b?1:aparseFloat(a))?String(b):a})();var $a=null,ab=null,bb=null;function cb(a,b){if(!fa(a))throw Error("encodeByteArray takes an array as a parameter");db();for(var c=b?ab:$a,d=[],e=0;e>2,f=(f&3)<<4|k>>4,k=(k&15)<<2|n>>6,n=n&63;l||(n=64,g||(k=64));d.push(c[u],c[f],c[k],c[n])}return d.join("")} +function db(){if(!$a){$a={};ab={};bb={};for(var a=0;65>a;a++)$a[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a),ab[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.".charAt(a),bb[ab[a]]=a}};var eb=function(){var a=1;return function(){return a++}}();function y(a,b){if(!a)throw fb(b);}function fb(a){return Error("Firebase INTERNAL ASSERT FAILED:"+a)} +function gb(a){try{var b;if("undefined"!==typeof atob)b=atob(a);else{db();for(var c=bb,d=[],e=0;e>4);64!=k&&(d.push(g<<4&240|k>>2),64!=l&&d.push(k<<6&192|l))}if(8192>d.length)b=String.fromCharCode.apply(null,d);else{a="";for(c=0;ca.Sb?a.update(a.Ad,56-a.Sb):a.update(a.Ad,a.Sa-(a.Sb-56));for(var d=a.Sa-1;56<=d;d--)a.be[d]=c&255,c/=256;Ea(a,a.be);for(d=c=0;5>d;d++)for(var e=24;0<=e;e-=8)b[c]=a.R[d]>>e&255,++c;return cb(b)} +function kb(a){for(var b="",c=0;ca?c.push(a.substring(d,a.length)):c.push(a.substring(d,d+b));return c}function zb(a,b){if(ea(a))for(var c=0;ca,a=Math.abs(a),a>=Math.pow(2,-1022)?(d=Math.min(Math.floor(Math.log(a)/Math.LN2),1023),c=d+1023,d=Math.round(a*Math.pow(2,52-d)-Math.pow(2,52))):(c=0,d=Math.round(a/Math.pow(2,-1074))));e=[];for(a=52;a;a-=1)e.push(d%2?1:0),d=Math.floor(d/2);for(a=11;a;a-=1)e.push(c%2?1:0),c=Math.floor(c/2);e.push(b?1:0);e.reverse();b=e.join("");c="";for(a=0;64>a;a+=8)d=parseInt(b.substr(a,8),2).toString(16),1===d.length&& +(d="0"+d),c+=d;return c.toLowerCase()}var Bb=/^-?\d{1,10}$/;function vb(a){return Bb.test(a)&&(a=Number(a),-2147483648<=a&&2147483647>=a)?a:null}function Cb(a){try{a()}catch(b){setTimeout(function(){z("Exception was thrown by user callback.",b.stack||"");throw b;},Math.floor(0))}}function B(a,b){if(ha(a)){var c=Array.prototype.slice.call(arguments,1).slice();Cb(function(){a.apply(null,c)})}};function Db(a,b,c,d){this.le=b;this.Nd=c;this.Fd=d;this.jd=a}Db.prototype.Qb=function(){var a=this.Nd.cc();return"value"===this.jd?a.path:a.parent().path};Db.prototype.pe=function(){return this.jd};Db.prototype.Lb=function(){return this.le.Lb(this)};Db.prototype.toString=function(){return this.Qb().toString()+":"+this.jd+":"+r(this.Nd.bf())};function Eb(a,b,c){this.le=a;this.error=b;this.path=c}Eb.prototype.Qb=function(){return this.path};Eb.prototype.pe=function(){return"cancel"}; +Eb.prototype.Lb=function(){return this.le.Lb(this)};Eb.prototype.toString=function(){return this.path.toString()+":cancel"};function C(a,b,c,d){this.type=a;this.Ha=b;this.Ua=c;this.De=d;this.Fd=void 0}function Fb(a){return new C(Gb,a)}var Gb="value";function Hb(a,b,c){this.Hb=a;this.kb=b;this.mb=c||null}h=Hb.prototype;h.wf=function(a){return"value"===a};h.createEvent=function(a,b){var c=b.n.g;return new Db("value",this,new D(a.Ha,b.cc(),c))};h.Lb=function(a){var b=this.mb;if("cancel"===a.pe()){y(this.kb,"Raising a cancel event on a listener with no cancel callback");var c=this.kb;return function(){c.call(b,a.error)}}var d=this.Hb;return function(){d.call(b,a.Nd)}};h.Ye=function(a,b){return this.kb?new Eb(this,a,b):null}; +h.matches=function(a){return a instanceof Hb?a.Hb&&this.Hb?a.Hb===this.Hb&&a.mb===this.mb:!0:!1};h.hf=function(){return null!==this.Hb};function Ib(a,b,c){this.da=a;this.kb=b;this.mb=c}h=Ib.prototype;h.wf=function(a){a="children_added"===a?"child_added":a;return("children_removed"===a?"child_removed":a)in this.da};h.Ye=function(a,b){return this.kb?new Eb(this,a,b):null}; +h.createEvent=function(a,b){y(null!=a.Ua,"Child events should have a childName.");var c=b.cc().o(a.Ua);return new Db(a.type,this,new D(a.Ha,c,b.n.g),a.Fd)};h.Lb=function(a){var b=this.mb;if("cancel"===a.pe()){y(this.kb,"Raising a cancel event on a listener with no cancel callback");var c=this.kb;return function(){c.call(b,a.error)}}var d=this.da[a.jd];return function(){d.call(b,a.Nd,a.Fd)}}; +h.matches=function(a){if(a instanceof Ib){if(!this.da||!a.da)return!0;if(this.mb===a.mb){var b=Jb(a.da);if(b===Jb(this.da)){if(1===b){var b=Kb(a.da),c=Kb(this.da);return c===b&&(!a.da[b]||!this.da[c]||a.da[b]===this.da[c])}return Lb(this.da,function(b,c){return a.da[c]===b})}}}return!1};h.hf=function(){return null!==this.da};function jb(a){for(var b=[],c=0,d=0;d=e&&(e-=55296,d++,y(de?b[c++]=e:(2048>e?b[c++]=e>>6|192:(65536>e?b[c++]=e>>12|224:(b[c++]=e>>18|240,b[c++]=e>>12&63|128),b[c++]=e>>6&63|128),b[c++]=e&63|128)}return b};function F(a,b,c,d){var e;dc&&(e=0===c?"none":"no more than "+c);if(e)throw Error(a+" failed: Was called with "+d+(1===d?" argument.":" arguments.")+" Expects "+e+".");}function G(a,b,c){var d="";switch(b){case 1:d=c?"first":"First";break;case 2:d=c?"second":"Second";break;case 3:d=c?"third":"Third";break;case 4:d=c?"fourth":"Fourth";break;default:throw Error("errorPrefix called with argumentNumber > 4. Need to update it?");}return a=a+" failed: "+(d+" argument ")} +function H(a,b,c,d){if((!d||m(c))&&!ha(c))throw Error(G(a,b,d)+"must be a valid function.");}function Mb(a,b,c){if(m(c)&&(!ia(c)||null===c))throw Error(G(a,b,!0)+"must be a valid context object.");};var Nb=/[\[\].#$\/\u0000-\u001F\u007F]/,Ob=/[\[\].#$\u0000-\u001F\u007F]/;function Pb(a){return p(a)&&0!==a.length&&!Nb.test(a)}function Qb(a){return null===a||p(a)||ga(a)&&!sb(a)||ia(a)&&s(a,".sv")}function Rb(a,b,c){c&&!m(b)||Sb(G(a,1,c),b)} +function Sb(a,b,c,d){c||(c=0);var e=d||[];if(!m(b))throw Error(a+"contains undefined"+Tb(e));if(ha(b))throw Error(a+"contains a function"+Tb(e)+" with contents: "+b.toString());if(sb(b))throw Error(a+"contains "+b.toString()+Tb(e));if(1E310485760/3&&10485760=this.g.compare(this.Vc,a)&&0>=this.g.compare(a,this.wc)};h.C=function(a,b,c,d,e){this.matches(new N(b,c))||(c=M);return this.re.C(a,b,c,d,e)};h.oa=function(a,b,c){b.M()&&(b=M);var d=b.Fb(this.g),d=d.Z(M),e=this;b.U(L,function(a,b){e.matches(new N(a,b))||(d=d.P(a,M))});return this.re.oa(a,d,c)}; +h.Z=function(a){return a};h.ya=function(){return!0};h.Mb=function(){return this.re};function ic(a,b){return ub(a.name,b.name)}function jc(a,b){return ub(a,b)};function kc(){}var lc={};function mc(a){return q(a.compare,a)}kc.prototype.jf=function(a,b){return 0!==this.compare(new N("[MIN_NAME]",a),new N("[MIN_NAME]",b))};kc.prototype.Ce=function(){return nc};function oc(a){this.Ub=a}ma(oc,kc);h=oc.prototype;h.ue=function(a){return!a.K(this.Ub).e()};h.compare=function(a,b){var c=a.Y.K(this.Ub),d=b.Y.K(this.Ub),c=c.he(d);return 0===c?ub(a.name,b.name):c};h.Ae=function(a,b){var c=O(a),c=M.P(this.Ub,c);return new N(b,c)}; +h.Be=function(){var a=M.P(this.Ub,pc);return new N("[MAX_NAME]",a)};h.toString=function(){return this.Ub};var L=new oc(".priority");function qc(){}ma(qc,kc);h=qc.prototype;h.compare=function(a,b){return ub(a.name,b.name)};h.ue=function(){throw fb("KeyIndex.isDefinedOn not expected to be called.");};h.jf=function(){return!1};h.Ce=function(){return nc};h.Be=function(){return new N("[MAX_NAME]",M)};h.Ae=function(a){y(p(a),"KeyIndex indexValue must always be a string.");return new N(a,M)}; +h.toString=function(){return".key"};var rc=new qc;function sc(){}sc.prototype.ef=function(){return null};sc.prototype.oe=function(){return null};var tc=new sc;function uc(a,b,c){this.Bf=a;this.Ia=b;this.zd=c}uc.prototype.ef=function(a){var b=this.Ia.F;if(vc(b,a))return b.j().K(a);b=null!=this.zd?new wc(this.zd,!0,!1):this.Ia.u();return this.Bf.Ta(a,b)};uc.prototype.oe=function(a,b,c){var d=null!=this.zd?this.zd:xc(this.Ia);a=this.Bf.ce(d,b,1,c,a);return 0===a.length?null:a[0]};function yc(){this.Za={}} +function cc(a,b){var c=b.type,d=b.Ua;y("child_added"==c||"child_changed"==c||"child_removed"==c,"Only child changes supported for tracking");y(".priority"!==d,"Only non-priority child changes can be tracked.");var e=t(a.Za,d);if(e){var f=e.type;if("child_added"==c&&"child_removed"==f)a.Za[d]=new C("child_changed",b.Ha,d,e.Ha);else if("child_removed"==c&&"child_added"==f)delete a.Za[d];else if("child_removed"==c&&"child_changed"==f)a.Za[d]=new C("child_removed",e.De,d);else if("child_changed"==c&& +"child_added"==f)a.Za[d]=new C("child_added",b.Ha,d);else if("child_changed"==c&&"child_changed"==f)a.Za[d]=new C("child_changed",b.Ha,d,e.De);else throw fb("Illegal combination of changes: "+b+" occurred after "+e);}else a.Za[d]=b};function N(a,b){this.name=a;this.Y=b}function zc(a,b){return new N(a,b)};function Ac(a){this.ma=new dc(a);this.g=a.g;y(a.ka,"Only valid if limit has been set");this.sa=a.sa;this.zb=!(""===a.Eb?a.ia:"l"===a.Eb)}h=Ac.prototype;h.C=function(a,b,c,d,e){this.ma.matches(new N(b,c))||(c=M);return a.K(b).ea(c)?a:a.ub()=this.g.compare(this.ma.Vc,f):0>=this.g.compare(f,this.ma.wc))d=d.P(f.name,f.Y),e++;else break}}else{d=b.Fb(this.g);d=d.Z(M);var k,l,n;if(this.zb){b=d.gf(this.g);k=this.ma.wc;l=this.ma.Vc;var u=mc(this.g);n=function(a,b){return u(b,a)}}else b=d.Ob(this.g),k=this.ma.Vc, +l=this.ma.wc,n=mc(this.g);for(var e=0,x=!1;0=n(k,f)&&(x=!0),(g=x&&e=n(f,l))?e++:d=d.P(f.name,M)}return this.ma.Mb().oa(a,d,c)};h.Z=function(a){return a};h.ya=function(){return!0};h.Mb=function(){return this.ma.Mb()}; +function Bc(a,b,c,d,e,f){var g;if(a.zb){var k=mc(a.g);g=function(a,b){return k(b,a)}}else g=mc(a.g);y(b.ub()==a.sa,"");var l=new N(c,d),n=a.zb?Cc(b,a.g):Dc(b,a.g),u=a.ma.matches(l);if(b.Da(c)){var x=b.K(c),n=e.oe(a.g,n,a.zb);null!=n&&n.name==c&&(n=e.oe(a.g,n,a.zb));e=null==n?1:g(n,l);if(u&&!d.e()&&0<=e)return null!=f&&cc(f,new C("child_changed",d,c,x)),b.P(c,d);null!=f&&cc(f,new C("child_removed",x,c));b=b.P(c,M);return null!=n&&a.ma.matches(n)?(null!=f&&cc(f,new C("child_added",n.Y,n.name)),b.P(n.name, +n.Y)):b}return d.e()?b:u&&0<=g(n,l)?(null!=f&&(cc(f,new C("child_removed",n.Y,n.name)),cc(f,new C("child_added",d,c))),b.P(c,d).P(n.name,M)):b};function Ec(){this.vc=this.qa=this.kc=this.ia=this.ka=!1;this.sa=0;this.Eb="";this.Ac=null;this.Wb="";this.zc=null;this.Tb="";this.g=L}var Fc=new Ec;function fc(a){y(a.ia,"Only valid if start has been set");return a.Ac}function ec(a){y(a.ia,"Only valid if start has been set");return a.kc?a.Wb:"[MIN_NAME]"}function hc(a){y(a.qa,"Only valid if end has been set");return a.zc}function gc(a){y(a.qa,"Only valid if end has been set");return a.vc?a.Tb:"[MAX_NAME]"} +function Gc(a){var b=new Ec;b.ka=a.ka;b.sa=a.sa;b.ia=a.ia;b.Ac=a.Ac;b.kc=a.kc;b.Wb=a.Wb;b.qa=a.qa;b.zc=a.zc;b.vc=a.vc;b.Tb=a.Tb;b.g=a.g;return b}h=Ec.prototype;h.xe=function(a){var b=Gc(this);b.ka=!0;b.sa=a;b.Eb="";return b};h.ye=function(a){var b=Gc(this);b.ka=!0;b.sa=a;b.Eb="l";return b};h.ze=function(a){var b=Gc(this);b.ka=!0;b.sa=a;b.Eb="r";return b};h.Od=function(a,b){var c=Gc(this);c.ia=!0;m(a)||(a=null);c.Ac=a;null!=b?(c.kc=!0,c.Wb=b):(c.kc=!1,c.Wb="");return c}; +h.hd=function(a,b){var c=Gc(this);c.qa=!0;m(a)||(a=null);c.zc=a;m(b)?(c.vc=!0,c.Tb=b):(c.Ig=!1,c.Tb="");return c};function Hc(a,b){var c=Gc(a);c.g=b;return c}function Ic(a){var b={};a.ia&&(b.sp=a.Ac,a.kc&&(b.sn=a.Wb));a.qa&&(b.ep=a.zc,a.vc&&(b.en=a.Tb));if(a.ka){b.l=a.sa;var c=a.Eb;""===c&&(c=a.ia?"l":"r");b.vf=c}a.g!==L&&(b.i=a.g.toString());return b}function Jc(a){return!(a.ia||a.qa||a.ka)}h.toString=function(){return r(Ic(this))};function Q(a,b,c,d){this.k=a;this.path=b;this.n=c;this.ac=d} +function Kc(a){var b=null,c=null;a.ia&&(b=fc(a));a.qa&&(c=hc(a));if(a.g===rc){if(a.ia){if("[MIN_NAME]"!=ec(a))throw Error("Query: When ordering by key, you may only pass one argument to startAt(), endAt(), or equalTo().");if(null!=b&&"string"!==typeof b)throw Error("Query: When ordering by key, the argument passed to startAt(), endAt(),or equalTo() must be a string.");}if(a.qa){if("[MAX_NAME]"!=gc(a))throw Error("Query: When ordering by key, you may only pass one argument to startAt(), endAt(), or equalTo().");if(null!= +c&&"string"!==typeof c)throw Error("Query: When ordering by key, the argument passed to startAt(), endAt(),or equalTo() must be a string.");}}else if(a.g===L){if(null!=b&&!Qb(b)||null!=c&&!Qb(c))throw Error("Query: When ordering by priority, the first argument passed to startAt(), endAt(), or equalTo() must be a valid priority value (null, a number, or a string).");}else if(y(a.g instanceof oc,"unknown index type."),null!=b&&"object"===typeof b||null!=c&&"object"===typeof c)throw Error("Query: First argument passed to startAt(), endAt(), or equalTo() cannot be an object."); +}function Lc(a){if(a.ia&&a.qa&&a.ka&&(!a.ka||""===a.Eb))throw Error("Query: Can't combine startAt(), endAt(), and limit(). Use limitToFirst() or limitToLast() instead.");}function Mc(a,b){if(!0===a.ac)throw Error(b+": You can't combine multiple orderBy calls.");}Q.prototype.cc=function(){F("Query.ref",0,0,arguments.length);return new R(this.k,this.path)};Q.prototype.ref=Q.prototype.cc; +Q.prototype.vb=function(a,b,c,d){F("Query.on",2,4,arguments.length);Wb("Query.on",a,!1);H("Query.on",2,b,!1);var e=Nc("Query.on",c,d);if("value"===a)Oc(this.k,this,new Hb(b,e.cancel||null,e.Ka||null));else{var f={};f[a]=b;Oc(this.k,this,new Ib(f,e.cancel,e.Ka))}return b};Q.prototype.on=Q.prototype.vb; +Q.prototype.Zb=function(a,b,c){F("Query.off",0,3,arguments.length);Wb("Query.off",a,!0);H("Query.off",2,b,!0);Mb("Query.off",3,c);var d=null,e=null;"value"===a?d=new Hb(b||null,null,c||null):a&&(b&&(e={},e[a]=b),d=new Ib(e,null,c||null));e=this.k;d=".info"===I(this.path)?e.qd.gb(this,d):e.N.gb(this,d);Pc(e.$,this.path,d)};Q.prototype.off=Q.prototype.Zb; +Q.prototype.lg=function(a,b){function c(g){f&&(f=!1,e.Zb(a,c),b.call(d.Ka,g))}F("Query.once",2,4,arguments.length);Wb("Query.once",a,!1);H("Query.once",2,b,!1);var d=Nc("Query.once",arguments[2],arguments[3]),e=this,f=!0;this.vb(a,c,function(b){e.Zb(a,c);d.cancel&&d.cancel.call(d.Ka,b)})};Q.prototype.once=Q.prototype.lg; +Q.prototype.xe=function(a){z("Query.limit() being deprecated. Please use Query.limitToFirst() or Query.limitToLast() instead.");F("Query.limit",1,1,arguments.length);if(!ga(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limit: First argument must be a positive integer.");if(this.n.ka)throw Error("Query.limit: Limit was already set (by another call to limit, limitToFirst, orlimitToLast.");var b=this.n.xe(a);Lc(b);return new Q(this.k,this.path,b,this.ac)};Q.prototype.limit=Q.prototype.xe; +Q.prototype.ye=function(a){F("Query.limitToFirst",1,1,arguments.length);if(!ga(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limitToFirst: First argument must be a positive integer.");if(this.n.ka)throw Error("Query.limitToFirst: Limit was already set (by another call to limit, limitToFirst, or limitToLast).");return new Q(this.k,this.path,this.n.ye(a),this.ac)};Q.prototype.limitToFirst=Q.prototype.ye; +Q.prototype.ze=function(a){F("Query.limitToLast",1,1,arguments.length);if(!ga(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limitToLast: First argument must be a positive integer.");if(this.n.ka)throw Error("Query.limitToLast: Limit was already set (by another call to limit, limitToFirst, or limitToLast).");return new Q(this.k,this.path,this.n.ze(a),this.ac)};Q.prototype.limitToLast=Q.prototype.ze; +Q.prototype.mg=function(a){F("Query.orderByChild",1,1,arguments.length);if("$key"===a)throw Error('Query.orderByChild: "$key" is invalid. Use Query.orderByKey() instead.');if("$priority"===a)throw Error('Query.orderByChild: "$priority" is invalid. Use Query.orderByPriority() instead.');Xb("Query.orderByChild",1,a,!1);Mc(this,"Query.orderByChild");var b=Hc(this.n,new oc(a));Kc(b);return new Q(this.k,this.path,b,!0)};Q.prototype.orderByChild=Q.prototype.mg; +Q.prototype.ng=function(){F("Query.orderByKey",0,0,arguments.length);Mc(this,"Query.orderByKey");var a=Hc(this.n,rc);Kc(a);return new Q(this.k,this.path,a,!0)};Q.prototype.orderByKey=Q.prototype.ng;Q.prototype.og=function(){F("Query.orderByPriority",0,0,arguments.length);Mc(this,"Query.orderByPriority");var a=Hc(this.n,L);Kc(a);return new Q(this.k,this.path,a,!0)};Q.prototype.orderByPriority=Q.prototype.og; +Q.prototype.Od=function(a,b){F("Query.startAt",0,2,arguments.length);Rb("Query.startAt",a,!0);Xb("Query.startAt",2,b,!0);var c=this.n.Od(a,b);Lc(c);Kc(c);if(this.n.ia)throw Error("Query.startAt: Starting point was already set (by another call to startAt or equalTo).");m(a)||(b=a=null);return new Q(this.k,this.path,c,this.ac)};Q.prototype.startAt=Q.prototype.Od; +Q.prototype.hd=function(a,b){F("Query.endAt",0,2,arguments.length);Rb("Query.endAt",a,!0);Xb("Query.endAt",2,b,!0);var c=this.n.hd(a,b);Lc(c);Kc(c);if(this.n.qa)throw Error("Query.endAt: Ending point was already set (by another call to endAt or equalTo).");return new Q(this.k,this.path,c,this.ac)};Q.prototype.endAt=Q.prototype.hd; +Q.prototype.Tf=function(a,b){F("Query.equalTo",1,2,arguments.length);Rb("Query.equalTo",a,!1);Xb("Query.equalTo",2,b,!0);if(this.n.ia)throw Error("Query.equalTo: Starting point was already set (by another call to endAt or equalTo).");if(this.n.qa)throw Error("Query.equalTo: Ending point was already set (by another call to endAt or equalTo).");return this.Od(a,b).hd(a,b)};Q.prototype.equalTo=Q.prototype.Tf;Q.prototype.Fa=function(){var a=xb(Ic(this.n));return"{}"===a?"default":a}; +function Nc(a,b,c){var d={cancel:null,Ka:null};if(b&&c)d.cancel=b,H(a,3,d.cancel,!0),d.Ka=c,Mb(a,4,d.Ka);else if(b)if("object"===typeof b&&null!==b)d.Ka=b;else if("function"===typeof b)d.cancel=b;else throw Error(G(a,3,!0)+" must either be a cancel callback or a context object.");return d};function S(a,b){if(1==arguments.length){this.w=a.split("/");for(var c=0,d=0;d=a.w.length?null:a.w[a.ca]}function Qc(a){return a.w.length-a.ca}function T(a){var b=a.ca;b=this.w.length)return null;for(var a=[],b=this.ca;b=this.w.length};var U=new S("");function V(a,b){var c=I(a);if(null===c)return b;if(c===I(b))return V(T(a),T(b));throw Error("INTERNAL ERROR: innerPath ("+b+") is not within outerPath ("+a+")");} +S.prototype.ea=function(a){if(Qc(this)!==Qc(a))return!1;for(var b=this.ca,c=a.ca;b<=this.w.length;b++,c++)if(this.w[b]!==a.w[c])return!1;return!0};S.prototype.contains=function(a){var b=this.ca,c=a.ca;if(Qc(this)>Qc(a))return!1;for(;bb?c=c.left:0c?d=d.left:0e)a=this.ve?a.left:a.right;else if(0===e){this.Na.push(a);break}else this.Na.push(a),a=this.ve?a.right:a.left} +function P(a){if(0===a.Na.length)return null;var b=a.Na.pop(),c;c=a.Id?a.Id(b.key,b.value):{key:b.key,value:b.value};if(a.ve)for(b=b.left;!b.e();)a.Na.push(b),b=b.right;else for(b=b.right;!b.e();)a.Na.push(b),b=b.left;return c}function cd(a){if(0===a.Na.length)return null;var b;b=a.Na;b=b[b.length-1];return a.Id?a.Id(b.key,b.value):{key:b.key,value:b.value}}function dd(a,b,c,d,e){this.key=a;this.value=b;this.color=null!=c?c:!0;this.left=null!=d?d:$c;this.right=null!=e?e:$c}h=dd.prototype; +h.X=function(a,b,c,d,e){return new dd(null!=a?a:this.key,null!=b?b:this.value,null!=c?c:this.color,null!=d?d:this.left,null!=e?e:this.right)};h.count=function(){return this.left.count()+1+this.right.count()};h.e=function(){return!1};h.fa=function(a){return this.left.fa(a)||a(this.key,this.value)||this.right.fa(a)};function ed(a){return a.left.e()?a:ed(a.left)}h.Ic=function(){return ed(this).key};h.Xb=function(){return this.right.e()?this.key:this.right.Xb()}; +h.La=function(a,b,c){var d,e;e=this;d=c(a,e.key);e=0>d?e.X(null,null,null,e.left.La(a,b,c),null):0===d?e.X(null,b,null,null,null):e.X(null,null,null,null,e.right.La(a,b,c));return fd(e)};function gd(a){if(a.left.e())return $c;a.left.ba()||a.left.left.ba()||(a=hd(a));a=a.X(null,null,null,gd(a.left),null);return fd(a)} +h.remove=function(a,b){var c,d;c=this;if(0>b(a,c.key))c.left.e()||c.left.ba()||c.left.left.ba()||(c=hd(c)),c=c.X(null,null,null,c.left.remove(a,b),null);else{c.left.ba()&&(c=jd(c));c.right.e()||c.right.ba()||c.right.left.ba()||(c=kd(c),c.left.left.ba()&&(c=jd(c),c=kd(c)));if(0===b(a,c.key)){if(c.right.e())return $c;d=ed(c.right);c=c.X(d.key,d.value,null,null,gd(c.right))}c=c.X(null,null,null,null,c.right.remove(a,b))}return fd(c)};h.ba=function(){return this.color}; +function fd(a){a.right.ba()&&!a.left.ba()&&(a=ld(a));a.left.ba()&&a.left.left.ba()&&(a=jd(a));a.left.ba()&&a.right.ba()&&(a=kd(a));return a}function hd(a){a=kd(a);a.right.left.ba()&&(a=a.X(null,null,null,null,jd(a.right)),a=ld(a),a=kd(a));return a}function ld(a){return a.right.X(null,null,a.color,a.X(null,null,!0,null,a.right.left),null)}function jd(a){return a.left.X(null,null,a.color,null,a.X(null,null,!0,a.left.right,null))} +function kd(a){return a.X(null,null,!a.color,a.left.X(null,null,!a.left.color,null,null),a.right.X(null,null,!a.right.color,null,null))}function md(){}h=md.prototype;h.X=function(){return this};h.La=function(a,b){return new dd(a,b,null)};h.remove=function(){return this};h.count=function(){return 0};h.e=function(){return!0};h.fa=function(){return!1};h.Ic=function(){return null};h.Xb=function(){return null};h.ba=function(){return!1};var $c=new md;function nd(a,b){this.D=a;y(m(this.D)&&null!==this.D,"LeafNode shouldn't be created with null/undefined value.");this.ha=b||M;od(this.ha);this.sb=null}h=nd.prototype;h.M=function(){return!0};h.L=function(){return this.ha};h.Z=function(a){return new nd(this.D,a)};h.K=function(a){return".priority"===a?this.ha:M};h.ra=function(a){return a.e()?this:".priority"===I(a)?this.ha:M};h.Da=function(){return!1};h.ff=function(){return null}; +h.P=function(a,b){return".priority"===a?this.Z(b):b.e()&&".priority"!==a?this:M.P(a,b).Z(this.ha)};h.C=function(a,b){var c=I(a);if(null===c)return b;if(b.e()&&".priority"!==c)return this;y(".priority"!==c||1===Qc(a),".priority must be the last token in a path");return this.P(c,M.C(T(a),b))};h.e=function(){return!1};h.ub=function(){return 0};h.I=function(a){return a&&!this.L().e()?{".value":this.za(),".priority":this.L().I()}:this.za()}; +h.hash=function(){if(null===this.sb){var a="";this.ha.e()||(a+="priority:"+pd(this.ha.I())+":");var b=typeof this.D,a=a+(b+":"),a="number"===b?a+Ab(this.D):a+this.D;this.sb=ib(a)}return this.sb};h.za=function(){return this.D};h.he=function(a){if(a===M)return 1;if(a instanceof W)return-1;y(a.M(),"Unknown node type");var b=typeof a.D,c=typeof this.D,d=Ga(qd,b),e=Ga(qd,c);y(0<=d,"Unknown leaf type: "+b);y(0<=e,"Unknown leaf type: "+c);return d===e?"object"===c?0:this.Db.compare(d,a);)P(c),d=cd(c);return c};h.gf=function(a){return this.Rb(a.Be(),a)};h.Rb=function(a,b){var c=yd(this,b);if(c)return c.Rb(a,function(a){return a});for(var c=this.m.Rb(a.name,zc),d=cd(c);null!=d&&0=a.length){var b=Number(a);if(!isNaN(b)){e.Te=b;e.frames=[];a=null;break a}}e.Te=1;e.frames=[]}null!==a&&ce(e,a)}};this.ta.onerror=function(a){e.f("WebSocket error. Closing connection.");(a=a.message||a.data)&&e.f(a);e.eb()}};$d.prototype.start=function(){}; +$d.isAvailable=function(){var a=!1;if("undefined"!==typeof navigator&&navigator.userAgent){var b=navigator.userAgent.match(/Android ([0-9]{0,}\.[0-9]{0,})/);b&&1parseFloat(b[1])&&(a=!0)}return!a&&null!==Zd&&!ae};$d.responsesRequiredToBeHealthy=2;$d.healthyTimeout=3E4;h=$d.prototype;h.sd=function(){za.remove("previous_websocket_failure")};function ce(a,b){a.frames.push(b);if(a.frames.length==a.Te){var c=a.frames.join("");a.frames=null;c=ta(c);a.hg(c)}} +h.send=function(a){be(this);a=r(a);this.jb+=a.length;Sd(this.Ra,"bytes_sent",a.length);a=yb(a,16384);1document.domain="'+document.domain+'";\x3c/script>');a=""+a+"";try{this.Ba.ab.open(),this.Ba.ab.write(a),this.Ba.ab.close()}catch(f){hb("frame writing exception"),f.stack&&hb(f.stack),hb(f)}} +le.prototype.close=function(){this.ae=!1;if(this.Ba){this.Ba.ab.body.innerHTML="";var a=this;setTimeout(function(){null!==a.Ba&&(document.body.removeChild(a.Ba),a.Ba=null)},Math.floor(0))}var b=this.fb;b&&(this.fb=null,b())}; +function oe(a){if(a.ae&&a.Kd&&a.Ie.count()<(0=a.Qc[0].af.length+30+c.length){var e=a.Qc.shift(),c=c+"&seg"+d+"="+e.tg+"&ts"+d+"="+e.Bg+"&d"+d+"="+e.af;d++}else break;pe(a,b+c,a.ke);return!0}return!1}function pe(a,b,c){function d(){a.Ie.remove(c);oe(a)}a.Ie.add(c);var e=setTimeout(d,Math.floor(25E3));ne(a,b,function(){clearTimeout(e);d()})} +function ne(a,b,c){setTimeout(function(){try{if(a.Kd){var d=a.Ba.ab.createElement("script");d.type="text/javascript";d.async=!0;d.src=b;d.onload=d.onreadystatechange=function(){var a=d.readyState;a&&"loaded"!==a&&"complete"!==a||(d.onload=d.onreadystatechange=null,d.parentNode&&d.parentNode.removeChild(d),c())};d.onerror=function(){hb("Long-poll script failed to load: "+b);a.Kd=!1;a.close()};a.Ba.ab.body.appendChild(d)}}catch(e){}},Math.floor(1))};function qe(a){re(this,a)}var se=[ie,$d];function re(a,b){var c=$d&&$d.isAvailable(),d=c&&!(za.lf||!0===za.get("previous_websocket_failure"));b.Dg&&(c||z("wss:// URL used, but browser isn't known to support websockets. Trying anyway."),d=!0);if(d)a.Xc=[$d];else{var e=a.Xc=[];zb(se,function(a,b){b&&b.isAvailable()&&e.push(b)})}}function te(a){if(0=a.yf?(a.f("Secondary connection is healthy."),a.rb=!0,a.B.sd(),a.B.start(),a.f("sending client ack on secondary"),a.B.send({t:"c",d:{t:"a",d:{}}}),a.f("Ending transmission on primary"),a.J.send({t:"c",d:{t:"n",d:{}}}),a.Yc=a.B,Ae(a)):(a.f("sending ping on secondary."),a.B.send({t:"c",d:{t:"p",d:{}}}))}ue.prototype.xd=function(a){Ce(this);this.$b(a)};function Ce(a){a.rb||(a.Ke--,0>=a.Ke&&(a.f("Primary connection is healthy."),a.rb=!0,a.J.sd()))} +function ze(a,b){a.B=new b("c:"+a.id+":"+a.Xe++,a.O,a.Md);a.yf=b.responsesRequiredToBeHealthy||0;a.B.open(we(a,a.B),xe(a,a.B));setTimeout(function(){a.B&&(a.f("Timed out trying to upgrade."),a.B.close())},Math.floor(6E4))}function ye(a,b,c){a.f("Realtime connection established.");a.J=b;a.Qa=1;a.Kc&&(a.Kc(c),a.Kc=null);0===a.Ke?(a.f("Primary connection is healthy."),a.rb=!0):setTimeout(function(){De(a)},Math.floor(5E3))} +function De(a){a.rb||1!==a.Qa||(a.f("sending ping on primary."),Fe(a,{t:"c",d:{t:"p",d:{}}}))}function Fe(a,b){if(1!==a.Qa)throw"Connection is not connected";a.Yc.send(b)}ue.prototype.close=function(){2!==this.Qa&&(this.f("Closing realtime connection."),this.Qa=2,Be(this),this.ga&&(this.ga(),this.ga=null))};function Be(a){a.f("Shutting down all connections");a.J&&(a.J.close(),a.J=null);a.B&&(a.B.close(),a.B=null);a.nd&&(clearTimeout(a.nd),a.nd=null)};function Ge(a){var b={},c={},d={},e="";try{var f=a.split("."),b=ta(gb(f[0])||""),c=ta(gb(f[1])||""),e=f[2],d=c.d||{};delete c.d}catch(g){}return{Gg:b,fe:c,data:d,xg:e}}function He(a){a=Ge(a).fe;return"object"===typeof a&&a.hasOwnProperty("iat")?t(a,"iat"):null}function Ie(a){a=Ge(a);var b=a.fe;return!!a.xg&&!!b&&"object"===typeof b&&b.hasOwnProperty("iat")};function Je(a,b,c,d){this.id=Ke++;this.f=ob("p:"+this.id+":");this.Cb=!0;this.Aa={};this.la=[];this.Nc=0;this.Jc=[];this.ja=!1;this.Wa=1E3;this.td=3E5;this.yd=b;this.wd=c;this.He=d;this.O=a;this.Oe=null;this.Sc={};this.sg=0;this.Dc=this.we=null;Le(this,0);Hd.Nb().vb("visible",this.kg,this);-1===a.host.indexOf("fblocal")&&Id.Nb().vb("online",this.ig,this)}var Ke=0,Me=0;h=Je.prototype; +h.Ca=function(a,b,c){var d=++this.sg;a={r:d,a:a,b:b};this.f(r(a));y(this.ja,"sendRequest call when we're not connected not allowed.");this.Oa.Ca(a);c&&(this.Sc[d]=c)};function Ne(a,b,c,d,e){var f=b.Fa(),g=b.path.toString();a.f("Listen called for "+g+" "+f);a.Aa[g]=a.Aa[g]||{};y(!a.Aa[g][f],"listen() called twice for same path/queryId.");b={H:e,md:c,pg:Ic(b.n),tag:d};a.Aa[g][f]=b;a.ja&&Oe(a,g,f,b)} +function Oe(a,b,c,d){a.f("Listen on "+b+" for "+c);var e={p:b};d.tag&&(e.q=d.pg,e.t=d.tag);e.h=d.md();a.Ca("q",e,function(e){if((a.Aa[b]&&a.Aa[b][c])===d){a.f("listen response",e);var g=e.s;"ok"!==g&&Pe(a,b,c);e=e.d;d.H&&d.H(g,e)}})}h.Q=function(a,b,c){this.Ib={Rf:a,cf:!1,qc:b,ad:c};this.f("Authenticating using credential: "+a);Qe(this);(b=40==a.length)||(a=Ge(a).fe,b="object"===typeof a&&!0===t(a,"admin"));b&&(this.f("Admin auth credential detected. Reducing max reconnect time."),this.td=3E4)}; +h.Ue=function(a){delete this.Ib;this.ja&&this.Ca("unauth",{},function(b){a(b.s,b.d)})};function Qe(a){var b=a.Ib;a.ja&&b&&a.Ca("auth",{cred:b.Rf},function(c){var d=c.s;c=c.d||"error";"ok"!==d&&a.Ib===b&&delete a.Ib;b.cf?"ok"!==d&&b.ad&&b.ad(d,c):(b.cf=!0,b.qc&&b.qc(d,c))})}function Re(a,b,c,d){a.ja?Se(a,"o",b,c,d):a.Jc.push({Pc:b,action:"o",data:c,H:d})}function Te(a,b,c,d){a.ja?Se(a,"om",b,c,d):a.Jc.push({Pc:b,action:"om",data:c,H:d})} +h.Fe=function(a,b){this.ja?Se(this,"oc",a,null,b):this.Jc.push({Pc:a,action:"oc",data:null,H:b})};function Se(a,b,c,d,e){c={p:c,d:d};a.f("onDisconnect "+b,c);a.Ca(b,c,function(a){e&&setTimeout(function(){e(a.s,a.d)},Math.floor(0))})}h.put=function(a,b,c,d){Ue(this,"p",a,b,c,d)};function Ve(a,b,c,d){Ue(a,"m",b,c,d,void 0)}function Ue(a,b,c,d,e,f){d={p:c,d:d};m(f)&&(d.h=f);a.la.push({action:b,uf:d,H:e});a.Nc++;b=a.la.length-1;a.ja?We(a,b):a.f("Buffering put: "+c)} +function We(a,b){var c=a.la[b].action,d=a.la[b].uf,e=a.la[b].H;a.la[b].qg=a.ja;a.Ca(c,d,function(d){a.f(c+" response",d);delete a.la[b];a.Nc--;0===a.Nc&&(a.la=[]);e&&e(d.s,d.d)})} +h.xd=function(a){if("r"in a){this.f("from server: "+r(a));var b=a.r,c=this.Sc[b];c&&(delete this.Sc[b],c(a.b))}else{if("error"in a)throw"A server-side error has occurred: "+a.error;"a"in a&&(b=a.a,c=a.b,this.f("handleServerMessage",b,c),"d"===b?this.yd(c.p,c.d,!1,c.t):"m"===b?this.yd(c.p,c.d,!0,c.t):"c"===b?Xe(this,c.p,c.q):"ac"===b?(a=c.s,b=c.d,c=this.Ib,delete this.Ib,c&&c.ad&&c.ad(a,b)):"sd"===b?this.Oe?this.Oe(c):"msg"in c&&"undefined"!==typeof console&&console.log("FIREBASE: "+c.msg.replace("\n", +"\nFIREBASE: ")):pb("Unrecognized action received from server: "+r(b)+"\nAre you using the latest client?"))}};h.Kc=function(a){this.f("connection ready");this.ja=!0;this.Dc=(new Date).getTime();this.He({serverTimeOffset:a-(new Date).getTime()});Ye(this);this.wd(!0)};function Le(a,b){y(!a.Oa,"Scheduling a connect when we're already connected/ing?");a.Kb&&clearTimeout(a.Kb);a.Kb=setTimeout(function(){a.Kb=null;Ze(a)},Math.floor(b))} +h.kg=function(a){a&&!this.mc&&this.Wa===this.td&&(this.f("Window became visible. Reducing delay."),this.Wa=1E3,this.Oa||Le(this,0));this.mc=a};h.ig=function(a){a?(this.f("Browser went online. Reconnecting."),this.Wa=1E3,this.Cb=!0,this.Oa||Le(this,0)):(this.f("Browser went offline. Killing connection; don't reconnect."),this.Cb=!1,this.Oa&&this.Oa.close())}; +h.of=function(){this.f("data client disconnected");this.ja=!1;this.Oa=null;for(var a=0;ae.status){try{a=ta(e.responseText)}catch(b){}c(null,a)}else 500<=e.status&&600>e.status?c(X("SERVER_ERROR")):c(X("NETWORK_ERROR"));c=null;qf(window,"beforeunload",d)}};if("GET"===f)a+=(/\?/.test(a)?"":"?")+tf(b),g=null;else{var k=this.options.headers.content_type; +"application/json"===k&&(g=r(b));"application/x-www-form-urlencoded"===k&&(g=tf(b))}e.open(f,a,!0);a={"X-Requested-With":"XMLHttpRequest",Accept:"application/json;text/plain"};Qd(a,this.options.headers);for(var l in a)e.setRequestHeader(l,a[l]);e.send(g)};yf.isAvailable=function(){return!!window.XMLHttpRequest&&"string"===typeof(new XMLHttpRequest).responseType&&(!(navigator.userAgent.match(/MSIE/)||navigator.userAgent.match(/Trident/))||xf())};yf.prototype.sc=function(){return"json"};function zf(a){this.fc=Fa()+Fa()+Fa();this.pf=a} +zf.prototype.open=function(a,b,c){function d(){c&&(c(X("USER_CANCELLED")),c=null)}var e=this,f=rb(jf),g;b.requestId=this.fc;b.redirectTo=f.scheme+"://"+f.host+"/blank/page.html";a+=/\?/.test(a)?"":"?";a+=tf(b);(g=window.open(a,"_blank","location=no"))&&ha(g.addEventListener)?(g.addEventListener("loadstart",function(a){var b;if(b=a&&a.url)a:{var n=a.url;try{var u=document.createElement("a");u.href=n;b=u.host===f.host&&"/blank/page.html"===u.pathname;break a}catch(x){}b=!1}b&&(a=sf(a.url),g.removeEventListener("exit", +d),g.close(),a=new kf(null,null,{requestId:e.fc,requestKey:a}),e.pf.requestWithCredential("/auth/session",a,c),c=null)}),g.addEventListener("exit",d)):c(X("TRANSPORT_UNAVAILABLE"))};zf.isAvailable=function(){return wf()};zf.prototype.sc=function(){return"redirect"};function Af(a){if(!a.window_features||-1!==navigator.userAgent.indexOf("Fennec/")||-1!==navigator.userAgent.indexOf("Firefox/")&&-1!==navigator.userAgent.indexOf("Android"))a.window_features=void 0;a.window_name||(a.window_name="_blank");this.options=a} +Af.prototype.open=function(a,b,c){function d(a){g&&(document.body.removeChild(g),g=void 0);u&&(u=clearInterval(u));qf(window,"message",e);qf(window,"unload",d);if(n&&!a)try{n.close()}catch(b){k.postMessage("die",l)}n=k=void 0}function e(a){if(a.origin===l)try{var b=ta(a.data);"ready"===b.a?k.postMessage(x,l):"error"===b.a?(d(!1),c&&(c(b.d),c=null)):"response"===b.a&&(d(b.forceKeepWindowOpen),c&&(c(null,b.d),c=null))}catch(e){}}var f=xf(),g,k;if(!this.options.relay_url)return c(Error("invalid arguments: origin of url and relay_url must match")); +var l=rf(a);if(l!==rf(this.options.relay_url))c&&setTimeout(function(){c(Error("invalid arguments: origin of url and relay_url must match"))},0);else{f&&(g=document.createElement("iframe"),g.setAttribute("src",this.options.relay_url),g.style.display="none",g.setAttribute("name","__winchan_relay_frame"),document.body.appendChild(g),k=g.contentWindow);a+=(/\?/.test(a)?"":"?")+tf(b);var n=window.open(a,this.options.window_name,this.options.window_features);k||(k=n);var u=setInterval(function(){n&&n.closed&& +(d(!1),c&&(c(X("USER_CANCELLED")),c=null))},500),x=r({a:"request",d:b});pf(window,"unload",d);pf(window,"message",e)}}; +Af.isAvailable=function(){return"postMessage"in window&&!/^file:\//.test(location.href)&&!(wf()||navigator.userAgent.match(/Windows Phone/)||window.Windows&&/^ms-appx:/.test(location.href)||navigator.userAgent.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i)||navigator.userAgent.match(/CriOS/)||navigator.userAgent.match(/Twitter for iPhone/)||navigator.userAgent.match(/FBAN\/FBIOS/)||window.navigator.standalone)&&!navigator.userAgent.match(/PhantomJS/)};Af.prototype.sc=function(){return"popup"};function Bf(a){a.callback_parameter||(a.callback_parameter="callback");this.options=a;window.__firebase_auth_jsonp=window.__firebase_auth_jsonp||{}} +Bf.prototype.open=function(a,b,c){function d(){c&&(c(X("REQUEST_INTERRUPTED")),c=null)}function e(){setTimeout(function(){window.__firebase_auth_jsonp[f]=void 0;Nd(window.__firebase_auth_jsonp)&&(window.__firebase_auth_jsonp=void 0);try{var a=document.getElementById(f);a&&a.parentNode.removeChild(a)}catch(b){}},1);qf(window,"beforeunload",d)}var f="fn"+(new Date).getTime()+Math.floor(99999*Math.random());b[this.options.callback_parameter]="__firebase_auth_jsonp."+f;a+=(/\?/.test(a)?"":"?")+tf(b); +pf(window,"beforeunload",d);window.__firebase_auth_jsonp[f]=function(a){c&&(c(null,a),c=null);e()};Cf(f,a,c)}; +function Cf(a,b,c){setTimeout(function(){try{var d=document.createElement("script");d.type="text/javascript";d.id=a;d.async=!0;d.src=b;d.onerror=function(){var b=document.getElementById(a);null!==b&&b.parentNode.removeChild(b);c&&c(X("NETWORK_ERROR"))};var e=document.getElementsByTagName("head");(e&&0!=e.length?e[0]:document.documentElement).appendChild(d)}catch(f){c&&c(X("NETWORK_ERROR"))}},0)}Bf.isAvailable=function(){return!wf()};Bf.prototype.sc=function(){return"json"};function Df(a,b){this.Je=["session",a.Dd,a.tb].join(":");this.Rd=b}Df.prototype.set=function(a,b){if(!b)if(this.Rd.length)b=this.Rd[0];else throw Error("fb.login.SessionManager : No storage options available!");b.set(this.Je,a)};Df.prototype.get=function(){var a=Ja(this.Rd,q(this.Zf,this)),a=Ia(a,function(a){return null!==a});Qa(a,function(a,c){return He(c.token)-He(a.token)});return 0=b&&Wg(g,c.path)?d=!1:c.path.contains(g.path)&&(e=!0));f--}if(d){if(e)this.T=Xg(this.wa,Yg,U),this.Ec=0f.Ec,"Stacking an older write on top of newer ones");m(g)||(g=!0);f.wa.push({path:b,Ga:c,Zd:d,visible:g});g&&(f.T=Pg(f.T,b,c));f.Ec=d;return e?ih(a,new $g(bh,b,c)):[]}function jh(a,b,c,d){var e=a.xb;y(d>e.Ec,"Stacking an older merge on top of newer ones");e.wa.push({path:b,children:c,Zd:d,visible:!0});e.T=Qg(e.T,b,c);e.Ec=d;c=yg(c);return ih(a,new dh(bh,b,c))} +function kh(a,b,c){c=c||!1;b=a.xb.Gd(b);return null==b?[]:ih(a,new ah(b,c))}function lh(a,b,c){c=yg(c);return ih(a,new dh(fh,b,c))}function mh(a,b,c,d){d=Od(a.Wc,"_"+d);if(null!=d){var e=nh(d);d=e.path;e=e.yb;b=V(d,b);c=new $g(new eh(!1,!0,e,!0),b,c);return oh(a,d,c)}return[]}function ph(a,b,c,d){if(d=Od(a.Wc,"_"+d)){var e=nh(d);d=e.path;e=e.yb;b=V(d,b);c=yg(c);c=new dh(new eh(!1,!0,e,!0),b,c);return oh(a,d,c)}return[]} +gh.prototype.Gb=function(a,b){var c=a.path,d=null,e=!1;Fg(this.na,c,function(a,b){var f=V(a,c);d=b.bb(f);e=e||null!=Kg(b);return!d});var f=this.na.get(c);f?(e=e||null!=Kg(f),d=d||f.bb(U)):(f=new Jg,this.na=this.na.set(c,f));var g;null!=d?g=!0:(g=!1,d=M,Ig(this.na.subtree(c),function(a,b){var c=b.bb(U);c&&(d=d.P(a,c))}));var k=null!=Mg(f,a);if(!k&&!Jc(a.n)){var l=qh(a);y(!(l in this.bc),"View does not exist, but we have a tag");var n=rh++;this.bc[l]=n;this.Wc["_"+n]=l}g=f.Gb(a,b,new Zg(c,this.xb), +d,g);k||e||(f=Mg(f,a),g=g.concat(sh(this,a,f)));return g}; +gh.prototype.gb=function(a,b,c){var d=a.path,e=this.na.get(d),f=[];if(e&&("default"===a.Fa()||null!=Mg(e,a))){f=e.gb(a,b,c);e.e()&&(this.na=this.na.remove(d));e=f.rg;f=f.Vf;b=-1!==Na(e,function(a){return Jc(a.n)});var g=Dg(this.na,d,function(a,b){return null!=Kg(b)});if(b&&!g&&(d=this.na.subtree(d),!d.e()))for(var d=th(d),k=0;kf;f++)b[f]=Math.floor(64*Math.random());for(f=0;12>f;f++)c+="-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(b[f]);y(20===c.length,"NextPushId: Length should be 20."); +return c}}();function R(a,b){var c,d,e;if(a instanceof zh)c=a,d=b;else{F("new Firebase",1,2,arguments.length);d=rb(arguments[0]);c=d.Ag;"firebase"===d.domain&&qb(d.host+" is no longer supported. Please use .firebaseio.com instead");c||qb("Cannot parse Firebase url. Please use https://.firebaseio.com");d.Ab||"undefined"!==typeof window&&window.location&&window.location.protocol&&-1!==window.location.protocol.indexOf("https:")&&z("Insecure Firebase access from a secure page. Please use https in calls to new Firebase()."); +c=new Aa(d.host,d.Ab,c,"ws"===d.scheme||"wss"===d.scheme);d=new S(d.Pc);e=d.toString();var f;!(f=!p(c.host)||0===c.host.length||!Pb(c.tb))&&(f=0!==e.length)&&(e&&(e=e.replace(/^\/*\.info(\/|$)/,"/")),f=!(p(e)&&0!==e.length&&!Ob.test(e)));if(f)throw Error(G("new Firebase",1,!1)+'must be a valid firebase URL and the path can\'t contain ".", "#", "$", "[", or "]".');if(b)if(b instanceof Th)e=b;else if(p(b))e=Th.Nb(),c.Dd=b;else throw Error("Expected a valid Firebase.Context for second argument to new Firebase()"); +else e=Th.Nb();f=c.toString();var g=t(e.ec,f);g||(g=new zh(c),e.ec[f]=g);c=g}Q.call(this,c,d,Fc,!1)}ma(R,Q);var Xh=R,Yh=["Firebase"],Zh=aa;Yh[0]in Zh||!Zh.execScript||Zh.execScript("var "+Yh[0]);for(var $h;Yh.length&&($h=Yh.shift());)!Yh.length&&m(Xh)?Zh[$h]=Xh:Zh=Zh[$h]?Zh[$h]:Zh[$h]={};R.prototype.name=function(){z("Firebase.name() being deprecated. Please use Firebase.key() instead.");F("Firebase.name",0,0,arguments.length);return this.key()};R.prototype.name=R.prototype.name; +R.prototype.key=function(){F("Firebase.key",0,0,arguments.length);return this.path.e()?null:Rc(this.path)};R.prototype.key=R.prototype.key;R.prototype.o=function(a){F("Firebase.child",1,1,arguments.length);if(ga(a))a=String(a);else if(!(a instanceof S))if(null===I(this.path)){var b=a;b&&(b=b.replace(/^\/*\.info(\/|$)/,"/"));Yb("Firebase.child",b)}else Yb("Firebase.child",a);return new R(this.k,this.path.o(a))};R.prototype.child=R.prototype.o; +R.prototype.parent=function(){F("Firebase.parent",0,0,arguments.length);var a=this.path.parent();return null===a?null:new R(this.k,a)};R.prototype.parent=R.prototype.parent;R.prototype.root=function(){F("Firebase.ref",0,0,arguments.length);for(var a=this;null!==a.parent();)a=a.parent();return a};R.prototype.root=R.prototype.root; +R.prototype.toString=function(){F("Firebase.toString",0,0,arguments.length);var a;if(null===this.parent())a=this.k.toString();else{a=this.parent().toString()+"/";var b=this.key();a+=encodeURIComponent(String(b))}return a};R.prototype.toString=R.prototype.toString;R.prototype.set=function(a,b){F("Firebase.set",1,2,arguments.length);Zb("Firebase.set",this.path);Rb("Firebase.set",a,!1);H("Firebase.set",2,b,!0);this.k.Bb(this.path,a,null,b||null)};R.prototype.set=R.prototype.set; +R.prototype.update=function(a,b){F("Firebase.update",1,2,arguments.length);Zb("Firebase.update",this.path);if(ea(a)){for(var c={},d=0;d + + start - timestamp of start + current - timestamp of current + time-out - interval of time-out +*/ + + +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_Timer = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_Timer.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + + this.exp_LastOwnerID = ""; + this.exp_LastTimerName = ""; + this.exp_LastTimer = null; + }; + + instanceProto.onDestroy = function () + { + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + if (!obj) + return null; + + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + var newTimerDate = function (interval) + { + var t = {"start": serverTimeStamp(), + "current": serverTimeStamp(), + "time-out": interval}; + return t; + } + instanceProto.start_timer = function(ref, interval, handler) + { + ref["set"](newTimerDate(interval), handler); + }; + + var get_deltaTime = function (timer) + { + var t; + if (timer) + t = get_timestamp(timer["current"]) - get_timestamp(timer["start"]); + else + t = 0; + + return t; + } + + ////////////////////////////////////// + // Conditions + function Cnds() {}; + pluginProto.cnds = new Cnds(); + + Cnds.prototype.OnStartTimerComplete = function () + { + return true; + }; + Cnds.prototype.OnStartTimerError = function () + { + return true; + }; + Cnds.prototype.OnGetTimerComplete = function () + { + return true; + }; + Cnds.prototype.OnGetTimerError = function () + { + return true; + }; + Cnds.prototype.OnRemoveTimerComplete = function () + { + return true; + }; + Cnds.prototype.OnRemoveTimerError = function () + { + return true; + }; + + Cnds.prototype.IsTimeOut = function () + { + if (!this.exp_LastTimer) + return false; + + var t = get_deltaTime(this.exp_LastTimer); + return (t/1000) > this.exp_LastTimer["time-out"]; + }; + + Cnds.prototype.IsValid = function () + { + return (this.exp_LastTimer != null); + }; + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetDomainRef = function (domain_ref, sub_domain_ref) + { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + }; + + Acts.prototype.StartTimer = function (ownerID, timer_name, interval) + { + var ref = this.get_ref()["child"](ownerID)["child"](timer_name); + + var self = this; + //2. read timer back + var on_read = function (snapshot) + { + self.exp_LastOwnerID = ownerID; + self.exp_LastTimerName = timer_name; + + self.exp_LastTimer = snapshot["val"](); + self.runtime.trigger(cr.plugins_.Rex_Firebase_Timer.prototype.cnds.OnStartTimerComplete, self); + }; + var read_timer = function() + { + ref["once"]("value", on_read); + }; + //2. read timer back + + //1. start timer + var onComplete = function(error) + { + if (error) + self.runtime.trigger(cr.plugins_.Rex_Firebase_Timer.prototype.cnds.OnStartTimerError, self); + else + read_timer(); + }; + + this.start_timer(ref, interval, onComplete); + //1. start timer + }; + + Acts.prototype.GetTimer = function (ownerID, timer_name, interval) + { + var startIfNotExists = (interval != null); + var isNewTimer = false; + var ref = this.get_ref()["child"](ownerID)["child"](timer_name); + var self = this; + + //3. read timer back + var on_read = function (snapshot) + { + self.exp_LastOwnerID = ownerID; + self.exp_LastTimerName = timer_name; + + self.exp_LastTimer = snapshot["val"](); + + if (isNewTimer) + self.runtime.trigger(cr.plugins_.Rex_Firebase_Timer.prototype.cnds.OnStartTimerComplete, self); + + self.runtime.trigger(cr.plugins_.Rex_Firebase_Timer.prototype.cnds.OnGetTimerComplete, self); + }; + var read_timer = function() + { + ref["once"]("value", on_read); + }; + //3. read timer back + + //2. update timer / start timer + var on_update = function(error) + { + if (error) + { + self.exp_LastOwnerID = ownerID; + self.exp_LastTimerName = timer_name; + self.runtime.trigger(cr.plugins_.Rex_Firebase_Timer.prototype.cnds.OnGetTimerError, self); + return; + } + + read_timer(); + }; + var update_timer = function() + { + var t = {"current": serverTimeStamp()}; + ref["update"](t, on_update); + }; + var start_timer = function() + { + isNewTimer = true; + self.start_timer(ref, interval, on_update); + }; + //2. update timer + + //1. check if timer is existed + var on_exist_check = function (snapshot) + { + if (snapshot["val"]()) + update_timer(); + else if (startIfNotExists) + start_timer(); + else + on_read(snapshot); + }; + ref["once"]("value", on_exist_check); + //1. check if timer is existed + }; + + Acts.prototype.RemoveTimer = function (ownerID, timer_name) + { + var ref = this.get_ref()["child"](ownerID)["child"](timer_name); + + var self = this; + var onComplete = function(error) + { + self.exp_LastOwnerID = ownerID; + self.exp_LastTimerName = timer_name; + var trig = (error)? cr.plugins_.Rex_Firebase_Timer.prototype.cnds.OnRemoveTimerError: + cr.plugins_.Rex_Firebase_Timer.prototype.cnds.OnRemoveTimerComplete; + self.runtime.trigger(trig, self); + }; + + ref["remove"](onComplete) + }; + + Acts.prototype.StartTimerWhenDisconnect = function (ownerID, timer_name, interval) + { + var ref = this.get_ref()["child"](ownerID)["child"](timer_name); + ref["onDisconnect"]()["set"](newTimerDate(interval)); + }; + + Acts.prototype.DeleteTimerWhenDisconnect = function (ownerID, timer_name, interval) + { + var ref = this.get_ref()["child"](ownerID)["child"](timer_name); + ref["onDisconnect"]()["remove"](); + }; + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.LastUserID = function (ret) + { + ret.set_string(this.exp_LastOwnerID); + }; + Exps.prototype.LastTimerName = function (ret) + { + ret.set_string(this.exp_LastTimerName); + }; + Exps.prototype.LastStartTimestamp = function (ret) + { + var t; + if (this.exp_LastTimer) + t = get_timestamp(this.exp_LastTimer["start"]); + + ret.set_float(t || 0); + }; + Exps.prototype.LastCurrentTimestamp = function (ret) + { + var t; + if (this.exp_LastTimer) + t = get_timestamp(this.exp_LastTimer["current"]); + + ret.set_float(t || 0); + }; + Exps.prototype.LastElapsedTime = function (ret) + { + var t; + if (this.exp_LastTimer) + t = get_deltaTime(this.exp_LastTimer)/1000; + + ret.set_float(t || 0); + }; + Exps.prototype.LastTimeoutInterval = function (ret) + { + var t; + if (this.exp_LastTimer) + t = this.exp_LastTimer["time-out"]; + + ret.set_float(t || 0); + }; + Exps.prototype.LastRemainInterval = function (ret) + { + var t; + if (this.exp_LastTimer) + t = this.exp_LastTimer["time-out"] - get_deltaTime(this.exp_LastTimer)/1000; + + ret.set_float(t || 0); + }; + + Exps.prototype.LastOwnerID = function (ret) + { + ret.set_string(this.exp_LastOwnerID); + }; +}()); \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/actions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/actions.js new file mode 100755 index 0000000..66e66e4 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/actions.js @@ -0,0 +1,138 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Timer.Acts = + { + SetDomainRef(domain_ref, sub_domain_ref) + { + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + }, + + StartTimer (ownerID, timer_name, interval) + { + var ref = this.get_ref()["child"](ownerID)["child"](timer_name); + + var self = this; + //2. read timer back + var on_read = function (snapshot) + { + self.exp_LastOwnerID = ownerID; + self.exp_LastTimerName = timer_name; + + self.exp_LastTimer = snapshot["val"](); + self.Trigger(C3.Plugins.Rex_Firebase_Timer.Cnds.OnStartTimerComplete); + }; + var read_timer = function() + { + ref["once"]("value", on_read); + }; + //2. read timer back + + //1. start timer + var onComplete = function(error) + { + if (error) + self.Trigger(C3.Plugins.Rex_Firebase_Timer.Cnds.OnStartTimerError); + else + read_timer(); + }; + + this.start_timer(ref, interval, onComplete); + //1. start timer + }, + + GetTimer(ownerID, timer_name, interval) + { + var startIfNotExists = (interval != null); + var isNewTimer = false; + var ref = this.get_ref()["child"](ownerID)["child"](timer_name); + var self = this; + + //3. read timer back + var on_read = function (snapshot) + { + self.exp_LastOwnerID = ownerID; + self.exp_LastTimerName = timer_name; + + self.exp_LastTimer = snapshot["val"](); + + if (isNewTimer) + self.Trigger(C3.Plugins.Rex_Firebase_Timer.Cnds.OnStartTimerComplete); + + self.Trigger(C3.Plugins.Rex_Firebase_Timer.Cnds.OnGetTimerComplete); + }; + var read_timer = function() + { + ref["once"]("value", on_read); + }; + //3. read timer back + + //2. update timer / start timer + var on_update = function(error) + { + if (error) + { + self.exp_LastOwnerID = ownerID; + self.exp_LastTimerName = timer_name; + self.Trigger(C3.Plugins.Rex_Firebase_Timer.Cnds.OnGetTimerError); + return; + } + + read_timer(); + }; + var update_timer = function() + { + var t = {"current": serverTimeStamp()}; + ref["update"](t, on_update); + }; + var start_timer = function() + { + isNewTimer = true; + self.start_timer(ref, interval, on_update); + }; + //2. update timer + + //1. check if timer is existed + var on_exist_check = function (snapshot) + { + if (snapshot["val"]()) + update_timer(); + else if (startIfNotExists) + start_timer(); + else + on_read(snapshot); + }; + ref["once"]("value", on_exist_check); + //1. check if timer is existed + }, + + RemoveTimer(ownerID, timer_name) + { + var ref = this.get_ref()["child"](ownerID)["child"](timer_name); + + var self = this; + var onComplete = function(error) + { + self.exp_LastOwnerID = ownerID; + self.exp_LastTimerName = timer_name; + var trig = (error)? C3.Plugins.Rex_Firebase_Timer.Cnds.OnRemoveTimerError: + C3.Plugins.Rex_Firebase_Timer.Cnds.OnRemoveTimerComplete; + self.Trigger(trig); + }; + + ref["remove"](onComplete) + }, + + StartTimerWhenDisconnect(ownerID, timer_name, interval) + { + var ref = this.get_ref()["child"](ownerID)["child"](timer_name); + ref["onDisconnect"]()["set"](newTimerDate(interval)); + }, + + DeleteTimerWhenDisconnect(ownerID, timer_name, interval) + { + var ref = this.get_ref()["child"](ownerID)["child"](timer_name); + ref["onDisconnect"]()["remove"](); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/conditions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/conditions.js new file mode 100755 index 0000000..e47c16b --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/conditions.js @@ -0,0 +1,45 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Timer.Cnds = + { + OnStartTimerComplete() + { + return true; + }, + OnStartTimerError() + { + return true; + }, + OnGetTimerComplete() + { + return true; + }, + OnGetTimerError() + { + return true; + }, + OnRemoveTimerComplete() + { + return true; + }, + OnRemoveTimerError() + { + return true; + }, + + IsTimeOut() + { + if (!this.exp_LastTimer) + return false; + + var t = get_deltaTime(this.exp_LastTimer); + return (t/1000) > this.exp_LastTimer["time-out"]; + }, + + IsValid() + { + return (this.exp_LastTimer != null); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/expressions.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/expressions.js new file mode 100755 index 0000000..6ce00b5 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/expressions.js @@ -0,0 +1,60 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Timer.Exps = + { + LastUserID() + { + return (this.exp_LastOwnerID); + }, + LastTimerName() + { + return (this.exp_LastTimerName); + }, + LastStartTimestamp() + { + var t; + if (this.exp_LastTimer) + t = get_timestamp(this.exp_LastTimer["start"]); + + return(t || 0); + }, + LastCurrentTimestamp() + { + var t; + if (this.exp_LastTimer) + t = get_timestamp(this.exp_LastTimer["current"]); + + return(t || 0); + }, + LastElapsedTime() + { + var t; + if (this.exp_LastTimer) + t = get_deltaTime(this.exp_LastTimer)/1000; + + return(t || 0); + }, + LastTimeoutInterval() + { + var t; + if (this.exp_LastTimer) + t = this.exp_LastTimer["time-out"]; + + return(t || 0); + }, + LastRemainInterval() + { + var t; + if (this.exp_LastTimer) + t = this.exp_LastTimer["time-out"] - get_deltaTime(this.exp_LastTimer)/1000; + + return(t || 0); + }, + + LastOwnerID() + { + return (this.exp_LastOwnerID); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/instance.js new file mode 100755 index 0000000..428c79e --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/instance.js @@ -0,0 +1,67 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Timer.Instance = class Rex_Firebase_TimerInstance extends C3.SDKInstanceBase + { + constructor(inst, properties) + { + super(inst); + + // Initialise object properties + this.exp_LastOwnerID = ""; + this.exp_LastTimerName = ""; + this.exp_LastTimer = null; + + if (properties) // note properties may be null in some cases + { + this.rootpath = properties[0] + "/" + properties[1] + "/"; + } + } + + Release() + { + super.Release(); + } + + SaveToJson() + { + return { + // data to be saved for savegames + }; + } + + LoadFromJson(o) + { + // load state for savegames + } + get_ref(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + } + start_timer(ref, interval, handler) + { + ref["set"](newTimerDate(interval), handler); + } + + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/plugin.js new file mode 100755 index 0000000..14784cb --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/plugin.js @@ -0,0 +1,72 @@ +"use strict"; + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + if (!obj) + return null; + + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + var newTimerDate = function (interval) + { + var t = {"start": serverTimeStamp(), + "current": serverTimeStamp(), + "time-out": interval}; + return t; + } + + var get_deltaTime = function (timer) + { + var t; + if (timer) + t = get_timestamp(timer["current"]) - get_timestamp(timer["start"]); + else + t = 0; + + return t; + } +{ + C3.Plugins.Rex_Firebase_Timer = class Rex_Firebase_TimerPlugin extends C3.SDKPluginBase + { + constructor(opts) + { + super(opts); + } + + Release() + { + super.Release(); + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/type.js new file mode 100755 index 0000000..3226a74 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/c3runtime/type.js @@ -0,0 +1,20 @@ +"use strict"; + +{ + C3.Plugins.Rex_Firebase_Timer.Type = class Rex_Firebase_TimerType extends C3.SDKTypeBase + { + constructor(objectClass) + { + super(objectClass); + } + + Release() + { + super.Release(); + } + + OnCreate() + { + } + }; +} \ No newline at end of file diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/icon.png b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/icon.png new file mode 100755 index 0000000..e2ef3f8 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/icon.png differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/instance.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/instance.js new file mode 100755 index 0000000..6b10cac --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/instance.js @@ -0,0 +1,26 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Timer; + + PLUGIN_CLASS.Instance = class Rex_Firebase_TimerInstance extends SDK.IInstanceBase + { + constructor(sdkType, inst) + { + super(sdkType, inst); + } + Release() + { + } + OnCreate() + { + } + OnPropertyChanged(id, value) + { + } + LoadC2Property(name, valueString) + { + return false; // not handled + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/lang/en-US.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/lang/en-US.json new file mode 100755 index 0000000..be59107 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/lang/en-US.json @@ -0,0 +1,177 @@ +{ + "languageTag": "en-US", + "fileDescription": "Strings for Timer.", + "text": { + "plugins": { + "rex_firebase_timer": { + "name": "Timer", + "description": "Get elapsed interval from firebase.", + "help-url": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_timer.html", + "properties": { + "domain": { + "name": "Domain", + "desc": "The root location of the Firebase data." + }, + "sub-domain": { + "name": "Sub domain", + "desc": "Sub domain for this function." + } + }, + "aceCategories": { + "domain": "Domain", + "timer": "Timer", + "on_disconnect": "On disconnect", + "start_timer": "Start timer", + "get_timer": "Get timer", + "remove_timer": "Remove timer", + "time_out": "Time out", + "valid": "Valid" + }, + "conditions": { + "onstarttimercomplete1": { + "list-name": "On start timer", + "display-text": "On start timer", + "description": "Triggered when start timer complete." + }, + "onstarttimererror2": { + "list-name": "On start timer error", + "display-text": "On start timer error", + "description": "Triggered when start timer error." + }, + "ongettimercomplete3": { + "list-name": "On get timer", + "display-text": "On get timer", + "description": "Triggered when get timer." + }, + "ongettimererror4": { + "list-name": "On get timer error", + "display-text": "On get timer error", + "description": "Triggered when get timer error." + }, + "onremovetimercomplete5": { + "list-name": "On remove timer complete", + "display-text": "On remove timer complete", + "description": "Triggered when remove timer complete." + }, + "onremovetimererror6": { + "list-name": "On remove timer error", + "display-text": "On remove timer error", + "description": "Triggered when remove timer error." + }, + "ıstimeout21": { + "list-name": "Is time-out", + "display-text": "Is time-out", + "description": "Return true if current triggered timer is time-out under \"Condition: On get timer\"." + }, + "ısvalid22": { + "list-name": "Is valid", + "display-text": "Is valid", + "description": "Return true if get valid timer." + } + }, + "actions": { + "setdomainref0": { + "list-name": "Set domain", + "display-text": "Set domain to [i]{0}[/i], sub domain to [i]{1}[/i]", + "description": "Set domain ref.", + "params": { + "domain0": { "name":"Domain", "desc":"The root location of the Firebase data."}, + "sub_domain1": { "name":"Sub domain", "desc":"Sub domain for this function."} + } + }, + "starttimer1": { + "list-name": "Start", + "display-text": "Start timer [i]{1}[/i] of user ID: [i]{0}[/i], with time-out interval to [i]{2}[/i]", + "description": "Start timer.", + "params": { + "user_ıd0": { "name":"User ID", "desc":"User ID."}, + "timer1": { "name":"Timer", "desc":"Name of timer."}, + "ınterval2": { "name":"Interval", "desc":"Time-out interval, in seconds."} + } + }, + "gettimer2": { + "list-name": "Get or start", + "display-text": "Get timer [i]{1}[/i] of user ID: [i]{0}[/i], or start timer with time-out interval to [i]{2}[/i]", + "description": "Get timer.", + "params": { + "user_ıd0": { "name":"User ID", "desc":"User ID."}, + "timer1": { "name":"Timer", "desc":"Name of timer."}, + "ınterval2": { "name":"Interval", "desc":"Time-out interval, in seconds, for starting timer."} + } + }, + "removetimer3": { + "list-name": "Remove", + "display-text": "Remove timer [i]{1}[/i] of user ID: [i]{0}[/i]", + "description": "Remove timer.", + "params": { + "user_ıd0": { "name":"User ID", "desc":"User ID."}, + "timer1": { "name":"Timer", "desc":"Name of timer."} + } + }, + "gettimer4": { + "list-name": "Get", + "display-text": "Get timer [i]{1}[/i] of user ID: [i]{0}[/i]", + "description": "Get timer.", + "params": { + "user_ıd0": { "name":"User ID", "desc":"User ID."}, + "timer1": { "name":"Timer", "desc":"Name of timer."} + } + }, + "starttimerwhendisconnect11": { + "list-name": "Start on disconnect", + "display-text": "Start timer [i]{1}[/i] of user ID: [i]{0}[/i] when disconnected, with time-out interval to [i]{2}[/i].", + "description": "Start timer when disconnected.", + "params": { + "user_ıd0": { "name":"User ID", "desc":"User ID."}, + "timer1": { "name":"Timer", "desc":"Name of timer."}, + "ınterval2": { "name":"Interval", "desc":"Time-out interval, in seconds, for starting timer."} + } + }, + "deletetimerwhendisconnect12": { + "list-name": "Delete on disconnect", + "display-text": "Delete timer [i]{1}[/i] of user ID: [i]{0}[/i] when disconnected.", + "description": "Delete timer when disconnected.", + "params": { + "user_ıd0": { "name":"User ID", "desc":"User ID."}, + "timer1": { "name":"Timer", "desc":"Name of timer."} + } + } + }, + "expressions": { + "lastuserıd1": { + "description": "Get user ID of last triggered timer", + "translated-name": "LastUserID" + }, + "lasttimername2": { + "description": "Get timer name of last triggered timer", + "translated-name": "LastTimerName" + }, + "laststarttimestamp3": { + "description": "Get start timestamp of last triggered timer under \"Condition: On get timer\".", + "translated-name": "LastStartTimestamp" + }, + "lastcurrenttimestamp4": { + "description": "Get current timestamp of last triggered timer under \"Condition: On get timer\".", + "translated-name": "LastCurrentTimestamp" + }, + "lastelapsedtime5": { + "description": "Get elapsed time (current - start) of last triggered timer under \"Condition: On get timer\", in seconds.", + "translated-name": "LastElapsedTime" + }, + "lasttimeoutınterval6": { + "description": "Get time-out interval of last triggered timer under \"Condition: On get timer\", in seconds.", + "translated-name": "LastTimeoutInterval" + }, + "lastremainınterval7": { + "description": "Get interval of last triggered timer under \"Condition: On get timer\", in seconds.", + "translated-name": "LastRemainInterval" + }, + "lastownerıd8": { + "description": "Get owner ID of last triggered timer", + "translated-name": "LastOwnerID" + } + } + } + } + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/plugin.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/plugin.js new file mode 100755 index 0000000..0f3dcee --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/plugin.js @@ -0,0 +1,42 @@ +//Converted with C2C3AddonConverter v1.0.1.0 +"use strict"; + +{ + const PLUGIN_ID = "Rex_Firebase_Timer"; + const PLUGIN_VERSION = "0.1.0.0"; + const PLUGIN_CATEGORY = "web"; + + let app = null; + + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Timer = class Rex_Firebase_Timer extends SDK.IPluginBase + { + constructor() + { + super(PLUGIN_ID); + SDK.Lang.PushContext("plugins." + PLUGIN_ID.toLowerCase()); + this._info.SetIcon("icon.png", "image/png"); + this._info.SetName(lang(".name")); + this._info.SetDescription(lang(".description")); + this._info.SetVersion(PLUGIN_VERSION); + this._info.SetCategory(PLUGIN_CATEGORY); + this._info.SetAuthor("Rex.Rainbow"); + this._info.SetHelpUrl(lang(".help-url")); + this._info.SetIsSingleGlobal(false); + this._info.SetIsDeprecated(false); + this._info.SetSupportsEffects(false); + this._info.SetMustPreDraw(false); + this._info.SetCanBeBundled(false); + + this._info.SetSupportedRuntimes(["c2","c3"]); + + SDK.Lang.PushContext(".properties"); + this._info.SetProperties([ + new SDK.PluginProperty("text", "domain", ""), + new SDK.PluginProperty("text", "sub-domain", "Timers") + ]); + SDK.Lang.PopContext(); // .properties + SDK.Lang.PopContext(); + } + }; + PLUGIN_CLASS.Register(PLUGIN_ID, PLUGIN_CLASS); +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/type.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/type.js new file mode 100755 index 0000000..5c01b0e --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_timer/source/type.js @@ -0,0 +1,13 @@ +"use strict"; + +{ + const PLUGIN_CLASS = SDK.Plugins.Rex_Firebase_Timer; + + PLUGIN_CLASS.Type = class Rex_Firebase_TimerType extends SDK.ITypeBase + { + constructor(sdkPlugin, iObjectType) + { + super(sdkPlugin, iObjectType); + } + }; +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/dist/rex_firebase_token.c3addon b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/dist/rex_firebase_token.c3addon new file mode 100644 index 0000000..764a4d5 Binary files /dev/null and b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/dist/rex_firebase_token.c3addon differ diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/source/aces.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/source/aces.json new file mode 100755 index 0000000..ff44e77 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/source/aces.json @@ -0,0 +1,86 @@ +{ + "domain": { + "conditions": [ + ], + "actions": [ + { + "c2id": 0, + "id": "setdomainref0", + "scriptName": "SetDomainRef", + "highlight": false, + "params": [ + {"id":"domain0", "type":"string", "initialValue":"\"\""}, + {"id":"sub_domain1", "type":"string", "initialValue":"\"\""} + ] + } + ], + "expressions": [ + ] + }, + "group": { + "conditions": [ + ], + "actions": [ + { + "c2id": 1, + "id": "joingroup1", + "scriptName": "JoinGroup", + "highlight": false, + "params": [ + {"id":"user_ıd0", "type":"string", "initialValue":"\"\""} + ] + }, + { + "c2id": 2, + "id": "leavegroup2", + "scriptName": "LeaveGroup", + "highlight": false + } + ], + "expressions": [ + ] + }, + "token": { + "conditions": [ + { + "c2id": 1, + "id": "ongettoken1", + "scriptName": "OnGetToken", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 2, + "id": "ontokenownerchanged2", + "scriptName": "OnTokenOwnerChanged", + "isTrigger": "true", + "highlight": false + }, + { + "c2id": 3, + "id": "ısowner3", + "scriptName": "IsOwner", + "highlight": false + }, + { + "c2id": 4, + "id": "onreleasetoken4", + "scriptName": "OnReleaseToken", + "isTrigger": "true", + "highlight": false + } + ], + "actions": [ + ], + "expressions": [ + { + "c2id": 1, + "id": "ownerıd1", + "expressionName": "OwnerID", + "scriptName": "OwnerID", + "highlight": false, + "returnType": "string" + } + ] + } +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/source/addon.json b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/source/addon.json new file mode 100755 index 0000000..e8391f5 --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/source/addon.json @@ -0,0 +1,33 @@ +{ + "is-c3-addon": true, + "type": "plugin", + "name": "Token", + "id": "Rex_Firebase_Token", + "version": "0.1.0.0", + "author": "Rex.Rainbow", + "website": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_token.html", + "documentation": "https://rexrainbow.github.io/C2RexDoc/c2rexpluginsACE/plugin_rex_firebase_token.html", + "description": "The first user of a group.", + "editor-scripts": [ + "plugin.js", + "type.js", + "instance.js" + ], + "file-list": [ + "c2runtime/runtime.js", + "c2runtime/runtime.js", + "c3runtime/plugin.js", + "c3runtime/type.js", + "c3runtime/instance.js", + "c3runtime/conditions.js", + "c3runtime/actions.js", + "c3runtime/expressions.js", + "lang/en-US.json", + "aces.json", + "addon.json", + "icon.png", + "plugin.js", + "type.js", + "instance.js" + ] +} diff --git a/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/source/c2runtime/runtime.js b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/source/c2runtime/runtime.js new file mode 100755 index 0000000..c6d878a --- /dev/null +++ b/ported_plugins/plugins/rex_firebase_pack/plugins/rex_firebase_token/source/c2runtime/runtime.js @@ -0,0 +1,359 @@ +/* + - UserID + +Push UserID into a list +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_Token = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_Token.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + this.token = new cr.plugins_.Rex_Firebase_Token.TokenKlass(this); + + var self = this; + var on_tokenOwner_changed = function () + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Token.prototype.cnds.OnTokenOwnerChanged, self); + }; + var on_get_token = function () + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Token.prototype.cnds.OnGetToken, self); + }; + var on_release_token = function () + { + self.runtime.trigger(cr.plugins_.Rex_Firebase_Token.prototype.cnds.OnReleaseToken, self); + }; + this.token.OnTokenOwnerChanged = on_tokenOwner_changed; + this.token.OnGetToken = on_get_token; + this.token.OnReleaseToken = on_release_token; + + + if (window.SuspendMgr == null) + { + window.SuspendMgr = new window.SuspendMgrKlass(this.runtime); + } + window.SuspendMgr.push(this); + }; + + instanceProto.onDestroy = function () + { + window.SuspendMgr.remove(this); + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + instanceProto.JoinGroup = function (UserID) + { + this.token.JoinGroup(UserID); + }; + + instanceProto.LeaveGroup = function () + { + this.token.LeaveGroup(); + }; + + // for window.SuspendMgr + instanceProto.OnSuspend = instanceProto.LeaveGroup; + instanceProto.OnResume = instanceProto.JoinGroup; + + ////////////////////////////////////// + // Conditions + function Cnds() {}; + pluginProto.cnds = new Cnds(); + + Cnds.prototype.OnGetToken = function () + { + return true; + }; + + Cnds.prototype.OnTokenOwnerChanged = function () + { + return true; + }; + + Cnds.prototype.IsOwner = function () + { + return (this.token.IsInGroup() && this.token.IsOwner()); + }; + + Cnds.prototype.OnReleaseToken = function () + { + return true; + }; + ////////////////////////////////////// + // Actions + function Acts() {}; + pluginProto.acts = new Acts(); + + Acts.prototype.SetDomainRef = function (domain_ref, sub_domain_ref) + { + this.LeaveGroup(); + this.rootpath = domain_ref + "/" + sub_domain_ref + "/"; + }; + + Acts.prototype.JoinGroup = function (UserID) + { + this.JoinGroup(UserID); + }; + + Acts.prototype.LeaveGroup = function () + { + this.LeaveGroup(); + }; + ////////////////////////////////////// + // Expressions + function Exps() {}; + pluginProto.exps = new Exps(); + + Exps.prototype.OwnerID = function (ret) + { + ret.set_string(this.token.ownerID); + }; +}()); + +(function () +{ + if (window.SuspendMgrKlass != null) + return; + + var SuspendMgrKlass = function(runtime) + { + this.objects = []; + this.addSuspendCallback(runtime); + }; + var SuspendMgrKlassProto = SuspendMgrKlass.prototype; + + SuspendMgrKlassProto.addSuspendCallback = function(runtime) + { + if (cr.plugins_.Rex_Waker) + return; + + var self = this; + var on_suspended = function (s) + { + var i, cnt=self.objects.length, inst; + if (s) + { + // suspended + for (i=0; i - UserID + +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_UserID2ID = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var pluginProto = cr.plugins_.Rex_Firebase_UserID2ID.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + }; + + ///////////////////////////////////// + // Instance class + pluginProto.Instance = function(type) + { + this.type = type; + this.runtime = type.runtime; + }; + + var instanceProto = pluginProto.Instance.prototype; + + instanceProto.onCreate = function() + { + this.rootpath = this.properties[0] + "/" + this.properties[1] + "/"; + + this.exp_ID = ""; + this.exp_UserID = ""; + this.error = null; + }; + + // 2.x , 3.x + var isFirebase3x = function() + { + return (window["FirebaseV3x"] === true); + }; + + var isFullPath = function (p) + { + return (p.substring(0,8) === "https://"); + }; + + instanceProto.get_ref = function(k) + { + if (k == null) + k = ""; + var path; + if (isFullPath(k)) + path = k; + else + path = this.rootpath + k + "/"; + + // 2.x + if (!isFirebase3x()) + { + return new window["Firebase"](path); + } + + // 3.x + else + { + var fnName = (isFullPath(path))? "refFromURL":"ref"; + return window["Firebase"]["database"]()[fnName](path); + } + + }; + + var get_key = function (obj) + { + return (!isFirebase3x())? obj["key"]() : obj["key"]; + }; + + var get_root = function (obj) + { + return (!isFirebase3x())? obj["root"]() : obj["root"]; + }; + + var serverTimeStamp = function () + { + if (!isFirebase3x()) + return window["Firebase"]["ServerValue"]["TIMESTAMP"]; + else + return window["Firebase"]["database"]["ServerValue"]; + }; + + var get_timestamp = function (obj) + { + return (!isFirebase3x())? obj : obj["TIMESTAMP"]; + }; + // 2.x , 3.x + + instanceProto.get_ID_ref = function(ID) + { + return this.get_ref()["child"](ID); + }; + + instanceProto.try_getID = function(UserID, ID, on_failed) + { + var ID_ref = this.get_ID_ref(ID); + var self = this; + + var on_write = function(current_value) + { + if (current_value === null) //this ID has not been occupied + return UserID; + else + return; // Abort the transaction + }; + var on_complete = function(error, committed, snapshot) + { + if (error || !committed) + { + if (on_failed) + on_failed(error); + } + else + { + // done + self.on_getID_successful(UserID, ID); + }; + }; + ID_ref["transaction"](on_write, on_complete); + }; + + instanceProto.on_getID_successful = function (UserID_, ID_) + { + this.exp_UserID = UserID_; + this.exp_ID = ID_; + this.runtime.trigger(cr.plugins_.Rex_Firebase_UserID2ID.prototype.cnds.OnRequestIDSuccessful, this); + }; + instanceProto.on_getID_failed = function (UserID_) + { + this.exp_UserID = UserID_; + this.exp_ID = ""; + this.runtime.trigger(cr.plugins_.Rex_Firebase_UserID2ID.prototype.cnds.OnRequestIDError, this); + }; + + instanceProto.on_getUserID_successful = function (UserID_, ID_) + { + this.exp_UserID = UserID_; + this.exp_ID = ID_; + this.runtime.trigger(cr.plugins_.Rex_Firebase_UserID2ID.prototype.cnds.OnRequestUserIDSuccessful, this); + }; + instanceProto.on_getUserID_failed = function (ID_) + { + this.exp_UserID = ""; + this.exp_ID = ID_; + this.runtime.trigger(cr.plugins_.Rex_Firebase_UserID2ID.prototype.cnds.OnRequestUserIDError, this); + }; + + var generate_ID = function(digits) + { + var ID = Math.floor(Math.random()*Math.pow(10, digits)).toString(); + var i, zeroes = digits - ID.length; + for (i=0; i/ + lists/ + / + + + invite/ + + inviter-id + inviter-list + my-list + message + +*/ +// ECMAScript 5 strict mode +"use strict"; + +assert2(cr, "cr namespace not created"); +assert2(cr.plugins_, "cr.plugins_ not created"); + +///////////////////////////////////// +// Plugin class +cr.plugins_.Rex_Firebase_Userlist = function(runtime) +{ + this.runtime = runtime; +}; + +(function () +{ + var input_text = ""; + var pluginProto = cr.plugins_.Rex_Firebase_Userlist.prototype; + + ///////////////////////////////////// + // Object type class + pluginProto.Type = function(plugin) + { + this.plugin = plugin; + this.runtime = plugin.runtime; + }; + + var typeProto = pluginProto.Type.prototype; + + typeProto.onCreate = function() + { + jsfile_load("firebase.js"); + }; + + var jsfile_load = function(file_name) + { + var scripts=document.getElementsByTagName("script"); + var exist=false; + for(var i=0;ib?e+="000":256>b?e+="00":4096>b&&(e+="0");return ra[a]=e+b.toString(16)}),'"')};function ta(a){return"undefined"!==typeof JSON&&m(JSON.parse)?JSON.parse(a):na(a)}function r(a){if("undefined"!==typeof JSON&&m(JSON.stringify))a=JSON.stringify(a);else{var b=[];pa(new oa,a,b);a=b.join("")}return a};function s(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function t(a,b){if(Object.prototype.hasOwnProperty.call(a,b))return a[b]}function ua(a,b){for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b(c,a[c])}function va(a){var b={};ua(a,function(a,d){b[a]=d});return b};function wa(a){this.uc=a;this.Ed="firebase:"}h=wa.prototype;h.set=function(a,b){null==b?this.uc.removeItem(this.Ed+a):this.uc.setItem(this.Ed+a,r(b))};h.get=function(a){a=this.uc.getItem(this.Ed+a);return null==a?null:ta(a)};h.remove=function(a){this.uc.removeItem(this.Ed+a)};h.lf=!1;h.toString=function(){return this.uc.toString()};function xa(){this.oc={}}xa.prototype.set=function(a,b){null==b?delete this.oc[a]:this.oc[a]=b};xa.prototype.get=function(a){return s(this.oc,a)?this.oc[a]:null};xa.prototype.remove=function(a){delete this.oc[a]};xa.prototype.lf=!0;function ya(a){try{if("undefined"!==typeof window&&"undefined"!==typeof window[a]){var b=window[a];b.setItem("firebase:sentinel","cache");b.removeItem("firebase:sentinel");return new wa(b)}}catch(c){}return new xa}var za=ya("localStorage"),v=ya("sessionStorage");function Aa(a,b,c,d,e){this.host=a.toLowerCase();this.domain=this.host.substr(this.host.indexOf(".")+1);this.Ab=b;this.tb=c;this.Dg=d;this.Dd=e||"";this.Ma=za.get("host:"+a)||this.host}function Ba(a,b){b!==a.Ma&&(a.Ma=b,"s-"===a.Ma.substr(0,2)&&za.set("host:"+a.host,a.Ma))}Aa.prototype.toString=function(){var a=(this.Ab?"https://":"http://")+this.host;this.Dd&&(a+="<"+this.Dd+">");return a};function Ca(){this.Sa=-1};function Da(){this.Sa=-1;this.Sa=64;this.R=[];this.be=[];this.Ef=[];this.Ad=[];this.Ad[0]=128;for(var a=1;ae;e++)d[e]=b.charCodeAt(c)<<24|b.charCodeAt(c+1)<<16|b.charCodeAt(c+2)<<8|b.charCodeAt(c+3),c+=4;else for(e=0;16>e;e++)d[e]=b[c]<<24|b[c+1]<<16|b[c+2]<<8|b[c+3],c+=4;for(e=16;80>e;e++){var f=d[e-3]^d[e-8]^d[e-14]^d[e-16];d[e]=(f<<1|f>>>31)&4294967295}b=a.R[0];c=a.R[1];for(var g=a.R[2],k=a.R[3],l=a.R[4],n,e=0;80>e;e++)40>e?20>e?(f=k^c&(g^k),n=1518500249):(f=c^g^k,n=1859775393):60>e?(f=c&g|k&(c|g),n=2400959708):(f=c^g^k,n=3395469782),f=(b<< +5|b>>>27)+f+l+n+d[e]&4294967295,l=k,k=g,g=(c<<30|c>>>2)&4294967295,c=b,b=f;a.R[0]=a.R[0]+b&4294967295;a.R[1]=a.R[1]+c&4294967295;a.R[2]=a.R[2]+g&4294967295;a.R[3]=a.R[3]+k&4294967295;a.R[4]=a.R[4]+l&4294967295} +Da.prototype.update=function(a,b){m(b)||(b=a.length);for(var c=b-this.Sa,d=0,e=this.be,f=this.Sb;dc?Math.max(0,a.length+c):c;if(p(a))return p(b)&&1==b.length?a.indexOf(b,c):-1;for(;cc?null:p(a)?a.charAt(c):a[c]}function Na(a,b,c){for(var d=a.length,e=p(a)?a.split(""):a,f=0;f=arguments.length?w.slice.call(a,b):w.slice.call(a,b,c)}function Qa(a,b){a.sort(b||Ra)}function Ra(a,b){return a>b?1:aparseFloat(a))?String(b):a})();var $a=null,ab=null,bb=null;function cb(a,b){if(!fa(a))throw Error("encodeByteArray takes an array as a parameter");db();for(var c=b?ab:$a,d=[],e=0;e>2,f=(f&3)<<4|k>>4,k=(k&15)<<2|n>>6,n=n&63;l||(n=64,g||(k=64));d.push(c[u],c[f],c[k],c[n])}return d.join("")} +function db(){if(!$a){$a={};ab={};bb={};for(var a=0;65>a;a++)$a[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a),ab[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.".charAt(a),bb[ab[a]]=a}};var eb=function(){var a=1;return function(){return a++}}();function y(a,b){if(!a)throw fb(b);}function fb(a){return Error("Firebase INTERNAL ASSERT FAILED:"+a)} +function gb(a){try{var b;if("undefined"!==typeof atob)b=atob(a);else{db();for(var c=bb,d=[],e=0;e>4);64!=k&&(d.push(g<<4&240|k>>2),64!=l&&d.push(k<<6&192|l))}if(8192>d.length)b=String.fromCharCode.apply(null,d);else{a="";for(c=0;ca.Sb?a.update(a.Ad,56-a.Sb):a.update(a.Ad,a.Sa-(a.Sb-56));for(var d=a.Sa-1;56<=d;d--)a.be[d]=c&255,c/=256;Ea(a,a.be);for(d=c=0;5>d;d++)for(var e=24;0<=e;e-=8)b[c]=a.R[d]>>e&255,++c;return cb(b)} +function kb(a){for(var b="",c=0;ca?c.push(a.substring(d,a.length)):c.push(a.substring(d,d+b));return c}function zb(a,b){if(ea(a))for(var c=0;ca,a=Math.abs(a),a>=Math.pow(2,-1022)?(d=Math.min(Math.floor(Math.log(a)/Math.LN2),1023),c=d+1023,d=Math.round(a*Math.pow(2,52-d)-Math.pow(2,52))):(c=0,d=Math.round(a/Math.pow(2,-1074))));e=[];for(a=52;a;a-=1)e.push(d%2?1:0),d=Math.floor(d/2);for(a=11;a;a-=1)e.push(c%2?1:0),c=Math.floor(c/2);e.push(b?1:0);e.reverse();b=e.join("");c="";for(a=0;64>a;a+=8)d=parseInt(b.substr(a,8),2).toString(16),1===d.length&& +(d="0"+d),c+=d;return c.toLowerCase()}var Bb=/^-?\d{1,10}$/;function vb(a){return Bb.test(a)&&(a=Number(a),-2147483648<=a&&2147483647>=a)?a:null}function Cb(a){try{a()}catch(b){setTimeout(function(){z("Exception was thrown by user callback.",b.stack||"");throw b;},Math.floor(0))}}function B(a,b){if(ha(a)){var c=Array.prototype.slice.call(arguments,1).slice();Cb(function(){a.apply(null,c)})}};function Db(a,b,c,d){this.le=b;this.Nd=c;this.Fd=d;this.jd=a}Db.prototype.Qb=function(){var a=this.Nd.cc();return"value"===this.jd?a.path:a.parent().path};Db.prototype.pe=function(){return this.jd};Db.prototype.Lb=function(){return this.le.Lb(this)};Db.prototype.toString=function(){return this.Qb().toString()+":"+this.jd+":"+r(this.Nd.bf())};function Eb(a,b,c){this.le=a;this.error=b;this.path=c}Eb.prototype.Qb=function(){return this.path};Eb.prototype.pe=function(){return"cancel"}; +Eb.prototype.Lb=function(){return this.le.Lb(this)};Eb.prototype.toString=function(){return this.path.toString()+":cancel"};function C(a,b,c,d){this.type=a;this.Ha=b;this.Ua=c;this.De=d;this.Fd=void 0}function Fb(a){return new C(Gb,a)}var Gb="value";function Hb(a,b,c){this.Hb=a;this.kb=b;this.mb=c||null}h=Hb.prototype;h.wf=function(a){return"value"===a};h.createEvent=function(a,b){var c=b.n.g;return new Db("value",this,new D(a.Ha,b.cc(),c))};h.Lb=function(a){var b=this.mb;if("cancel"===a.pe()){y(this.kb,"Raising a cancel event on a listener with no cancel callback");var c=this.kb;return function(){c.call(b,a.error)}}var d=this.Hb;return function(){d.call(b,a.Nd)}};h.Ye=function(a,b){return this.kb?new Eb(this,a,b):null}; +h.matches=function(a){return a instanceof Hb?a.Hb&&this.Hb?a.Hb===this.Hb&&a.mb===this.mb:!0:!1};h.hf=function(){return null!==this.Hb};function Ib(a,b,c){this.da=a;this.kb=b;this.mb=c}h=Ib.prototype;h.wf=function(a){a="children_added"===a?"child_added":a;return("children_removed"===a?"child_removed":a)in this.da};h.Ye=function(a,b){return this.kb?new Eb(this,a,b):null}; +h.createEvent=function(a,b){y(null!=a.Ua,"Child events should have a childName.");var c=b.cc().o(a.Ua);return new Db(a.type,this,new D(a.Ha,c,b.n.g),a.Fd)};h.Lb=function(a){var b=this.mb;if("cancel"===a.pe()){y(this.kb,"Raising a cancel event on a listener with no cancel callback");var c=this.kb;return function(){c.call(b,a.error)}}var d=this.da[a.jd];return function(){d.call(b,a.Nd,a.Fd)}}; +h.matches=function(a){if(a instanceof Ib){if(!this.da||!a.da)return!0;if(this.mb===a.mb){var b=Jb(a.da);if(b===Jb(this.da)){if(1===b){var b=Kb(a.da),c=Kb(this.da);return c===b&&(!a.da[b]||!this.da[c]||a.da[b]===this.da[c])}return Lb(this.da,function(b,c){return a.da[c]===b})}}}return!1};h.hf=function(){return null!==this.da};function jb(a){for(var b=[],c=0,d=0;d=e&&(e-=55296,d++,y(de?b[c++]=e:(2048>e?b[c++]=e>>6|192:(65536>e?b[c++]=e>>12|224:(b[c++]=e>>18|240,b[c++]=e>>12&63|128),b[c++]=e>>6&63|128),b[c++]=e&63|128)}return b};function F(a,b,c,d){var e;dc&&(e=0===c?"none":"no more than "+c);if(e)throw Error(a+" failed: Was called with "+d+(1===d?" argument.":" arguments.")+" Expects "+e+".");}function G(a,b,c){var d="";switch(b){case 1:d=c?"first":"First";break;case 2:d=c?"second":"Second";break;case 3:d=c?"third":"Third";break;case 4:d=c?"fourth":"Fourth";break;default:throw Error("errorPrefix called with argumentNumber > 4. Need to update it?");}return a=a+" failed: "+(d+" argument ")} +function H(a,b,c,d){if((!d||m(c))&&!ha(c))throw Error(G(a,b,d)+"must be a valid function.");}function Mb(a,b,c){if(m(c)&&(!ia(c)||null===c))throw Error(G(a,b,!0)+"must be a valid context object.");};var Nb=/[\[\].#$\/\u0000-\u001F\u007F]/,Ob=/[\[\].#$\u0000-\u001F\u007F]/;function Pb(a){return p(a)&&0!==a.length&&!Nb.test(a)}function Qb(a){return null===a||p(a)||ga(a)&&!sb(a)||ia(a)&&s(a,".sv")}function Rb(a,b,c){c&&!m(b)||Sb(G(a,1,c),b)} +function Sb(a,b,c,d){c||(c=0);var e=d||[];if(!m(b))throw Error(a+"contains undefined"+Tb(e));if(ha(b))throw Error(a+"contains a function"+Tb(e)+" with contents: "+b.toString());if(sb(b))throw Error(a+"contains "+b.toString()+Tb(e));if(1E310485760/3&&10485760=this.g.compare(this.Vc,a)&&0>=this.g.compare(a,this.wc)};h.C=function(a,b,c,d,e){this.matches(new N(b,c))||(c=M);return this.re.C(a,b,c,d,e)};h.oa=function(a,b,c){b.M()&&(b=M);var d=b.Fb(this.g),d=d.Z(M),e=this;b.U(L,function(a,b){e.matches(new N(a,b))||(d=d.P(a,M))});return this.re.oa(a,d,c)}; +h.Z=function(a){return a};h.ya=function(){return!0};h.Mb=function(){return this.re};function ic(a,b){return ub(a.name,b.name)}function jc(a,b){return ub(a,b)};function kc(){}var lc={};function mc(a){return q(a.compare,a)}kc.prototype.jf=function(a,b){return 0!==this.compare(new N("[MIN_NAME]",a),new N("[MIN_NAME]",b))};kc.prototype.Ce=function(){return nc};function oc(a){this.Ub=a}ma(oc,kc);h=oc.prototype;h.ue=function(a){return!a.K(this.Ub).e()};h.compare=function(a,b){var c=a.Y.K(this.Ub),d=b.Y.K(this.Ub),c=c.he(d);return 0===c?ub(a.name,b.name):c};h.Ae=function(a,b){var c=O(a),c=M.P(this.Ub,c);return new N(b,c)}; +h.Be=function(){var a=M.P(this.Ub,pc);return new N("[MAX_NAME]",a)};h.toString=function(){return this.Ub};var L=new oc(".priority");function qc(){}ma(qc,kc);h=qc.prototype;h.compare=function(a,b){return ub(a.name,b.name)};h.ue=function(){throw fb("KeyIndex.isDefinedOn not expected to be called.");};h.jf=function(){return!1};h.Ce=function(){return nc};h.Be=function(){return new N("[MAX_NAME]",M)};h.Ae=function(a){y(p(a),"KeyIndex indexValue must always be a string.");return new N(a,M)}; +h.toString=function(){return".key"};var rc=new qc;function sc(){}sc.prototype.ef=function(){return null};sc.prototype.oe=function(){return null};var tc=new sc;function uc(a,b,c){this.Bf=a;this.Ia=b;this.zd=c}uc.prototype.ef=function(a){var b=this.Ia.F;if(vc(b,a))return b.j().K(a);b=null!=this.zd?new wc(this.zd,!0,!1):this.Ia.u();return this.Bf.Ta(a,b)};uc.prototype.oe=function(a,b,c){var d=null!=this.zd?this.zd:xc(this.Ia);a=this.Bf.ce(d,b,1,c,a);return 0===a.length?null:a[0]};function yc(){this.Za={}} +function cc(a,b){var c=b.type,d=b.Ua;y("child_added"==c||"child_changed"==c||"child_removed"==c,"Only child changes supported for tracking");y(".priority"!==d,"Only non-priority child changes can be tracked.");var e=t(a.Za,d);if(e){var f=e.type;if("child_added"==c&&"child_removed"==f)a.Za[d]=new C("child_changed",b.Ha,d,e.Ha);else if("child_removed"==c&&"child_added"==f)delete a.Za[d];else if("child_removed"==c&&"child_changed"==f)a.Za[d]=new C("child_removed",e.De,d);else if("child_changed"==c&& +"child_added"==f)a.Za[d]=new C("child_added",b.Ha,d);else if("child_changed"==c&&"child_changed"==f)a.Za[d]=new C("child_changed",b.Ha,d,e.De);else throw fb("Illegal combination of changes: "+b+" occurred after "+e);}else a.Za[d]=b};function N(a,b){this.name=a;this.Y=b}function zc(a,b){return new N(a,b)};function Ac(a){this.ma=new dc(a);this.g=a.g;y(a.ka,"Only valid if limit has been set");this.sa=a.sa;this.zb=!(""===a.Eb?a.ia:"l"===a.Eb)}h=Ac.prototype;h.C=function(a,b,c,d,e){this.ma.matches(new N(b,c))||(c=M);return a.K(b).ea(c)?a:a.ub()=this.g.compare(this.ma.Vc,f):0>=this.g.compare(f,this.ma.wc))d=d.P(f.name,f.Y),e++;else break}}else{d=b.Fb(this.g);d=d.Z(M);var k,l,n;if(this.zb){b=d.gf(this.g);k=this.ma.wc;l=this.ma.Vc;var u=mc(this.g);n=function(a,b){return u(b,a)}}else b=d.Ob(this.g),k=this.ma.Vc, +l=this.ma.wc,n=mc(this.g);for(var e=0,x=!1;0=n(k,f)&&(x=!0),(g=x&&e=n(f,l))?e++:d=d.P(f.name,M)}return this.ma.Mb().oa(a,d,c)};h.Z=function(a){return a};h.ya=function(){return!0};h.Mb=function(){return this.ma.Mb()}; +function Bc(a,b,c,d,e,f){var g;if(a.zb){var k=mc(a.g);g=function(a,b){return k(b,a)}}else g=mc(a.g);y(b.ub()==a.sa,"");var l=new N(c,d),n=a.zb?Cc(b,a.g):Dc(b,a.g),u=a.ma.matches(l);if(b.Da(c)){var x=b.K(c),n=e.oe(a.g,n,a.zb);null!=n&&n.name==c&&(n=e.oe(a.g,n,a.zb));e=null==n?1:g(n,l);if(u&&!d.e()&&0<=e)return null!=f&&cc(f,new C("child_changed",d,c,x)),b.P(c,d);null!=f&&cc(f,new C("child_removed",x,c));b=b.P(c,M);return null!=n&&a.ma.matches(n)?(null!=f&&cc(f,new C("child_added",n.Y,n.name)),b.P(n.name, +n.Y)):b}return d.e()?b:u&&0<=g(n,l)?(null!=f&&(cc(f,new C("child_removed",n.Y,n.name)),cc(f,new C("child_added",d,c))),b.P(c,d).P(n.name,M)):b};function Ec(){this.vc=this.qa=this.kc=this.ia=this.ka=!1;this.sa=0;this.Eb="";this.Ac=null;this.Wb="";this.zc=null;this.Tb="";this.g=L}var Fc=new Ec;function fc(a){y(a.ia,"Only valid if start has been set");return a.Ac}function ec(a){y(a.ia,"Only valid if start has been set");return a.kc?a.Wb:"[MIN_NAME]"}function hc(a){y(a.qa,"Only valid if end has been set");return a.zc}function gc(a){y(a.qa,"Only valid if end has been set");return a.vc?a.Tb:"[MAX_NAME]"} +function Gc(a){var b=new Ec;b.ka=a.ka;b.sa=a.sa;b.ia=a.ia;b.Ac=a.Ac;b.kc=a.kc;b.Wb=a.Wb;b.qa=a.qa;b.zc=a.zc;b.vc=a.vc;b.Tb=a.Tb;b.g=a.g;return b}h=Ec.prototype;h.xe=function(a){var b=Gc(this);b.ka=!0;b.sa=a;b.Eb="";return b};h.ye=function(a){var b=Gc(this);b.ka=!0;b.sa=a;b.Eb="l";return b};h.ze=function(a){var b=Gc(this);b.ka=!0;b.sa=a;b.Eb="r";return b};h.Od=function(a,b){var c=Gc(this);c.ia=!0;m(a)||(a=null);c.Ac=a;null!=b?(c.kc=!0,c.Wb=b):(c.kc=!1,c.Wb="");return c}; +h.hd=function(a,b){var c=Gc(this);c.qa=!0;m(a)||(a=null);c.zc=a;m(b)?(c.vc=!0,c.Tb=b):(c.Ig=!1,c.Tb="");return c};function Hc(a,b){var c=Gc(a);c.g=b;return c}function Ic(a){var b={};a.ia&&(b.sp=a.Ac,a.kc&&(b.sn=a.Wb));a.qa&&(b.ep=a.zc,a.vc&&(b.en=a.Tb));if(a.ka){b.l=a.sa;var c=a.Eb;""===c&&(c=a.ia?"l":"r");b.vf=c}a.g!==L&&(b.i=a.g.toString());return b}function Jc(a){return!(a.ia||a.qa||a.ka)}h.toString=function(){return r(Ic(this))};function Q(a,b,c,d){this.k=a;this.path=b;this.n=c;this.ac=d} +function Kc(a){var b=null,c=null;a.ia&&(b=fc(a));a.qa&&(c=hc(a));if(a.g===rc){if(a.ia){if("[MIN_NAME]"!=ec(a))throw Error("Query: When ordering by key, you may only pass one argument to startAt(), endAt(), or equalTo().");if(null!=b&&"string"!==typeof b)throw Error("Query: When ordering by key, the argument passed to startAt(), endAt(),or equalTo() must be a string.");}if(a.qa){if("[MAX_NAME]"!=gc(a))throw Error("Query: When ordering by key, you may only pass one argument to startAt(), endAt(), or equalTo().");if(null!= +c&&"string"!==typeof c)throw Error("Query: When ordering by key, the argument passed to startAt(), endAt(),or equalTo() must be a string.");}}else if(a.g===L){if(null!=b&&!Qb(b)||null!=c&&!Qb(c))throw Error("Query: When ordering by priority, the first argument passed to startAt(), endAt(), or equalTo() must be a valid priority value (null, a number, or a string).");}else if(y(a.g instanceof oc,"unknown index type."),null!=b&&"object"===typeof b||null!=c&&"object"===typeof c)throw Error("Query: First argument passed to startAt(), endAt(), or equalTo() cannot be an object."); +}function Lc(a){if(a.ia&&a.qa&&a.ka&&(!a.ka||""===a.Eb))throw Error("Query: Can't combine startAt(), endAt(), and limit(). Use limitToFirst() or limitToLast() instead.");}function Mc(a,b){if(!0===a.ac)throw Error(b+": You can't combine multiple orderBy calls.");}Q.prototype.cc=function(){F("Query.ref",0,0,arguments.length);return new R(this.k,this.path)};Q.prototype.ref=Q.prototype.cc; +Q.prototype.vb=function(a,b,c,d){F("Query.on",2,4,arguments.length);Wb("Query.on",a,!1);H("Query.on",2,b,!1);var e=Nc("Query.on",c,d);if("value"===a)Oc(this.k,this,new Hb(b,e.cancel||null,e.Ka||null));else{var f={};f[a]=b;Oc(this.k,this,new Ib(f,e.cancel,e.Ka))}return b};Q.prototype.on=Q.prototype.vb; +Q.prototype.Zb=function(a,b,c){F("Query.off",0,3,arguments.length);Wb("Query.off",a,!0);H("Query.off",2,b,!0);Mb("Query.off",3,c);var d=null,e=null;"value"===a?d=new Hb(b||null,null,c||null):a&&(b&&(e={},e[a]=b),d=new Ib(e,null,c||null));e=this.k;d=".info"===I(this.path)?e.qd.gb(this,d):e.N.gb(this,d);Pc(e.$,this.path,d)};Q.prototype.off=Q.prototype.Zb; +Q.prototype.lg=function(a,b){function c(g){f&&(f=!1,e.Zb(a,c),b.call(d.Ka,g))}F("Query.once",2,4,arguments.length);Wb("Query.once",a,!1);H("Query.once",2,b,!1);var d=Nc("Query.once",arguments[2],arguments[3]),e=this,f=!0;this.vb(a,c,function(b){e.Zb(a,c);d.cancel&&d.cancel.call(d.Ka,b)})};Q.prototype.once=Q.prototype.lg; +Q.prototype.xe=function(a){z("Query.limit() being deprecated. Please use Query.limitToFirst() or Query.limitToLast() instead.");F("Query.limit",1,1,arguments.length);if(!ga(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limit: First argument must be a positive integer.");if(this.n.ka)throw Error("Query.limit: Limit was already set (by another call to limit, limitToFirst, orlimitToLast.");var b=this.n.xe(a);Lc(b);return new Q(this.k,this.path,b,this.ac)};Q.prototype.limit=Q.prototype.xe; +Q.prototype.ye=function(a){F("Query.limitToFirst",1,1,arguments.length);if(!ga(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limitToFirst: First argument must be a positive integer.");if(this.n.ka)throw Error("Query.limitToFirst: Limit was already set (by another call to limit, limitToFirst, or limitToLast).");return new Q(this.k,this.path,this.n.ye(a),this.ac)};Q.prototype.limitToFirst=Q.prototype.ye; +Q.prototype.ze=function(a){F("Query.limitToLast",1,1,arguments.length);if(!ga(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limitToLast: First argument must be a positive integer.");if(this.n.ka)throw Error("Query.limitToLast: Limit was already set (by another call to limit, limitToFirst, or limitToLast).");return new Q(this.k,this.path,this.n.ze(a),this.ac)};Q.prototype.limitToLast=Q.prototype.ze; +Q.prototype.mg=function(a){F("Query.orderByChild",1,1,arguments.length);if("$key"===a)throw Error('Query.orderByChild: "$key" is invalid. Use Query.orderByKey() instead.');if("$priority"===a)throw Error('Query.orderByChild: "$priority" is invalid. Use Query.orderByPriority() instead.');Xb("Query.orderByChild",1,a,!1);Mc(this,"Query.orderByChild");var b=Hc(this.n,new oc(a));Kc(b);return new Q(this.k,this.path,b,!0)};Q.prototype.orderByChild=Q.prototype.mg; +Q.prototype.ng=function(){F("Query.orderByKey",0,0,arguments.length);Mc(this,"Query.orderByKey");var a=Hc(this.n,rc);Kc(a);return new Q(this.k,this.path,a,!0)};Q.prototype.orderByKey=Q.prototype.ng;Q.prototype.og=function(){F("Query.orderByPriority",0,0,arguments.length);Mc(this,"Query.orderByPriority");var a=Hc(this.n,L);Kc(a);return new Q(this.k,this.path,a,!0)};Q.prototype.orderByPriority=Q.prototype.og; +Q.prototype.Od=function(a,b){F("Query.startAt",0,2,arguments.length);Rb("Query.startAt",a,!0);Xb("Query.startAt",2,b,!0);var c=this.n.Od(a,b);Lc(c);Kc(c);if(this.n.ia)throw Error("Query.startAt: Starting point was already set (by another call to startAt or equalTo).");m(a)||(b=a=null);return new Q(this.k,this.path,c,this.ac)};Q.prototype.startAt=Q.prototype.Od; +Q.prototype.hd=function(a,b){F("Query.endAt",0,2,arguments.length);Rb("Query.endAt",a,!0);Xb("Query.endAt",2,b,!0);var c=this.n.hd(a,b);Lc(c);Kc(c);if(this.n.qa)throw Error("Query.endAt: Ending point was already set (by another call to endAt or equalTo).");return new Q(this.k,this.path,c,this.ac)};Q.prototype.endAt=Q.prototype.hd; +Q.prototype.Tf=function(a,b){F("Query.equalTo",1,2,arguments.length);Rb("Query.equalTo",a,!1);Xb("Query.equalTo",2,b,!0);if(this.n.ia)throw Error("Query.equalTo: Starting point was already set (by another call to endAt or equalTo).");if(this.n.qa)throw Error("Query.equalTo: Ending point was already set (by another call to endAt or equalTo).");return this.Od(a,b).hd(a,b)};Q.prototype.equalTo=Q.prototype.Tf;Q.prototype.Fa=function(){var a=xb(Ic(this.n));return"{}"===a?"default":a}; +function Nc(a,b,c){var d={cancel:null,Ka:null};if(b&&c)d.cancel=b,H(a,3,d.cancel,!0),d.Ka=c,Mb(a,4,d.Ka);else if(b)if("object"===typeof b&&null!==b)d.Ka=b;else if("function"===typeof b)d.cancel=b;else throw Error(G(a,3,!0)+" must either be a cancel callback or a context object.");return d};function S(a,b){if(1==arguments.length){this.w=a.split("/");for(var c=0,d=0;d=a.w.length?null:a.w[a.ca]}function Qc(a){return a.w.length-a.ca}function T(a){var b=a.ca;b=this.w.length)return null;for(var a=[],b=this.ca;b=this.w.length};var U=new S("");function V(a,b){var c=I(a);if(null===c)return b;if(c===I(b))return V(T(a),T(b));throw Error("INTERNAL ERROR: innerPath ("+b+") is not within outerPath ("+a+")");} +S.prototype.ea=function(a){if(Qc(this)!==Qc(a))return!1;for(var b=this.ca,c=a.ca;b<=this.w.length;b++,c++)if(this.w[b]!==a.w[c])return!1;return!0};S.prototype.contains=function(a){var b=this.ca,c=a.ca;if(Qc(this)>Qc(a))return!1;for(;bb?c=c.left:0c?d=d.left:0e)a=this.ve?a.left:a.right;else if(0===e){this.Na.push(a);break}else this.Na.push(a),a=this.ve?a.right:a.left} +function P(a){if(0===a.Na.length)return null;var b=a.Na.pop(),c;c=a.Id?a.Id(b.key,b.value):{key:b.key,value:b.value};if(a.ve)for(b=b.left;!b.e();)a.Na.push(b),b=b.right;else for(b=b.right;!b.e();)a.Na.push(b),b=b.left;return c}function cd(a){if(0===a.Na.length)return null;var b;b=a.Na;b=b[b.length-1];return a.Id?a.Id(b.key,b.value):{key:b.key,value:b.value}}function dd(a,b,c,d,e){this.key=a;this.value=b;this.color=null!=c?c:!0;this.left=null!=d?d:$c;this.right=null!=e?e:$c}h=dd.prototype; +h.X=function(a,b,c,d,e){return new dd(null!=a?a:this.key,null!=b?b:this.value,null!=c?c:this.color,null!=d?d:this.left,null!=e?e:this.right)};h.count=function(){return this.left.count()+1+this.right.count()};h.e=function(){return!1};h.fa=function(a){return this.left.fa(a)||a(this.key,this.value)||this.right.fa(a)};function ed(a){return a.left.e()?a:ed(a.left)}h.Ic=function(){return ed(this).key};h.Xb=function(){return this.right.e()?this.key:this.right.Xb()}; +h.La=function(a,b,c){var d,e;e=this;d=c(a,e.key);e=0>d?e.X(null,null,null,e.left.La(a,b,c),null):0===d?e.X(null,b,null,null,null):e.X(null,null,null,null,e.right.La(a,b,c));return fd(e)};function gd(a){if(a.left.e())return $c;a.left.ba()||a.left.left.ba()||(a=hd(a));a=a.X(null,null,null,gd(a.left),null);return fd(a)} +h.remove=function(a,b){var c,d;c=this;if(0>b(a,c.key))c.left.e()||c.left.ba()||c.left.left.ba()||(c=hd(c)),c=c.X(null,null,null,c.left.remove(a,b),null);else{c.left.ba()&&(c=jd(c));c.right.e()||c.right.ba()||c.right.left.ba()||(c=kd(c),c.left.left.ba()&&(c=jd(c),c=kd(c)));if(0===b(a,c.key)){if(c.right.e())return $c;d=ed(c.right);c=c.X(d.key,d.value,null,null,gd(c.right))}c=c.X(null,null,null,null,c.right.remove(a,b))}return fd(c)};h.ba=function(){return this.color}; +function fd(a){a.right.ba()&&!a.left.ba()&&(a=ld(a));a.left.ba()&&a.left.left.ba()&&(a=jd(a));a.left.ba()&&a.right.ba()&&(a=kd(a));return a}function hd(a){a=kd(a);a.right.left.ba()&&(a=a.X(null,null,null,null,jd(a.right)),a=ld(a),a=kd(a));return a}function ld(a){return a.right.X(null,null,a.color,a.X(null,null,!0,null,a.right.left),null)}function jd(a){return a.left.X(null,null,a.color,null,a.X(null,null,!0,a.left.right,null))} +function kd(a){return a.X(null,null,!a.color,a.left.X(null,null,!a.left.color,null,null),a.right.X(null,null,!a.right.color,null,null))}function md(){}h=md.prototype;h.X=function(){return this};h.La=function(a,b){return new dd(a,b,null)};h.remove=function(){return this};h.count=function(){return 0};h.e=function(){return!0};h.fa=function(){return!1};h.Ic=function(){return null};h.Xb=function(){return null};h.ba=function(){return!1};var $c=new md;function nd(a,b){this.D=a;y(m(this.D)&&null!==this.D,"LeafNode shouldn't be created with null/undefined value.");this.ha=b||M;od(this.ha);this.sb=null}h=nd.prototype;h.M=function(){return!0};h.L=function(){return this.ha};h.Z=function(a){return new nd(this.D,a)};h.K=function(a){return".priority"===a?this.ha:M};h.ra=function(a){return a.e()?this:".priority"===I(a)?this.ha:M};h.Da=function(){return!1};h.ff=function(){return null}; +h.P=function(a,b){return".priority"===a?this.Z(b):b.e()&&".priority"!==a?this:M.P(a,b).Z(this.ha)};h.C=function(a,b){var c=I(a);if(null===c)return b;if(b.e()&&".priority"!==c)return this;y(".priority"!==c||1===Qc(a),".priority must be the last token in a path");return this.P(c,M.C(T(a),b))};h.e=function(){return!1};h.ub=function(){return 0};h.I=function(a){return a&&!this.L().e()?{".value":this.za(),".priority":this.L().I()}:this.za()}; +h.hash=function(){if(null===this.sb){var a="";this.ha.e()||(a+="priority:"+pd(this.ha.I())+":");var b=typeof this.D,a=a+(b+":"),a="number"===b?a+Ab(this.D):a+this.D;this.sb=ib(a)}return this.sb};h.za=function(){return this.D};h.he=function(a){if(a===M)return 1;if(a instanceof W)return-1;y(a.M(),"Unknown node type");var b=typeof a.D,c=typeof this.D,d=Ga(qd,b),e=Ga(qd,c);y(0<=d,"Unknown leaf type: "+b);y(0<=e,"Unknown leaf type: "+c);return d===e?"object"===c?0:this.Db.compare(d,a);)P(c),d=cd(c);return c};h.gf=function(a){return this.Rb(a.Be(),a)};h.Rb=function(a,b){var c=yd(this,b);if(c)return c.Rb(a,function(a){return a});for(var c=this.m.Rb(a.name,zc),d=cd(c);null!=d&&0=a.length){var b=Number(a);if(!isNaN(b)){e.Te=b;e.frames=[];a=null;break a}}e.Te=1;e.frames=[]}null!==a&&ce(e,a)}};this.ta.onerror=function(a){e.f("WebSocket error. Closing connection.");(a=a.message||a.data)&&e.f(a);e.eb()}};$d.prototype.start=function(){}; +$d.isAvailable=function(){var a=!1;if("undefined"!==typeof navigator&&navigator.userAgent){var b=navigator.userAgent.match(/Android ([0-9]{0,}\.[0-9]{0,})/);b&&1parseFloat(b[1])&&(a=!0)}return!a&&null!==Zd&&!ae};$d.responsesRequiredToBeHealthy=2;$d.healthyTimeout=3E4;h=$d.prototype;h.sd=function(){za.remove("previous_websocket_failure")};function ce(a,b){a.frames.push(b);if(a.frames.length==a.Te){var c=a.frames.join("");a.frames=null;c=ta(c);a.hg(c)}} +h.send=function(a){be(this);a=r(a);this.jb+=a.length;Sd(this.Ra,"bytes_sent",a.length);a=yb(a,16384);1document.domain="'+document.domain+'";\x3c/script>');a=""+a+"";try{this.Ba.ab.open(),this.Ba.ab.write(a),this.Ba.ab.close()}catch(f){hb("frame writing exception"),f.stack&&hb(f.stack),hb(f)}} +le.prototype.close=function(){this.ae=!1;if(this.Ba){this.Ba.ab.body.innerHTML="";var a=this;setTimeout(function(){null!==a.Ba&&(document.body.removeChild(a.Ba),a.Ba=null)},Math.floor(0))}var b=this.fb;b&&(this.fb=null,b())}; +function oe(a){if(a.ae&&a.Kd&&a.Ie.count()<(0=a.Qc[0].af.length+30+c.length){var e=a.Qc.shift(),c=c+"&seg"+d+"="+e.tg+"&ts"+d+"="+e.Bg+"&d"+d+"="+e.af;d++}else break;pe(a,b+c,a.ke);return!0}return!1}function pe(a,b,c){function d(){a.Ie.remove(c);oe(a)}a.Ie.add(c);var e=setTimeout(d,Math.floor(25E3));ne(a,b,function(){clearTimeout(e);d()})} +function ne(a,b,c){setTimeout(function(){try{if(a.Kd){var d=a.Ba.ab.createElement("script");d.type="text/javascript";d.async=!0;d.src=b;d.onload=d.onreadystatechange=function(){var a=d.readyState;a&&"loaded"!==a&&"complete"!==a||(d.onload=d.onreadystatechange=null,d.parentNode&&d.parentNode.removeChild(d),c())};d.onerror=function(){hb("Long-poll script failed to load: "+b);a.Kd=!1;a.close()};a.Ba.ab.body.appendChild(d)}}catch(e){}},Math.floor(1))};function qe(a){re(this,a)}var se=[ie,$d];function re(a,b){var c=$d&&$d.isAvailable(),d=c&&!(za.lf||!0===za.get("previous_websocket_failure"));b.Dg&&(c||z("wss:// URL used, but browser isn't known to support websockets. Trying anyway."),d=!0);if(d)a.Xc=[$d];else{var e=a.Xc=[];zb(se,function(a,b){b&&b.isAvailable()&&e.push(b)})}}function te(a){if(0=a.yf?(a.f("Secondary connection is healthy."),a.rb=!0,a.B.sd(),a.B.start(),a.f("sending client ack on secondary"),a.B.send({t:"c",d:{t:"a",d:{}}}),a.f("Ending transmission on primary"),a.J.send({t:"c",d:{t:"n",d:{}}}),a.Yc=a.B,Ae(a)):(a.f("sending ping on secondary."),a.B.send({t:"c",d:{t:"p",d:{}}}))}ue.prototype.xd=function(a){Ce(this);this.$b(a)};function Ce(a){a.rb||(a.Ke--,0>=a.Ke&&(a.f("Primary connection is healthy."),a.rb=!0,a.J.sd()))} +function ze(a,b){a.B=new b("c:"+a.id+":"+a.Xe++,a.O,a.Md);a.yf=b.responsesRequiredToBeHealthy||0;a.B.open(we(a,a.B),xe(a,a.B));setTimeout(function(){a.B&&(a.f("Timed out trying to upgrade."),a.B.close())},Math.floor(6E4))}function ye(a,b,c){a.f("Realtime connection established.");a.J=b;a.Qa=1;a.Kc&&(a.Kc(c),a.Kc=null);0===a.Ke?(a.f("Primary connection is healthy."),a.rb=!0):setTimeout(function(){De(a)},Math.floor(5E3))} +function De(a){a.rb||1!==a.Qa||(a.f("sending ping on primary."),Fe(a,{t:"c",d:{t:"p",d:{}}}))}function Fe(a,b){if(1!==a.Qa)throw"Connection is not connected";a.Yc.send(b)}ue.prototype.close=function(){2!==this.Qa&&(this.f("Closing realtime connection."),this.Qa=2,Be(this),this.ga&&(this.ga(),this.ga=null))};function Be(a){a.f("Shutting down all connections");a.J&&(a.J.close(),a.J=null);a.B&&(a.B.close(),a.B=null);a.nd&&(clearTimeout(a.nd),a.nd=null)};function Ge(a){var b={},c={},d={},e="";try{var f=a.split("."),b=ta(gb(f[0])||""),c=ta(gb(f[1])||""),e=f[2],d=c.d||{};delete c.d}catch(g){}return{Gg:b,fe:c,data:d,xg:e}}function He(a){a=Ge(a).fe;return"object"===typeof a&&a.hasOwnProperty("iat")?t(a,"iat"):null}function Ie(a){a=Ge(a);var b=a.fe;return!!a.xg&&!!b&&"object"===typeof b&&b.hasOwnProperty("iat")};function Je(a,b,c,d){this.id=Ke++;this.f=ob("p:"+this.id+":");this.Cb=!0;this.Aa={};this.la=[];this.Nc=0;this.Jc=[];this.ja=!1;this.Wa=1E3;this.td=3E5;this.yd=b;this.wd=c;this.He=d;this.O=a;this.Oe=null;this.Sc={};this.sg=0;this.Dc=this.we=null;Le(this,0);Hd.Nb().vb("visible",this.kg,this);-1===a.host.indexOf("fblocal")&&Id.Nb().vb("online",this.ig,this)}var Ke=0,Me=0;h=Je.prototype; +h.Ca=function(a,b,c){var d=++this.sg;a={r:d,a:a,b:b};this.f(r(a));y(this.ja,"sendRequest call when we're not connected not allowed.");this.Oa.Ca(a);c&&(this.Sc[d]=c)};function Ne(a,b,c,d,e){var f=b.Fa(),g=b.path.toString();a.f("Listen called for "+g+" "+f);a.Aa[g]=a.Aa[g]||{};y(!a.Aa[g][f],"listen() called twice for same path/queryId.");b={H:e,md:c,pg:Ic(b.n),tag:d};a.Aa[g][f]=b;a.ja&&Oe(a,g,f,b)} +function Oe(a,b,c,d){a.f("Listen on "+b+" for "+c);var e={p:b};d.tag&&(e.q=d.pg,e.t=d.tag);e.h=d.md();a.Ca("q",e,function(e){if((a.Aa[b]&&a.Aa[b][c])===d){a.f("listen response",e);var g=e.s;"ok"!==g&&Pe(a,b,c);e=e.d;d.H&&d.H(g,e)}})}h.Q=function(a,b,c){this.Ib={Rf:a,cf:!1,qc:b,ad:c};this.f("Authenticating using credential: "+a);Qe(this);(b=40==a.length)||(a=Ge(a).fe,b="object"===typeof a&&!0===t(a,"admin"));b&&(this.f("Admin auth credential detected. Reducing max reconnect time."),this.td=3E4)}; +h.Ue=function(a){delete this.Ib;this.ja&&this.Ca("unauth",{},function(b){a(b.s,b.d)})};function Qe(a){var b=a.Ib;a.ja&&b&&a.Ca("auth",{cred:b.Rf},function(c){var d=c.s;c=c.d||"error";"ok"!==d&&a.Ib===b&&delete a.Ib;b.cf?"ok"!==d&&b.ad&&b.ad(d,c):(b.cf=!0,b.qc&&b.qc(d,c))})}function Re(a,b,c,d){a.ja?Se(a,"o",b,c,d):a.Jc.push({Pc:b,action:"o",data:c,H:d})}function Te(a,b,c,d){a.ja?Se(a,"om",b,c,d):a.Jc.push({Pc:b,action:"om",data:c,H:d})} +h.Fe=function(a,b){this.ja?Se(this,"oc",a,null,b):this.Jc.push({Pc:a,action:"oc",data:null,H:b})};function Se(a,b,c,d,e){c={p:c,d:d};a.f("onDisconnect "+b,c);a.Ca(b,c,function(a){e&&setTimeout(function(){e(a.s,a.d)},Math.floor(0))})}h.put=function(a,b,c,d){Ue(this,"p",a,b,c,d)};function Ve(a,b,c,d){Ue(a,"m",b,c,d,void 0)}function Ue(a,b,c,d,e,f){d={p:c,d:d};m(f)&&(d.h=f);a.la.push({action:b,uf:d,H:e});a.Nc++;b=a.la.length-1;a.ja?We(a,b):a.f("Buffering put: "+c)} +function We(a,b){var c=a.la[b].action,d=a.la[b].uf,e=a.la[b].H;a.la[b].qg=a.ja;a.Ca(c,d,function(d){a.f(c+" response",d);delete a.la[b];a.Nc--;0===a.Nc&&(a.la=[]);e&&e(d.s,d.d)})} +h.xd=function(a){if("r"in a){this.f("from server: "+r(a));var b=a.r,c=this.Sc[b];c&&(delete this.Sc[b],c(a.b))}else{if("error"in a)throw"A server-side error has occurred: "+a.error;"a"in a&&(b=a.a,c=a.b,this.f("handleServerMessage",b,c),"d"===b?this.yd(c.p,c.d,!1,c.t):"m"===b?this.yd(c.p,c.d,!0,c.t):"c"===b?Xe(this,c.p,c.q):"ac"===b?(a=c.s,b=c.d,c=this.Ib,delete this.Ib,c&&c.ad&&c.ad(a,b)):"sd"===b?this.Oe?this.Oe(c):"msg"in c&&"undefined"!==typeof console&&console.log("FIREBASE: "+c.msg.replace("\n", +"\nFIREBASE: ")):pb("Unrecognized action received from server: "+r(b)+"\nAre you using the latest client?"))}};h.Kc=function(a){this.f("connection ready");this.ja=!0;this.Dc=(new Date).getTime();this.He({serverTimeOffset:a-(new Date).getTime()});Ye(this);this.wd(!0)};function Le(a,b){y(!a.Oa,"Scheduling a connect when we're already connected/ing?");a.Kb&&clearTimeout(a.Kb);a.Kb=setTimeout(function(){a.Kb=null;Ze(a)},Math.floor(b))} +h.kg=function(a){a&&!this.mc&&this.Wa===this.td&&(this.f("Window became visible. Reducing delay."),this.Wa=1E3,this.Oa||Le(this,0));this.mc=a};h.ig=function(a){a?(this.f("Browser went online. Reconnecting."),this.Wa=1E3,this.Cb=!0,this.Oa||Le(this,0)):(this.f("Browser went offline. Killing connection; don't reconnect."),this.Cb=!1,this.Oa&&this.Oa.close())}; +h.of=function(){this.f("data client disconnected");this.ja=!1;this.Oa=null;for(var a=0;ae.status){try{a=ta(e.responseText)}catch(b){}c(null,a)}else 500<=e.status&&600>e.status?c(X("SERVER_ERROR")):c(X("NETWORK_ERROR"));c=null;qf(window,"beforeunload",d)}};if("GET"===f)a+=(/\?/.test(a)?"":"?")+tf(b),g=null;else{var k=this.options.headers.content_type; +"application/json"===k&&(g=r(b));"application/x-www-form-urlencoded"===k&&(g=tf(b))}e.open(f,a,!0);a={"X-Requested-With":"XMLHttpRequest",Accept:"application/json;text/plain"};Qd(a,this.options.headers);for(var l in a)e.setRequestHeader(l,a[l]);e.send(g)};yf.isAvailable=function(){return!!window.XMLHttpRequest&&"string"===typeof(new XMLHttpRequest).responseType&&(!(navigator.userAgent.match(/MSIE/)||navigator.userAgent.match(/Trident/))||xf())};yf.prototype.sc=function(){return"json"};function zf(a){this.fc=Fa()+Fa()+Fa();this.pf=a} +zf.prototype.open=function(a,b,c){function d(){c&&(c(X("USER_CANCELLED")),c=null)}var e=this,f=rb(jf),g;b.requestId=this.fc;b.redirectTo=f.scheme+"://"+f.host+"/blank/page.html";a+=/\?/.test(a)?"":"?";a+=tf(b);(g=window.open(a,"_blank","location=no"))&&ha(g.addEventListener)?(g.addEventListener("loadstart",function(a){var b;if(b=a&&a.url)a:{var n=a.url;try{var u=document.createElement("a");u.href=n;b=u.host===f.host&&"/blank/page.html"===u.pathname;break a}catch(x){}b=!1}b&&(a=sf(a.url),g.removeEventListener("exit", +d),g.close(),a=new kf(null,null,{requestId:e.fc,requestKey:a}),e.pf.requestWithCredential("/auth/session",a,c),c=null)}),g.addEventListener("exit",d)):c(X("TRANSPORT_UNAVAILABLE"))};zf.isAvailable=function(){return wf()};zf.prototype.sc=function(){return"redirect"};function Af(a){if(!a.window_features||-1!==navigator.userAgent.indexOf("Fennec/")||-1!==navigator.userAgent.indexOf("Firefox/")&&-1!==navigator.userAgent.indexOf("Android"))a.window_features=void 0;a.window_name||(a.window_name="_blank");this.options=a} +Af.prototype.open=function(a,b,c){function d(a){g&&(document.body.removeChild(g),g=void 0);u&&(u=clearInterval(u));qf(window,"message",e);qf(window,"unload",d);if(n&&!a)try{n.close()}catch(b){k.postMessage("die",l)}n=k=void 0}function e(a){if(a.origin===l)try{var b=ta(a.data);"ready"===b.a?k.postMessage(x,l):"error"===b.a?(d(!1),c&&(c(b.d),c=null)):"response"===b.a&&(d(b.forceKeepWindowOpen),c&&(c(null,b.d),c=null))}catch(e){}}var f=xf(),g,k;if(!this.options.relay_url)return c(Error("invalid arguments: origin of url and relay_url must match")); +var l=rf(a);if(l!==rf(this.options.relay_url))c&&setTimeout(function(){c(Error("invalid arguments: origin of url and relay_url must match"))},0);else{f&&(g=document.createElement("iframe"),g.setAttribute("src",this.options.relay_url),g.style.display="none",g.setAttribute("name","__winchan_relay_frame"),document.body.appendChild(g),k=g.contentWindow);a+=(/\?/.test(a)?"":"?")+tf(b);var n=window.open(a,this.options.window_name,this.options.window_features);k||(k=n);var u=setInterval(function(){n&&n.closed&& +(d(!1),c&&(c(X("USER_CANCELLED")),c=null))},500),x=r({a:"request",d:b});pf(window,"unload",d);pf(window,"message",e)}}; +Af.isAvailable=function(){return"postMessage"in window&&!/^file:\//.test(location.href)&&!(wf()||navigator.userAgent.match(/Windows Phone/)||window.Windows&&/^ms-appx:/.test(location.href)||navigator.userAgent.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i)||navigator.userAgent.match(/CriOS/)||navigator.userAgent.match(/Twitter for iPhone/)||navigator.userAgent.match(/FBAN\/FBIOS/)||window.navigator.standalone)&&!navigator.userAgent.match(/PhantomJS/)};Af.prototype.sc=function(){return"popup"};function Bf(a){a.callback_parameter||(a.callback_parameter="callback");this.options=a;window.__firebase_auth_jsonp=window.__firebase_auth_jsonp||{}} +Bf.prototype.open=function(a,b,c){function d(){c&&(c(X("REQUEST_INTERRUPTED")),c=null)}function e(){setTimeout(function(){window.__firebase_auth_jsonp[f]=void 0;Nd(window.__firebase_auth_jsonp)&&(window.__firebase_auth_jsonp=void 0);try{var a=document.getElementById(f);a&&a.parentNode.removeChild(a)}catch(b){}},1);qf(window,"beforeunload",d)}var f="fn"+(new Date).getTime()+Math.floor(99999*Math.random());b[this.options.callback_parameter]="__firebase_auth_jsonp."+f;a+=(/\?/.test(a)?"":"?")+tf(b); +pf(window,"beforeunload",d);window.__firebase_auth_jsonp[f]=function(a){c&&(c(null,a),c=null);e()};Cf(f,a,c)}; +function Cf(a,b,c){setTimeout(function(){try{var d=document.createElement("script");d.type="text/javascript";d.id=a;d.async=!0;d.src=b;d.onerror=function(){var b=document.getElementById(a);null!==b&&b.parentNode.removeChild(b);c&&c(X("NETWORK_ERROR"))};var e=document.getElementsByTagName("head");(e&&0!=e.length?e[0]:document.documentElement).appendChild(d)}catch(f){c&&c(X("NETWORK_ERROR"))}},0)}Bf.isAvailable=function(){return!wf()};Bf.prototype.sc=function(){return"json"};function Df(a,b){this.Je=["session",a.Dd,a.tb].join(":");this.Rd=b}Df.prototype.set=function(a,b){if(!b)if(this.Rd.length)b=this.Rd[0];else throw Error("fb.login.SessionManager : No storage options available!");b.set(this.Je,a)};Df.prototype.get=function(){var a=Ja(this.Rd,q(this.Zf,this)),a=Ia(a,function(a){return null!==a});Qa(a,function(a,c){return He(c.token)-He(a.token)});return 0=b&&Wg(g,c.path)?d=!1:c.path.contains(g.path)&&(e=!0));f--}if(d){if(e)this.T=Xg(this.wa,Yg,U),this.Ec=0f.Ec,"Stacking an older write on top of newer ones");m(g)||(g=!0);f.wa.push({path:b,Ga:c,Zd:d,visible:g});g&&(f.T=Pg(f.T,b,c));f.Ec=d;return e?ih(a,new $g(bh,b,c)):[]}function jh(a,b,c,d){var e=a.xb;y(d>e.Ec,"Stacking an older merge on top of newer ones");e.wa.push({path:b,children:c,Zd:d,visible:!0});e.T=Qg(e.T,b,c);e.Ec=d;c=yg(c);return ih(a,new dh(bh,b,c))} +function kh(a,b,c){c=c||!1;b=a.xb.Gd(b);return null==b?[]:ih(a,new ah(b,c))}function lh(a,b,c){c=yg(c);return ih(a,new dh(fh,b,c))}function mh(a,b,c,d){d=Od(a.Wc,"_"+d);if(null!=d){var e=nh(d);d=e.path;e=e.yb;b=V(d,b);c=new $g(new eh(!1,!0,e,!0),b,c);return oh(a,d,c)}return[]}function ph(a,b,c,d){if(d=Od(a.Wc,"_"+d)){var e=nh(d);d=e.path;e=e.yb;b=V(d,b);c=yg(c);c=new dh(new eh(!1,!0,e,!0),b,c);return oh(a,d,c)}return[]} +gh.prototype.Gb=function(a,b){var c=a.path,d=null,e=!1;Fg(this.na,c,function(a,b){var f=V(a,c);d=b.bb(f);e=e||null!=Kg(b);return!d});var f=this.na.get(c);f?(e=e||null!=Kg(f),d=d||f.bb(U)):(f=new Jg,this.na=this.na.set(c,f));var g;null!=d?g=!0:(g=!1,d=M,Ig(this.na.subtree(c),function(a,b){var c=b.bb(U);c&&(d=d.P(a,c))}));var k=null!=Mg(f,a);if(!k&&!Jc(a.n)){var l=qh(a);y(!(l in this.bc),"View does not exist, but we have a tag");var n=rh++;this.bc[l]=n;this.Wc["_"+n]=l}g=f.Gb(a,b,new Zg(c,this.xb), +d,g);k||e||(f=Mg(f,a),g=g.concat(sh(this,a,f)));return g}; +gh.prototype.gb=function(a,b,c){var d=a.path,e=this.na.get(d),f=[];if(e&&("default"===a.Fa()||null!=Mg(e,a))){f=e.gb(a,b,c);e.e()&&(this.na=this.na.remove(d));e=f.rg;f=f.Vf;b=-1!==Na(e,function(a){return Jc(a.n)});var g=Dg(this.na,d,function(a,b){return null!=Kg(b)});if(b&&!g&&(d=this.na.subtree(d),!d.e()))for(var d=th(d),k=0;kf;f++)b[f]=Math.floor(64*Math.random());for(f=0;12>f;f++)c+="-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(b[f]);y(20===c.length,"NextPushId: Length should be 20."); +return c}}();function R(a,b){var c,d,e;if(a instanceof zh)c=a,d=b;else{F("new Firebase",1,2,arguments.length);d=rb(arguments[0]);c=d.Ag;"firebase"===d.domain&&qb(d.host+" is no longer supported. Please use .firebaseio.com instead");c||qb("Cannot parse Firebase url. Please use https://.firebaseio.com");d.Ab||"undefined"!==typeof window&&window.location&&window.location.protocol&&-1!==window.location.protocol.indexOf("https:")&&z("Insecure Firebase access from a secure page. Please use https in calls to new Firebase()."); +c=new Aa(d.host,d.Ab,c,"ws"===d.scheme||"wss"===d.scheme);d=new S(d.Pc);e=d.toString();var f;!(f=!p(c.host)||0===c.host.length||!Pb(c.tb))&&(f=0!==e.length)&&(e&&(e=e.replace(/^\/*\.info(\/|$)/,"/")),f=!(p(e)&&0!==e.length&&!Ob.test(e)));if(f)throw Error(G("new Firebase",1,!1)+'must be a valid firebase URL and the path can\'t contain ".", "#", "$", "[", or "]".');if(b)if(b instanceof Th)e=b;else if(p(b))e=Th.Nb(),c.Dd=b;else throw Error("Expected a valid Firebase.Context for second argument to new Firebase()"); +else e=Th.Nb();f=c.toString();var g=t(e.ec,f);g||(g=new zh(c),e.ec[f]=g);c=g}Q.call(this,c,d,Fc,!1)}ma(R,Q);var Xh=R,Yh=["Firebase"],Zh=aa;Yh[0]in Zh||!Zh.execScript||Zh.execScript("var "+Yh[0]);for(var $h;Yh.length&&($h=Yh.shift());)!Yh.length&&m(Xh)?Zh[$h]=Xh:Zh=Zh[$h]?Zh[$h]:Zh[$h]={};R.prototype.name=function(){z("Firebase.name() being deprecated. Please use Firebase.key() instead.");F("Firebase.name",0,0,arguments.length);return this.key()};R.prototype.name=R.prototype.name; +R.prototype.key=function(){F("Firebase.key",0,0,arguments.length);return this.path.e()?null:Rc(this.path)};R.prototype.key=R.prototype.key;R.prototype.o=function(a){F("Firebase.child",1,1,arguments.length);if(ga(a))a=String(a);else if(!(a instanceof S))if(null===I(this.path)){var b=a;b&&(b=b.replace(/^\/*\.info(\/|$)/,"/"));Yb("Firebase.child",b)}else Yb("Firebase.child",a);return new R(this.k,this.path.o(a))};R.prototype.child=R.prototype.o; +R.prototype.parent=function(){F("Firebase.parent",0,0,arguments.length);var a=this.path.parent();return null===a?null:new R(this.k,a)};R.prototype.parent=R.prototype.parent;R.prototype.root=function(){F("Firebase.ref",0,0,arguments.length);for(var a=this;null!==a.parent();)a=a.parent();return a};R.prototype.root=R.prototype.root; +R.prototype.toString=function(){F("Firebase.toString",0,0,arguments.length);var a;if(null===this.parent())a=this.k.toString();else{a=this.parent().toString()+"/";var b=this.key();a+=encodeURIComponent(String(b))}return a};R.prototype.toString=R.prototype.toString;R.prototype.set=function(a,b){F("Firebase.set",1,2,arguments.length);Zb("Firebase.set",this.path);Rb("Firebase.set",a,!1);H("Firebase.set",2,b,!0);this.k.Bb(this.path,a,null,b||null)};R.prototype.set=R.prototype.set; +R.prototype.update=function(a,b){F("Firebase.update",1,2,arguments.length);Zb("Firebase.update",this.path);if(ea(a)){for(var c={},d=0;d