diff --git a/.codio b/.codio index d12cbf60..4d215c0d 100644 --- a/.codio +++ b/.codio @@ -8,7 +8,7 @@ // Preview button configuration "preview": { - "Prieview": "https://period-sheriff-3000.codio.io", + "Prieview": "http://period-sheriff-3000.codio.io", "Ungit": "https://period-sheriff-9501.codio.io/#/repository?path=/home/codio/workspace" } } \ No newline at end of file diff --git a/rpg-docs/Model/Character/Characters.js b/rpg-docs/Model/Character/Characters.js index 4fd1173c..3ad0b355 100644 --- a/rpg-docs/Model/Character/Characters.js +++ b/rpg-docs/Model/Character/Characters.js @@ -60,6 +60,8 @@ Schemas.Character = new SimpleSchema({ ki: {type: Schemas.Attribute}, sorceryPoints: {type: Schemas.Attribute}, rages: {type: Schemas.Attribute}, + superiorityDice: {type: Schemas.Attribute}, + expertiseDice: {type: Schemas.Attribute}, //hit dice @@ -236,9 +238,9 @@ Schemas.Character = new SimpleSchema({ deathSave: { type: Schemas.DeathSave }, time: { type: Number, min: 0, decimal: true, defaultValue: 0}, initiativeOrder:{ type: Number, min: 0, max: 1, decimal: true, defaultValue: 0}, - expirations: { type: [Schemas.Expiration], defaultValue: []} + expirations: { type: [Schemas.Expiration], defaultValue: []}, + spells: { type: [Schemas.Spell], defaultValue: []} //TODO add permission stuff for owner, readers and writers - //TODO spells }); Characters.attachSchema(Schemas.Character); @@ -257,6 +259,32 @@ Characters.find({},{fields: {time: 1, expirations: 1}}).observe({ } }); +var attributeBase = function(attribute){ + var value = 0; + //add all values in add array + _.each(attribute.add, function(effect){ + value += evaluateEffect(charId, effect); + }); + + //multiply all values in mul array + _.each(attribute.mul, function(effect){ + value *= evaluateEffect(charId, effect); + }); + + //largest min + _.each(attribute.min, function(effect){ + var min = evaluateEffect(charId, effect); + value = value > min? value : min; + }); + + //smallest max + _.each(attribute.max, function(effect){ + var max = evaluateEffect(charId, effect); + value = value < max? value : max; + }); + return value; +} + //functions and calculated values. //These functions can only rely on this._id since no other //field is likely to be attached to all returned characters @@ -311,29 +339,37 @@ Characters.helpers({ var charId = this._id; var attribute = this.getField(attributeName); //base value - var value = attribute.base; - //add all values in add array - _.each(attribute.add, function(effect){ - value += evaluateEffect(charId, effect); - }); + var value = attributeBase(attribute); + value += attribute.adjustment; + + //this attribute returns, pull it from the array, we may visit it again safely + visitedAttributes = _.without(visitedAttributes, attributeName); + return value; + } + })(), - //multiply all values in mul array - _.each(attribute.mul, function(effect){ - value *= evaluateEffect(charId, effect); - }); + attributeBase: (function(){ + //store a private array of attributes we've visited without returning + //if we try to visit the same attribute twice before resolving its value + //we are in a dependency loop and need to GTFO + var visitedAttributes = []; + return function(attributeName){ + check(attributeName, String); + //we're still evaluating this attribute, must be in a loop + if(_.contains(visitedAttributes, attributeName)) { + console.log("dependency loop detected"); + return NaN; + } + //push this attribute to the list of visited attributes + //we can't visit it again unless it returns first + visitedAttributes.push(attributeName); - //largest min - _.each(attribute.min, function(effect){ - var min = evaluateEffect(charId, effect); - value = value > min? value : min; - }); - - //smallest max - _.each(attribute.max, function(effect){ - var max = evaluateEffect(charId, effect); - value = value < max? value : max; - }); - //done traversing the tree, this attribute returns, pull it from the array + var charId = this._id; + var attribute = this.getField(attributeName); + //base value + var value = attributeBase(attribute); + + //this attribute returns, pull it from the array, we may visit it again safely visitedAttributes = _.without(visitedAttributes, attributeName); return value; } diff --git a/rpg-docs/Model/Character/SubSchemas/Attribute.js b/rpg-docs/Model/Character/SubSchemas/Attribute.js index 79c5e92f..8214ead9 100644 --- a/rpg-docs/Model/Character/SubSchemas/Attribute.js +++ b/rpg-docs/Model/Character/SubSchemas/Attribute.js @@ -1,7 +1,7 @@ Schemas.Attribute = new SimpleSchema({ - //the unmodified value of the attribute + //the temporary shift of the attribute //should be zero for most attributes after a long rest - base: { + adjustment: { type: Number, defaultValue: 0 }, @@ -16,7 +16,7 @@ Schemas.Attribute = new SimpleSchema({ //note that to make an invulnerability add a new max of zero value Schemas.Vulnerability = new SimpleSchema({ //same as attribute - base: { + adjustment: { type: Number, defaultValue: 0 }, diff --git a/rpg-docs/Model/Inventory/Items.js b/rpg-docs/Model/Inventory/Items.js index b0ba3f4f..ea6bfa42 100644 --- a/rpg-docs/Model/Inventory/Items.js +++ b/rpg-docs/Model/Inventory/Items.js @@ -1,15 +1,17 @@ Items = new Meteor.Collection('items'); Schemas.Item = new SimpleSchema({ - name: {type: String}, - description:{type: String}, + name: {type: String, defaultValue: "New Item"}, + plural: {type: String, optional: true}, + description:{type: String, defaultValue: ""}, container: {type: String, regEx: SimpleSchema.RegEx.Id}, quantity: {type: Number, min: 0, defaultValue: 1}, weight: {type: Number, min: 0, defaultValue: 0, decimal: true}, value: {type: Number, min: 0, defaultValue: 0, decimal: true}, tradeGood: {type: Boolean, defaultValue: false}, stackable: {type: Boolean, defaultValue: false}, - buffs: {type: [Schemas.Buff]} + buffs: {type: [Schemas.Buff], defaultValue: []}, + equipmentSlot: {type: String, defaultValue: "", allowedValues: ["head", "body", "arms", "hands", "held", "feet"]}, }); Items.attachSchema(Schemas.Item); diff --git a/rpg-docs/client/globalHelpers/canCast.js b/rpg-docs/client/globalHelpers/canCast.js new file mode 100644 index 00000000..840fd638 --- /dev/null +++ b/rpg-docs/client/globalHelpers/canCast.js @@ -0,0 +1,3 @@ +Template.registerHelper("canCast", function(){ + return Characters.find({_id: this._id, spells: {$size: 0}}).count() === 0; +}); \ No newline at end of file diff --git a/rpg-docs/client/views/character/features.html b/rpg-docs/client/views/character/Features/features.html similarity index 100% rename from rpg-docs/client/views/character/features.html rename to rpg-docs/client/views/character/Features/features.html diff --git a/rpg-docs/client/views/character/features.js b/rpg-docs/client/views/character/Features/features.js similarity index 100% rename from rpg-docs/client/views/character/features.js rename to rpg-docs/client/views/character/Features/features.js diff --git a/rpg-docs/client/views/character/SideAbilities/sideAbilities.css b/rpg-docs/client/views/character/SideAbilities/sideAbilities.css new file mode 100644 index 00000000..dc075a28 --- /dev/null +++ b/rpg-docs/client/views/character/SideAbilities/sideAbilities.css @@ -0,0 +1,43 @@ +.abilityDetails { + background-color: #ebe2d5; + + position: absolute; + + top: 0px; + height: 300px; + right: 0px; + width: 160px; + + z-index: 10; + + background-color: #ebe2d5; + + transition: right 0.3s ease; +} + +.stubHolder { + display: flex; + flex-direction: column; + justify-content: space-around; + + position: absolute; + + top: 0px; + bottom: 0px; + width: 40px; + left: -40px; +} + +.abilityStub { + text-align: center; + cursor: pointer; + background-color: #ebe2d5; +} + +.abilityDetails.collapse{ + right: -160px; +} + +.abilityDetails.expand{ + right: 0px; +} \ No newline at end of file diff --git a/rpg-docs/client/views/character/SideAbilities/sideAbilities.html b/rpg-docs/client/views/character/SideAbilities/sideAbilities.html new file mode 100644 index 00000000..9680ba3f --- /dev/null +++ b/rpg-docs/client/views/character/SideAbilities/sideAbilities.html @@ -0,0 +1,62 @@ + \ No newline at end of file diff --git a/rpg-docs/client/views/character/SideAbilities/sideAbilities.js b/rpg-docs/client/views/character/SideAbilities/sideAbilities.js new file mode 100644 index 00000000..be006a42 --- /dev/null +++ b/rpg-docs/client/views/character/SideAbilities/sideAbilities.js @@ -0,0 +1,38 @@ +Template.sideAbilities.created = function(){ + Template.instance().openedAbility = new ReactiveVar(null); +}; + +Template.sideAbilities.helpers({ + openedAbility: function(){ + Template.instance().openedAbility.get(); + }, + selected: function(string){ + return Template.instance().openedAbility.get() === string; + }, + expanded: function(){ + if(Template.instance().openedAbility.get() === null){ + return "collapse"; + } else{ + return "expand"; + } + } +}); + +var abilityOpener = function(ability){ + return function(){ + if(Template.instance().openedAbility.get() === ability){ + Template.instance().openedAbility.set(null); + } else{ + Template.instance().openedAbility.set(ability); + } + }; +}; + +Template.sideAbilities.events({ + "click .strengthStub": abilityOpener("strength"), + "click .dexterityStub": abilityOpener("dexterity"), + "click .constitutionStub": abilityOpener("constitution"), + "click .intelligenceStub": abilityOpener("intelligence"), + "click .wisdomStub": abilityOpener("wisdom"), + "click .charismaStub": abilityOpener("charisma") +}); \ No newline at end of file diff --git a/rpg-docs/client/views/character/skills/skills.css b/rpg-docs/client/views/character/SideAbilities/skills/skills.css similarity index 100% rename from rpg-docs/client/views/character/skills/skills.css rename to rpg-docs/client/views/character/SideAbilities/skills/skills.css diff --git a/rpg-docs/client/views/character/SideAbilities/skills/skills.html b/rpg-docs/client/views/character/SideAbilities/skills/skills.html new file mode 100644 index 00000000..7200eabf --- /dev/null +++ b/rpg-docs/client/views/character/SideAbilities/skills/skills.html @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/rpg-docs/client/views/character/skills/skills.js b/rpg-docs/client/views/character/SideAbilities/skills/skills.js similarity index 98% rename from rpg-docs/client/views/character/skills/skills.js rename to rpg-docs/client/views/character/SideAbilities/skills/skills.js index 9b24a995..7e6e7442 100644 --- a/rpg-docs/client/views/character/skills/skills.js +++ b/rpg-docs/client/views/character/SideAbilities/skills/skills.js @@ -30,7 +30,10 @@ Template.skills.helpers({ {name: "Stealth", skill: "stealth"}, {name: "Survival", skill: "survival"} ]; - }, + } +}); + +Template.skillRow.helpers({ profIcon: function(skill){ var prof = Template.parentData(1).proficiency(this.skill); if(prof > 0 && prof < 1) return "profHalf.png"; diff --git a/rpg-docs/client/views/character/Stats/stats.css b/rpg-docs/client/views/character/Stats/stats.css new file mode 100644 index 00000000..d045e793 --- /dev/null +++ b/rpg-docs/client/views/character/Stats/stats.css @@ -0,0 +1,4 @@ +#stats{ + display: flex; + justify-content: space-around; +} \ No newline at end of file diff --git a/rpg-docs/client/views/character/Stats/stats.html b/rpg-docs/client/views/character/Stats/stats.html new file mode 100644 index 00000000..d67c5fc7 --- /dev/null +++ b/rpg-docs/client/views/character/Stats/stats.html @@ -0,0 +1,80 @@ + + + + + \ No newline at end of file diff --git a/rpg-docs/client/views/character/characterName.html b/rpg-docs/client/views/character/Title/characterName.html similarity index 100% rename from rpg-docs/client/views/character/characterName.html rename to rpg-docs/client/views/character/Title/characterName.html diff --git a/rpg-docs/client/views/character/bigAbilities/bigAbilities.css b/rpg-docs/client/views/character/bigAbilities/bigAbilities.css index 48e91cd1..79551a3d 100644 --- a/rpg-docs/client/views/character/bigAbilities/bigAbilities.css +++ b/rpg-docs/client/views/character/bigAbilities/bigAbilities.css @@ -1,3 +1,9 @@ +.flexItem.abilities { + flex-grow: 1; + width: 100px; + max-width: 400px; +} + .floatBox.ability { width: 85px; text-align: center; diff --git a/rpg-docs/client/views/character/bigAbilities/bigAbilities.html b/rpg-docs/client/views/character/bigAbilities/bigAbilities.html index a142b929..05bb32f8 100644 --- a/rpg-docs/client/views/character/bigAbilities/bigAbilities.html +++ b/rpg-docs/client/views/character/bigAbilities/bigAbilities.html @@ -1,68 +1,32 @@ + + \ No newline at end of file diff --git a/rpg-docs/client/views/character/character.css b/rpg-docs/client/views/character/character.css deleted file mode 100644 index 754a148a..00000000 --- a/rpg-docs/client/views/character/character.css +++ /dev/null @@ -1,65 +0,0 @@ -.flexContainer { - display: flex; - flex-wrap: wrap; - justify-content: space-around; - align-items: flex-start; -} - -#abilityScores { - text-align: center; - flex-basis: 120px; - flex-grow: 1; - max-width: 340px; -} - -/*Float boxes are indivisble, have shadows*/ -.floatBox{ - color: #301d02; - - /*Fancy image border*/ - border-image-width: 92px 60px 57px 60px; - border-image-outset: 15px; - border-image-source: url('/png/big-border.png'); - border-image-slice: 275 179 171 179; - border-image-repeat: stretch; - - /*Shadow*/ - box-shadow: 0px 5px 20px rgba(0, 0, 0, 1); - - padding: 0px 5px 5px 5px; - margin: 15px; - background: #f0e3d1; - border-radius: 20px; - - min-width: 200px; -} - -.bigborder{ - -} - -/* headings in floatboxes */ -.floatBox h2{ - font-size: 1em; -} - -.floatBox.rounded { - display: inline-block; - text-align: center; -} - -/* Stats */ -#armorClassBox { - width: 90px; - height: 100px; - background-image: url('/svg/ac.svg'); - background-repeat: no-repeat; - text-align: center; - display: flex; - flex-direction: column; - justify-content: center; -} - -.statValue { - font-size: 2em; -} \ No newline at end of file diff --git a/rpg-docs/client/views/character/character.html b/rpg-docs/client/views/character/character.html deleted file mode 100644 index 6e2bbc66..00000000 --- a/rpg-docs/client/views/character/character.html +++ /dev/null @@ -1,38 +0,0 @@ - \ No newline at end of file diff --git a/rpg-docs/client/views/character/characterSheet.css b/rpg-docs/client/views/character/characterSheet.css new file mode 100644 index 00000000..bc5ef555 --- /dev/null +++ b/rpg-docs/client/views/character/characterSheet.css @@ -0,0 +1,11 @@ +#characterSheetTabs { + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: flex-start; +} + +.characterTab { + flex-grow: 1; + min-width: 100px; +} \ No newline at end of file diff --git a/rpg-docs/client/views/character/characterSheet.html b/rpg-docs/client/views/character/characterSheet.html new file mode 100644 index 00000000..7a681a59 --- /dev/null +++ b/rpg-docs/client/views/character/characterSheet.html @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/rpg-docs/client/views/character/characterSheet.js b/rpg-docs/client/views/character/characterSheet.js new file mode 100644 index 00000000..0adb911c --- /dev/null +++ b/rpg-docs/client/views/character/characterSheet.js @@ -0,0 +1,34 @@ +Template.characterSheet.created = function(){ + Template.instance().tab = new ReactiveVar("characterStats") +} + +Template.characterSheet.helpers({ + getTab: function(){ + return Template.instance().tab.get(); + }, +}); + +var setTab = function(value){ + Template.instance().tab.set(value); +} + +Template.characterSheet.events({ + "click #statsTab": function(){ + setTab("stats"); + }, + "click #featuresTab": function(){ + setTab("features"); + }, + "click #personaTab": function(){ + setTab("persona"); + }, + "click #inventoryTab": function(){ + setTab("inventory"); + }, + "click #spellsTab": function(){ + setTab("spellbook"); + }, + "click #journalTab": function(){ + setTab("journal"); + }, +}) \ No newline at end of file diff --git a/rpg-docs/client/views/character/characterStats.html b/rpg-docs/client/views/character/characterStats.html deleted file mode 100644 index 7c7c35f6..00000000 --- a/rpg-docs/client/views/character/characterStats.html +++ /dev/null @@ -1,50 +0,0 @@ - \ No newline at end of file diff --git a/rpg-docs/client/views/character/healthBar/healthBar.css b/rpg-docs/client/views/character/healthBar/healthBar.css index 91db0c5b..b32cbd5d 100644 --- a/rpg-docs/client/views/character/healthBar/healthBar.css +++ b/rpg-docs/client/views/character/healthBar/healthBar.css @@ -44,7 +44,7 @@ top: 0px; left: -1px; height: 0px; - width: 228px; + width: 302px; border-width: 15px 37px 16px 37px; border-image: url('/png/bar-border.png') 46 112 48 112 stretch; display: flex; diff --git a/rpg-docs/client/views/character/healthBar/healthBar.js b/rpg-docs/client/views/character/healthBar/healthBar.js index 8ecaf172..4a5466f2 100644 --- a/rpg-docs/client/views/character/healthBar/healthBar.js +++ b/rpg-docs/client/views/character/healthBar/healthBar.js @@ -160,7 +160,7 @@ Template.deathSaves.events({ Characters.update(this._id, {$set: {"deathSave.pass": 0}}); }, "click .heal": function(){ - Characters.update(this._id, {$inc: {"attributes.hitPoints.base": 1}}); + Characters.update(this._id, {$inc: {"hitPoints.base": 1}}); }, "click .untickedDeathFail" : function(){ Characters.update(this._id, {$inc: {"deathSave.fail": 1}}); diff --git a/rpg-docs/client/views/inventory/containerTable/containerTable.html b/rpg-docs/client/views/character/inventory/containerTable/containerTable.html similarity index 100% rename from rpg-docs/client/views/inventory/containerTable/containerTable.html rename to rpg-docs/client/views/character/inventory/containerTable/containerTable.html diff --git a/rpg-docs/client/views/inventory/containerTable/containerTable.js b/rpg-docs/client/views/character/inventory/containerTable/containerTable.js similarity index 100% rename from rpg-docs/client/views/inventory/containerTable/containerTable.js rename to rpg-docs/client/views/character/inventory/containerTable/containerTable.js diff --git a/rpg-docs/client/views/character/inventory/inventory.html b/rpg-docs/client/views/character/inventory/inventory.html new file mode 100644 index 00000000..962aeca5 --- /dev/null +++ b/rpg-docs/client/views/character/inventory/inventory.html @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/rpg-docs/client/views/inventory/inventoryTables/inventoryTables.html b/rpg-docs/client/views/character/inventory/inventoryTables/inventoryTables.html similarity index 100% rename from rpg-docs/client/views/inventory/inventoryTables/inventoryTables.html rename to rpg-docs/client/views/character/inventory/inventoryTables/inventoryTables.html diff --git a/rpg-docs/client/views/inventory/inventoryTables/inventoryTables.js b/rpg-docs/client/views/character/inventory/inventoryTables/inventoryTables.js similarity index 100% rename from rpg-docs/client/views/inventory/inventoryTables/inventoryTables.js rename to rpg-docs/client/views/character/inventory/inventoryTables/inventoryTables.js diff --git a/rpg-docs/client/views/inventory/itemRow/itemRow.css b/rpg-docs/client/views/character/inventory/itemRow/itemRow.css similarity index 100% rename from rpg-docs/client/views/inventory/itemRow/itemRow.css rename to rpg-docs/client/views/character/inventory/itemRow/itemRow.css diff --git a/rpg-docs/client/views/inventory/itemRow/itemRow.html b/rpg-docs/client/views/character/inventory/itemRow/itemRow.html similarity index 100% rename from rpg-docs/client/views/inventory/itemRow/itemRow.html rename to rpg-docs/client/views/character/inventory/itemRow/itemRow.html diff --git a/rpg-docs/client/views/inventory/itemRow/itemRow.js b/rpg-docs/client/views/character/inventory/itemRow/itemRow.js similarity index 100% rename from rpg-docs/client/views/inventory/itemRow/itemRow.js rename to rpg-docs/client/views/character/inventory/itemRow/itemRow.js diff --git a/rpg-docs/client/views/character/persona/persona.html b/rpg-docs/client/views/character/persona/persona.html new file mode 100644 index 00000000..97934fd0 --- /dev/null +++ b/rpg-docs/client/views/character/persona/persona.html @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/rpg-docs/client/views/character/skills/skills.html b/rpg-docs/client/views/character/skills/skills.html deleted file mode 100644 index 0fccfb2b..00000000 --- a/rpg-docs/client/views/character/skills/skills.html +++ /dev/null @@ -1,30 +0,0 @@ - \ No newline at end of file diff --git a/rpg-docs/client/views/general.css b/rpg-docs/client/views/general.css index d7a91ec0..3b527843 100644 --- a/rpg-docs/client/views/general.css +++ b/rpg-docs/client/views/general.css @@ -1,13 +1,24 @@ root { - display: block; + display: block; } body { font-family: sans-serif; background: #201500; + overflow-x: hidden; + margin: 0px; + box-sizing: border-box; } .calculatedValue { color: #021C33; font-weight: bold; +} + +* { + box-sizing: border-box; +} + +h2 { + margin: 0; } \ No newline at end of file diff --git a/rpg-docs/client/views/index.html b/rpg-docs/client/views/index.html index b6554729..0a0b08ac 100644 --- a/rpg-docs/client/views/index.html +++ b/rpg-docs/client/views/index.html @@ -1,4 +1,4 @@ RPG Docs - + \ No newline at end of file diff --git a/rpg-docs/nohup.out b/rpg-docs/nohup.out new file mode 100644 index 00000000..b659aa0b --- /dev/null +++ b/rpg-docs/nohup.out @@ -0,0 +1,19 @@ +[[[[[ ~/workspace/rpg-docs ]]]]] + +=> Started proxy. +=> Started MongoDB. +I20141122-15:44:13.239(0)? ** You've set up some data subscriptions with Meteor.publish(), but +I20141122-15:44:13.351(0)? ** you still have autopublish turned on. Because autopublish is still +I20141122-15:44:13.352(0)? ** on, your Meteor.publish() calls won't have much effect. All data +I20141122-15:44:13.352(0)? ** will still be sent to all clients. +I20141122-15:44:13.352(0)? ** +I20141122-15:44:13.352(0)? ** Turn off autopublish by removing the autopublish package: +I20141122-15:44:13.353(0)? ** +I20141122-15:44:13.353(0)? ** $ meteor remove autopublish +I20141122-15:44:13.353(0)? ** +I20141122-15:44:13.353(0)? ** .. and make sure you have Meteor.publish() and Meteor.subscribe() calls +I20141122-15:44:13.353(0)? ** for each collection that you want clients to see. +I20141122-15:44:13.353(0)?  +=> Started your app. + +=> App running at: http://localhost:3000/ diff --git a/rpg-docs/tests/mocha/client/sampleClientTest.js b/rpg-docs/tests/mocha/client/sampleClientTest.js new file mode 100644 index 00000000..8122e829 --- /dev/null +++ b/rpg-docs/tests/mocha/client/sampleClientTest.js @@ -0,0 +1,9 @@ +if (!(typeof MochaWeb === 'undefined')){ + MochaWeb.testOnly(function(){ + describe("a group of tests", function(){ + it("should respect equality", function(){ + chai.assert.equal(5,5); + }); + }); + }); +} diff --git a/rpg-docs/tests/mocha/server/sampleServerTest.js b/rpg-docs/tests/mocha/server/sampleServerTest.js new file mode 100644 index 00000000..bb220ccd --- /dev/null +++ b/rpg-docs/tests/mocha/server/sampleServerTest.js @@ -0,0 +1,9 @@ +if (!(typeof MochaWeb === 'undefined')){ + MochaWeb.testOnly(function(){ + describe("Server initialization", function(){ + it("should have a Meteor version defined", function(){ + chai.assert(Meteor.release); + }); + }); + }); +}