diff --git a/Projects/Governance/UI/Function-Libraries/Claims.js b/Projects/Governance/UI/Function-Libraries/Claims.js new file mode 100644 index 000000000..cc0935662 --- /dev/null +++ b/Projects/Governance/UI/Function-Libraries/Claims.js @@ -0,0 +1,11 @@ +function newGovernanceFunctionLibraryClaims() { + let thisObject = { + calculate: calculate + } + + return thisObject + + function calculate() { + + } +} \ No newline at end of file diff --git a/Projects/Governance/UI/Function-Libraries/DistributionProcess.js b/Projects/Governance/UI/Function-Libraries/DistributionProcess.js new file mode 100644 index 000000000..bcdc86280 --- /dev/null +++ b/Projects/Governance/UI/Function-Libraries/DistributionProcess.js @@ -0,0 +1,11 @@ +function newGovernanceFunctionLibraryDistributionProcess() { + let thisObject = { + calculate: calculate + } + + return thisObject + + function calculate() { + + } +} \ No newline at end of file diff --git a/Projects/Governance/UI/Function-Libraries/Tokens.js b/Projects/Governance/UI/Function-Libraries/Tokens.js new file mode 100644 index 000000000..0183c7cba --- /dev/null +++ b/Projects/Governance/UI/Function-Libraries/Tokens.js @@ -0,0 +1,173 @@ +function newGovernanceFunctionLibraryTokens() { + let thisObject = { + calculate: calculate + } + + return thisObject + + function calculate() { + let pools = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Pools') + + /* Weight Calculation Follows */ + for (let i = 0; i < pools.length; i++) { + let poolsNode = pools[i] + UI.projects.governance.functionLibraries.weights.calculate(poolsNode) + } + /* + We will reset all the token flows, and then distribute it. + */ + for (let i = 0; i < pools.length; i++) { + let poolsNode = pools[i] + poolsReset(poolsNode) + } + for (let i = 0; i < pools.length; i++) { + let poolsNode = pools[i] + poolsDistribute(poolsNode) + } + } + + function poolsReset(pools) { + resetTokenFlow(pools) + } + + function poolsDistribute(pools) { + let tokenFlow = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(pools.payload, 'tokens') + distributeTokens(pools, tokenFlow) + } + + function resetTokenFlow(node) { + if (node === undefined) { return } + if (node.payload === undefined) { return } + node.payload.tokenFlow = 0 + /* + If there is a reference parent defined, this means that the token flow is + transfered to it and not distributed among children. + */ + if (node.payload.referenceParent !== undefined) { + resetTokenFlow(node.payload.referenceParent) + return + } + /* + When we reach certain node types, we will halt the distribution, because thse are targets for + token flow. + */ + if ( + node.type === 'Asset' || + node.type === 'Feature' + ) { return } + /* + If there is no reference parent we will redistribute token flow among children. + */ + let schemaDocument = getSchemaDocument(node) + if (schemaDocument === undefined) { return } + + if (schemaDocument.childrenNodesProperties !== undefined) { + for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { + let property = schemaDocument.childrenNodesProperties[i] + + switch (property.type) { + case 'node': { + if (node.type === 'Pools' && property.name === "votesDistribution") { + let childNode = node[property.name] + resetTokenFlow(childNode) + } + } + break + case 'array': { + let propertyArray = node[property.name] + if (propertyArray !== undefined) { + for (let m = 0; m < propertyArray.length; m++) { + let childNode = propertyArray[m] + resetTokenFlow(childNode) + } + } + break + } + } + } + } + } + + function distributeTokens(node, tokenFlow) { + if (node === undefined) { return } + if (node.payload === undefined) { return } + /* + Let's get the schemaDocument first + */ + let schemaDocument = getSchemaDocument(node) + if (schemaDocument === undefined) { return } + /* + At hierarchy heads we will shouw how many tokens are comming in. + */ + if ( + schemaDocument.isHierarchyHead === true + ) { + drawTokenFlow(node, tokenFlow) + } + /* + We will also have tokens at nodes with weight. + */ + if ( + isNaN(node.payload.weight) !== true && + node.payload.weight !== undefined && + node.payload.weight !== 0 + ) { + node.payload.tokenFlow = tokenFlow * node.payload.weight + drawTokenFlow(node, node.payload.tokenFlow, node.payload.weight) + } + /* + If there is a reference parent defined, this means that the token flow is + transfered to it and not distributed among children. + */ + if (node.payload.referenceParent !== undefined) { + distributeTokens(node.payload.referenceParent, node.payload.tokenFlow) + return + } + /* + When we reach certain node types, we will halt the distribution, because these are targets for + token flow. + */ + if ( + node.type === 'Asset' || + node.type === 'Feature' + ) { return } + + if (schemaDocument.childrenNodesProperties !== undefined) { + for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { + let property = schemaDocument.childrenNodesProperties[i] + + switch (property.type) { + case 'node': { + if (node.type === 'Pools' && property.name === "votesDistribution") { + let childNode = node[property.name] + distributeTokens(childNode, tokenFlow) + } + } + break + case 'array': { + let propertyArray = node[property.name] + if (propertyArray !== undefined) { + for (let m = 0; m < propertyArray.length; m++) { + let childNode = propertyArray[m] + distributeTokens(childNode, tokenFlow) + } + } + break + } + } + } + } + } + + function drawTokenFlow(node, tokenFlow, weight) { + if (weight !== undefined && weight !== 0) { + tokenFlow = new Intl.NumberFormat().format(tokenFlow) + ' ' + 'SA Tokens' + ' - ' + 'Weight: ' + weight.toFixed(2) + } else { + tokenFlow = new Intl.NumberFormat().format(tokenFlow) + ' ' + 'SA Tokens' + } + + if (node.payload !== undefined) { + node.payload.uiObject.setStatus(tokenFlow) + } + } +} \ No newline at end of file diff --git a/Projects/Governance/UI/Function-Libraries/Votes.js b/Projects/Governance/UI/Function-Libraries/Votes.js new file mode 100644 index 000000000..eb09ce06d --- /dev/null +++ b/Projects/Governance/UI/Function-Libraries/Votes.js @@ -0,0 +1,274 @@ +function newGovernanceFunctionLibraryVotes() { + let thisObject = { + calculate: calculate + } + + return thisObject + + function calculate() { + let pools = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Pools') + /* Reset Votes at Pools */ + for (let i = 0; i < pools.length; i++) { + let poolsNode = pools[i] + resetVotes(poolsNode) + } + + let features = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Features') + /* Reset Votes at Features */ + for (let i = 0; i < features.length; i++) { + let feature = features[i] + resetVotes(feature) + } + + let assets = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Assets') + /* Reset Votes at Features */ + for (let i = 0; i < assets.length; i++) { + let asset = assets[i] + resetVotes(asset) + } + + let positions = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Positions') + /* Reset Votes at Features */ + for (let i = 0; i < positions.length; i++) { + let position = positions[i] + resetVotes(position) + } + + let userProfiles = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('User Profile') + /* + We will first reset all the voting power, and then distribute it. + */ + for (let i = 0; i < userProfiles.length; i++) { + let userProfile = userProfiles[i] + resetVotes(userProfile) + } + for (let i = 0; i < userProfiles.length; i++) { + let userProfile = userProfiles[i] + distributeVotes(userProfile) + } + } + + function resetVotes(userProfile) { + resetVotingPower(userProfile) + } + + function distributeVotes(userProfile) { + let votes = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(userProfile.payload, 'tokens') + distributeVotingPower(userProfile, votes) + } + + function resetVotingPower(node) { + if (node === undefined) { return } + if (node.payload === undefined) { return } + node.payload.votes = 0 + /* + If there is a reference parent defined, this means that the voting power is + transfered to it and not distributed among children. + */ + if (node.payload.referenceParent !== undefined) { + resetVotingPower(node.payload.referenceParent) + return + } + /* + When we reach certain node types, we will halt the distribution, because thse are targets for + voting power. + */ + if ( + node.type === 'Position' || + node.type === 'Asset' || + node.type === 'Feature' + ) { return } + /* + If there is no reference parent we will redistribute voting power among children. + */ + let schemaDocument = getSchemaDocument(node) + if (schemaDocument === undefined) { return } + + if (schemaDocument.childrenNodesProperties !== undefined) { + for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { + let property = schemaDocument.childrenNodesProperties[i] + + if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue } + + switch (property.type) { + case 'node': { + if (node.type === 'User Profile' && property.name === "votesDistribution") { + let childNode = node[property.name] + resetVotingPower(childNode) + } + } + break + case 'array': { + let propertyArray = node[property.name] + if (propertyArray !== undefined) { + for (let m = 0; m < propertyArray.length; m++) { + let childNode = propertyArray[m] + resetVotingPower(childNode) + } + } + break + } + } + } + } + } + + function distributeVotingPower(node, votes, switchPercentage) { + if (node === undefined) { return } + if (node.payload === undefined) { return } + node.payload.votes = node.payload.votes + votes + drawVotingPower(node, node.payload.votes, switchPercentage) + /* + When we reach certain node types, we will halt the distribution, because thse are targets for + voting power. + */ + if ( + node.type === 'Position' || + node.type === 'Asset' || + node.type === 'Feature' || + node.type === 'Pool' || + node.type === 'Position Contribution Claim' || + node.type === 'Asset Contribution Claim' || + node.type === 'Feature Contribution Claim' + ) { return } + /* + If there is a reference parent defined, this means that the voting power is + transfered to it and not distributed among children. + */ + if (node.payload.referenceParent !== undefined) { + distributeVotingPower(node.payload.referenceParent, votes) + return + } + /* + If there is no reference parent we will redistribute voting power among children. + */ + let schemaDocument = getSchemaDocument(node) + if (schemaDocument === undefined) { return } + + if (schemaDocument.childrenNodesProperties !== undefined) { + /* + Before distributing the voting power, we will calculate how the power + is going to be switched between all nodes. The first pass is about + scanning all sibling nodes to see which ones have a percentage defined + at their config, and check that all percentages don't add more than 100. + */ + let totalPercentage = 0 + let totalNodesWithoutPercentage = 0 + for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { + let property = schemaDocument.childrenNodesProperties[i] + + if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue } + + switch (property.type) { + case 'node': { + if (node.type === 'User Profile' && property.name === "votesDistribution") { + let childNode = node[property.name] + let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage') + if (percentage !== undefined && isNaN(percentage) !== true) { + totalPercentage = totalPercentage + percentage + } else { + totalNodesWithoutPercentage++ + } + } + } + break + case 'array': { + let propertyArray = node[property.name] + if (propertyArray !== undefined) { + + for (let m = 0; m < propertyArray.length; m++) { + let childNode = propertyArray[m] + let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage') + if (percentage !== undefined && isNaN(percentage) !== true) { + totalPercentage = totalPercentage + percentage + } else { + totalNodesWithoutPercentage++ + } + } + } + break + } + } + } + if (totalPercentage > 100) { + node.payload.uiObject.setErrorMessage('Voting Power Switching Error. Total Percentage of children nodes is grater that 100.') + return + } + let defaultPercentage = 0 + if (totalNodesWithoutPercentage > 0) { + defaultPercentage = (100 - totalPercentage) / totalNodesWithoutPercentage + } + /* + Here we do the actual distribution. + */ + for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { + let property = schemaDocument.childrenNodesProperties[i] + + if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue } + + switch (property.type) { + case 'node': { + if (node.type === 'User Profile' && property.name === "votesDistribution") { + let childNode = node[property.name] + let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage') + if (percentage === undefined || isNaN(percentage) === true) { + percentage = defaultPercentage + } + distributeVotingPower(childNode, votes * percentage / 100, percentage) + } + } + break + case 'array': { + let propertyArray = node[property.name] + if (propertyArray !== undefined) { + for (let m = 0; m < propertyArray.length; m++) { + let childNode = propertyArray[m] + let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage') + if (percentage === undefined || isNaN(percentage) === true) { + percentage = defaultPercentage + } + distributeVotingPower(childNode, votes * percentage / 100, percentage) + } + } + break + } + } + } + } + } + + function drawVotingPower(node, votes, percentage) { + votes = new Intl.NumberFormat().format(votes) + ' ' + 'Votes' + if (node.payload !== undefined) { + if (node.type === 'User Profile') { + return + } + if ( + node.type === 'Position' || + node.type === 'Position Class' || + node.type === 'Pool' || + node.type === 'Tokens Switch' || + node.type === 'Asset' || + node.type === 'Asset Class' || + node.type === 'Feature' || + node.type === 'Feature Class' || + node.type === 'Position Contribution Claim' || + node.type === 'Asset Contribution Claim' || + node.type === 'Feature Contribution Claim' + ) { + node.payload.uiObject.valueAngleOffset = 0 + node.payload.uiObject.valueAtAngle = false + } else { + node.payload.uiObject.valueAngleOffset = 180 + node.payload.uiObject.valueAtAngle = true + } + + node.payload.uiObject.setValue(votes) + + if (percentage !== undefined) { + node.payload.uiObject.setPercentage(percentage.toFixed(2)) + } + } + } + +} \ No newline at end of file diff --git a/Projects/Governance/UI/Function-Libraries/Weights.js b/Projects/Governance/UI/Function-Libraries/Weights.js index e988f3097..671a334a7 100644 --- a/Projects/Governance/UI/Function-Libraries/Weights.js +++ b/Projects/Governance/UI/Function-Libraries/Weights.js @@ -1,11 +1,11 @@ function newGovernanceFunctionLibraryWeights() { let thisObject = { - calculateWeights: calculateWeights + calculate: calculate } return thisObject - function calculateWeights(node) { + function calculate(node) { let totalVotes = 0 countVotesAndResetWeights(node) applyWeightCalculation(node) diff --git a/Projects/Governance/UI/Spaces/Assets-Space/Assets.js b/Projects/Governance/UI/Spaces/Assets-Space/Assets.js index b299efd07..da7d3fcf0 100644 --- a/Projects/Governance/UI/Spaces/Assets-Space/Assets.js +++ b/Projects/Governance/UI/Spaces/Assets-Space/Assets.js @@ -32,7 +32,7 @@ function newGobernanceAssetsSpace() { /* Weight Calculation Follows */ for (let i = 0; i < assets.length; i++) { let asset = assets[i] - UI.projects.governance.functionLibraries.weights.calculateWeights(asset) + UI.projects.governance.functionLibraries.weights.calculate(asset) } } diff --git a/Projects/Governance/UI/Spaces/Features-Space/Features.js b/Projects/Governance/UI/Spaces/Features-Space/Features.js index 31221b350..b89e531cc 100644 --- a/Projects/Governance/UI/Spaces/Features-Space/Features.js +++ b/Projects/Governance/UI/Spaces/Features-Space/Features.js @@ -32,7 +32,7 @@ function newGovernanceFeaturesSpace() { /* Weight Calculation Follows */ for (let i = 0; i < features.length; i++) { let feature = features[i] - UI.projects.governance.functionLibraries.weights.calculateWeights(feature) + UI.projects.governance.functionLibraries.weights.calculate(feature) } } diff --git a/Projects/Governance/UI/Spaces/Pools-Space/Pools.js b/Projects/Governance/UI/Spaces/Pools-Space/Pools.js index f861a0262..e88b69fe6 100644 --- a/Projects/Governance/UI/Spaces/Pools-Space/Pools.js +++ b/Projects/Governance/UI/Spaces/Pools-Space/Pools.js @@ -37,169 +37,7 @@ function newGovernancePoolsSpace() { function physics() { if (UI.projects.superalgos.spaces.designSpace.workspace === undefined) { return } - let pools = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Pools') - - /* Weight Calculation Follows */ - for (let i = 0; i < pools.length; i++) { - let poolsNode = pools[i] - UI.projects.governance.functionLibraries.weights.calculateWeights(poolsNode) - } - /* - We will reset all the token flows, and then distribute it. - */ - for (let i = 0; i < pools.length; i++) { - let poolsNode = pools[i] - poolsReset(poolsNode) - } - for (let i = 0; i < pools.length; i++) { - let poolsNode = pools[i] - poolsDistribute(poolsNode) - } - } - - function poolsReset(pools) { - resetTokenFlow(pools) - } - - function poolsDistribute(pools) { - let tokenFlow = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(pools.payload, 'tokens') - distributeTokens(pools, tokenFlow) - } - - function resetTokenFlow(node) { - if (node === undefined) { return } - if (node.payload === undefined) { return } - node.payload.tokenFlow = 0 - /* - If there is a reference parent defined, this means that the token flow is - transfered to it and not distributed among children. - */ - if (node.payload.referenceParent !== undefined) { - resetTokenFlow(node.payload.referenceParent) - return - } - /* - When we reach certain node types, we will halt the distribution, because thse are targets for - token flow. - */ - if ( - node.type === 'Asset' || - node.type === 'Feature' - ) { return } - /* - If there is no reference parent we will redistribute token flow among children. - */ - let schemaDocument = getSchemaDocument(node) - if (schemaDocument === undefined) { return } - - if (schemaDocument.childrenNodesProperties !== undefined) { - for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { - let property = schemaDocument.childrenNodesProperties[i] - - switch (property.type) { - case 'node': { - if (node.type === 'Pools' && property.name === "votesDistribution") { - let childNode = node[property.name] - resetTokenFlow(childNode) - } - } - break - case 'array': { - let propertyArray = node[property.name] - if (propertyArray !== undefined) { - for (let m = 0; m < propertyArray.length; m++) { - let childNode = propertyArray[m] - resetTokenFlow(childNode) - } - } - break - } - } - } - } - } - - function distributeTokens(node, tokenFlow) { - if (node === undefined) { return } - if (node.payload === undefined) { return } - /* - Let's get the schemaDocument first - */ - let schemaDocument = getSchemaDocument(node) - if (schemaDocument === undefined) { return } - /* - At hierarchy heads we will shouw how many tokens are comming in. - */ - if ( - schemaDocument.isHierarchyHead === true - ) { - drawTokenFlow(node, tokenFlow) - } - /* - We will also have tokens at nodes with weight. - */ - if ( - isNaN(node.payload.weight ) !== true && - node.payload.weight !== undefined && - node.payload.weight !== 0 - ) { - node.payload.tokenFlow = tokenFlow * node.payload.weight - drawTokenFlow(node, node.payload.tokenFlow, node.payload.weight) - } - /* - If there is a reference parent defined, this means that the token flow is - transfered to it and not distributed among children. - */ - if (node.payload.referenceParent !== undefined) { - distributeTokens(node.payload.referenceParent, node.payload.tokenFlow) - return - } - /* - When we reach certain node types, we will halt the distribution, because these are targets for - token flow. - */ - if ( - node.type === 'Asset' || - node.type === 'Feature' - ) { return } - - if (schemaDocument.childrenNodesProperties !== undefined) { - for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { - let property = schemaDocument.childrenNodesProperties[i] - - switch (property.type) { - case 'node': { - if (node.type === 'Pools' && property.name === "votesDistribution") { - let childNode = node[property.name] - distributeTokens(childNode, tokenFlow) - } - } - break - case 'array': { - let propertyArray = node[property.name] - if (propertyArray !== undefined) { - for (let m = 0; m < propertyArray.length; m++) { - let childNode = propertyArray[m] - distributeTokens(childNode, tokenFlow) - } - } - break - } - } - } - } - } - - function drawTokenFlow(node, tokenFlow, weight) { - if (weight !== undefined && weight !== 0) { - tokenFlow = new Intl.NumberFormat().format(tokenFlow) + ' ' + 'SA Tokens' + ' - ' + 'Weight: ' + weight.toFixed(2) - } else { - tokenFlow = new Intl.NumberFormat().format(tokenFlow) + ' ' + 'SA Tokens' - } - - if (node.payload !== undefined) { - node.payload.uiObject.setStatus(tokenFlow) - } + UI.projects.governance.functionLibraries.tokens.calculate() } function draw() { diff --git a/Projects/Governance/UI/Spaces/Positions-Space/Positions.js b/Projects/Governance/UI/Spaces/Positions-Space/Positions.js index 91a45f5d6..b2c9360b1 100644 --- a/Projects/Governance/UI/Spaces/Positions-Space/Positions.js +++ b/Projects/Governance/UI/Spaces/Positions-Space/Positions.js @@ -34,7 +34,7 @@ function newGovernancePositionsSpace() { /* Weight Calculation Follows */ for (let i = 0; i < positions.length; i++) { let position = positions[i] - UI.projects.governance.functionLibraries.weights.calculateWeights(position) + UI.projects.governance.functionLibraries.weights.calculate(position) } } diff --git a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js index fb2b13715..0b2367533 100644 --- a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js +++ b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js @@ -37,266 +37,7 @@ function newGovernanceUserProfileSpace() { function physics() { if (UI.projects.superalgos.spaces.designSpace.workspace === undefined) { return } - let pools = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Pools') - /* Reset Votes at Pools */ - for (let i = 0; i < pools.length; i++) { - let poolsNode = pools[i] - resetVotes(poolsNode) - } - - let features = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Features') - /* Reset Votes at Features */ - for (let i = 0; i < features.length; i++) { - let feature = features[i] - resetVotes(feature) - } - - let assets = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Assets') - /* Reset Votes at Features */ - for (let i = 0; i < assets.length; i++) { - let asset = assets[i] - resetVotes(asset) - } - - let positions = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Positions') - /* Reset Votes at Features */ - for (let i = 0; i < positions.length; i++) { - let position = positions[i] - resetVotes(position) - } - - let userProfiles = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('User Profile') - /* - We will first reset all the voting power, and then distribute it. - */ - for (let i = 0; i < userProfiles.length; i++) { - let userProfile = userProfiles[i] - resetVotes(userProfile) - } - for (let i = 0; i < userProfiles.length; i++) { - let userProfile = userProfiles[i] - distributeVotes(userProfile) - } - } - - function resetVotes(userProfile) { - resetVotingPower(userProfile) - } - - function distributeVotes(userProfile) { - let votes = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(userProfile.payload, 'tokens') - distributeVotingPower(userProfile, votes) - } - - function resetVotingPower(node) { - if (node === undefined) { return } - if (node.payload === undefined) { return } - node.payload.votes = 0 - /* - If there is a reference parent defined, this means that the voting power is - transfered to it and not distributed among children. - */ - if (node.payload.referenceParent !== undefined) { - resetVotingPower(node.payload.referenceParent) - return - } - /* - When we reach certain node types, we will halt the distribution, because thse are targets for - voting power. - */ - if ( - node.type === 'Position' || - node.type === 'Asset' || - node.type === 'Feature' - ) { return } - /* - If there is no reference parent we will redistribute voting power among children. - */ - let schemaDocument = getSchemaDocument(node) - if (schemaDocument === undefined) { return } - - if (schemaDocument.childrenNodesProperties !== undefined) { - for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { - let property = schemaDocument.childrenNodesProperties[i] - - if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue } - - switch (property.type) { - case 'node': { - if (node.type === 'User Profile' && property.name === "votesDistribution") { - let childNode = node[property.name] - resetVotingPower(childNode) - } - } - break - case 'array': { - let propertyArray = node[property.name] - if (propertyArray !== undefined) { - for (let m = 0; m < propertyArray.length; m++) { - let childNode = propertyArray[m] - resetVotingPower(childNode) - } - } - break - } - } - } - } - } - - function distributeVotingPower(node, votes, switchPercentage) { - if (node === undefined) { return } - if (node.payload === undefined) { return } - node.payload.votes = node.payload.votes + votes - drawVotingPower(node, node.payload.votes, switchPercentage) - /* - When we reach certain node types, we will halt the distribution, because thse are targets for - voting power. - */ - if ( - node.type === 'Position' || - node.type === 'Asset' || - node.type === 'Feature' || - node.type === 'Pool' - ) { return } - /* - If there is a reference parent defined, this means that the voting power is - transfered to it and not distributed among children. - */ - if (node.payload.referenceParent !== undefined) { - distributeVotingPower(node.payload.referenceParent, votes) - return - } - /* - If there is no reference parent we will redistribute voting power among children. - */ - let schemaDocument = getSchemaDocument(node) - if (schemaDocument === undefined) { return } - - if (schemaDocument.childrenNodesProperties !== undefined) { - /* - Before distributing the voting power, we will calculate how the power - is going to be switched between all nodes. The first pass is about - scanning all sibling nodes to see which ones have a percentage defined - at their config, and check that all percentages don't add more than 100. - */ - let totalPercentage = 0 - let totalNodesWithoutPercentage = 0 - for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { - let property = schemaDocument.childrenNodesProperties[i] - - if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue } - - switch (property.type) { - case 'node': { - if (node.type === 'User Profile' && property.name === "votesDistribution") { - let childNode = node[property.name] - let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage') - if (percentage !== undefined && isNaN(percentage) !== true) { - totalPercentage = totalPercentage + percentage - } else { - totalNodesWithoutPercentage++ - } - } - } - break - case 'array': { - let propertyArray = node[property.name] - if (propertyArray !== undefined) { - - for (let m = 0; m < propertyArray.length; m++) { - let childNode = propertyArray[m] - let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage') - if (percentage !== undefined && isNaN(percentage) !== true) { - totalPercentage = totalPercentage + percentage - } else { - totalNodesWithoutPercentage++ - } - } - } - break - } - } - } - if (totalPercentage > 100) { - node.payload.uiObject.setErrorMessage('Voting Power Switching Error. Total Percentage of children nodes is grater that 100.') - return - } - let defaultPercentage = 0 - if (totalNodesWithoutPercentage > 0) { - defaultPercentage = (100 - totalPercentage) / totalNodesWithoutPercentage - } - /* - Here we do the actual distribution. - */ - for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { - let property = schemaDocument.childrenNodesProperties[i] - - if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue } - - switch (property.type) { - case 'node': { - if (node.type === 'User Profile' && property.name === "votesDistribution") { - let childNode = node[property.name] - let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage') - if (percentage === undefined || isNaN(percentage) === true) { - percentage = defaultPercentage - } - distributeVotingPower(childNode, votes * percentage / 100, percentage) - } - } - break - case 'array': { - let propertyArray = node[property.name] - if (propertyArray !== undefined) { - for (let m = 0; m < propertyArray.length; m++) { - let childNode = propertyArray[m] - let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage') - if (percentage === undefined || isNaN(percentage) === true) { - percentage = defaultPercentage - } - distributeVotingPower(childNode, votes * percentage / 100, percentage) - } - } - break - } - } - } - } - } - - function drawVotingPower(node, votes, percentage) { - votes = new Intl.NumberFormat().format(votes) + ' ' + 'Votes' - if (node.payload !== undefined) { - if (node.type === 'User Profile') { - return - } - if ( - node.type === 'Position' || - node.type === 'Position Class' || - node.type === 'Pool' || - node.type === 'Tokens Switch' || - node.type === 'Asset' || - node.type === 'Asset Class' || - node.type === 'Feature' || - node.type === 'Feature Class' || - node.type === 'Position Contribution Claim' || - node.type === 'Asset Contribution Claim' || - node.type === 'Feature Contribution Claim' - ) { - node.payload.uiObject.valueAngleOffset = 0 - node.payload.uiObject.valueAtAngle = false - } else { - node.payload.uiObject.valueAngleOffset = 180 - node.payload.uiObject.valueAtAngle = true - } - - node.payload.uiObject.setValue(votes) - - if (percentage !== undefined) { - node.payload.uiObject.setPercentage(percentage.toFixed(2)) - } - } + UI.projects.governance.functionLibraries.votes.calculate() } function draw() { diff --git a/Projects/ProjectsSchema.json b/Projects/ProjectsSchema.json index 8e2eb41dc..35c56119d 100644 --- a/Projects/ProjectsSchema.json +++ b/Projects/ProjectsSchema.json @@ -995,10 +995,30 @@ } ], "functionLibraries": [ + { + "name": "Votes", + "propertyName": "votes", + "functionName": "newGovernanceFunctionLibraryVotes" + }, + { + "name": "Tokens", + "propertyName": "tokens", + "functionName": "newGovernanceFunctionLibraryTokens" + }, { "name": "Weights", "propertyName": "weights", "functionName": "newGovernanceFunctionLibraryWeights" + }, + { + "name": "Claims", + "propertyName": "claims", + "functionName": "newGovernanceFunctionLibraryClaims" + }, + { + "name": "Distribution Process", + "propertyName": "distributionProcess", + "functionName": "newGovernanceFunctionLibraryDistributionProcess" } ], "utilities": [