diff --git a/Client/WebServer/css/governance.css b/Client/WebServer/css/governance.css
new file mode 100644
index 000000000..ec2258bec
--- /dev/null
+++ b/Client/WebServer/css/governance.css
@@ -0,0 +1,1117 @@
+
+.governance-page {
+ border: 0px solid;
+ background-color: whitesmoke;
+ /*background-color: #fdfdfd;*/
+ }
+
+ .governance-search-page-container {
+ font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+ color: #365558;
+ line-height: 150%;
+ margin: 20 25 20 30px;
+ }
+
+ .governance-common-style-container{
+ /*background-color: white;*/
+ font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+ color: #324d50;
+ line-height: 150%;
+ margin: 20 30px;
+ margin: 20 25 20 30px;
+ caret-color: transparent;
+ }
+
+ .governance-node-html-footer-container {
+ font: 400 14px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+ color: #e6eaea;
+ background-color: #365558;
+ line-height: 160%;
+ border-top: 5px solid #0295aa;
+ margin: 80px 0 0 0;
+ padding: 30 0 20 0px;
+ caret-color: transparent;
+ }
+
+ /* DELETE candidate (delete class assignment on DocsSapace.js too)
+
+ .governance-context-menu-clickeable-container {
+ font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+ color: #111;
+ line-height: 150%;
+ margin: 20 20 20 30px;
+ }
+
+ */
+
+ #governance-common-style-container-div ul {
+ padding: 0px;
+ margin-left: 35px;
+ list-style-position: outside;
+ }
+
+ .governance-font-normal {
+ font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+ color: #111;
+ line-height: 150%;
+ }
+
+ .governance-title-table {
+ vertical-align: middle;
+ width: 100%;
+ min-width: 95px;
+ margin-bottom: 0px;
+ margin-top: 0px;
+ border: 0px solid #cdcdcd;
+ padding: 5px;
+ }
+
+ .governance-table-cell{
+ display: table-cell;
+ width: 100%;
+ }
+
+ .governance-definition-table {
+ background-color: white;
+ vertical-align: middle;
+ margin-bottom: 20px;
+ margin-top: 0px;
+ border: 1px solid #cdcdcd;
+ border-radius: 5px;
+ padding: 10px;
+ display: table;
+ width: 100%;
+ box-sizing: border-box;
+ border-collapse: separate;
+ border-spacing: 10px;
+ /* DELETE candidate
+ margin-right: 20px;
+ */
+ }
+
+ .governance-definition-text {
+ display: table-cell;
+ vertical-align: middle;
+ padding: 0 20px;
+ }
+
+ .governance-image-container {
+ padding: 5px 0px 5px 5px;
+ border: solid 0px;
+ display: table-cell;
+ vertical-align: middle;
+ }
+
+ .governance-hierarchy-image-container {
+ padding: 0px 0px 0px 0px;
+ border: solid 0px;
+ margin-left: auto;
+ margin-right: auto;
+ width: 100%;
+ }
+
+ /* Link without tooltip */
+ .governance-link {
+ position: relative;
+ display: inline-block;
+ color: #0295aa !important;
+ text-decoration: underline !important;
+ cursor: pointer;
+ }
+
+ /* Tooltip container */
+ .governance-tooltip {
+ position: relative;
+ display: inline-block;
+ border-bottom: 1px dashed #999;
+ cursor: pointer;
+ line-height: inherit;
+ }
+
+ /* Tooltip text */
+ .governance-tooltip .governance-tooltiptext {
+ visibility: hidden;
+ width: 240px;
+ background-color: #0295aa;
+ color: #fff;
+ font-weight: normal;
+ font-style: normal;
+ font-size: 15px;
+ line-height: 130%;
+ text-align: center;
+ padding: 15px;
+ border-radius: 6px;
+
+ /* Position the governance-tooltip text */
+ position: absolute;
+ z-index: 0;
+ bottom: 125%;
+ left: 50%;
+ margin-left: -120px;
+
+
+ /* Fade in governance-tooltip */
+ opacity: 0;
+ transition: opacity 0.3s;
+ }
+
+ /* Tooltip arrow */
+ .governance-tooltip .governance-tooltiptext::after {
+ content: "";
+ position: absolute;
+ top: 100%;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 5px;
+ border-style: solid;
+ border-color: #0295aa transparent transparent transparent;
+ }
+
+ /* Show the tooltip text when you mouse over the tooltip container */
+ .governance-tooltip:hover .governance-tooltiptext {
+ visibility: visible;
+ opacity: 1;
+ }
+
+ /* Headings */
+
+ .governance-h1 {
+ font-size:210%;
+ margin-top: 40px;
+ padding-bottom: 5px;
+ }
+
+ .governance-h2 {
+ font-weight:700;
+ font-size:170%;
+ line-height: 170%;
+ margin-top: 30px;
+ padding-bottom: 5px;
+ overflow:hidden;
+ }
+
+ .governance-h2::after{
+ content:'';
+ display:inline-block;
+ width:90%;
+ margin-right:-100%;
+ border-bottom: 1px solid #cdd4d5;
+ margin-left: 20px;
+ }
+
+ .governance-h3 {
+ font-weight:500;
+ font-size:150%;
+ margin-top: 40px;
+ margin-bottom: 20px;
+ }
+
+ .governance-h4 {
+ font-weight:400;
+ font-style: italic;
+ font-size:135%;
+ margin-top: 30px;
+ margin-bottom: 20px;
+ }
+
+ /* DELETE candidate
+
+ .governance-h5 {font-weight:400; font-size:140%; margin-top: 35px; font-style:italic;}
+
+ .governance-h6 {font-weight:400; font-size:130%; margin-top: 35px; font-style:italic;}
+ margin-right: 20px;
+
+ */
+ .governance-text-area {
+ font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+ resize: none;
+ outline: none;
+ box-shadow: none;
+ overflow:hidden;
+ background-color: #eff;
+ border: 1px solid #0295aa;
+ border-radius: 5px;
+ color: #111;
+ width: 100%;
+ height: 25%;
+ z-index:100;
+ padding: 0px 10px;
+ font-size: 95%;
+ line-height: 140%;
+ caret-color: #111;
+ }
+
+ /* Alerts */
+ .governance-alert-note {
+ color: #31708f;
+ background-color: #d9edf7;
+ padding: 15px;
+ border: 1px solid rgba(49, 112, 143, .3);
+ border-radius: 4px;
+ margin: 20px 0;
+ width: 100%;
+ box-sizing: border-box;
+ }
+
+ .governance-alert-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+ padding: 15px;
+ border: 1px solid rgba(60, 118, 61, .3);
+ border-radius: 4px;
+ margin: 20px 0;
+ width: 100%;
+ box-sizing: border-box;
+ }
+
+ .governance-alert-important {
+ color: #5e3e07;
+ background-color: #fcf8e3;
+ padding: 15px;
+ border: 1px solid rgba(138, 109, 59, .3);
+ border-radius: 4px;
+ margin: 20px 0;
+ width: 100%;
+ box-sizing: border-box;
+ }
+
+ .governance-alert-warning {
+ color: #a94442;
+ background-color: #f2dede;
+ padding: 15px;
+ border: 1px solid rgba(169, 68, 66, .3);
+ border-radius: 4px;
+ margin: 20px 0;
+ width: 100%;
+ box-sizing: border-box;
+ }
+
+ .governance-alert-error {
+ color: #fff16c;
+ background-color: #ff3131;
+ padding: 30px;
+ border: 1px solid rgba(0, 0, 0, .5);
+ border-radius: 4px;
+ margin: 20px 0;
+ width: 100%;
+ box-sizing: border-box;
+ }
+
+ .governance-callout {
+ background-color:white;
+ padding: 20px;
+ margin: 20px 0;
+ border: 1px solid rgba(54, 85, 88, .3);
+ border-left-width: 5px;
+ border-radius: 3px;
+ border-left-color: #bcd643;
+ font-weight: 550 !important;
+ width: 100%;
+ box-sizing: border-box;
+ }
+
+ .governance-topic-index {
+ background-color:white;
+ padding: 25 20px;
+ margin: 40px 0 0 0;
+ border: 1px solid rgba(49, 112, 143, .2);
+ border-left-width: 5px;
+ border-radius: 5px;
+ border-left-color: #365558;
+ width: 100%;
+ box-sizing: border-box;
+ }
+
+ .governance-topic-index h2 {
+ font-size: 130%;
+ font-weight: 300;
+ margin: 10px 0 35 -5;
+ padding: 0px;
+ }
+
+ .governance-topic-index h3 {
+ font-size: 150%;
+ font-weight: 300;
+ margin: 25px 0;
+ padding: 0px;
+ }
+
+ .governance-topic-index p {
+ font-size: 100%;
+ padding: 0px;
+ margin: 2px 0;
+ }
+
+ .governance-topic-index a {
+ color: #365558;
+ }
+
+ .governance-topic-index a:hover {
+ text-decoration: underline;
+ cursor: pointer;
+ color: #0295aa;
+ }
+
+ .governance-summary {
+ background-color:white;
+ font-weight: 600;
+ color: #365558;
+ padding: 20px;
+ margin-bottom: 20px;
+ border-radius: 5px;
+ border: 1px solid rgba(54, 85, 88, .3);
+ border-left: 5px solid #fd6a33;
+ width: 100%;
+ box-sizing: border-box;
+ }
+
+ .governance-section {
+ font-size:120%;
+ padding: 200px;
+ }
+
+ .governance-note-circle:before {
+ content:"\f05a"
+ }
+
+ .governance-check-square-o:before {
+ content:"\f046"
+ }
+
+ .governance-exclamation-circle:before {
+ content:"\f06a"
+ }
+
+ .governance-warning-sign:before,.fa-exclamation-triangle:before {
+ content:"\f06a"
+ }
+
+ .governance-fa {
+ font:normal normal normal 14px/1 FontAwesome;
+ font-size:inherit;
+ text-rendering:auto;
+ -webkit-font-smoothing:antialiased;
+ -moz-osx-font-smoothing:grayscale
+ }
+
+ .governance-font-small {
+ font:normal normal normal 14px/1 "segoeui";
+ font-size:inherit;
+ text-rendering:auto;
+ -webkit-font-smoothing:antialiased;
+ -moz-osx-font-smoothing:grayscale;
+ line-height: 150%
+ }
+
+ li > .governance-font-small {
+ margin-bottom:7px;
+ }
+
+ div.governance-font-small {
+ margin-bottom:7px;
+ }
+
+ hr.governance-shaded {
+ box-shadow: inset 0 6px 6px -6px rgba(0,0,0,0.5);
+ margin: 90 0 70 0;
+ height: 12px;
+ border: 0;
+ background: white;
+ width: 100%;
+ }
+
+ /* Topic Navigation */
+
+ .governance-topic-navigation {
+ display: table;
+ width: 100%;
+ vertical-align: middle;
+ margin: 80px 0 0 0;
+ /*
+ border-top: 1px solid rgba(54, 85, 88, .3);
+ margin: 60px 0 0 0;
+ padding-top: 20px;
+ */
+ }
+
+ .governance-topic-navigation div {
+ display: table-cell;
+ width: 50%;
+ max-width: 50%;
+ text-align: center;
+ vertical-align: top;
+ padding: 10px;
+ /*
+ height: 40px;
+ */
+ }
+
+ .governance-topic-navigation div button{
+ border-radius: 50px;
+ border: 0px;
+ color: #e6eaea;
+ background-color: #365558;
+ padding: 10px;
+ margin: 0 0 10 10px;
+ font-size: 100%;
+ line-height: 150%;
+ width: 150px;
+ height:100%;
+ }
+
+ .governance-topic-navigation div button:hover {
+ background-color: #0295aa;
+ cursor: pointer;
+ }
+
+ /* Footer */
+
+ .governance-node-html-footer-table {
+ display: table;
+ width: 100%;
+ border-collapse: separate;
+ border-spacing: 6px;
+ }
+
+ .governance-footer-row {
+ display: table-row;
+ }
+
+ .governance-footer-cell {
+ padding: 5px 15px 0px 30px;
+ display: table-cell;
+ width: 33%;
+ }
+
+ #governance-footer h3 {
+ font-size: 180%;
+ font-weight: 300;
+ padding: 10px 0 0 0;
+ }
+
+ #governance-footer h4 {
+ font-size: 120%;
+ font-weight: 300;
+ }
+
+ #governance-footer button{
+ border: 1px outset #e6eaea;
+ border-radius: 20px;
+ background-color: transparent;
+ color: e6eaea;
+ padding: 10px;
+ margin: 0 0 0 10px;
+ }
+
+ #governance-footer button:hover {
+ border: 1px inset #e6eaea;
+ cursor: pointer;
+ }
+
+ #governance-footer a:hover {
+ text-decoration: none;
+ color: #ff8c29 !important;
+ cursor: pointer;
+ }
+
+ #governance-footer a:link,
+ #governance-footer a:visited,
+ #governance-footer a:active {
+ text-decoration: none;
+ color: #ffd1a9;
+ }
+
+ .governance-footer-language {
+ width: 30px;
+ margin-top: 7px;
+ padding: 7 7px;
+ }
+
+ .governance-footer-language-selected {
+ width: 30px;
+ margin-top: 7px;
+ padding: 7 7px;
+ background-color: rgba(230, 234, 234, 0.2);
+ /* border: 1px solid rgba(205, 212, 213, 0.5); DELETE Candidate*/
+ border: 1px solid rgba(200, 200, 200, .5);
+ border-radius: 3px;
+ }
+
+
+ /* DELETE candidate
+ .governance-footer-body {
+ position: relative;
+ min-height: 1px;
+ padding-right: 15px;
+ padding-left: 15px;
+ }
+ */
+
+ /* Links */
+ a:link.governance-plain-link {
+ text-decoration: none;
+ }
+
+ a:visited.governance-plain-link {
+ text-decoration: none;
+ }
+
+ a:hover.governance-plain-link {
+ text-decoration: none;
+ }
+
+ a:active.governance-plain-link {
+ text-decoration: none;
+ }
+
+ /* Icon after external links, using FontAwesome*/
+ a[href^="http://"]:after, a[href^="https://"]:after {
+ content: "\f08e";
+ font-family: FontAwesome;
+ font-weight: normal;
+ font-style: normal;
+ display: inline-block;
+ text-decoration: none;
+ padding-left: 3px;
+ }
+
+ /* Tags */
+
+ kbd.governance-kbd {
+ margin: 0 0 0 15px;
+ }
+
+ code.governance-code {
+ color: #d9534f;
+ background-color: rgba(230, 234, 234, .5);
+ /* border: 1px solid rgba(205, 212, 213, 0.5); DELETE Candidate*/
+ border: 1px solid rgba(54, 85, 88, .1);
+ border-radius: 3px;
+ padding: 0 5;
+ }
+
+ code.governance-footer-code {
+ color: #eee;
+ background-color: rgba(230, 234, 234, 0.2);
+ /* border: 1px solid rgba(205, 212, 213, 0.5); DELETE Candidate*/
+ border: 1px solid rgba(200, 200, 200, .5);
+ border-radius: 3px;
+ padding: 0 5;
+ }
+
+ a:hover.code.governance-footer-code {
+ color: #eee;
+ background-color: rgba(253, 106, 51, 1);
+ /* border: 1px solid rgba(205, 212, 213, 0.5); DELETE Candidate*/
+ border: 1px solid rgba(200, 200, 200, .5);
+ border-radius: 3px;
+ padding: 0 5;
+ }
+
+ /* Style the button that is used to open and close the governance-collapsible-element content */
+ .governance-collapsible-element {
+ background-color: #eee;
+ color: #31708f;
+ cursor: pointer;
+ width: 97.5%;
+ text-align: left;
+ outline: none;
+ font-size: 100%;
+ padding: 10px;
+ margin: 4px 0 4 20;
+ transition: 0.1s;
+ /* border: 1px solid #ddd; DELETE Candidate*/
+ border: 1px solid rgba(54, 85, 88, .3);
+ border-radius: 5px;
+ background-color: white;
+ vertical-align: middle;
+ box-sizing: border-box;
+ }
+
+ .governance-collapsible-element img {
+ vertical-align: middle;
+ display: inline-block;
+ margin: 0 20px 0 0;
+ width: 40px;
+ height: 40px;
+ }
+
+ /* This definition is redundant with .governance-collapsible-element img but affects some images. Investigation required to delete it.*/
+
+ .governance-collapsible-image {
+ vertical-align: middle;
+ display: inline-block;
+ margin: 0 20px 0 0;
+ width: 40px;
+ height: 40px;
+ }
+
+ /* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */
+ .active, .governance-collapsible-element:hover {
+ border: 1px solid #0295aa;
+ background-color: #eff;
+ }
+
+ /* Style the governance-collapsible-element content. Note: hidden by default */
+ .governance-collapsible-content {
+ padding: 0 18px;
+ display: none;
+ margin-left: 75px;
+ z-index: 1;
+ font-size: 90%;
+ line-height: 90%;
+ }
+
+ .governance-collapsible-code-content {
+ padding: 0;
+ display: none;
+ margin-left: 0px;
+ z-index: 1;
+ }
+
+ .governance-collapsible-element:after {
+ content: '\02795'; /* Unicode character for "plus" sign (+) */
+ font-size: 60%;
+ color: #31708f;
+ margin-left: 5px;
+ float: right;
+ vertical-align: middle;
+ line-height: 40px;
+ }
+
+ .governance-collapsible-active:after {
+ content: "\2796"; /* Unicode character for "minus" sign (-) */
+ }
+
+ /* This is the same Style as the collapsible counter part but will not hold any collapsed content inside. */
+ .governance-non-collapsible-element {
+ /*
+ background-color: #fdfdfd;
+ color: #444;
+ padding: 15px;
+ width: 100%;
+ border: none;
+ text-align: left;
+ outline: none;
+ font-size: 125%;
+ vertical-align: middle;
+ min-height: 80px;
+ */
+ background-color: #eee;
+ color: #31708f;
+ width: 97.5%;
+ text-align: left;
+ outline: none;
+ font-size: 100%;
+ vertical-align: middle;
+ padding: 10px;
+ margin: 4px 0 4 20;
+ transition: 0.1s;
+ /* border: 1px solid #ddd;DELETE Candidate*/
+ border: 1px solid rgba(54, 85, 88, .3);
+ border-radius: 5px;
+ background-color: white;
+
+ box-sizing: border-box;
+ }
+
+ /* Info Tables */
+ .governance-info-table {
+ background-color: transparent;
+ max-width: 100%;
+ margin-bottom: 20px;
+ margin-top: 20px;
+ /* border: 1px solid #cdcdcd; DELETE Candidate*/
+ border: 1px solid rgba(54, 85, 88, .3);
+ border-spacing: 0px;
+ }
+
+ .governance-info-table > thead > tr > th,
+ .governance-info-table > tbody > tr > th,
+ .governance-info-table > tfoot > tr > th,
+ .governance-info-table > thead > tr > td,
+ .governance-info-table > tbody > tr > td,
+ .governance-info-table > tfoot > tr > td {
+ padding: 8px;
+ line-height: 150%;
+ vertical-align: top;
+ }
+
+ .governance-info-table > thead > tr > th > a {
+ vertical-align: middle;
+ text-transform: none;
+ background-color: #333;
+ color: white;
+ text-align: left;
+ }
+
+ .governance-info-table > tbody > tr > td {
+ /* border-top: 1px solid #cdcdcd; DELETE Candidate*/
+ border: 1px solid rgba(54, 85, 88, .3);
+ }
+
+ .governance-info-table-alt-bg td {
+ background-color: #f9f9f9;
+ }
+
+ /* Gif Image */
+ .governance-gif {
+ max-width: 100%;
+ width: 100%;
+ /* border: 1px solid #cdcdcd; DELETE Candidate*/
+ border: 1px solid rgba(54, 85, 88, .3);
+ border-spacing: 1px;
+ }
+
+ /* PNG Image */
+ .governance-png {
+ max-width: 100%;
+ width: 100%;
+ /* border: 1px solid #cdcdcd; DELETE Candidate*/
+ border: 1px solid rgba(54, 85, 88, .3);
+ border-spacing: 1px;
+ }
+
+ /* Search Page */
+ .governance-image-logo-search {
+ margin: auto;
+ margin-top: 225px;
+ margin-bottom: 25px;
+ }
+
+ .governance-search-box {
+ width: 700px;
+ height: 45px;
+ margin-top: 50px;
+ margin-bottom: 600px;
+ border-radius: 30px;
+ border: 1px solid #0295aa;
+ background-color: white;
+ vertical-align: middle;
+ }
+
+ .governance-search-input {
+ width: 95%;
+ height: 45px;
+ margin: 0 20px;
+ font-size: 100%;
+ color: #6b6b6b;
+ border: none;
+ outline: none;
+ background-color: transparent;
+ }
+
+ /* Search Results Page */
+
+ /* Search Results Page Header*/
+
+ .governance-report-page-header {
+ display: table;
+ }
+
+ .governance-image-logo-report-page {
+ vertical-align: middle;
+ display: table-cell;
+ padding-right: 25px;
+ caret-color: transparent;
+ }
+
+ .governance-report-page-box {
+ height: 45px;
+ border-radius: 30px;
+ border: 1px solid #0295aa;
+ background-color: white;
+ vertical-align: middle;
+ display: table-cell;
+ width: 100%;
+ }
+
+ .governance-report-page-header-tabs-container {
+ display: table;
+ padding-left: 180px;
+ margin-top: 20px;
+ caret-color: transparent;
+ }
+
+ .governance-report-page-header-tabs-container > input {
+ display: none;
+ }
+
+ .governance-report-page-header-tabs-container > label {
+ display: inline-block;
+ vertical-align: bottom;
+ padding: 0 15px 3px 15px;
+ color: #365558;
+ font-size: 90%;
+ }
+
+ .governance-report-page-header-tabs-container > label:hover {
+ color: #0295aa;
+ padding-bottom: 3px;
+ cursor: pointer;
+ }
+
+ .governance-report-page-header-tabs-container > input:checked + label {
+ color: #0295aa;
+ padding-bottom: 2px;
+ border-bottom: 3px solid #0295aa;
+ }
+
+ /* Search Results Page Content */
+ .governance-search-result-content {
+ border-top: 1px solid #0295aa;
+ margin-left: -180px;
+ caret-color: transparent;
+ }
+
+ .governance-search-result-content > div {
+ display: none;
+ }
+
+ #tab1:checked ~ .governance-search-result-content #content1,
+ #tab2:checked ~ .governance-search-result-content #content2,
+ #tab3:checked ~ .governance-search-result-content #content3,
+ #tab4:checked ~ .governance-search-result-content #content4,
+ #tab5:checked ~ .governance-search-result-content #content5,
+ #tab6:checked ~ .governance-search-result-content #content6,
+ #tab7:checked ~ .governance-search-result-content #content7,
+ #tab8:checked ~ .governance-search-result-content #content8 {
+ display: block;
+ }
+
+ /* Search Results Page Record */
+
+ .governance-search-result-content-record-container {
+ margin: 20px 0;
+ }
+
+ .governance-search-result-content-record-container > p {
+ margin: 1px;
+ }
+
+ .governance-search-result-content-record-project-category {
+ font-size: 90%;
+ color: #31708f;
+ }
+
+ .governance-search-result-content-record-project-category-link {
+ font-size: 90%;
+ color: #31708f;
+ }
+
+ a:hover.governance-search-result-content-record-project-category-link {
+ text-decoration: underline;
+ cursor: pointer;
+ }
+
+ .governance-search-result-content-record-topic {
+ font-size: 90%;
+ color: #31708f;
+ }
+
+ .governance-search-result-content-record-tutorial {
+ font-size: 90%;
+ color: #31708f;
+ }
+
+ .governance-search-result-content-record-review {
+ font-size: 90%;
+ color: #31708f;
+ }
+
+ .governance-search-result-content-record-topic {
+ font-size: 90%;
+ color: #31708f;
+ }
+
+ .governance-search-result-content-record-tutorial {
+ font-size: 90%;
+ color: #31708f;
+ }
+
+ .governance-search-result-content-record-review {
+ font-size: 90%;
+ color: #31708f;
+ }
+
+ .governance-search-result-content-record-title {
+ font-size: 120%;
+ font-weight: 500;
+ text-decoration: none;
+ color: #e44d40;
+ }
+
+ a:link.governance-search-result-content-record-title {
+ text-decoration: none;
+ color: #e44d40;
+ }
+
+ a:visited.governance-search-result-content-record-title {
+ text-decoration: none;
+ color: #fd6a33;
+ }
+
+ a:hover.governance-search-result-content-record-title {
+ text-decoration: underline;
+ cursor: pointer;
+ }
+
+ a:active.governance-search-result-content-record-title {
+ text-decoration: none;
+ color: #fd6a33;
+ }
+
+ .governance-search-result-content-record-extract {
+ font-size: 100%;
+ color: #333;
+ margin-top: 5px!important;
+ }
+
+ /* Command Results Page Content */
+ .governance-command-result-content {
+ /* border-top: 1px solid #cdcdcd; DELETE Candidate*/
+ border: 1px solid rgba(54, 85, 88, .3);
+ margin-left: -240px;
+ }
+
+ .governance-command-result-message {
+ font-size: 90%;
+ color: #31708f;
+ }
+
+ .governance-hidden-anchor {
+ border-top: 1px solid #eee;
+ padding: 0px;
+ margin: -20px 0px -40px 0;
+ width: 100%;
+ text-align: right;
+ color: transparent;
+ font-size: 75%;
+ }
+
+ .governance-hidden-anchor::after{
+ content:' \2693';
+ color: transparent;
+ font-size: 130%;
+ }
+
+ .governance-hidden-anchor:hover::after{
+ content:' \2693';
+ color: #365558;
+ font-size: 130%;
+ }
+
+ .governance-hidden-block {
+ border-top: 1px solid #eee;
+ padding: 0px;
+ margin: -5px 0px -30px 0;
+ width: 100%;
+ text-align: right;
+ color: transparent;
+ font-size: 75%;
+ }
+
+ .governance-hidden-block::after{
+ content:' \25BD';
+ color: #e0e0e0;
+ font-size: 150%;
+ }
+
+ .governance-hidden-block:hover::after{
+ content:' \25BC';
+ color: #365558;
+ font-size: 150%;
+ }
+
+ .governance-hidden-include {
+ border-top: 1px solid #eee;
+ padding: 0px;
+ margin: -5px 0px -30px 0;
+ width: 100%;
+ text-align: right;
+ color: transparent;
+ font-size: 75%;
+ }
+
+ .governance-hidden-include::after{
+ content:' \275E';
+ color: #e6e6e6;
+ font-size: 200%;
+ }
+
+ .governance-hidden-include:hover::after{
+ content:' \275E';
+ color: #365558;
+ font-size: 200%;
+ }
+
+ .governance-hidden-placeholder {
+ border-top: 1px solid #eee;
+ padding: 0px;
+ margin: -5px 0px -30px 0;
+ width: 100%;
+ text-align: right;
+ color: transparent;
+ font-size: 75%;
+ }
+
+ .governance-hidden-placeholder::after{
+ content:' \275E';
+ color: #e6e6e6;
+ font-size: 200%;
+ }
+
+ .governance-hidden-placeholder:hover::after{
+ content:' \275E';
+ color: #365558;
+ font-size: 200%;
+ }
+
+ /* Hierarchy Table */
+ .governance-hierarchy-table {
+ min-width: 100%;
+ max-width: 100%;
+ margin-bottom: 20px;
+ margin-top: 20px;
+ /* border: 1px solid #cdcdcd; DELETE Candidate*/
+ border: 1px solid rgba(54, 85, 88, .3);
+ border-spacing: 0;
+ border-collapse: collapse;
+ font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+ color: #111;
+ }
+
+ .governance-hierarchy-table-row{
+ background-color: #f5f5f5;
+ }
+
+ .governance-hierarchy-table-cell{
+ text-align: center;
+ vertical-align: middle;
+ }
+
+ .governance-external-link {
+ text-decoration: underline;
+ color: #31708f;
+ }
+
+ .governance-chapter {
+ border-top: 1px solid #eee;
+ padding: 0px;
+ margin: -5px 0px -30px 0;
+ width: 100%;
+ height: 40px;
+ text-align: right;
+ color: transparent;
+ font-size: 75%;
+ }
+
+ .governance-youtube-video-container{
+ background-color: white;
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
+ margin-bottom: 35px;
+ max-width: 830px;
+ max-height: 476px;
+ }
+
+
\ No newline at end of file
diff --git a/Client/WebServer/index.html b/Client/WebServer/index.html
index a693d0d9d..73898b909 100644
--- a/Client/WebServer/index.html
+++ b/Client/WebServer/index.html
@@ -8,6 +8,7 @@
+
@@ -115,6 +116,9 @@
+
diff --git a/Client/httpInterface.js b/Client/httpInterface.js
index 44900a6e5..283405b10 100644
--- a/Client/httpInterface.js
+++ b/Client/httpInterface.js
@@ -1547,6 +1547,12 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
}
break
+ case 'governance.css':
+ {
+ sendStyleSheet('governance.css')
+ }
+ break
+
case 'context-menu.css':
{
sendStyleSheet('context-menu.css')
diff --git a/Projects/Education/UI/Spaces/Docs-Space/DocsSpace.js b/Projects/Education/UI/Spaces/Docs-Space/DocsSpace.js
index b4053b0e3..bc35e0c59 100644
--- a/Projects/Education/UI/Spaces/Docs-Space/DocsSpace.js
+++ b/Projects/Education/UI/Spaces/Docs-Space/DocsSpace.js
@@ -171,11 +171,8 @@ function newEducationDocSpace() {
}
function setupSidePanelTab() {
- thisObject.sidePanelTab = newSidePanelTab()
- thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false)
- thisObject.sidePanelTab.tabIcon = UI.projects.foundations.spaces.designSpace.getIconByProjectAndName('Education', 'docs-tab')
- thisObject.sidePanelTab.tabLabel = 'Docs'
- thisObject.sidePanelTab.initialize('right')
+ thisObject.sidePanelTab = UI.projects.foundations.spaces.sideSpace.createSidePanelTab(thisObject.container, 'Education', 'docs-tab', 'Docs', 'right')
+
openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', onOpening)
closingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closing', onClosing)
@@ -437,7 +434,6 @@ function newEducationDocSpace() {
}
function physics() {
- thisObject.sidePanelTab.physics()
docsAppDivPhysics()
function docsAppDivPhysics() {
@@ -461,7 +457,6 @@ function newEducationDocSpace() {
if (CAN_SPACES_DRAW === false) { return }
if (isInitialized === false) { return }
borders()
- thisObject.sidePanelTab.draw()
}
function borders() {
diff --git a/Projects/Education/UI/Spaces/Tutorial-Space/TutorialSpace.js b/Projects/Education/UI/Spaces/Tutorial-Space/TutorialSpace.js
index dc7b974c9..c6d05730c 100644
--- a/Projects/Education/UI/Spaces/Tutorial-Space/TutorialSpace.js
+++ b/Projects/Education/UI/Spaces/Tutorial-Space/TutorialSpace.js
@@ -363,7 +363,7 @@ function newEducationTutorialSpace() {
This forces the tutorial to close the workspaces panel and to keep it closed.
*/
if (workspacesCounter === 5) {
- UI.projects.foundations.spaces.sideSpace.sidePanelTab.close()
+ UI.projects.foundations.spaces.workspaceSpace.sidePanelTab.close()
}
return
}
@@ -372,7 +372,7 @@ function newEducationTutorialSpace() {
This forces the tutorial to open the workspaces panel and to keep it closed.
*/
if (workspacesCounter === 5) {
- UI.projects.foundations.spaces.sideSpace.sidePanelTab.open()
+ UI.projects.foundations.spaces.workspaceSpace.sidePanelTab.open()
}
return
}
diff --git a/Projects/Foundations/UI/Spaces/Chat-Space/ChatSpace.js b/Projects/Foundations/UI/Spaces/Chat-Space/ChatSpace.js
index d4450a10d..5df19ec8f 100644
--- a/Projects/Foundations/UI/Spaces/Chat-Space/ChatSpace.js
+++ b/Projects/Foundations/UI/Spaces/Chat-Space/ChatSpace.js
@@ -31,10 +31,9 @@ function newFoundationsChatSpace() {
return thisObject
function initialize() {
-
- thisObject.sidePanelTab = newSidePanelTab()
- thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false)
- thisObject.sidePanelTab.initialize('right', 1)
+ return
+ thisObject.sidePanelTab = UI.projects.foundations.spaces.sideSpace.createSidePanelTab(thisObject.container, 'Education', 'docs-tab', 'Docs', 'right')
+
openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', onOpening)
closingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closing', onClosing)
@@ -89,15 +88,14 @@ function newFoundationsChatSpace() {
return thisObject.container
} else {
UI.projects.foundations.spaces.chartingSpace.viewport.onMouseWheel(event)
- return
+ return
}
} else {
- return
+ return
}
}
function physics() {
- thisObject.sidePanelTab.physics()
chatAppDivPhysics()
iFramePhysics()
@@ -108,18 +106,18 @@ function newFoundationsChatSpace() {
y: 0
}
chatAppDivPosition = thisObject.container.frame.frameThisPoint(chatAppDivPosition)
- chatAppDiv.style = ' ' +
- 'position:fixed; top:' + chatAppDivPosition.y + 'px; ' +
- 'left:' + chatAppDivPosition.x + 'px; z-index:1; ' +
- 'width: ' + thisObject.container.frame.width + 'px;' +
- 'height: ' + thisObject.container.frame.height + 'px'
+ chatAppDiv.style = ' ' +
+ 'position:fixed; top:' + chatAppDivPosition.y + 'px; ' +
+ 'left:' + chatAppDivPosition.x + 'px; z-index:1; ' +
+ 'width: ' + thisObject.container.frame.width + 'px;' +
+ 'height: ' + thisObject.container.frame.height + 'px'
}
function iFramePhysics() {
let docIFrame = document.getElementById('chatIFrame')
- docIFrame.style = ' ' +
- 'width: ' + thisObject.container.frame.width + 'px;' +
- 'height: ' + thisObject.container.frame.height + 'px'
+ docIFrame.style = ' ' +
+ 'width: ' + thisObject.container.frame.width + 'px;' +
+ 'height: ' + thisObject.container.frame.height + 'px'
}
}
@@ -127,7 +125,6 @@ function newFoundationsChatSpace() {
if (CAN_SPACES_DRAW === false) { return }
if (isInitialized === false) { return }
borders()
- thisObject.sidePanelTab.draw()
}
function borders() {
diff --git a/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js b/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js
index 16a8f958d..ccde486e1 100644
--- a/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js
+++ b/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js
@@ -311,7 +311,7 @@ function newWorkspace() {
workingAtTask = 0
UI.projects.education.spaces.docsSpace.sidePanelTab.close()
- UI.projects.foundations.spaces.sideSpace.sidePanelTab.close()
+ UI.projects.foundations.spaces.workspaceSpace.sidePanelTab.close()
UI.projects.foundations.spaces.floatingSpace.inMapMode = true
workingAtTask = 2
break
@@ -413,6 +413,8 @@ function newWorkspace() {
UI.projects.foundations.spaces.floatingSpace.inMapMode = false
thisObject.isInitialized = true
+ UI.projects.governance.spaces.reportsSpace.reset()
+
await UI.projects.education.spaces.docsSpace.reset()
await UI.projects.education.spaces.tutorialSpace.reset()
diff --git a/Projects/Foundations/UI/Spaces/Side-Space/SidePanelTab.js b/Projects/Foundations/UI/Spaces/Side-Space/SidePanelTab.js
index cb6fb44ae..0fe13a547 100644
--- a/Projects/Foundations/UI/Spaces/Side-Space/SidePanelTab.js
+++ b/Projects/Foundations/UI/Spaces/Side-Space/SidePanelTab.js
@@ -15,7 +15,8 @@ function newSidePanelTab() {
physics: physics,
draw: draw,
getContainer: getContainer,
- initialize: initialize
+ initialize: initialize,
+ finalize: finalize
}
const TAB_WIDTH = 60
@@ -26,6 +27,7 @@ function newSidePanelTab() {
let animation = 'none'
let ORIGINAL_PARENT_POSITON
let xOffset = 0
+ let onMouseClickEventSubscriptionId
thisObject.container = newContainer()
thisObject.container.name = MODULE_NAME
@@ -35,6 +37,11 @@ function newSidePanelTab() {
return thisObject
+ function finalize() {
+ thisObject.pointerDirection = undefined
+ thisObject.container.eventHandler.stopListening(onMouseClickEventSubscriptionId)
+ }
+
function initialize(screenside, index) {
thisObject.screenside = screenside
if (index !== undefined) {
@@ -54,7 +61,7 @@ function newSidePanelTab() {
thisObject.container.frame.width = TAB_WIDTH
thisObject.container.frame.height = TAB_HEIGHT
- thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
+ onMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
resize()
isInitialized = true
}
@@ -126,9 +133,7 @@ function newSidePanelTab() {
}
function positionPhysics() {
- if (UI.projects.foundations.spaces.chartingSpace.viewport !== undefined) {
- thisObject.container.frame.position.y = browserCanvas.height / 2 - TAB_HEIGHT / 2 // TOP_SPACE_HEIGHT + UI.projects.foundations.spaces.chartingSpace.viewport.marginAmount + TAB_HEIGHT * thisObject.index
- }
+ thisObject.container.frame.position.y = browserCanvas.height / 2 - TAB_HEIGHT / 2 + (thisObject.index - 1) * TAB_HEIGHT
}
function draw() {
@@ -382,7 +387,7 @@ function newSidePanelTab() {
labelPosition = thisObject.container.frame.frameThisPoint(labelPosition)
- browserCanvasContext.font = 12 + 'px ' + UI_FONT.PRIMARY
+ browserCanvasContext.font = 12 + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREY + ', 1)'
browserCanvasContext.fillText(
thisObject.tabLabel,
diff --git a/Projects/Foundations/UI/Spaces/Side-Space/SideSpace.js b/Projects/Foundations/UI/Spaces/Side-Space/SideSpace.js
index 3ea331d34..54c027dab 100644
--- a/Projects/Foundations/UI/Spaces/Side-Space/SideSpace.js
+++ b/Projects/Foundations/UI/Spaces/Side-Space/SideSpace.js
@@ -1,173 +1,129 @@
function newFoundationsSideSpace() {
- const MODULE_NAME = 'Side Space'
let thisObject = {
sidePanelTab: undefined,
container: undefined,
+ leftTabs: undefined,
+ rightTabs: undefined,
physics: physics,
draw: draw,
+ createSidePanelTab: createSidePanelTab,
+ deleteSidePanelTab: deleteSidePanelTab,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
}
- let isInitialized = false
+ let existingTabs = new Map()
- thisObject.container = newContainer()
- thisObject.container.name = MODULE_NAME
- thisObject.container.initialize()
- thisObject.container.isClickeable = true
- thisObject.container.isDraggeable = false
- thisObject.container.detectMouseOver = true
- thisObject.container.status = 'hidden'
-
- let listView
-
- resize()
-
- let openingEventSubscriptionId
- let closedEventSubscriptionId
- let browserResizedEventSubscriptionId
return thisObject
function initialize() {
- thisObject.sidePanelTab = newSidePanelTab()
- thisObject.sidePanelTab.tabIcon = UI.projects.foundations.spaces.designSpace.getIconByProjectAndName('Foundations', 'workspace')
- thisObject.sidePanelTab.tabLabel = 'Workspaces'
- thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false)
- thisObject.sidePanelTab.initialize('left')
-
- browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize)
-
- initializeListView()
- isInitialized = true
+ thisObject.leftTabs = []
+ thisObject.rightTabs = []
}
function finalize() {
- canvas.eventHandler.stopListening(browserResizedEventSubscriptionId)
- thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId)
- thisObject.sidePanelTab.container.eventHandler.stopListening(closedEventSubscriptionId)
+ thisObject.leftTabs = undefined
+ thisObject.rightTabs = undefined
+ existingTabs = undefined
}
- function initializeListView() {
- listView = newListView()
- listView.initialize()
- listView.container.connectToParent(thisObject.container, false, false)
- openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', listView.turnOn)
- closedEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closed', listView.turnOff)
- }
+ function createSidePanelTab(container, porject, iconName, label, side) {
- function resize() {
- thisObject.container.frame.width = SIDE_PANEL_WIDTH
- thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT
- thisObject.container.frame.position.x = -SIDE_PANEL_WIDTH
- thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT
+ let sidePanel
- if (listView !== undefined) {
- listView.resize()
+ sidePanel = newSidePanelTab()
+ sidePanel.container.connectToParent(container, false, false)
+ sidePanel.tabIcon = UI.projects.foundations.spaces.designSpace.getIconByProjectAndName(porject, iconName)
+ sidePanel.tabLabel = label
+ sidePanel.initialize(side)
+
+ let key = porject + '-' + iconName + '-' + label + '-' + side
+ if (existingTabs.get(key) !== undefined) { return existingTabs.get(key) }
+
+ switch (side) {
+ case 'left': {
+ thisObject.leftTabs.push(sidePanel)
+ sidePanel.index = thisObject.leftTabs.length
+
+ existingTabs.set(key, sidePanel)
+ break
+ }
+ case 'right': {
+ thisObject.rightTabs.push(sidePanel)
+ sidePanel.index = thisObject.rightTabs.length
+
+ existingTabs.set(key, sidePanel)
+ break
+ }
}
- if (thisObject.sidePanelTab !== undefined) {
- thisObject.sidePanelTab.resize()
+ return sidePanel
+ }
+
+ function deleteSidePanelTab(porject, iconName, label, side) {
+
+ let key = porject + '-' + iconName + '-' + label + '-' + side
+ if (existingTabs.get(key) !== undefined) {
+ let sidePanelTab = existingTabs.get(key)
+
+ switch (side) {
+ case 'left': {
+ thisObject.leftTabs.splice(sidePanelTab.index - 1, 1)
+ break
+ }
+ case 'right': {
+ thisObject.rightTabs.splice(sidePanelTab.index - 1, 1)
+ break
+ }
+ }
+
+ sidePanelTab.finalize()
+ existingTabs.delete(key)
+
+ /*
+ Reindex Remaining SidTabs
+ */
+ let indexLeft = 1
+ let indexRight = 1
+
+ existingTabs.forEach(reindex)
+
+ function reindex(sideTab, key, map) {
+ switch (sideTab.screenside) {
+ case 'left': {
+ sideTab.index = indexLeft
+ indexLeft++
+ break
+ }
+ case 'right': {
+ sideTab.index = indexRight
+ indexRight++
+ break
+ }
+ }
+
+ }
}
}
function getContainer(point, purpose) {
- if (thisObject.sidePanelTab === undefined) { return }
- let container
- container = thisObject.sidePanelTab.getContainer(point, purpose)
- if (container !== undefined) { return container }
-
- container = listView.getContainer(point, purpose)
- if (container !== undefined) { return container }
-
- if (thisObject.container.frame.isThisPointHere(point, true) === true) {
- return thisObject.container
- } else {
- return undefined
- }
}
function physics() {
- thisObject.sidePanelTab.physics()
- listView.physics()
+ existingTabs.forEach(sideTabPhysics)
+
+ function sideTabPhysics(sideTab, key, map) {
+ sideTab.physics()
+ }
}
function draw() {
- if (CAN_SPACES_DRAW === false) { return }
- if (isInitialized === false) { return }
- borders()
- thisObject.sidePanelTab.draw()
- listView.draw()
- }
+ existingTabs.forEach(sideTabDraw)
- function borders() {
- let point1
- let point2
- let point3
- let point4
-
- point1 = {
- x: 0,
- y: 0
- }
-
- point2 = {
- x: thisObject.container.frame.width,
- y: 0
- }
-
- point3 = {
- x: thisObject.container.frame.width,
- y: thisObject.container.frame.height
- }
-
- point4 = {
- x: 0,
- y: thisObject.container.frame.height
- }
-
- point1 = thisObject.container.frame.frameThisPoint(point1)
- point2 = thisObject.container.frame.frameThisPoint(point2)
- point3 = thisObject.container.frame.frameThisPoint(point3)
- point4 = thisObject.container.frame.frameThisPoint(point4)
-
- browserCanvasContext.setLineDash([]) // Resets Line Dash
- browserCanvasContext.beginPath()
- browserCanvasContext.moveTo(point1.x, point1.y)
- browserCanvasContext.lineTo(point2.x, point2.y)
- browserCanvasContext.lineTo(point3.x, point3.y)
- browserCanvasContext.lineTo(point4.x, point4.y)
- browserCanvasContext.lineTo(point1.x, point1.y)
- browserCanvasContext.closePath()
-
- let opacity = 1
-
- browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + opacity + ''
- browserCanvasContext.fill()
-
- browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + ''
- browserCanvasContext.lineWidth = 0.3
- browserCanvasContext.setLineDash([]) // Resets Line Dash
- browserCanvasContext.stroke()
-
- /* Shadow */
-
- if (thisObject.container.status !== 'hidden') {
- for (let i = 0; i <= 30; i++) {
- opacity = 1 - (i / 300) - 0.95
-
- browserCanvasContext.setLineDash([]) // Resets Line Dash
- browserCanvasContext.beginPath()
- browserCanvasContext.moveTo(point2.x + i, point2.y)
- browserCanvasContext.lineTo(point3.x + i, point3.y)
- browserCanvasContext.closePath()
-
- browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + ''
- browserCanvasContext.lineWidth = 1
- browserCanvasContext.setLineDash([]) // Resets Line Dash
- browserCanvasContext.stroke()
- }
+ function sideTabDraw(sideTab, key, map) {
+ sideTab.draw()
}
}
}
diff --git a/Projects/Foundations/UI/Spaces/Workspace-Space/WorkspaceSpace.js b/Projects/Foundations/UI/Spaces/Workspace-Space/WorkspaceSpace.js
new file mode 100644
index 000000000..e90711410
--- /dev/null
+++ b/Projects/Foundations/UI/Spaces/Workspace-Space/WorkspaceSpace.js
@@ -0,0 +1,168 @@
+function newFoundationsWorkspaceSpace() {
+ const MODULE_NAME = 'Workspace Space'
+ let thisObject = {
+ sidePanelTab: undefined,
+ container: undefined,
+ physics: physics,
+ draw: draw,
+ getContainer: getContainer,
+ initialize: initialize,
+ finalize: finalize
+ }
+
+ let isInitialized = false
+
+ thisObject.container = newContainer()
+ thisObject.container.name = MODULE_NAME
+ thisObject.container.initialize()
+ thisObject.container.isClickeable = true
+ thisObject.container.isDraggeable = false
+ thisObject.container.detectMouseOver = true
+ thisObject.container.status = 'hidden'
+
+ let listView
+
+ resize()
+
+ let openingEventSubscriptionId
+ let closedEventSubscriptionId
+ let browserResizedEventSubscriptionId
+ return thisObject
+
+ function initialize() {
+
+ thisObject.sidePanelTab = UI.projects.foundations.spaces.sideSpace.createSidePanelTab(thisObject.container, 'Foundations', 'workspace', 'Workspaces', 'left')
+
+ browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize)
+
+ initializeListView()
+ isInitialized = true
+ }
+
+ function finalize() {
+ canvas.eventHandler.stopListening(browserResizedEventSubscriptionId)
+ thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId)
+ thisObject.sidePanelTab.container.eventHandler.stopListening(closedEventSubscriptionId)
+ }
+
+ function initializeListView() {
+ listView = newListView()
+ listView.initialize()
+ listView.container.connectToParent(thisObject.container, false, false)
+ openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', listView.turnOn)
+ closedEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closed', listView.turnOff)
+ }
+
+ function resize() {
+ thisObject.container.frame.width = SIDE_PANEL_WIDTH
+ thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT
+ thisObject.container.frame.position.x = -SIDE_PANEL_WIDTH
+ thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT
+
+ if (listView !== undefined) {
+ listView.resize()
+ }
+
+ if (thisObject.sidePanelTab !== undefined) {
+ thisObject.sidePanelTab.resize()
+ }
+ }
+
+ function getContainer(point, purpose) {
+ if (thisObject.sidePanelTab === undefined) { return }
+ let container
+
+ container = thisObject.sidePanelTab.getContainer(point, purpose)
+ if (container !== undefined) { return container }
+
+ container = listView.getContainer(point, purpose)
+ if (container !== undefined) { return container }
+
+ if (thisObject.container.frame.isThisPointHere(point, true) === true) {
+ return thisObject.container
+ } else {
+ return undefined
+ }
+ }
+
+ function physics() {
+ listView.physics()
+ }
+
+ function draw() {
+ if (CAN_SPACES_DRAW === false) { return }
+ if (isInitialized === false) { return }
+ borders()
+ listView.draw()
+ }
+
+ function borders() {
+ let point1
+ let point2
+ let point3
+ let point4
+
+ point1 = {
+ x: 0,
+ y: 0
+ }
+
+ point2 = {
+ x: thisObject.container.frame.width,
+ y: 0
+ }
+
+ point3 = {
+ x: thisObject.container.frame.width,
+ y: thisObject.container.frame.height
+ }
+
+ point4 = {
+ x: 0,
+ y: thisObject.container.frame.height
+ }
+
+ point1 = thisObject.container.frame.frameThisPoint(point1)
+ point2 = thisObject.container.frame.frameThisPoint(point2)
+ point3 = thisObject.container.frame.frameThisPoint(point3)
+ point4 = thisObject.container.frame.frameThisPoint(point4)
+
+ browserCanvasContext.setLineDash([]) // Resets Line Dash
+ browserCanvasContext.beginPath()
+ browserCanvasContext.moveTo(point1.x, point1.y)
+ browserCanvasContext.lineTo(point2.x, point2.y)
+ browserCanvasContext.lineTo(point3.x, point3.y)
+ browserCanvasContext.lineTo(point4.x, point4.y)
+ browserCanvasContext.lineTo(point1.x, point1.y)
+ browserCanvasContext.closePath()
+
+ let opacity = 1
+
+ browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + opacity + ''
+ browserCanvasContext.fill()
+
+ browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + ''
+ browserCanvasContext.lineWidth = 0.3
+ browserCanvasContext.setLineDash([]) // Resets Line Dash
+ browserCanvasContext.stroke()
+
+ /* Shadow */
+
+ if (thisObject.container.status !== 'hidden') {
+ for (let i = 0; i <= 30; i++) {
+ opacity = 1 - (i / 300) - 0.95
+
+ browserCanvasContext.setLineDash([]) // Resets Line Dash
+ browserCanvasContext.beginPath()
+ browserCanvasContext.moveTo(point2.x + i, point2.y)
+ browserCanvasContext.lineTo(point3.x + i, point3.y)
+ browserCanvasContext.closePath()
+
+ browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + ''
+ browserCanvasContext.lineWidth = 1
+ browserCanvasContext.setLineDash([]) // Resets Line Dash
+ browserCanvasContext.stroke()
+ }
+ }
+ }
+}
diff --git a/Projects/Governance/Icons/governance-tab.png b/Projects/Governance/Icons/governance-tab.png
new file mode 100644
index 000000000..281622484
Binary files /dev/null and b/Projects/Governance/Icons/governance-tab.png differ
diff --git a/Projects/Governance/UI/Globals/Reports.js b/Projects/Governance/UI/Globals/Reports.js
new file mode 100644
index 000000000..1315a1ec9
--- /dev/null
+++ b/Projects/Governance/UI/Globals/Reports.js
@@ -0,0 +1,6 @@
+function newGovernanceGlobalsReports() {
+ let thisObject = {
+ REPORTS_SPACE_WIDTH: 900
+ }
+ return thisObject
+}
\ No newline at end of file
diff --git a/Projects/Governance/UI/Spaces/Assets-Space/Assets.js b/Projects/Governance/UI/Spaces/Assets-Space/Assets.js
deleted file mode 100644
index 3433850fc..000000000
--- a/Projects/Governance/UI/Spaces/Assets-Space/Assets.js
+++ /dev/null
@@ -1,47 +0,0 @@
-function newGobernanceAssetsSpace() {
- const MODULE_NAME = 'Assets Space'
-
- let thisObject = {
- container: undefined,
- physics: physics,
- draw: draw,
- getContainer: getContainer,
- finalize: finalize,
- initialize: initialize
- }
-
- thisObject.container = newContainer()
- thisObject.container.initialize(MODULE_NAME)
- thisObject.container.isDraggeable = false
-
- return thisObject
-
- function finalize() {
- thisObject.container.finalize()
- thisObject.container = undefined
- }
-
- function initialize() {
-
- }
-
- function physics() {
- if (UI.projects.foundations.spaces.designSpace.workspace === undefined) { return }
- }
-
- function getContainer(point) {
-
- return undefined // since this space does not draw anything we return here
-
- if (thisObject.container.frame.isThisPointHere(point, true) === true) {
- thisObject.container.space = MODULE_NAME
- return thisObject.container
- } else {
- return undefined
- }
- }
-
- function draw() {
-
- }
-}
diff --git a/Projects/Governance/UI/Spaces/Reports-Space/Footer.js b/Projects/Governance/UI/Spaces/Reports-Space/Footer.js
new file mode 100644
index 000000000..f6ec9335b
--- /dev/null
+++ b/Projects/Governance/UI/Spaces/Reports-Space/Footer.js
@@ -0,0 +1,158 @@
+function newGovernanceReportsFooter() {
+ let thisObject = {
+ addFooter: addFooter,
+ initialize: initialize,
+ finalize: finalize
+ }
+
+ return thisObject
+
+ function initialize() {
+
+ }
+
+ function finalize() {
+
+ }
+
+ function addFooter() {
+
+ let HTML = ''
+
+ HTML = HTML + '' // Container Ends
+
+ return HTML
+ }
+}
\ No newline at end of file
diff --git a/Projects/Governance/UI/Spaces/Reports-Space/ReportsPage.js b/Projects/Governance/UI/Spaces/Reports-Space/ReportsPage.js
new file mode 100644
index 000000000..2b979d977
--- /dev/null
+++ b/Projects/Governance/UI/Spaces/Reports-Space/ReportsPage.js
@@ -0,0 +1,87 @@
+function newGovernanceReportsReportsPage() {
+ let thisObject = {
+ render: render,
+ initialize: initialize,
+ finalize: finalize
+ }
+
+ return thisObject
+
+ function initialize() {
+
+ }
+
+ function finalize() {
+
+ }
+
+ function render() {
+
+ let resultsArary = []
+ let initialTime = new Date()
+ buildHTML()
+
+ function buildHTML() {
+ const tabs = ['Profiles', 'Referrals', 'Mentors', 'Supporters', 'Pools', 'Assets', 'Features', 'Positions']
+ let HTML = ''
+ HTML = HTML + ''
+ HTML = HTML + UI.projects.education.spaces.docsSpace.mainSearchPage.addSearchHeader()
+
+ // Tabs
+ HTML = HTML + ''
+
+ // End Section
+ HTML = HTML + ' '
+
+ // Total Seconds Calculation
+ let finalTime = new Date()
+ let totalSeconds = ((finalTime.valueOf() - initialTime.valueOf()) / 1000).toFixed(3)
+ for (let i = 0; i < tabs.length; i++) {
+ let tab = tabs[i]
+ HTML = HTML.replace(tab.toUpperCase() + '_TOTAL_SECONDS', totalSeconds)
+ let resultCounter = totalResults.get(tab)
+ HTML = HTML.replace(tab.toUpperCase() + '_TOTAL_RESULTS', resultCounter)
+ }
+
+ let docsContentDiv = document.getElementById('governance-content-div')
+ docsContentDiv.innerHTML = HTML + UI.projects.governance.spaces.reportsSpace.footer.addFooter()
+
+ UI.projects.education.spaces.docsSpace.mainSearchPage.detectEnterOnSearchBox()
+ UI.projects.education.spaces.docsSpace.mainSearchPage.setFocusOnSearchBox()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Projects/Governance/UI/Spaces/Reports-Space/ReportsSpace.js b/Projects/Governance/UI/Spaces/Reports-Space/ReportsSpace.js
new file mode 100644
index 000000000..6f3e4abac
--- /dev/null
+++ b/Projects/Governance/UI/Spaces/Reports-Space/ReportsSpace.js
@@ -0,0 +1,233 @@
+function newGobernanceReportsSpace() {
+ const MODULE_NAME = 'Reports Space'
+
+ let thisObject = {
+ container: undefined,
+ sidePanelTab: undefined,
+ reportsPage: undefined,
+ footer: undefined,
+ userProfiles: undefined,
+ tablesSortingOrders: undefined,
+ changeTableSortingOrder,
+ physics: physics,
+ draw: draw,
+ getContainer: getContainer,
+ finalize: finalize,
+ initialize: initialize,
+ reset: reset
+ }
+
+ let browserResizedEventSubscriptionId
+ let openingEventSubscriptionId
+ let closingEventSubscriptionId
+
+ let isInitialized = false
+
+ return thisObject
+
+ function finalize() {
+
+ if (isInitialized === false) { return }
+
+ thisObject.container.finalize()
+ thisObject.container = undefined
+
+ canvas.eventHandler.stopListening(browserResizedEventSubscriptionId)
+ thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId)
+ thisObject.sidePanelTab.container.eventHandler.stopListening(closingEventSubscriptionId)
+ thisObject.sidePanelTab = undefined
+
+ UI.projects.foundations.spaces.sideSpace.deleteSidePanelTab('Governance', 'governance-tab', 'Gov', 'right')
+
+ thisObject.reportsPage.finalize()
+ thisObject.reportsPage = undefined
+
+ thisObject.footer.finalize()
+ thisObject.footer = undefined
+
+ thisObject.userProfiles.finalize()
+ thisObject.userProfiles = undefined
+
+ isInitialized = false
+ }
+
+ function initialize() {
+ let resultsArary = UI.projects.foundations.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('User Profile')
+ if (resultsArary.length === 0) { return }
+
+ thisObject.container = newContainer()
+ thisObject.container.name = MODULE_NAME
+ thisObject.container.initialize()
+ thisObject.container.isClickeable = true
+ thisObject.container.isDraggeable = false
+ thisObject.container.detectMouseOver = true
+ thisObject.container.status = 'hidden'
+
+ resize()
+
+ thisObject.reportsPage = newGovernanceReportsReportsPage()
+ thisObject.footer = newGovernanceReportsFooter()
+ thisObject.userProfiles = newGovernanceReportsUserProfiles()
+
+ thisObject.reportsPage.initialize()
+ thisObject.footer.initialize()
+ thisObject.userProfiles.initialize()
+
+ setupSidePanelTab()
+
+ thisObject.tablesSortingOrders = {}
+
+ isInitialized = true
+
+ function setupSidePanelTab() {
+
+ thisObject.sidePanelTab = UI.projects.foundations.spaces.sideSpace.createSidePanelTab(thisObject.container, 'Governance', 'governance-tab', 'Gov', 'right')
+
+ openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', onOpening)
+ closingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closing', onClosing)
+
+ browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize)
+ }
+ }
+
+ function reset() {
+ finalize()
+ initialize()
+ }
+
+ function resize() {
+ thisObject.container.frame.width = UI.projects.governance.globals.reports.REPORTS_SPACE_WIDTH
+ thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT
+ thisObject.container.frame.position.x = browserCanvas.width
+ thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT
+
+ if (thisObject.sidePanelTab !== undefined) {
+ thisObject.sidePanelTab.resize()
+ }
+ }
+
+ function physics() {
+ if (isInitialized === false) { return }
+
+ docsAppDivPhysics()
+
+ function docsAppDivPhysics() {
+ let docsSpaceDiv = document.getElementById('governance-reports-space-div')
+ docsAppDivPosition = {
+ x: 0,
+ y: 0
+ }
+ docsAppDivPosition = thisObject.container.frame.frameThisPoint(docsAppDivPosition)
+ docsSpaceDiv.style = ' ' +
+ 'overflow-y: scroll;' +
+ 'overflow-x: hidden;' +
+ 'position:fixed; top:' + docsAppDivPosition.y + 'px; ' +
+ 'left:' + docsAppDivPosition.x + 'px; z-index:1; ' +
+ 'width: ' + thisObject.container.frame.width + 'px;' +
+ 'height: ' + thisObject.container.frame.height + 'px'
+ }
+ }
+
+ function getContainer(point, purpose) {
+ if (isInitialized === false) { return }
+ if (thisObject.sidePanelTab === undefined) { return }
+ let container
+
+ container = thisObject.sidePanelTab.getContainer(point, purpose)
+ if (container !== undefined) { return container }
+
+ if (thisObject.container.frame.isThisPointHere(point, true) === true) {
+ return thisObject.container
+ } else {
+ return undefined
+ }
+ }
+
+ function changeTableSortingOrder(table, property, order) {
+ thisObject.tablesSortingOrders[table].property = property
+ thisObject.tablesSortingOrders[table].order = order
+ thisObject.reportsPage.render()
+ }
+
+ function onOpening() {
+ thisObject.reportsPage.render()
+ }
+
+ function onClosing() {
+
+ }
+
+ function draw() {
+ if (CAN_SPACES_DRAW === false) { return }
+ if (isInitialized === false) { return }
+ borders()
+ }
+
+ function borders() {
+ let point1
+ let point2
+ let point3
+ let point4
+
+ point1 = {
+ x: 0,
+ y: 0
+ }
+
+ point2 = {
+ x: thisObject.container.frame.width,
+ y: 0
+ }
+
+ point3 = {
+ x: thisObject.container.frame.width,
+ y: thisObject.container.frame.height
+ }
+
+ point4 = {
+ x: 0,
+ y: thisObject.container.frame.height
+ }
+
+ point1 = thisObject.container.frame.frameThisPoint(point1)
+ point2 = thisObject.container.frame.frameThisPoint(point2)
+ point3 = thisObject.container.frame.frameThisPoint(point3)
+ point4 = thisObject.container.frame.frameThisPoint(point4)
+
+ browserCanvasContext.setLineDash([]) // Resets Line Dash
+ browserCanvasContext.beginPath()
+ browserCanvasContext.moveTo(point1.x, point1.y)
+ browserCanvasContext.lineTo(point2.x, point2.y)
+ browserCanvasContext.lineTo(point3.x, point3.y)
+ browserCanvasContext.lineTo(point4.x, point4.y)
+ browserCanvasContext.lineTo(point1.x, point1.y)
+ browserCanvasContext.closePath()
+
+ let opacity = 1
+
+ browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + opacity + ''
+ browserCanvasContext.fill()
+
+ browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + ''
+ browserCanvasContext.lineWidth = 0.3
+ browserCanvasContext.stroke()
+
+ /* Shadow */
+
+ if (thisObject.container.status !== 'hidden') {
+ for (let i = 0; i <= 30; i++) {
+ opacity = 1 - (i / 300) - 0.95
+
+ browserCanvasContext.setLineDash([]) // Resets Line Dash
+ browserCanvasContext.beginPath()
+ browserCanvasContext.moveTo(point2.x + i, point2.y)
+ browserCanvasContext.lineTo(point3.x + i, point3.y)
+ browserCanvasContext.closePath()
+
+ browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + ''
+ browserCanvasContext.lineWidth = 1
+ browserCanvasContext.stroke()
+ }
+ }
+ }
+}
diff --git a/Projects/Governance/UI/Spaces/Reports-Space/UserProfiles.js b/Projects/Governance/UI/Spaces/Reports-Space/UserProfiles.js
new file mode 100644
index 000000000..03fc5dbcf
--- /dev/null
+++ b/Projects/Governance/UI/Spaces/Reports-Space/UserProfiles.js
@@ -0,0 +1,205 @@
+function newGovernanceReportsUserProfiles() {
+ let thisObject = {
+ resultCounter: undefined,
+ addHTML: addHTML,
+ initialize: initialize,
+ finalize: finalize
+ }
+
+ return thisObject
+
+ function initialize() {
+
+ }
+
+ function finalize() {
+
+ }
+
+ function addHTML() {
+
+ thisObject.resultCounter = 0
+ let HTML = ''
+ let tableRecords = []
+ let table = 'userProfiles'
+ let tableRecordDefinition = {
+ "properties": [
+ {
+ "name": "name",
+ "label": "Name",
+ "type": "string",
+ "order": "ascending"
+ },
+ {
+ "name": "blockchainPower",
+ "label": "Blockchain Power",
+ "type": "number",
+ "order": "descending"
+ },
+ {
+ "name": "delegatedPower",
+ "label": "Delegated Power",
+ "type": "number",
+ "order": "descending"
+ },
+ {
+ "name": "tokenPower",
+ "label": "Token Power",
+ "type": "number",
+ "order": "descending"
+ }
+ ]
+ }
+ /*
+ Here we get from the workspace all the nodes representing User Profiles.
+ */
+ let resultsArary = UI.projects.foundations.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('User Profile')
+ /*
+ Transform the result array into table records.
+ */
+ for (let j = 0; j < resultsArary.length; j++) {
+ let node = resultsArary[j]
+
+ let tableRecord = {
+ "name": node.name,
+ "blockchainPower": node.payload.blockchainTokens | 0,
+ "delegatedPower": node.payload.tokenPower - node.payload.blockchainTokens | 0,
+ "tokenPower": node.payload.tokenPower | 0
+ }
+
+ tableRecords.push(tableRecord)
+ }
+ /*
+ Get the sorting order for this table.
+ */
+ let sortingOrder = UI.projects.governance.spaces.reportsSpace.tablesSortingOrders[table]
+ /*
+ Set the default sorting order for this table.
+ */
+ if (sortingOrder === undefined) {
+ UI.projects.governance.spaces.reportsSpace.tablesSortingOrders[table] = {
+ property: 'name',
+ order: 'ascending'
+ }
+ sortingOrder = UI.projects.governance.spaces.reportsSpace.tablesSortingOrders[table]
+ }
+ /*
+ Get the property type for the current sorting order.
+ */
+ let propertyType
+ for (let i = 0; i < tableRecordDefinition.properties.length; i++) {
+ let property = tableRecordDefinition.properties[i]
+ if (property.name === sortingOrder.property) {
+ propertyType = property.type
+ break
+ }
+ }
+ /*
+ Apply the sorting order for this table.
+ */
+ switch (propertyType) {
+ case 'string': {
+ switch (sortingOrder.order) {
+ case 'ascending': {
+ tableRecords.sort((a, b) => (a[sortingOrder.property].toLowerCase() > b[sortingOrder.property].toLowerCase()) ? 1 : -1)
+ break
+ }
+ case 'descending': {
+ tableRecords.sort((a, b) => (a[sortingOrder.property].toLowerCase() > b[sortingOrder.property].toLowerCase()) ? -1 : 1)
+ break
+ }
+ }
+ break
+ }
+ case 'number': {
+ switch (sortingOrder.order) {
+ case 'ascending': {
+ tableRecords.sort((a, b) => (a[sortingOrder.property] > b[sortingOrder.property]) ? 1 : -1)
+ break
+ }
+ case 'descending': {
+ tableRecords.sort((a, b) => (a[sortingOrder.property] > b[sortingOrder.property]) ? -1 : 1)
+ break
+ }
+ }
+ break
+ }
+ }
+
+ /*
+ Build the HTML
+ */
+ let odd = false
+ const upArrow = '↑'
+ const downArrow = '↓'
+
+ HTML = HTML + ''
+ HTML = HTML + ''
+ HTML = HTML + ''
+ for (let i = 0; i < tableRecordDefinition.properties.length; i++) {
+ let property = tableRecordDefinition.properties[i]
+ let newOrder
+ let orderArrow
+ /*
+ If the property is the one defining the order, then the new order will be
+ the opossite order.
+ */
+ if (property.name === sortingOrder.property) {
+ if (sortingOrder.order === 'ascending') {
+ newOrder = 'descending'
+ orderArrow = upArrow
+ } else {
+ newOrder = 'ascending'
+ orderArrow = downArrow
+ }
+ } else {
+ orderArrow = ""
+ /*
+ If the property is not the current defininf the order, then the new order will
+ be the default order for that property.
+ */
+ for (let i = 0; i < tableRecordDefinition.properties.length; i++) {
+ let propertyDefinition = tableRecordDefinition.properties[i]
+ if (property.name === propertyDefinition.name) {
+ newOrder = propertyDefinition.order
+ break
+ }
+ }
+ }
+ HTML = HTML + '' + '' + property.label + ' ' + orderArrow +' ' + ' '
+ }
+ HTML = HTML + ' '
+ HTML = HTML + ''
+ HTML = HTML + ' '
+
+ for (let j = 0; j < tableRecords.length; j++) {
+ let tableRecord = tableRecords[j]
+
+ if (odd === true) {
+ HTML = HTML + ''
+ odd = false
+ } else {
+ HTML = HTML + ' '
+ odd = true
+ }
+
+ /*
+ Iterate through tableRecord properties.
+ */
+ for (var property in tableRecord) {
+ if (Object.prototype.hasOwnProperty.call(tableRecord, property)) {
+ HTML = HTML + '' + tableRecord[property] + ' '
+ }
+ }
+
+ thisObject.resultCounter++
+
+ HTML = HTML + ' '
+ }
+
+ HTML = HTML + ' '
+ HTML = HTML + '
'
+
+ return HTML
+ }
+}
\ No newline at end of file
diff --git a/Projects/ProjectsSchema.json b/Projects/ProjectsSchema.json
index 45d7cf427..38bf41a33 100644
--- a/Projects/ProjectsSchema.json
+++ b/Projects/ProjectsSchema.json
@@ -228,8 +228,8 @@
"initializationIndex": 0,
"animationPhysicsIndex": 1,
"animationDrawIndex": 0,
- "onMouseWheelIndex": 5,
- "onMouseOverIndex": 6,
+ "onMouseWheelIndex": 6,
+ "onMouseOverIndex": 7,
"onMouseClickIndex": 4,
"onMouseDownIndex": 6
},
@@ -253,8 +253,8 @@
"initializationIndex": 2,
"animationPhysicsIndex": 0,
"animationDrawIndex": 5,
- "onMouseWheelIndex": 3,
- "onMouseOverIndex": 2,
+ "onMouseWheelIndex": 4,
+ "onMouseOverIndex": 3,
"onMouseClickIndex": 2,
"onMouseDownIndex": 3
},
@@ -267,7 +267,7 @@
"animationPhysicsIndex": 3,
"animationDrawIndex": 2,
"onMouseWheelIndex": 0,
- "onMouseOverIndex": 5,
+ "onMouseOverIndex": 6,
"onMouseClickIndex": 0,
"onMouseDownIndex": 1
},
@@ -279,8 +279,8 @@
"initializationIndex": 4,
"animationPhysicsIndex": 4,
"animationDrawIndex": 3,
- "onMouseWheelIndex": 2,
- "onMouseOverIndex": 3,
+ "onMouseWheelIndex": 3,
+ "onMouseOverIndex": 4,
"onMouseClickIndex": 3,
"onMouseDownIndex": 4
},
@@ -292,8 +292,8 @@
"initializationIndex": 5,
"animationPhysicsIndex": 2,
"animationDrawIndex": 1,
- "onMouseWheelIndex": 4,
- "onMouseOverIndex": 4,
+ "onMouseWheelIndex": 5,
+ "onMouseOverIndex": 5,
"onMouseClickIndex": 5,
"onMouseDownIndex": 5
},
@@ -305,11 +305,24 @@
"initializationIndex": 6,
"animationPhysicsIndex": 6,
"animationDrawIndex": 6,
- "onMouseWheelIndex": 1,
- "onMouseOverIndex": 2,
+ "onMouseWheelIndex": 2,
+ "onMouseOverIndex": 3,
"onMouseClickIndex": 6,
"onMouseDownIndex": 0
},
+ {
+ "name": "Workspace Space",
+ "folderName": "Workspace-Space",
+ "propertyName": "workspaceSpace",
+ "functionName": "newFoundationsWorkspaceSpace",
+ "initializationIndex": 7,
+ "animationPhysicsIndex": 7,
+ "animationDrawIndex": 7,
+ "onMouseWheelIndex": 1,
+ "onMouseOverIndex": 2,
+ "onMouseClickIndex": 7,
+ "onMouseDownIndex": 0
+ },
{
"name": "Chat Space",
"folderName": "Chat-Space",
@@ -956,7 +969,13 @@
"name": "Governance",
"propertyName": "governance",
"UI": {
- "globals": [],
+ "globals": [
+ {
+ "name": "Reports",
+ "propertyName": "reports",
+ "functionName": "newGovernanceGlobalsReports"
+ }
+ ],
"functionLibraries": [
{
"name": "Assets",
@@ -1066,10 +1085,10 @@
"onMouseDownIndex": 0
},
{
- "name": "Assets Space",
- "folderName": "Assets-Space",
- "propertyName": "assetsSpace",
- "functionName": "newGobernanceAssetsSpace",
+ "name": "Reports Space",
+ "folderName": "Reports-Space",
+ "propertyName": "reportsSpace",
+ "functionName": "newGobernanceReportsSpace",
"initializationIndex": 1,
"animationPhysicsIndex": 1,
"animationDrawIndex": 1,