You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/07/02 10:27:02 UTC

[7/9] incubator-ignite git commit: # ignite-843 Cleanup module.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/stylesheets/style.css
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/stylesheets/style.css b/modules/web-control-center/nodejs/public/stylesheets/style.css
new file mode 100644
index 0000000..fb21a65
--- /dev/null
+++ b/modules/web-control-center/nodejs/public/stylesheets/style.css
@@ -0,0 +1 @@
+.main-header .logo{height:auto}.main-sidebar{padding-top:60px}.navbar-default .navbar-brand,.navbar-default .navbar-brand:hover{position:absolute;width:100%;left:0;text-align:center}.modal-backdrop.am-fade{opacity:.5;transition:opacity .15s linear}.modal-backdrop.am-fade.ng-enter{opacity:0}.modal-backdrop.am-fade.ng-enter.ng-enter-active{opacity:.5}.modal-backdrop.am-fade.ng-leave{opacity:.5}.modal-backdrop.am-fade.ng-leave.ng-leave-active{opacity:0}.modal.center .modal-dialog{position:fixed;top:40%;left:50%;min-width:320px;max-width:630px;width:50%;transform:translateX(-50%) translateY(-50%)}.border-left{box-shadow:1px 0 0 0 #eee inset}.border-right{box-shadow:1px 0 0 0 #eee}.theme-line{background-color:#f9f9f9}.theme-line header{background-color:#fff}.theme-line header a.btn{border:0 none;padding:10px 25px;background-color:rgba(0,0,0,0.15)}.theme-line header a.btn:hover{background-color:rgba(0,0,0,0.25)}.theme-line header a.btn.btn-link{background:transparent;color:rgba(255,255,25
 5,0.8)}.theme-line header a.btn.btn-link:hover{color:#fff;text-decoration:none}.theme-line .navbar-nav a{background-color:transparent}.theme-line .navbar-nav a:hover,.theme-line .navbar-nav a:active,.theme-line .navbar-nav a:focus{background-color:transparent}.theme-line .main-links{padding-top:50px}.theme-line .main-links h3{margin-top:0;font-size:17px}.theme-line .main-links .links a{color:#888}.theme-line .main-links .links a:hover{text-decoration:none}.theme-line #category-columns,.theme-solid #category-columns{margin:50px 30px 0}.theme-line #category-columns h4{text-transform:uppercase;font-weight:300;color:#999;font-size:14px}.theme-line #category-columns ul{list-style:none;padding:0;margin-bottom:15px}.theme-line #category-columns ul li a{padding:4px 0;display:block;font-size:16px}.theme-line #category-columns ul .view-all{font-size:0.85em}.theme-line .docs-header{color:#999;overflow:hidden}.theme-line .docs-header h1{color:#444;margin-top:0;font-size:25px}.theme-line .btn-pr
 imary{border:0 none;background-color:#ec1c24}.theme-line .btn-primary:hover{background-color:#950d12}.theme-line .main-content .nav-horizontal a{box-shadow:0 0;border:0 none;background-color:#fff;border-radius:0;color:#aaa;padding:6px;margin:0 14px}.theme-line .main-content .nav-horizontal a:hover{color:#999;border-bottom:4px solid #ddd}.theme-line .main-content .nav-horizontal a.active{border-bottom:4px solid #888}.theme-line .sidebar-nav{color:#474a54;padding-bottom:30px}.theme-line .sidebar-nav ul{padding:0;list-style:none;font-size:13px;margin:3px 0 0}.theme-line .sidebar-nav ul li a{padding:3px 0;display:block;color:#666;position:relative;white-space:nowrap;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis}.theme-line .sidebar-nav ul li a:before{top:0;content:" ";display:block;width:6px;height:100%;position:absolute;left:-30px}.theme-line .sidebar-nav ul li a:hover{text-decoration:none}.theme-line .select li a{color:#666}.theme-line .select li a:hover,.theme-line
  .select .active{color:#ec1c24;background-color:white}.theme-line .sidebar-nav ul li .subcategory{padding-left:15px}.theme-line .sidebar-nav h4{margin-top:2em;font-weight:normal;text-transform:uppercase;font-size:11px;margin-bottom:10px;color:#bbb}.theme-line .sidebar-nav h4:first-child{margin-top:0}.theme-line .sidebar-nav .ask{width:100%;text-align:center;padding:10px}.theme-line .border-left .sidebar-nav{padding-left:15px}.theme-line .suggest{padding:4px;display:inline-block;font-size:12px}.header{padding:15px}.header .has-github{padding-right:136px}.header h1.navbar-brand{height:40px;width:200px;padding:0;margin:5px 15px 0 0}.header h1.navbar-brand a{text-indent:-99999px;background:no-repeat center center;display:block;width:100%;height:100%;background-size:contain}.header .nav.navbar-nav.pull-right{position:relative;right:-30px}.header .nav.navbar-nav .not-link{padding:15px;display:inline-block}.header .nav.navbar-nav .stable,.header .nav.navbar-nav .beta,.header .nav.navbar-na
 v .private{font-size:9px;padding:3px 5px;display:inline-block;line-height:8px;border-radius:3px;margin-left:6px;color:#fff;top:-2px;position:relative;opacity:0.6;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";filter:alpha(opacity=60)}.header .nav.navbar-nav a:hover>.stable,.header .nav.navbar-nav a:hover>.beta,.header .nav.navbar-nav a:hover>.private{opacity:1;-ms-filter:none;filter:none}.header .nav.navbar-nav .beta{background-color:#59c3d1}.header .nav.navbar-nav .stable{background-color:#41b841}.header .nav.navbar-nav .private{background-color:#333}.theme-line header{border-bottom:8px solid}.theme-line header h2{color:#aaa}.theme-line header p{color:#666}.theme-line header{border-bottom-color:#ec1c24}.theme-line .navbar-nav{color:#888}.theme-line .navbar-nav a{color:#bbb}.theme-line header a.btn{background-color:#ec1c24}.theme-line header a.btn:hover{background-color:#950d12}.theme-line header .navbar-nav .tt-cursor{background-color:#ec1c24}.theme-line header .n
 avbar-nav a:hover,.theme-line header .navbar-nav .open>a{color:#ec1c24}.theme-line .navbar-nav .active a{color:#ec1c24}.theme-line .navbar-nav .active a:hover{color:#950d12}.theme-line .main-links .links a:hover{color:#ec1c24}.theme-line .main-content a{color:#666}.theme-line .main-content a:hover{color:#950d12}.theme-line .sidebar-nav ul li a.active:before{background-color:#ec1c24}.theme-line .sidebar-nav ul li a.active{color:#ec1c24}.theme-line .sidebar-nav ul li a:hover,.theme-line .sidebar-nav ul li a.active:hover{color:#950d12}.theme-line .main-content .nav-horizontal a.active{border-color:#ec1c24;color:#ec1c24}.theme-line .main-content .nav-horizontal a:hover{color:#950d12}.theme-line .main-content .nav-horizontal a.active:hover{border-color:#950d12}.theme-line header .navbar-nav a.active,.theme-line #versions-list li a:hover strong,.theme-line #versions-list li a.active .current,.theme-line #versions-list li a:active .current{color:#ec1c24}.theme-line.body-threes .section-rig
 ht .threes-nav .btn-default:hover,.theme-line.page-docs.body-threes .section-right .threes-nav .pull-right a:hover{color:#ec1c24;border-color:#ec1c24}.theme-line .section-right{padding-left:30px}.body-overlap .main-content{margin-top:30px}.body-box .main-content,.body-overlap .main-content{padding:30px;box-shadow:0 0 0 1px rgba(0,0,0,0.1);background-color:#fff}body{font-weight:400;font-family:Roboto Slab, serif}h1,h2,h3,h4,h5,h6{font-weight:700;font-family:Roboto Slab, serif}.submit-vote.submit-vote-parent.voted a.submit-vote-button,.submit-vote.submit-vote-parent a.submit-vote-button:hover{background-color:#ec1c24}div.submit-vote.submit-vote-parent.voted a.submit-vote-button:hover{background-color:#950d12}a,.link .title{color:#ec1c24}a:hover,.link:hover .title{color:#950d12}.header h1.navbar-brand a{background-image:url("https://www.filepicker.io/api/file/QagunjDGRFul2JgNCAli")}.header h1.navbar-brand{width:96px}.block-edit-parameters{text-align:right;padding-bottom:5px}.ng-table-p
 ager{display:none}.container-footer{margin-top:20px}.vcenter{display:inline-block;vertical-align:middle;float:none}.vcenter2{position:relative;top:50%;transform:translateY(-50%)}.modal{display:block;overflow:hidden}.modal .close{position:absolute;top:0.65em;right:0.65em;float:none}.modal-header .close{margin-right:-2px}.modal .modal-dialog{width:610px}.modal .modal-content{border-radius:0;background-color:#f7f7f7}.modal .modal-content .modal-header{background-color:#fff;text-align:center;color:#555;padding:24px;font-family:"myriad-pro",sans-serif}.modal .modal-content .modal-header h4{font-family:"myriad-pro",sans-serif;font-size:22px}.modal .modal-content .modal-header h4 .fa{display:block;font-size:41px;color:#ddd;margin-bottom:5px}.modal .modal-content .modal-header p{color:#aaa;font-size:1em;margin:3px 0 0}.modal .modal-content .modal-spacer{padding:10px 10px 0 10px}.modal .modal-content .modal-footer{margin-top:0}.modal-body{padding-top:30px}h1.ignite-logo{background-image:url(
 "https://www.filepicker.io/api/file/QagunjDGRFul2JgNCAli")}.st-sort-ascent:after{font-family:FontAwesome, serif;content:'\f077'}.st-sort-descent:after{font-family:FontAwesome, serif;content:'\f078'}.block-display-image img{max-width:100%;max-height:450px;margin:auto;display:block}.greedy{min-height:200px;height:calc(100vh - 230px)}@media (min-width:768px){.navbar-nav>li>a{padding-top:20px;padding-bottom:10px}}.details-row{padding-left:1.3em}.details-table-row{padding:0}.details-row,.settings-row{display:block;margin:0.65em 0;line-height:28px}.details-row [class*="col-"],.settings-row [class*="col-"]{display:inline-block;vertical-align:middle;float:none;padding-left:0 !important;padding-right:0 !important}.details-row input[type="checkbox"],.settings-row input[type="checkbox"]{line-height:20px;margin-right:4px}.details-row .checkbox label,.settings-row .checkbox label{line-height:20px;vertical-align:middle}button{margin-right:4px}h1,h2,h3{user-select:none;font-weight:normal;line-heig
 ht:1}h3{color:black;font-size:1.2em;margin-top:0;margin-bottom:1.5em}table tr:hover{cursor:pointer}.input-group{display:inline-block}.input-group .form-control{width:auto;margin-left:0;margin-right:0}.form-control{display:inline-block;text-align:left;padding:3px 3px;height:28px}.form-control button{text-align:left}.table-form-control{width:auto}.form-horizontal .control-label{padding-top:4px}button .caret{float:right;margin-left:0;margin-top:7px}.theme-line .panel-heading{padding:10px 10px;margin:0}.theme-line .panel-heading h3{margin-bottom:0}.theme-line .panel-heading h3>a{color:black;cursor:pointer}.theme-line .panel-title a{color:#ec1c24}.theme-line .panel-title h3{margin-bottom:1.3em}.theme-line .panel-body{padding:0.65em 1.3em}.theme-line .main-content a.customize{color:#ec1c24;cursor:pointer}.theme-line .panel-collapse{margin:0}.theme-line .links table,.theme-line table.links-edit,.theme-line table.links-edit-small-padding{display:table;table-layout:fixed;margin-bottom:10px}.
 theme-line .links table td,.theme-line table.links-edit td,.theme-line table.links-edit-small-padding td{padding-left:18px}.theme-line .links table .active a,.theme-line table.links-edit .active a,.theme-line table.links-edit-small-padding .active a{color:#ec1c24;font-weight:bold}.theme-line .links table a:hover,.theme-line table.links-edit a:hover,.theme-line table.links-edit-small-padding a:hover{color:#950d12}.theme-line .links table a,.theme-line table.links-edit a,.theme-line table.links-edit-small-padding a{color:#666}.theme-line table.links-edit label{line-height:28px;color:#666}.btn{padding:3px 6px}.panel-title a{font-size:14px}.panel-details{margin-top:1.3em;margin-bottom:0.65em;padding:0.65em;border-radius:4px;border:thin dotted lightgrey}.tooltip.right .tooltip-arrow{border-right-color:#ec1c24}.tooltip>.tooltip-inner{max-width:400px;text-align:left;background-color:#ec1c24}label{font-weight:normal;line-height:14px;margin-bottom:0}.form-horizontal .checkbox{padding-top:0}.
 input-tip{display:block;overflow:hidden;padding-right:4px}.labelField{float:left;margin-right:4px}.tipField{float:right;line-height:28px;margin-right:5px}.tipLabel{font-size:14px;margin-left:4px}.fieldButton{float:right;margin-left:4px;margin-right:0}.table-nowrap{table-layout:fixed}.td-overflow{max-width:100px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fa-edit{cursor:pointer}.fa-remove{color:#ec1c24;margin-left:5px;margin-right:5px;cursor:pointer}label.required:after{color:#ec1c24;content:' *';display:inline}.blank{visibility:hidden}.alert{outline:0}.alert.bottom,.alert.bottom-left,.alert.bottom-right,.alert.top,.alert.top-left,.alert.top-right{position:fixed;z-index:1050;margin:20px}.alert.top,.alert.top-left,.alert.top-right{top:50px}.alert.top{right:0;left:0}.alert.top-right{right:0}.alert.top-right .close{padding-left:10px}.alert.top-left{left:0}.alert.top-left .close{padding-right:10px}.alert.bottom,.alert.bottom-left,.alert.bottom-right{bottom:0}.alert.bottom{
 right:0;left:0}.alert.bottom-right{right:0}.alert.bottom-right .close{padding-left:10px}.alert.bottom-left{left:0}.alert.bottom-left .close{padding-right:10px}#cfgResult textarea{font-family:monospace;font-size:12px}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type="number"]{-moz-appearance:textfield}input.ng-invalid{border-color:#ec1c24}input.ng-invalid :focus{border-color:#ec1c24}.form-control-feedback{display:inline-block;color:#ec1c24;right:18px;line-height:28px;pointer-events:initial}.syntaxhighlighter{padding:10px 5px;border-radius:6px}.theme-line table.links-edit-small-padding{margin-top:10px}.theme-line table.links-edit-small-padding label{line-height:28px;color:#666}.theme-line table.links-edit-small-padding a{line-height:28px}.theme-line table.links-edit-small-padding input[type="checkbox"]{line-height:20px;margin-right:4px}.theme-line table.links-edit-small-padding .checkbox label{li
 ne-height:20px;vertical-align:middle}.theme-line table.links-edit-small-padding th{text-align:center}.theme-line table.links-edit-small-padding td{padding-left:10px}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/stylesheets/style.less
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/stylesheets/style.less b/modules/web-control-center/nodejs/public/stylesheets/style.less
new file mode 100644
index 0000000..3a41467
--- /dev/null
+++ b/modules/web-control-center/nodejs/public/stylesheets/style.less
@@ -0,0 +1,997 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@logo-path: "https://www.filepicker.io/api/file/QagunjDGRFul2JgNCAli";
+@input-height: 28px;
+
+.main-header .logo {
+  height: auto;
+}
+
+.main-sidebar {
+  padding-top: 60px;
+}
+
+.navbar-default .navbar-brand, .navbar-default .navbar-brand:hover {
+  position: absolute;
+  width: 100%;
+  left: 0;
+  text-align: center;
+}
+
+.modal-backdrop.am-fade {
+  opacity: .5;
+  transition: opacity .15s linear;
+  &.ng-enter {
+    opacity: 0;
+    &.ng-enter-active {
+      opacity: .5;
+    }
+  }
+  &.ng-leave {
+    opacity: .5;
+    &.ng-leave-active {
+      opacity: 0;
+    }
+  }
+}
+
+.modal.center .modal-dialog {
+  position: fixed;
+  top: 40%;
+  left: 50%;
+  min-width: 320px;
+  max-width: 630px;
+  width: 50%;
+  transform: translateX(-50%) translateY(-50%);
+}
+
+.border-left {
+  box-shadow: 1px 0 0 0 #eee inset;
+}
+
+.border-right {
+  box-shadow: 1px 0 0 0 #eee;
+}
+
+.theme-line {
+  background-color: #f9f9f9;
+}
+
+.theme-line header {
+  background-color: #fff;
+}
+
+.theme-line header a.btn {
+  border: 0 none;
+  padding: 10px 25px;
+  background-color: rgba(0, 0, 0, 0.15);
+}
+
+.theme-line header a.btn:hover {
+  background-color: rgba(0, 0, 0, 0.25);
+}
+
+.theme-line header a.btn.btn-link {
+  background: transparent;
+  color: rgba(255, 255, 255, 0.8);
+}
+
+.theme-line header a.btn.btn-link:hover {
+  color: #fff;
+  text-decoration: none;
+}
+
+.theme-line .navbar-nav a {
+  background-color: transparent;
+}
+
+.theme-line .navbar-nav a:hover,
+.theme-line .navbar-nav a:active,
+.theme-line .navbar-nav a:focus {
+  background-color: transparent;
+}
+
+.theme-line .main-links {
+  padding-top: 50px;
+}
+
+.theme-line .main-links h3 {
+  margin-top: 0;
+  font-size: 17px;
+}
+
+.theme-line .main-links .links a {
+  color: #888;
+}
+
+.theme-line .main-links .links a:hover {
+  text-decoration: none;
+}
+
+.theme-line #category-columns,
+.theme-solid #category-columns {
+  margin: 50px 30px 0;
+}
+
+.theme-line #category-columns h4 {
+  text-transform: uppercase;
+  font-weight: 300;
+  color: #999;
+  font-size: 14px;
+}
+
+.theme-line #category-columns ul {
+  list-style: none;
+  padding: 0;
+  margin-bottom: 15px;
+}
+
+.theme-line #category-columns ul li a {
+  padding: 4px 0;
+  display: block;
+  font-size: 16px;
+}
+
+.theme-line #category-columns ul .view-all {
+  font-size: 0.85em;
+}
+
+.theme-line .docs-header {
+  color: #999;
+  overflow: hidden;
+}
+
+.theme-line .docs-header h1 {
+  color: #444;
+  margin-top: 0;
+  font-size: 25px;
+}
+
+.theme-line .btn-primary {
+  border: 0 none;
+  background-color: #ec1c24;
+}
+
+.theme-line .btn-primary:hover {
+  background-color: #950d12;
+}
+
+.theme-line .main-content .nav-horizontal a {
+  box-shadow: 0 0;
+  border: 0 none;
+  background-color: #fff;
+  border-radius: 0;
+  color: #aaa;
+  padding: 6px;
+  margin: 0 14px;
+}
+
+.theme-line .main-content .nav-horizontal a:hover {
+  color: #999;
+  border-bottom: 4px solid #ddd;
+}
+
+.theme-line .main-content .nav-horizontal a.active {
+  border-bottom: 4px solid #888;
+}
+
+.theme-line .sidebar-nav {
+  color: #474a54;
+  padding-bottom: 30px;
+}
+
+.theme-line .sidebar-nav ul {
+  padding: 0;
+  list-style: none;
+  font-size: 13px;
+  margin: 3px 0 0;
+}
+
+.theme-line .sidebar-nav ul li a {
+  padding: 3px 0;
+  display: block;
+  color: #666;
+  position: relative;
+  white-space: nowrap;
+  overflow: hidden;
+  -o-text-overflow: ellipsis;
+  text-overflow: ellipsis;
+}
+
+.theme-line .sidebar-nav ul li a:before {
+  top: 0;
+  content: " ";
+  display: block;
+  width: 6px;
+  height: 100%;
+  position: absolute;
+  left: -30px;
+}
+
+.theme-line .sidebar-nav ul li a:hover {
+  text-decoration: none;
+}
+
+.theme-line .select li a {
+  color: #666;
+}
+
+.theme-line .select  {
+  li a:hover, .active {
+    color: #ec1c24;
+    background-color: white;
+  }
+}
+
+.theme-line .sidebar-nav ul li .subcategory {
+  padding-left: 15px;
+}
+
+.theme-line .sidebar-nav h4 {
+  margin-top: 2em;
+  font-weight: normal;
+  text-transform: uppercase;
+  font-size: 11px;
+  margin-bottom: 10px;
+  color: #bbb;
+}
+
+.theme-line .sidebar-nav h4:first-child {
+  margin-top: 0;
+}
+
+.theme-line .sidebar-nav .ask {
+  width: 100%;
+  text-align: center;
+  padding: 10px;
+}
+
+.theme-line .border-left .sidebar-nav {
+  padding-left: 15px;
+}
+
+.theme-line .suggest {
+  padding: 4px;
+  display: inline-block;
+  font-size: 12px;
+}
+
+.header {
+  padding: 15px;
+}
+
+.header .has-github {
+  padding-right: 136px;
+}
+
+.header h1.navbar-brand {
+  height: 40px;
+  width: 200px;
+  padding: 0;
+  margin: 5px 15px 0 0;
+}
+
+.header h1.navbar-brand a {
+  text-indent: -99999px;
+  background: no-repeat center center;
+  display: block;
+  width: 100%;
+  height: 100%;
+  background-size: contain;
+}
+
+.header .nav.navbar-nav.pull-right {
+  position: relative;
+  right: -30px;
+}
+
+.header .nav.navbar-nav .not-link {
+  padding: 15px;
+  display: inline-block;
+}
+
+.header .nav.navbar-nav .stable,
+.header .nav.navbar-nav .beta,
+.header .nav.navbar-nav .private {
+  font-size: 9px;
+  padding: 3px 5px;
+  display: inline-block;
+  line-height: 8px;
+  border-radius: 3px;
+  margin-left: 6px;
+  color: #fff;
+  top: -2px;
+  position: relative;
+  opacity: 0.6;
+  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
+  filter: alpha(opacity=60);
+}
+
+.header .nav.navbar-nav a:hover > .stable,
+.header .nav.navbar-nav a:hover > .beta,
+.header .nav.navbar-nav a:hover > .private {
+  opacity: 1;
+  -ms-filter: none;
+  filter: none;
+}
+
+.header .nav.navbar-nav .beta {
+  background-color: #59c3d1;
+}
+
+.header .nav.navbar-nav .stable {
+  background-color: #41b841;
+}
+
+.header .nav.navbar-nav .private {
+  background-color: #333;
+}
+
+.theme-line header {
+  border-bottom: 8px solid;
+}
+
+.theme-line header h2 {
+  color: #aaa;
+}
+
+.theme-line header p {
+  color: #666;
+}
+
+.theme-line header {
+  border-bottom-color: #ec1c24;
+}
+
+.theme-line .navbar-nav {
+  color: #888;
+}
+
+.theme-line .navbar-nav a {
+  color: #bbb;
+}
+
+.theme-line header a.btn {
+  background-color: #ec1c24;
+}
+
+.theme-line header a.btn:hover {
+  background-color: #950d12;
+}
+
+.theme-line header .navbar-nav .tt-cursor {
+  background-color: #ec1c24;
+}
+
+.theme-line header .navbar-nav a:hover, .theme-line header .navbar-nav .open > a {
+  color: #ec1c24;
+}
+
+.theme-line .navbar-nav .active a {
+  //font-weight: bold;
+  color: #ec1c24;
+}
+
+.theme-line .navbar-nav .active a:hover {
+  color: #950d12;
+}
+
+.theme-line .main-links .links a:hover {
+  color: #ec1c24;
+}
+
+.theme-line .main-content a {
+  color: #666;
+}
+
+.theme-line .main-content a:hover {
+  color: #950d12;
+}
+
+.theme-line .sidebar-nav ul li a.active:before {
+  background-color: #ec1c24;
+}
+
+.theme-line .sidebar-nav ul li a.active {
+  color: #ec1c24;
+}
+
+.theme-line .sidebar-nav ul li a:hover, .theme-line .sidebar-nav ul li a.active:hover {
+  color: #950d12;
+}
+
+.theme-line .main-content .nav-horizontal a.active {
+  border-color: #ec1c24;
+  color: #ec1c24;
+}
+
+.theme-line .main-content .nav-horizontal a:hover {
+  color: #950d12;
+}
+
+.theme-line .main-content .nav-horizontal a.active:hover {
+  border-color: #950d12;
+}
+
+.theme-line header .navbar-nav a.active, .theme-line #versions-list li a:hover strong, .theme-line #versions-list li a.active .current, .theme-line #versions-list li a:active .current {
+  color: #ec1c24;
+}
+
+.theme-line.body-threes .section-right .threes-nav .btn-default:hover, .theme-line.page-docs.body-threes .section-right .threes-nav .pull-right a:hover {
+  color: #ec1c24;
+  border-color: #ec1c24;
+}
+
+.theme-line .section-right {
+  padding-left: 30px;
+}
+
+.body-overlap .main-content {
+  margin-top: 30px;
+}
+
+.body-box .main-content,
+.body-overlap .main-content {
+  padding: 30px;
+  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
+  background-color: #fff;
+}
+
+body {
+  font-weight: 400;
+  font-family: Roboto Slab, serif;;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  font-weight: 700;
+  font-family: Roboto Slab, serif;
+}
+
+.submit-vote.submit-vote-parent.voted a.submit-vote-button, .submit-vote.submit-vote-parent a.submit-vote-button:hover {
+  background-color: #ec1c24;
+}
+
+div.submit-vote.submit-vote-parent.voted a.submit-vote-button:hover {
+  background-color: #950d12;
+}
+
+a, .link .title {
+  color: #ec1c24;
+}
+
+a:hover, .link:hover .title {
+  color: #950d12;
+}
+
+.header h1.navbar-brand a {
+  background-image: url("@{logo-path}");
+}
+
+.header h1.navbar-brand {
+  width: 96px;
+}
+
+.block-edit-parameters {
+  text-align: right;
+  padding-bottom: 5px;
+}
+
+.ng-table-pager {
+  display: none;
+}
+
+.container-footer {
+  margin-top: 20px;
+}
+
+.vcenter {
+  display: inline-block;
+  vertical-align: middle;
+  float: none;
+}
+
+.vcenter2 {
+  position: relative;
+  top: 50%;
+  transform: translateY(-50%);
+}
+
+.border-right-remove {
+
+}
+
+/* Modal */
+.modal {
+  display: block;
+  overflow: hidden;
+}
+
+.modal .close {
+  position: absolute;
+  top: 0.65em;
+  right: 0.65em;
+  float: none;
+}
+
+// Close icon
+.modal-header .close {
+  margin-right: -2px;
+}
+
+.modal .modal-dialog {
+  width: 610px;
+}
+
+.modal .modal-content {
+  border-radius: 0;
+  background-color: #f7f7f7;
+}
+
+.modal .modal-content .modal-header {
+  background-color: #fff;
+  text-align: center;
+  color: #555;
+  padding: 24px;
+  font-family: "myriad-pro", sans-serif;
+}
+
+.modal .modal-content .modal-header h4 {
+  font-family: "myriad-pro", sans-serif;
+  font-size: 22px;
+}
+
+.modal .modal-content .modal-header h4 .fa {
+  display: block;
+  font-size: 41px;
+  color: #ddd;
+  margin-bottom: 5px;
+}
+
+.modal .modal-content .modal-header p {
+  color: #aaa;
+  font-size: 1em;
+  margin: 3px 0 0;
+}
+
+.modal .modal-content .modal-spacer {
+  padding: 10px 10px 0 10px;
+}
+
+.modal .modal-content .modal-footer {
+  margin-top: 0;
+}
+
+.modal-body {
+  padding-top: 30px;
+}
+
+h1.ignite-logo {
+  background-image: url("@{logo-path}");
+}
+
+.st-sort-ascent:after {
+  font-family: FontAwesome, serif;
+  content: '\f077';
+}
+
+.st-sort-descent:after {
+  font-family: FontAwesome, serif;
+  content: '\f078';
+}
+
+.block-display-image img {
+  max-width: 100%;
+  max-height: 450px;
+  margin: auto;
+  display: block;
+}
+
+.greedy {
+  min-height: 200px;
+  height: ~"calc(100vh - 230px)";
+}
+
+@media (min-width: 768px) {
+  .navbar-nav > li > a {
+    padding-top: 20px;
+    padding-bottom: 10px;
+  }
+}
+
+.details-row {
+  padding-left: 1.3em;
+}
+
+.details-table-row  {
+  padding: 0;
+}
+
+.details-row, .settings-row {
+  display: block;
+  margin: 0.65em 0;
+  line-height: @input-height;
+
+  [class*="col-"] {
+    display: inline-block;
+    vertical-align: middle;
+    float: none;
+
+    padding-left: 0 !important;
+    padding-right: 0 !important;
+  }
+
+  input[type="checkbox"] {
+    line-height: 20px;
+    margin-right: 4px;
+  }
+
+  .checkbox label {
+    line-height: 20px;
+    vertical-align: middle;
+  }
+}
+
+button {
+  margin-right: 4px;
+}
+
+h1,
+h2,
+h3 {
+  user-select: none;
+  font-weight: normal;
+  /* Makes the vertical size of the text the same for all fonts. */
+  line-height: 1;
+}
+
+h3 {
+  color: black;
+  font-size: 1.2em;
+  margin-top: 0;
+  margin-bottom: 1.5em;
+}
+
+table tr:hover{ cursor:pointer; }
+
+.input-group {
+  display: inline-block;
+}
+
+.input-group .form-control {
+  width: auto;
+  margin-left: 0;
+  margin-right: 0;
+}
+
+.form-control {
+  display: inline-block;
+  text-align: left;
+  padding: 3px 3px;
+  height: @input-height;
+
+  button {
+    text-align: left;
+  }
+}
+
+.table-form-control {
+  width: auto;
+}
+
+.form-horizontal .control-label {
+  padding-top: 4px;
+}
+
+button .caret {
+  float: right;
+  margin-left: 0;
+  margin-top: 7px;
+}
+
+.theme-line .panel-heading {
+  padding: 10px 10px;
+  margin: 0;
+
+  h3 {
+    margin-bottom: 0;
+  }
+
+  h3 > a {
+    color: black;
+    cursor: pointer;
+  }
+}
+
+.theme-line .panel-title {
+  a {
+    color: #ec1c24;
+  }
+
+  h3 {
+    margin-bottom: 1.3em;
+  }
+}
+
+.theme-line .panel-body {
+  padding: 0.65em 1.3em;
+}
+
+.theme-line .main-content a.customize {
+  //margin-left: 10px;
+  color: #ec1c24;
+  cursor: pointer;
+}
+
+.theme-line .panel-collapse {
+  margin: 0;
+}
+
+.theme-line .links table {
+  display: table;
+  table-layout: fixed;
+  margin-bottom: 10px;
+
+  td {
+    padding-left: 18px;
+  }
+
+  .active a {
+    color: #ec1c24;
+    font-weight: bold;
+  }
+
+  a:hover {
+    color: #950d12;
+  }
+
+  a {
+    color: #666;
+  }
+}
+
+.theme-line table.links-edit:extend(.theme-line .links table all) {
+  label {
+    line-height: @input-height;
+    color: #666;
+  }
+}
+
+.btn {
+  padding: 3px 6px;
+}
+
+.panel-title a {
+  font-size: 14px;
+}
+
+.panel-details {
+  margin-top: 1.3em;
+  margin-bottom: 0.65em;
+  padding: 0.65em;
+
+  border-radius: 4px;
+  border: thin dotted lightgrey;
+}
+
+.tooltip.right .tooltip-arrow {
+  border-right-color: #ec1c24;
+}
+
+.tooltip > .tooltip-inner {
+  max-width: 400px;
+  text-align: left;
+  background-color: #ec1c24;
+}
+
+label {
+  font-weight: normal;
+  line-height: 14px;
+  margin-bottom: 0;
+}
+
+.form-horizontal .checkbox {
+  padding-top: 0;
+}
+
+.input-tip {
+  display: block;
+  overflow: hidden;
+  padding-right:4px;
+}
+
+.labelField {
+  float: left;
+  margin-right: 4px;
+}
+
+.tipField {
+  float: right;
+  line-height: @input-height;
+  margin-right: 5px;
+}
+
+.tipLabel {
+  font-size: 14px;
+  margin-left: 4px;
+}
+
+.fieldButton {
+  float: right;
+  margin-left: 4px;
+  margin-right: 0;
+}
+
+.table-nowrap {
+  table-layout:fixed;
+}
+
+.td-overflow {
+  max-width: 100px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.fa-edit {
+  cursor: pointer;
+}
+
+.fa-remove {
+  color: #ec1c24;
+  margin-left: 5px;
+  margin-right: 5px;
+  cursor: pointer;
+}
+
+label.required:after {
+  color: #ec1c24;
+  content: ' *';
+  display:inline;
+}
+
+.blank {
+  visibility:hidden;
+}
+
+.alert {
+  outline: 0
+}
+
+.alert.bottom, .alert.bottom-left, .alert.bottom-right, .alert.top,
+.alert.top-left, .alert.top-right {
+  position: fixed;
+  z-index: 1050;
+  margin: 20px
+}
+
+.alert.top, .alert.top-left, .alert.top-right {
+  top: 50px
+}
+
+.alert.top {
+  right: 0;
+  left: 0
+}
+
+.alert.top-right {
+  right: 0
+}
+
+.alert.top-right .close {
+  padding-left: 10px
+}
+
+.alert.top-left {
+  left: 0
+}
+
+.alert.top-left .close {
+  padding-right: 10px
+}
+
+.alert.bottom, .alert.bottom-left, .alert.bottom-right {
+  bottom: 0
+}
+
+.alert.bottom {
+  right: 0;
+  left: 0
+}
+
+.alert.bottom-right {
+  right: 0
+}
+
+.alert.bottom-right .close {
+  padding-left: 10px
+}
+
+.alert.bottom-left {
+  left: 0
+}
+
+.alert.bottom-left .close {
+  padding-right: 10px
+}
+
+//  Summary page
+#cfgResult textarea {
+  font-family: monospace;
+  font-size: 12px;
+}
+
+input[type="number"]::-webkit-outer-spin-button,
+input[type="number"]::-webkit-inner-spin-button {
+  -webkit-appearance: none;
+  margin: 0;
+}
+input[type="number"] {
+  -moz-appearance: textfield;
+}
+
+input.ng-invalid {
+  border-color: #ec1c24;
+
+  :focus {
+    border-color: #ec1c24;
+  }
+}
+
+.form-control-feedback {
+  display: inline-block;
+  color: #ec1c24;
+  right: 18px;
+  line-height: @input-height;
+  pointer-events: initial;
+}
+
+.syntaxhighlighter {
+  padding: 10px 5px;
+  border-radius: 6px;
+}
+
+.theme-line table.links-edit-small-padding:extend(.theme-line .links table all) {
+  label {
+    line-height: @input-height;
+    color: #666;
+  }
+
+  a {
+    line-height: @input-height;
+  }
+
+  input[type="checkbox"] {
+    line-height: 20px;
+    margin-right: 4px;
+  }
+
+  .checkbox label {
+    line-height: 20px;
+    vertical-align: middle;
+  }
+
+  th {
+    text-align: center;
+  }
+
+  td {
+    padding-left: 10px;
+  }
+
+  margin-top: 10px;
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/routes/auth.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/routes/auth.js b/modules/web-control-center/nodejs/routes/auth.js
new file mode 100644
index 0000000..5ed7278
--- /dev/null
+++ b/modules/web-control-center/nodejs/routes/auth.js
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var passport = require('passport');
+var router = require('express').Router();
+
+var db = require('../db');
+
+/**
+ * Register new account.
+ */
+router.post('/register', function(req, res, next) {
+    db.Account.register(new db.Account(req.body), req.body.password, function(err, account) {
+        if (err)
+            return res.status(401).send(err.message);
+
+        if (!account)
+            return res.status(500).send('Failed to create account.');
+
+        new db.Space({name: 'Personal space', owner: account._id}).save();
+
+        req.logIn(account, {}, function(err) {
+            if (err)
+                return res.status(401).send(err.message);
+
+            return res.redirect('/clusters');
+        });
+    });
+});
+
+/**
+ * Login in exist account.
+ */
+router.post('/login', function(req, res, next) {
+    passport.authenticate('local', function(err, user) {
+        if (err)
+            return res.status(401).send(err.message);
+
+        if (!user)
+            return res.status(401).send('Invalid email or password');
+
+        req.logIn(user, {}, function(err) {
+            if (err)
+                return res.status(401).send(err.message);
+
+            res.redirect('/clusters');
+        });
+    })(req, res, next);
+});
+
+/**
+ * Logout.
+ */
+router.get('/logout', function(req, res) {
+    req.logout();
+
+    res.redirect('/');
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/routes/caches.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/routes/caches.js b/modules/web-control-center/nodejs/routes/caches.js
new file mode 100644
index 0000000..7de5d57
--- /dev/null
+++ b/modules/web-control-center/nodejs/routes/caches.js
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+var db = require('../db');
+
+/**
+ * Send spaces and caches accessed for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+function selectAll(req, res) {
+    var user_id = req.user._id;
+
+    // Get owned space and all accessed space.
+    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        var space_ids = spaces.map(function(value) {
+            return value._id;
+        });
+
+        // Get all caches for spaces.
+        db.Cache.find({space: {$in: space_ids}}, function (err, caches) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.json({spaces: spaces, caches: caches});
+        });
+    });
+}
+
+/**
+ * Get spaces and caches accessed for user account.
+ */
+router.get('/', function(req, res) {
+    selectAll(req, res);
+});
+
+/**
+ * Save cache.
+ */
+router.post('/save', function(req, res) {
+    if (req.body._id)
+        db.Cache.update({_id: req.body._id}, req.body, {upsert: true}, function(err) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.send(req.body._id);
+        });
+    else {
+        var cache = new db.Cache(req.body);
+
+        cache.save(function(err, cache) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.send(cache._id);
+        });
+    }
+});
+
+/**
+ * Remove cache by ._id.
+ */
+router.post('/remove', function(req, res) {
+    db.Cache.remove(req.body, function (err) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        res.sendStatus(200);
+    })
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/routes/clusters.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/routes/clusters.js b/modules/web-control-center/nodejs/routes/clusters.js
new file mode 100644
index 0000000..91ac50a
--- /dev/null
+++ b/modules/web-control-center/nodejs/routes/clusters.js
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+var db = require('../db');
+
+/**
+ * Send spaces and clusters accessed for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+function selectAll(req, res) {
+    var user_id = req.user._id;
+
+    // Get owned space and all accessed space.
+    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        var space_ids = spaces.map(function(value) {
+            return value._id;
+        });
+
+        db.Cache.find({space: {$in: space_ids}}, '_id name swapEnabled', function (err, caches) {
+            if (err)
+                return res.status(500).send(err);
+
+            // Get all clusters for spaces.
+            db.Cluster.find({space: {$in: space_ids}}, function (err, clusters) {
+                if (err)
+                    return res.status(500).send(err.message);
+
+                var cachesJson = caches.map(function(cache) {
+                    return {value: cache._id, label: cache.name, swapEnabled: cache.swapEnabled};
+                });
+
+                res.json({spaces: spaces, caches: cachesJson, clusters: clusters});
+            });
+        });
+    });
+}
+
+/**
+ * Get spaces and clusters accessed for user account.
+ */
+router.get('/', function(req, res) {
+    selectAll(req, res);
+});
+
+/**
+ * Save cluster.
+ */
+router.post('/save', function(req, res) {
+    if (req.body._id)
+        db.Cluster.update({_id: req.body._id}, req.body, {upsert: true}, function(err) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.send(req.body._id);
+        });
+    else {
+        var cluster = new db.Cluster(req.body);
+
+        cluster.save(function(err, cluster) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.send(cluster._id);
+        });
+    }
+});
+
+/**
+ * Remove cluster by ._id.
+ */
+router.post('/remove', function(req, res) {
+    db.Cluster.remove(req.body, function (err) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        res.sendStatus(200);
+    })
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/routes/configGenerator.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/routes/configGenerator.js b/modules/web-control-center/nodejs/routes/configGenerator.js
new file mode 100644
index 0000000..407514a
--- /dev/null
+++ b/modules/web-control-center/nodejs/routes/configGenerator.js
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('../db');
+
+var router = require('express').Router();
+
+var generatorXml = require('./../utils/generatorXml');
+var generatorJava = require('./../utils/generatorJava');
+
+router.get('/', function(req, res) {
+    var lang = req.query.lang;
+    var name = req.query.name;
+
+    var user_id = req.user._id;
+    
+    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        var space_ids = spaces.map(function(value) {
+            return value._id;
+        });
+
+        // Get all clusters for spaces.
+        db.Cluster.find({name: name, space: {$in: space_ids}}).populate('caches').exec(function (err, clusters) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            if (clusters.length == 0) {
+                res.sendStatus(404);
+
+                return
+            }
+
+            var cluster = clusters[0];
+
+            switch (lang) {
+                case 'xml':
+                    res.send(generatorXml.generateClusterConfiguration(cluster));
+                    break;
+
+                case 'java':
+                    res.send(generatorJava.generateClusterConfiguration(cluster, req.query.generateJavaClass == 'true'));
+                    break;
+
+                default:
+                    res.status(404).send("Unknown language: " + lang);
+                    break;
+            }
+        });
+    });
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/routes/pages.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/routes/pages.js b/modules/web-control-center/nodejs/routes/pages.js
new file mode 100644
index 0000000..7b6c24e
--- /dev/null
+++ b/modules/web-control-center/nodejs/routes/pages.js
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+
+// GET dropdown-menu template.
+router.get('/select', function(req, res) {
+    res.render('templates/select', { });
+});
+
+/* GET login page. */
+router.get('/login', function(req, res) {
+    res.render('login');
+});
+
+/* GET home page. */
+router.get('/', function(req, res) {
+    if (req.isAuthenticated())
+        res.redirect('/clusters');
+    else
+        res.render('index', { user: req.user });
+});
+
+/* GET clusters page. */
+router.get('/clusters', function(req, res) {
+    res.render('clusters', { user: req.user });
+});
+
+/* GET caches page. */
+router.get('/caches', function(req, res) {
+    res.render('caches', { user: req.user });
+});
+
+/* GET persistence page. */
+router.get('/persistence', function(req, res) {
+    res.render('persistence', { user: req.user });
+});
+
+/* GET sql page. */
+router.get('/sql', function(req, res) {
+    res.render('sql', { user: req.user });
+});
+
+/* GET clients page. */
+router.get('/clients', function(req, res) {
+    res.render('clients', { user: req.user });
+});
+
+/* GET summary page. */
+router.get('/summary', function(req, res) {
+    res.render('summary', { user: req.user });
+});
+
+module.exports = router;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/routes/persistences.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/routes/persistences.js b/modules/web-control-center/nodejs/routes/persistences.js
new file mode 100644
index 0000000..409ff5f
--- /dev/null
+++ b/modules/web-control-center/nodejs/routes/persistences.js
@@ -0,0 +1,313 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+var db = require('../db');
+var ds = require('../public/javascripts/dataStructures.js'), jdbcTypes = ds.jdbcTypes, javaTypes = ds.javaTypes;
+
+/**
+ * Send spaces and persistences accessed for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+function selectAll(req, res) {
+    var user_id = req.user._id;
+
+    // Get owned space and all accessed space.
+    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        var space_ids = spaces.map(function(value) {
+            return value._id;
+        });
+
+        // Get all persistences for spaces.
+        db.Persistence.find({space: {$in: space_ids}}, function (err, persistences) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.json({spaces: spaces, persistences: persistences});
+        });
+    });
+}
+
+/**
+ * Get spaces and persistences accessed for user account.
+ */
+router.get('/', function(req, res) {
+    selectAll(req, res);
+});
+
+/**
+ * Save persistence.
+ */
+router.post('/save', function(req, res) {
+    if (req.body._id)
+        db.Persistence.update({_id: req.body._id}, req.body, {upsert: true}, function(err) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.send(req.body._id);
+        });
+    else {
+        var persistence = new db.Persistence(req.body);
+
+        persistence.save(function(err, persistence) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.send(persistence._id);
+        });
+    }
+});
+
+/**
+ * Remove persistence by ._id.
+ */
+router.post('/remove', function(req, res) {
+    db.Persistence.remove(req.body, function (err) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        res.sendStatus(200);
+    })
+});
+
+// simple countdown latch
+function CDL(countdown, completion) {
+    this.countDown = function() {
+        if(--countdown < 1) completion();
+    };
+}
+
+/**
+ * @param name Source name.
+ * @return String converted to java class name notation.
+ */
+function toJavaClassName(name) {
+    var len = name.length;
+
+    var buf = [];
+
+    var capitalizeNext = true;
+
+    for (var i = 0; i < len; i++) {
+        var ch = name.charAt(i);
+
+        if (' ' == ch || '_' == ch)
+            capitalizeNext = true;
+        else if (capitalizeNext) {
+            buf.push(ch.toUpperCase());
+
+            capitalizeNext = false;
+        }
+        else
+            buf.push(ch.toLowerCase());
+    }
+
+    return buf.join("");
+}
+
+/**
+ * @param name Source name.
+ * @return String converted to java field name notation.
+ */
+function toJavaFieldName(name) {
+    var javaName = toJavaClassName(name);
+
+    return javaName.charAt(0).toLowerCase() + javaName.substring(1);
+}
+
+
+//
+router.post('/pg', function(req, res) {
+    var pg = require('pg');
+    var util = require('util');
+
+    var host = req.body.host;
+    var port = req.body.port;
+
+    var username = req.body.username;
+    var password = req.body.password;
+
+    var dbName = req.body.dbName;
+
+    var connectionString = util.format('postgres://%s:%s@%s:%d/%s', username, password, host, port, dbName);
+
+    pg.connect(connectionString, function(err, client, done) {
+        var sendError = function (err) {
+            done();
+
+            res.status(500).send(err.message);
+        };
+
+        if(err)
+            return sendError(err);
+
+        var sendResponse = function () {
+            done();
+
+            console.log(JSON.stringify(tables));
+
+            res.status(200).send(tables);
+        }, jdbcType = function (dataType) {
+            switch (dataType) {
+                case 'smallint':
+                case 'int2':
+                    return jdbcTypes.SMALLINT;
+                case 'integer':
+                case 'int':
+                case 'int4':
+                    return jdbcTypes.INTEGER;
+                case 'oid':
+                case 'bigint':
+                case 'int8':
+                    return jdbcTypes.BIGINT;
+                case 'money':
+                    return jdbcTypes.DOUBLE;
+                case 'decimal':
+                case 'numeric':
+                    return jdbcTypes.NUMERIC;
+                case 'float4':
+                    return jdbcTypes.REAL;
+                case 'float':
+                case 'float8':
+                    return jdbcTypes.DOUBLE;
+                case 'char':
+                case 'bpchar':
+                    return jdbcTypes.CHAR;
+                case 'varchar':
+                case 'text':
+                case 'name':
+                    return jdbcTypes.VARCHAR;
+                case 'bytea':
+                    return jdbcTypes.BINARY;
+                case 'boolean':
+                case 'bool':
+                case 'bit':
+                    return jdbcTypes.BIT;
+                case 'date':
+                    return jdbcTypes.DATE;
+                case 'time':
+                case 'timetz':
+                    return jdbcTypes.TIME;
+                case 'timestamp':
+                case 'timestamptz':
+                    return jdbcTypes.TIMESTAMP;
+            }
+        }, javaType = function (dataType) {
+            switch (dataType) {
+                case jdbcTypes.SMALLINT:
+                case jdbcTypes.INTEGER:
+                    return javaTypes.INTEGER;
+                case jdbcTypes.BIGINT:
+                    return javaTypes.LONG;
+                case jdbcTypes.DOUBLE:
+                    return javaTypes.DOUBLE;
+                case jdbcTypes.NUMERIC:
+                    return javaTypes.BIGDECIMAL;
+                case jdbcTypes.REAL:
+                    return javaTypes.FLOAT;
+                case jdbcTypes.CHAR:
+                case jdbcTypes.VARCHAR:
+                    return javaTypes.STRING;
+                case jdbcTypes.BINARY:
+                    return javaTypes.BYTE_ARRAY;
+                case jdbcTypes.BIT:
+                    return javaTypes.BOOLEAN;
+                case jdbcTypes.DATE:
+                    return javaTypes.DATE;
+                case jdbcTypes.TIME:
+                    return javaTypes.TIME;
+                case jdbcTypes.TIMESTAMP:
+                    return javaTypes.TIMESTAMP;
+            }
+        };
+
+        var tables = [];
+
+        client.query(
+            'SELECT table_schema, table_name ' +
+            'FROM information_schema.tables ' +
+            'WHERE table_schema = ANY (current_schemas(false)) ' +
+            'ORDER BY table_schema, table_name', function(err, result) {
+
+            if(err)
+                return sendError(err);
+
+            if (result.rows.length > 0) {
+                // usage
+                var latch = new CDL(result.rows.length, sendResponse);
+
+                result.rows.forEach(function (table) {
+
+                    var indisprimary = client.query(
+                        "SELECT a.attname " +
+                        "FROM pg_index i " +
+                        "JOIN pg_attribute a " +
+                        "  ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) " +
+                        "WHERE  i.indrelid = $1::regclass AND i.indisprimary", [table.table_schema + '.' + table.table_name],
+                        function (err, result) {
+                            if (err)
+                                return sendError(err);
+
+                            var pks = result.rows.map(function(row) {
+                                return row.attname;
+                            });
+
+                            client.query(
+                                'SELECT column_name, udt_name, is_nullable ' +
+                                'FROM information_schema.columns ' +
+                                'WHERE table_schema = $1 AND table_name = $2', [table.table_schema, table.table_name],
+                                function (err, result) {
+                                    if (err)
+                                        return sendError(err);
+
+                                    var cols = [];
+
+                                    result.rows.forEach(function (column) {
+                                        var dataType = jdbcType(column.udt_name);
+
+                                        cols.push({
+                                            pk: pks.indexOf(column.column_name) >= 0,
+                                            use: true,
+                                            notNull: column.is_nullable == 'NO',
+                                            dbName: column.column_name, dbType: dataType,
+                                            javaName: toJavaFieldName(column.column_name), javaType: javaType(dataType) });
+                                    });
+
+                                    var valClsName = toJavaClassName(table.table_name);
+
+                                    tables.push({
+                                        use: pks.length > 0,
+                                        schemaName: table.table_schema, tableName: table.table_name,
+                                        keyClass: valClsName + 'Key', valueClass: valClsName,
+                                        columns: cols
+                                    });
+
+                                    latch.countDown();
+                                })
+                        });
+                });
+            }
+        });
+    });
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/test/routes/persistence.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/test/routes/persistence.js b/modules/web-control-center/nodejs/test/routes/persistence.js
new file mode 100644
index 0000000..e5d8390
--- /dev/null
+++ b/modules/web-control-center/nodejs/test/routes/persistence.js
@@ -0,0 +1,32 @@
+var request = require('supertest'),
+    should = require('should'),
+    express = require('express'),
+    persistenceRouter = require('../../routes/persistences');
+
+var app = express();
+
+app.use(require('body-parser').json());
+
+app.use('/rest/persistence', persistenceRouter);
+
+describe('request.persistence', function(){
+    var agent = request.agent(app);
+
+    it('should return 200', function(done){
+        agent
+            .post('/rest/persistence/pg')
+            .send({
+                    username: 'nva',
+                    password: 'nva.141',
+                    host: 'localhost',
+                    port: '5432',
+                    dbName: 'ggmonitor'
+                })
+            .end(function(err, res) {
+                if (err)
+                    throw err;
+
+                done();
+            });
+    });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/utils/generatorJava.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/utils/generatorJava.js b/modules/web-control-center/nodejs/utils/generatorJava.js
new file mode 100644
index 0000000..223f85f
--- /dev/null
+++ b/modules/web-control-center/nodejs/utils/generatorJava.js
@@ -0,0 +1,555 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var generatorUtils = require("./generatorUtils");
+
+exports.generateClusterConfiguration = function(cluster, generateJavaClass) {
+    var res = generatorUtils.builder();
+
+    if (generateJavaClass) {
+        res.line('/**');
+        res.line(' * ' + generatorUtils.mainComment());
+        res.line(' */');
+        res.startBlock('public class ConfigurationFactory {');
+        res.line();
+        res.startBlock('public IgniteConfiguration createConfiguration() {');
+    }
+    
+    res.importClass('org.apache.ignite.configuration.IgniteConfiguration');
+    
+    res.line('IgniteConfiguration cfg = new IgniteConfiguration();');
+    res.line();
+
+    if (cluster.discovery) {
+        var d = cluster.discovery;
+
+        res.importClass('org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi');
+        res.line('TcpDiscoverySpi discovery = new TcpDiscoverySpi();');
+        switch (d.kind) {
+            case 'Multicast':
+                addBeanWithProperties(res, d.Multicast, 'discovery', 'ipFinder', 'ipFinder',
+                    'org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder', {
+                        multicastGroup: null,
+                        multicastPort: null,
+                        responseWaitTime: null,
+                        addressRequestAttempts: null,
+                        localAddress: null
+                    }, true);
+
+                break;
+
+            case 'Vm':
+                addBeanWithProperties(res, d.Vm, 'discovery', 'ipFinder', 'ipFinder',
+                    'org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder', {
+                        addresses: {type: 'list'}
+                    }, true);
+
+                break;
+
+            case 'S3':
+                if (d.S3) {
+                    addBeanWithProperties(res, d.S3, 'discovery', 'ipFinder', 'ipFinder',
+                        'org.apache.ignite.spi.discovery.tcp.ipfinder.s3.TcpDiscoveryS3IpFinder', {bucketName: null}, 
+                        true);
+                }
+                else {
+                    res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.s3.TcpDiscoveryS3IpFinder');
+                    
+                    res.line('discovery.setIpFinder(new TcpDiscoveryS3IpFinder());');
+                }
+
+                break;
+
+            case 'Cloud':
+                addBeanWithProperties(res, d.Cloud, 'discovery', 'ipFinder', 'ipFinder',
+                    'org.apache.ignite.spi.discovery.tcp.ipfinder.cloud.TcpDiscoveryCloudIpFinder', {
+                        credential: null,
+                        credentialPath: null,
+                        identity: null,
+                        provider: null
+                    }, true);
+
+                break;
+
+            case 'GoogleStorage':
+                addBeanWithProperties(res, d.GoogleStorage, 'discovery', 'ipFinder', 'ipFinder',
+                    'org.apache.ignite.spi.discovery.tcp.ipfinder.gce.TcpDiscoveryGoogleStorageIpFinder', {
+                        projectName: null,
+                        bucketName: null,
+                        serviceAccountP12FilePath: null
+                    }, true);
+
+                //if (d.GoogleStorage.addrReqAttempts) todo ????
+                //    res.line('<property name="serviceAccountP12FilePath" value="' + escapeAttr(d.GoogleStorage.addrReqAttempts) + '"/>');
+
+                break;
+
+            case 'Jdbc':
+                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.jdbc.TcpDiscoveryJdbcIpFinder');
+                
+                res.line();
+                res.line('TcpDiscoveryJdbcIpFinder ipFinder = new TcpDiscoveryJdbcIpFinder();');
+                res.line('ipFinder.setInitSchema(' + (d.Jdbc.initSchema != null || d.Jdbc.initSchema) + ');');
+                res.line('discovery.setIpFinder(ipFinder);');
+                res.needEmptyLine = true;
+
+                break;
+
+            case 'SharedFs':
+                addBeanWithProperties(res, d.SharedFs, 'discovery', 'ipFinder', 'ipFinder',
+                    'org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder', {path: null}, 
+                    true);
+
+                break;
+
+            default:
+                throw "Unknown discovery kind: " + d.kind;
+        }
+
+        res.emptyLineIfNeeded();
+
+        res.line('cfg.setDiscoverySpi(discovery);');
+
+        res.needEmptyLine = true;
+    }
+
+    if (cluster.caches && cluster.caches.length > 0) {
+        res.emptyLineIfNeeded();
+
+        var names = [];
+
+        for (var i = 0; i < cluster.caches.length; i++) {
+            res.emptyLineIfNeeded();
+
+            var cache = cluster.caches[i];
+
+            var cacheName = cache.name.replace(/[^A-Za-z_0-9]+/, '_');
+            cacheName = 'cache' + cacheName.charAt(0).toLocaleUpperCase() + cacheName.slice(1);
+
+            names.push(cacheName);
+
+            generateCacheConfiguration(cache, cacheName, res);
+
+            res.needEmptyLine = true;
+        }
+
+        res.emptyLineIfNeeded();
+
+        res.append('cfg.setCacheConfiguration(');
+
+        for (i = 0; i < names.length; i++) {
+            if (i > 0)
+                res.append(', ');
+
+            res.append(names[i]);
+        }
+
+        res.line(');');
+
+        res.needEmptyLine = true;
+    }
+
+    addBeanWithProperties(res, cluster.atomicConfiguration, 'cfg', 'atomicConfiguration', 'atomicCfg',
+        generatorUtils.atomicConfiguration.className, generatorUtils.atomicConfiguration.fields);
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'networkTimeout');
+    addProperty(res, cluster, 'cfg', 'networkSendRetryDelay');
+    addProperty(res, cluster, 'cfg', 'networkSendRetryCount');
+    addProperty(res, cluster, 'cfg', 'segmentCheckFrequency');
+    addProperty(res, cluster, 'cfg', 'waitForSegmentOnStart');
+    addProperty(res, cluster, 'cfg', 'discoveryStartupDelay');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'deploymentMode', 'DeploymentMode');
+
+    res.needEmptyLine = true;
+
+    if (cluster.includeEventTypes && cluster.includeEventTypes.length > 0) {
+        res.emptyLineIfNeeded();
+        
+        if (cluster.includeEventTypes.length == 1) {
+            res.importClass('org.apache.ignite.events.EventType');
+            
+            res.line('cfg.setIncludeEventTypes(EventType.' + cluster.includeEventTypes[0] + ');');
+        }
+        else {
+            res.append('int[] events = new int[EventType.' + cluster.includeEventTypes[0] + '.length');
+            
+            for (i = 1; i < cluster.includeEventTypes.length; i++) {
+                res.line();
+                
+                res.append('    + EventType.' + cluster.includeEventTypes[i] + '.length');
+            }
+            
+            res.line('];');
+            res.line();
+            res.line('int k = 0;');
+
+            for (i = 0; i < cluster.includeEventTypes.length; i++) {
+                res.line();
+
+                var e = cluster.includeEventTypes[i];
+                
+                res.line('System.arraycopy(EventType.' + e + ', 0, events, k, EventType.' + e + '.length);');
+                res.line('k += EventType.' + e + '.length;');
+            }
+            
+            res.line();
+            res.line('cfg.setIncludeEventTypes(events);');
+        }
+
+        res.needEmptyLine = true;
+    }
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'marshalLocalJobs');
+    addProperty(res, cluster, 'cfg', 'marshCacheKeepAliveTime');
+    addProperty(res, cluster, 'cfg', 'marshCachePoolSize');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'metricsExpireTime');
+    addProperty(res, cluster, 'cfg', 'metricsHistorySize');
+    addProperty(res, cluster, 'cfg', 'metricsLogFrequency');
+    addProperty(res, cluster, 'cfg', 'metricsUpdateFrequency');
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'peerClassLoadingEnabled');
+    addMultiparamProperty(res, cluster, 'cfg', 'peerClassLoadingLocalClassPathExclude');
+    addProperty(res, cluster, 'cfg', 'peerClassLoadingMissedResourcesCacheSize');
+    addProperty(res, cluster, 'cfg', 'peerClassLoadingThreadPoolSize');
+    res.needEmptyLine = true;
+
+    if (cluster.swapSpaceSpi && cluster.swapSpaceSpi.kind == 'FileSwapSpaceSpi') {
+        addBeanWithProperties(res, cluster.swapSpaceSpi.FileSwapSpaceSpi, 'cfg', 'swapSpaceSpi', 'swapSpi',
+            generatorUtils.swapSpaceSpi.className, generatorUtils.swapSpaceSpi.fields, true);
+
+        res.needEmptyLine = true;
+    }
+
+    addProperty(res, cluster, 'cfg', 'clockSyncSamples');
+    addProperty(res, cluster, 'cfg', 'clockSyncFrequency');
+    addProperty(res, cluster, 'cfg', 'timeServerPortBase');
+    addProperty(res, cluster, 'cfg', 'timeServerPortRange');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'publicThreadPoolSize');
+    addProperty(res, cluster, 'cfg', 'systemThreadPoolSize');
+    addProperty(res, cluster, 'cfg', 'managementThreadPoolSize');
+    addProperty(res, cluster, 'cfg', 'igfsThreadPoolSize');
+
+    res.needEmptyLine = true;
+
+    addBeanWithProperties(res, cluster.transactionConfiguration, 'cfg', 'transactionConfiguration',
+        'transactionConfiguration', generatorUtils.transactionConfiguration.className,
+        generatorUtils.transactionConfiguration.fields);
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'cacheSanityCheckEnabled');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'utilityCacheKeepAliveTime');
+    addProperty(res, cluster, 'cfg', 'utilityCachePoolSize');
+
+    if (generateJavaClass) {
+        res.line('return cfg;');
+        res.endBlock('}');
+        res.endBlock('}');
+        
+        return res.generateImports() + '\n\n' + res.join('')
+    }
+    
+    return res.join('');
+};
+
+function createEvictionPolicy(res, evictionPolicy, varName, propertyName) {
+    if (evictionPolicy && evictionPolicy.kind) {
+        var e = generatorUtils.evictionPolicies[evictionPolicy.kind];
+
+        var obj = evictionPolicy[evictionPolicy.kind.toUpperCase()];
+
+        addBeanWithProperties(res, obj, varName, propertyName, propertyName, e.className, e.fields, true);
+    }
+}
+
+exports.generateCacheConfiguration = generateCacheConfiguration;
+
+function generateCacheConfiguration(cacheCfg, varName, res) {
+    if (!res)
+        res = generatorUtils.builder();
+
+    res.emptyLineIfNeeded();
+
+    res.importClass('org.apache.ignite.configuration.CacheConfiguration');
+    
+    res.line('CacheConfiguration ' + varName + ' = new CacheConfiguration();');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, varName, 'name');
+    
+    addProperty(res, cacheCfg, varName, 'mode', 'CacheMode', 'cacheMode');
+
+    addProperty(res, cacheCfg, varName, 'atomicityMode', 'CacheAtomicityMode');
+    addProperty(res, cacheCfg, varName, 'backups');
+    
+    res.needEmptyLine = true;
+    
+    addProperty(res, cacheCfg, varName, 'memoryMode', 'CacheMemoryMode');
+    addProperty(res, cacheCfg, varName, 'offHeapMaxMemory');
+    addProperty(res, cacheCfg, varName, 'swapEnabled');
+
+    res.needEmptyLine = true;
+
+    createEvictionPolicy(res, cacheCfg.evictionPolicy, varName, 'evictionPolicy');
+
+    if (cacheCfg.nearConfiguration && (cacheCfg.nearConfiguration.nearStartSize || cacheCfg.nearConfiguration.nearEvictionPolicy.kind)) {
+        res.needEmptyLine = true;
+
+        addBeanWithProperties(res, cacheCfg.nearConfiguration, varName, 'nearConfiguration', 'nearConfiguration',
+            'org.apache.ignite.configuration.NearCacheConfiguration',
+            {nearStartSize: null, atomicSequenceReserveSize: null}, true);
+
+        if (cacheCfg.nearConfiguration && cacheCfg.nearConfiguration.nearEvictionPolicy && cacheCfg.nearConfiguration.nearEvictionPolicy.kind) {
+            createEvictionPolicy(res, cacheCfg.nearConfiguration.nearEvictionPolicy, 'nearConfiguration', 'nearEvictionPolicy');
+        }
+    }
+
+    res.needEmptyLine = true;
+    
+    addProperty(res, cacheCfg, varName, 'sqlEscapeAll');
+    addProperty(res, cacheCfg, varName, 'sqlOnheapRowCacheSize');
+    addProperty(res, cacheCfg, varName, 'longQueryWarningTimeout');
+    
+    if (cacheCfg.indexedTypes && cacheCfg.indexedTypes.length > 0) {
+        res.emptyLineIfNeeded();
+        
+        res.append(varName + '.setIndexedTypes(');
+        
+        for (var i = 0; i < cacheCfg.indexedTypes.length; i++) {
+            if (i > 0)
+                res.append(', ');
+
+            var pair = cacheCfg.indexedTypes[i];
+            
+            res.append(toJavaCode(pair.keyClass, 'class')).append(', ').append(toJavaCode(pair.valueClass, 'class'))
+        }
+        
+        res.line(');');
+    }
+
+    addMultiparamProperty(res, cacheCfg, varName, 'sqlFunctionClasses', 'class');
+    
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, varName, 'rebalanceMode', 'CacheRebalanceMode');
+    addProperty(res, cacheCfg, varName, 'rebalanceThreadPoolSize');
+    addProperty(res, cacheCfg, varName, 'rebalanceBatchSize');
+    addProperty(res, cacheCfg, varName, 'rebalanceOrder');
+    addProperty(res, cacheCfg, varName, 'rebalanceDelay');
+    addProperty(res, cacheCfg, varName, 'rebalanceTimeout');
+    addProperty(res, cacheCfg, varName, 'rebalanceThrottle');
+
+    res.needEmptyLine = true;
+    
+    if (cacheCfg.cacheStoreFactory && cacheCfg.cacheStoreFactory.kind) {
+        var obj = cacheCfg.cacheStoreFactory[cacheCfg.cacheStoreFactory.kind];
+        var data = generatorUtils.storeFactories[cacheCfg.cacheStoreFactory.kind];
+
+        addBeanWithProperties(res, obj, varName, 'cacheStoreFactory', 'cacheStoreFactory', data.className,
+            data.fields, true);
+    }
+
+    res.needEmptyLine = true;
+    
+    addProperty(res, cacheCfg, varName, 'invalidate');
+    addProperty(res, cacheCfg, varName, 'defaultLockTimeout');
+    addProperty(res, cacheCfg, varName, 'transactionManagerLookupClassName');
+    
+    res.needEmptyLine = true;
+    
+    addProperty(res, cacheCfg, varName, 'writeBehindEnabled');
+    addProperty(res, cacheCfg, varName, 'writeBehindBatchSize');
+    addProperty(res, cacheCfg, varName, 'writeBehindFlushSize');
+    addProperty(res, cacheCfg, varName, 'writeBehindFlushFrequency');
+    addProperty(res, cacheCfg, varName, 'writeBehindFlushThreadCount');
+    
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, varName, 'statisticsEnabled');
+    addProperty(res, cacheCfg, varName, 'managementEnabled');
+    addProperty(res, cacheCfg, varName, 'readFromBackup');
+    addProperty(res, cacheCfg, varName, 'copyOnRead');
+    addProperty(res, cacheCfg, varName, 'maxConcurrentAsyncOperations');
+    
+    return res;
+}
+
+function toJavaCode(val, type) {
+    if (val == null)
+       return 'null';
+
+    if (type == 'float')
+        return val + 'f';
+    
+    if (type == 'class')
+        return val + '.class';
+    
+    if (type)
+        return type + '.' + val;
+    
+    if (typeof(val) == 'string')
+        return '"' + val.replace('"', '\\"') + '"';
+
+    if (typeof(val) == 'number' || typeof(val) == 'boolean')
+        return '' + val;
+
+    throw "Unknown type: " + typeof(val) + ' (' + val + ')';
+}
+
+function addProperty(res, obj, objVariableName, propName, enumType, setterName) {
+    var val = obj[propName];
+    
+    if (val) {
+        res.emptyLineIfNeeded();
+
+        res.line(objVariableName + '.' + getSetterName(setterName ? setterName : propName)
+            + '(' + toJavaCode(val, enumType)  + ');');
+    }
+}
+
+function getSetterName(propName) {
+    return 'set' + propName.charAt(0).toLocaleUpperCase() + propName.slice(1);
+}
+
+function addListProperty(res, obj, objVariableName, propName, enumType, setterName) {
+    var val = obj[propName];
+    
+    if (val && val.length > 0) {
+        res.append(objVariableName + '.' + getSetterName(setterName ? setterName : propName) + '(Arrays.asList(');
+
+        for (var i = 0; i < val.length; i++) {
+            if (i > 0)
+                res.append(', ');
+            
+            res.append(toJavaCode(val[i], enumType));
+        }
+        
+        res.line('));');
+    }
+}
+
+function addMultiparamProperty(res, obj, objVariableName, propName, type, setterName) {
+    var val = obj[propName];
+    
+    if (val && val.length > 0) {
+        res.append(objVariableName + '.' + getSetterName(setterName ? setterName : propName) + '(');
+
+        for (var i = 0; i < val.length; i++) {
+            if (i > 0)
+                res.append(', ');
+            
+            res.append(toJavaCode(val[i], type));
+        }
+        
+        res.line(');');
+    }
+}
+
+function addBeanWithProperties(res, bean, objVarName, beanPropName, beanVarName, beanClass, props, createBeanAlthoughNoProps) {
+    if (!bean)
+        return;
+    
+    if (generatorUtils.hasProperty(bean, props)) {
+        if (!res.emptyLineIfNeeded()) {
+            res.line();
+        }
+        
+        res.line(beanClass + ' ' + beanVarName + ' = new ' + beanClass + '();');
+        for (var propName in props) {
+            if (props.hasOwnProperty(propName)) {
+                var descr = props[propName];
+
+                if (descr) {
+                    switch (descr.type) {
+                        case 'list':
+                            addListProperty(res, bean, beanVarName, propName, descr.elementsType, descr.setterName);
+                            break;
+                        
+                        case 'enum':
+                            addProperty(res, bean, beanVarName, propName, descr.enumClass, descr.setterName);
+                            break;
+                        
+                        case 'float':
+                            addProperty(res, bean, beanVarName, propName, 'float', descr.setterName);
+                            break;
+                        
+                        case 'propertiesAsList':
+                            var val = bean[propName];
+                            
+                            if (val && val.length > 0) {
+                                res.line('Properties ' + descr.propVarName + ' = new Properties();');
+                                
+                                for (var i = 0; i < val.length; i++) {
+                                    var nameAndValue = val[i];
+                                    
+                                    var eqIndex = nameAndValue.indexOf('=');
+                                    if (eqIndex >= 0) {
+                                        res.line(descr.propVarName + '.setProperty(' 
+                                            + nameAndValue.substring(0, eqIndex) + ', ' 
+                                            + nameAndValue.substr(eqIndex + 1) + ');');
+                                    }
+
+                                }
+                                
+                                res.line(beanVarName + '.' + getSetterName(propName) + '(' + descr.propVarName + ');');
+                            }
+                            break;
+                        
+                        case 'className':
+                            if (bean[propName]) {
+                                res.line(beanVarName + '.' + getSetterName(propName) + '(new ' + bean[propName] + '());');
+                            }
+                            break;
+                        
+                        default:
+                            addProperty(res, bean, beanVarName, propName, null, descr.setterName);
+                    }
+                }
+                else {
+                    addProperty(res, bean, beanVarName, propName);
+                }
+            }
+        }
+        
+        res.line(objVarName + '.' + getSetterName(beanPropName) + '(' + beanVarName + ');');
+        
+        res.needEmptyLine = true;
+    }
+    else if (createBeanAlthoughNoProps) {
+        res.emptyLineIfNeeded();
+        
+        res.line(objVarName + '.' + getSetterName(beanPropName) + '(new ' + beanClass + '());');
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/utils/generatorUtils.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/utils/generatorUtils.js b/modules/web-control-center/nodejs/utils/generatorUtils.js
new file mode 100644
index 0000000..82df5bb
--- /dev/null
+++ b/modules/web-control-center/nodejs/utils/generatorUtils.js
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+exports.mainComment = function() {
+    return 'This configuration was generated by automatically by Ignite (' 
+        + formatDate(new Date()) + ')';
+};
+
+function addLeadingZero(numberStr, minSize) {
+    if (typeof (numberStr) != 'string')
+        numberStr = '' + numberStr;
+    
+    while (numberStr.length < minSize) {
+        numberStr = '0' + numberStr;
+    }
+    
+    return numberStr;
+}
+
+exports.formatDate = formatDate;
+
+function formatDate(date) {
+    var dd = addLeadingZero(date.getDate(), 2);
+    var mm = addLeadingZero(date.getMonth() + 1, 2);
+    
+    var yyyy = date.getFullYear();
+
+    return mm + '/' + dd + '/' + yyyy + ' ' + addLeadingZero(date.getHours(), 2) + ':' + addLeadingZero(date.getMinutes(), 2);
+}
+
+exports.builder = function () {
+    var res = [];
+
+    res.deep = 0;
+    res.lineStart = true;
+
+    res.append = function(s) {
+        if (this.lineStart) {
+            for (var i = 0; i < this.deep; i++)
+                this.push('    ');
+
+            this.lineStart = false;
+        }
+
+        this.push(s);
+
+        return this;
+    };
+
+    res.line = function(s) {
+        if (s)
+            this.append(s);
+
+        this.push('\n');
+        this.lineStart = true;
+
+        return this;
+    };
+
+    res.startBlock = function(s) {
+        if (s)
+            this.append(s);
+
+        this.push('\n');
+        this.lineStart = true;
+        this.deep++;
+
+        return this;
+    };
+
+    res.endBlock = function(s) {
+        this.deep--;
+
+        if (s)
+            this.append(s);
+
+        this.push('\n');
+        this.lineStart = true;
+
+        return this;
+    };
+
+    res.emptyLineIfNeeded = function() {
+        if (this.needEmptyLine) {
+            this.line();
+
+            this.needEmptyLine = false;
+            
+            return true;
+        }
+
+        return false;
+    };
+
+    res.imports = {};
+    
+    res.importClass = function(fullClassName) {
+        var dotIdx = fullClassName.lastIndexOf('.');
+        
+        var shortName;
+        
+        if (dotIdx > 0)
+            shortName = fullClassName.substr(dotIdx + 1);
+        else 
+            shortName = fullClassName;
+        
+        if (this.imports[shortName]) {
+            if (this.imports[shortName] != fullClassName)
+                throw "Class name conflict: " + this.imports[shortName] + ' and ' + fullClassName;
+        }
+        else {
+            this.imports[shortName] = fullClassName;
+        }
+        
+        return shortName;
+    };
+    
+    res.generateImports = function() {
+        var res = [];
+        
+        for (var clsName in this.imports) {
+            if (this.imports.hasOwnProperty(clsName))
+                res.push('import ' + this.imports[clsName] + ';');
+        }
+        
+        return res.join('\n')
+    };
+    
+    return res;
+};
+
+function ClassDescriptor(className, fields) {
+    this.className = className;
+
+    this.fields = fields;
+}
+
+exports.evictionPolicies = {
+    'LRU': new ClassDescriptor('org.apache.ignite.cache.eviction.lru.LruEvictionPolicy',
+        {batchSize: null, maxMemorySize: null, maxSize: null}),
+    'RND': new ClassDescriptor('org.apache.ignite.cache.eviction.random.RandomEvictionPolicy', {maxSize: null}),
+    'FIFO': new ClassDescriptor('org.apache.ignite.cache.eviction.fifo.FifoEvictionPolicy',
+        {batchSize: null, maxMemorySize: null, maxSize: null}),
+    'SORTED': new ClassDescriptor('org.apache.ignite.cache.eviction.sorted.SortedEvictionPolicy',
+        {batchSize: null, maxMemorySize: null, maxSize: null})
+};
+
+exports.knownClasses = {
+    
+    
+    OracleDialect: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.OracleDialect', {}),
+    BasicJdbcDialect: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.BasicJdbcDialect', {}),
+    DB2Dialect: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.DB2Dialect', {}),
+    SQLServerDialect: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.SQLServerDialect', {}),
+    MySQLDialect: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.MySQLDialect', {}),
+    H2Dialect: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.H2Dialect', {})
+};
+
+exports.storeFactories = {
+    CacheJdbcPojoStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory', {
+        dataSourceBean: null,
+        dialect: {type: 'className'}
+    }),
+
+    CacheJdbcBlobStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStoreFactory', {
+        user: null,
+        dataSourceBean: null,
+        initSchema: null,
+        createTableQuery: null,
+        loadQuery: null,
+        insertQuery: null,
+        updateQuery: null,
+        deleteQuery: null
+    }),
+
+    CacheHibernateBlobStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.hibernate.CacheHibernateBlobStoreFactory', {
+        hibernateProperties: {type: 'propertiesAsList', propVarName: 'props'}
+    })
+};
+
+exports.atomicConfiguration = new ClassDescriptor('org.apache.ignite.configuration.AtomicConfiguration', {
+    backups: null,
+    cacheMode: {type: 'enum', enumClass: 'CacheMode'},
+    atomicSequenceReserveSize: null
+});
+
+exports.swapSpaceSpi = new ClassDescriptor('org.apache.ignite.spi.swapspace.file.FileSwapSpaceSpi', {
+    baseDirectory: null,
+    readStripesNumber: null,
+    maximumSparsity: {type: 'float'},
+    maxWriteQueueSize: null,
+    writeBufferSize: null
+});
+
+exports.transactionConfiguration = new ClassDescriptor('org.apache.ignite.configuration.TransactionConfiguration', {
+    defaultTxConcurrency: {type: 'enum', enumClass: 'TransactionConcurrency'},
+    transactionIsolation: {type: 'TransactionIsolation', setterName: 'defaultTxIsolation'},
+    defaultTxTimeout: null,
+    pessimisticTxLogLinger: null,
+    pessimisticTxLogSize: null,
+    txSerializableEnabled: null
+});
+
+exports.hasProperty = function(obj, props) {
+    for (var propName in props) {
+        if (props.hasOwnProperty(propName)) {
+            if (obj[propName])
+                return true;
+        }
+    }
+
+    return false;
+};
\ No newline at end of file